Hide menu
Loading...
Searching...
No Matches
MTKConverter/MTKConverter.java
Refer to the MTK Converter Example.

MTKConverter_PartProcessor.java

// ****************************************************************************
//
// Copyright (C) 2008-2014, Roman Lygin. All rights reserved.
// Copyright (C) 2014-2026, CADEX. All rights reserved.
//
// This file is part of the Manufacturing Toolkit software.
//
// You may use this file under the terms of the BSD license as follows:
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// ****************************************************************************
import cadex.*;
import cadex.Drawing.*;
import cadex.ModelData.*;
import java.util.ArrayList;
class MTKConverter_ProcessData {
protected MTKConverter_ProcessData(Part thePart) {
myPart = thePart;
mySourceSheets = new ArrayList<Sheet>();
}
protected MTKConverter_ProcessData(ArrayList<Sheet> theSheets) {
myPart = new Part(new UTF16String(""));
mySourceSheets = theSheets;
}
public Part myPart;
public ArrayList<Sheet> mySourceSheets;
}
abstract class MTKConverter_PartProcessor extends ModelElementVoidVisitor {
protected MTKConverter_PartProcessor() {
myData = new ArrayList<MTKConverter_ProcessData>();
}
@Override
public void Apply(Part thePart) {
boolean aPartWasProcessed = false;
MTKConverter_ProcessData aProcessData = CreateProcessData(thePart);
for (Body aBody : thePart.Bodies()) {
if (MeshBody.CompareType(aBody)) {
if (ProcessMeshBody(aProcessData, MeshBody.Cast(aBody))) {
aPartWasProcessed = true;
}
} else if (ProcessBRepBody(aProcessData, aBody)) {
aPartWasProcessed = true;
}
}
if (aPartWasProcessed) {
PostProcessPart(thePart);
myData.add(aProcessData);
}
}
private boolean ProcessBRepBody(MTKConverter_ProcessData theProcessData, Body theBody) {
boolean aBodyWasProcessed = false;
ShapeIterator aShapeIt = new ShapeIterator(theBody);
while (aShapeIt.HasNext()) {
Shape aShape = aShapeIt.Next();
if (aShape.Type() == ShapeType.Solid) {
ProcessSolid(theProcessData, Solid.Cast(aShape));
aBodyWasProcessed = true;
} else if (aShape.Type() == ShapeType.Shell) {
ProcessShell(theProcessData, Shell.Cast(aShape));
aBodyWasProcessed = true;
}
}
return aBodyWasProcessed;
}
private boolean ProcessMeshBody(MTKConverter_ProcessData theProcessData, MeshBody theBody) {
boolean aBodyWasProcessed = false;
for (MeshShape aMeshShape : theBody.Shapes()) {
if (IndexedTriangleSet.CompareType(aMeshShape)) {
ProcessMesh(theProcessData, IndexedTriangleSet.Cast(aMeshShape));
aBodyWasProcessed = true;
}
}
return aBodyWasProcessed;
}
public abstract MTKConverter_ProcessData CreateProcessData(Part thePart);
public abstract void ProcessSolid(MTKConverter_ProcessData theProcessData, Solid theSolid);
public abstract void ProcessShell(MTKConverter_ProcessData theProcessData, Shell theShell);
public abstract void ProcessMesh(MTKConverter_ProcessData theProcessData, IndexedTriangleSet theMesh);
public abstract void PostProcessPart(Part thePart);
public ArrayList<MTKConverter_ProcessData> myData;
}
abstract class MTKConverter_VoidPartProcessor extends MTKConverter_PartProcessor {
public MTKConverter_VoidPartProcessor() {
super();
}
@Override
public void ProcessSolid(MTKConverter_ProcessData theProcessData, Solid theSolid) {
}
@Override
public void ProcessShell(MTKConverter_ProcessData theProcessData, Shell theShell) {
}
@Override
public void ProcessMesh(MTKConverter_ProcessData theProcessData, IndexedTriangleSet theMesh) {
}
@Override
public void PostProcessPart(Part thePart) {
}
}
Contains classes, types and enums related to drawings.
Defines classes, types, enums, and functions related to topological entities and scene graph elements...
Contains classes, namespaces, enums, types, and global functions related to Manufacturing Toolkit.

MTKConverter_DrawingProcessor.java

// ****************************************************************************
//
// Copyright (C) 2008-2014, Roman Lygin. All rights reserved.
// Copyright (C) 2014-2026, CADEX. All rights reserved.
//
// This file is part of the Manufacturing Toolkit software.
//
// You may use this file under the terms of the BSD license as follows:
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// ****************************************************************************
import cadex.Drawing.*;
import java.util.ArrayList;
abstract class MTKConverter_DrawingProcessor {
protected MTKConverter_DrawingProcessor() {
myData = new ArrayList<MTKConverter_ProcessData>();
}
public abstract boolean Apply(Drawing theDrawing);
public static ArrayList<Sheet> ExtractDrawingSheets(Drawing theDrawing) {
ArrayList<Sheet> aSheets = new ArrayList<Sheet>();
Drawing.SheetIterator aSheetIt = new Drawing.SheetIterator(theDrawing);
while (aSheetIt.HasNext()) {
aSheets.add(aSheetIt.Next());
}
return aSheets;
}
public static Drawing AddSheets(Drawing theSrc, Drawing theDst) {
if (theSrc == null) {
return theDst;
}
if (theDst == null) {
return theSrc;
}
Drawing.SheetIterator anIt = new Drawing.SheetIterator(theSrc);
while (anIt.HasNext()) {
theDst.AddSheet(anIt.Next());
}
return theDst;
}
public ArrayList<MTKConverter_ProcessData> myData;
}

MTKConverter_MachiningProcessor.java

// ****************************************************************************
//
// Copyright (C) 2008-2014, Roman Lygin. All rights reserved.
// Copyright (C) 2014-2026, CADEX. All rights reserved.
//
// This file is part of the Manufacturing Toolkit software.
//
// You may use this file under the terms of the BSD license as follows:
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// ****************************************************************************
import cadex.*;
import cadex.ModelData.*;
class MTKConverter_MachiningData extends MTKConverter_ProcessData {
public MTKConverter_MachiningData(Part thePart) {
super(thePart);
myFeatureList = new MTKBase_FeatureList();
myIssueList = new MTKBase_FeatureList();
}
public MTKBase_FeatureList myFeatureList;
public MTKBase_FeatureList myIssueList;
public Machining_OperationType myOperation;
}
class MTKConverter_MachiningProcessor extends MTKConverter_VoidPartProcessor {
public MTKConverter_MachiningProcessor(Machining_OperationType theOperation) {
super();
myOperation = theOperation;
}
public MTKConverter_ProcessData CreateProcessData(Part thePart) {
return new MTKConverter_MachiningData(thePart);
}
public void ProcessSolid(MTKConverter_ProcessData theProcessData, Solid theSolid) {
MTKConverter_MachiningData aMachiningData = (MTKConverter_MachiningData) theProcessData;
aMachiningData.myOperation = myOperation;
Machining_FeatureRecognizer aFeatureRecognizer = new Machining_FeatureRecognizer();
aFeatureRecognizer.Parameters().SetOperation(myOperation);
Machining_Analyzer anAnalyzer = new Machining_Analyzer();
anAnalyzer.AddTool(aFeatureRecognizer);
Machining_Data aData = anAnalyzer.Perform(theSolid);
if (aData.IsEmpty()) {
return;
}
//features
aMachiningData.myFeatureList.Append(aData.FeatureList());
//issues
DFMMachining_DrillingAnalyzerParameters aDrillingParameters = new DFMMachining_DrillingAnalyzerParameters();
DFMMachining_Analyzer aDrillingAnalyzer = new DFMMachining_Analyzer(aDrillingParameters);
aMachiningData.myIssueList.Append(aDrillingAnalyzer.Perform(theSolid, aData));
DFMMachining_MillingAnalyzerParameters aMillingParameters = new DFMMachining_MillingAnalyzerParameters();
DFMMachining_Analyzer aMillingAnalyzer = new DFMMachining_Analyzer(aMillingParameters);
MTKBase_FeatureList aMillingIssueList = aMillingAnalyzer.Perform(theSolid, aData);
for (long i = 0; i < aMillingIssueList.Size(); ++i) {
MTKBase_Feature anIssue = aMillingIssueList.Feature(i);
if (myOperation == Machining_OperationType.Machining_OT_LatheMilling
&& !DFMMachining_DeepPocketIssue.CompareType(anIssue)) {
continue;
}
aMachiningData.myIssueList.Append(anIssue);
}
if (myOperation == Machining_OperationType.Machining_OT_LatheMilling) {
DFMMachining_TurningAnalyzerParameters aTurninigParameters = new DFMMachining_TurningAnalyzerParameters();
DFMMachining_Analyzer aTurningAnalyzer = new DFMMachining_Analyzer(aTurninigParameters);
MTKBase_FeatureList aTurningIssueList = aTurningAnalyzer.Perform(theSolid, aData);
for (long i = 0; i < aTurningIssueList.Size(); ++i) {
MTKBase_Feature anIssue = aTurningIssueList.Feature(i);
aMachiningData.myIssueList.Append(anIssue);
}
}
}
private Machining_OperationType myOperation;
}

MTKConverter_MoldingProcessor.java

// ****************************************************************************
//
// Copyright (C) 2008-2014, Roman Lygin. All rights reserved.
// Copyright (C) 2014-2026, CADEX. All rights reserved.
//
// This file is part of the Manufacturing Toolkit software.
//
// You may use this file under the terms of the BSD license as follows:
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// ****************************************************************************
import cadex.*;
import cadex.ModelData.*;
import java.util.HashSet;
class MTKConverter_MoldingData extends MTKConverter_ProcessData {
public MTKConverter_MoldingData(Part thePart) {
super(thePart);
myFeatureList = new MTKBase_FeatureList();
myIssueList = new MTKBase_FeatureList();
}
public MTKBase_FeatureList myFeatureList;
public MTKBase_FeatureList myIssueList;
}
class MTKConverter_MoldingProcessor extends MTKConverter_VoidPartProcessor {
public MTKConverter_MoldingProcessor(Model theExtraDataModel) {
super();
myExtraDataModel = theExtraDataModel;
myCurrentNewFaces = new SheetBody();
}
public MTKConverter_ProcessData CreateProcessData(Part thePart) {
return new MTKConverter_MoldingData(thePart);
}
public void ProcessSolid(MTKConverter_ProcessData theProcessData, Solid theSolid) {
MTKConverter_MoldingData aMoldingData = (MTKConverter_MoldingData) theProcessData;
Molding_FeatureRecognizer aFeatureRecognizer = new Molding_FeatureRecognizer();
Molding_Analyzer anAnalyzer = new Molding_Analyzer();
anAnalyzer.AddTool(aFeatureRecognizer);
Molding_Data aData = anAnalyzer.Perform(theSolid);
if (aData.IsEmpty()) {
return;
}
//features
cadex.MTKBase_FeatureList aFeatureList = aData.FeatureList();
AddNewFacesFromFeatures(aFeatureList, theSolid);
aMoldingData.myFeatureList.Append(aFeatureList);
//issues
DFMMolding_AnalyzerParameters aParameters = new DFMMolding_AnalyzerParameters();
DFMMolding_Analyzer aAnalyzer = new DFMMolding_Analyzer(aParameters);
aMoldingData.myIssueList.Append(aAnalyzer.Perform(aData));
}
public void PostProcessPart(Part thePart) {
if (myCurrentNewFaces.Shapes().isEmpty()) {
return;
}
Part anExtraDataPart = new Part(thePart.Name());
anExtraDataPart.AddBody(myCurrentNewFaces);
anExtraDataPart.SetUuid(thePart.Uuid());
myExtraDataModel.AddRoot(anExtraDataPart);
myCurrentNewFaces = new SheetBody();
}
private void AddNewFacesFromFeatures(MTKBase_FeatureList theFeatureList, Solid theSolid) {
HashSet<java.math.BigInteger> aFaceIdSet = new HashSet<java.math.BigInteger>();
{
ShapeIterator aFaceIt = new ShapeIterator(theSolid, ShapeType.Face);
while (aFaceIt.HasNext()) {
Shape aFace = aFaceIt.Next();
aFaceIdSet.add(aFace.Id());
}
}
for (long i = 0; i < theFeatureList.Size(); ++i) {
MTKBase_ShapeFeature aFeature = MTKBase_ShapeFeature.Cast(theFeatureList.Feature(i));
ShapeIterator aFaceIt = new ShapeIterator(aFeature.Shape(), ShapeType.Face);
while (aFaceIt.HasNext()) {
Shape aFace = aFaceIt.Next();
if (!aFaceIdSet.contains(aFace.Id())) {
myCurrentNewFaces.Append(Face.Cast(aFace));
}
}
}
}
private Model myExtraDataModel;
private SheetBody myCurrentNewFaces;
}

MTKConverter_SheetMetalProcessor.java

// ****************************************************************************
//
// Copyright (C) 2008-2014, Roman Lygin. All rights reserved.
// Copyright (C) 2014-2026, CADEX. All rights reserved.
//
// This file is part of the Manufacturing Toolkit software.
//
// You may use this file under the terms of the BSD license as follows:
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// ****************************************************************************
import cadex.*;
import cadex.Drawing.*;
import cadex.ModelData.*;
import java.util.ArrayList;
class MTKConverter_UnfoldedPartData {
public MTKConverter_UnfoldedPartData() {
myFlatPatterns = new ArrayList<SheetMetal_FlatPattern>();
myIssueList = new MTKBase_FeatureList();
}
public boolean IsInit() {
return !myFlatPatterns.isEmpty();
}
public ArrayList<SheetMetal_FlatPattern> myFlatPatterns;
public MTKBase_FeatureList myIssueList;
}
class MTKConverter_SheetMetalData extends MTKConverter_ProcessData {
public MTKConverter_SheetMetalData(Part thePart) {
super(thePart);
myFeatureList = new MTKBase_FeatureList();
myIssueList = new MTKBase_FeatureList();
myUnfoldedPartData = new MTKConverter_UnfoldedPartData();
}
public boolean myIsSheetMetalPart = false;
public MTKBase_FeatureList myFeatureList;
public MTKBase_FeatureList myIssueList;
public MTKConverter_UnfoldedPartData myUnfoldedPartData;
}
class MTKConverter_SheetMetalProcessor extends MTKConverter_VoidPartProcessor {
public MTKConverter_SheetMetalProcessor(Model theUnfoldedModel) {
super();
myAnalyzer = new SheetMetal_Analyzer();
myAnalyzer.AddTool(new SheetMetal_FeatureRecognizer());
myAnalyzer.AddTool(new SheetMetal_Unfolder());
myUnfoldedModel = theUnfoldedModel;
myCurrentUnfoldedBody = new SheetBody();
}
@Override
public MTKConverter_ProcessData CreateProcessData(Part thePart) {
return new MTKConverter_SheetMetalData(thePart);
}
@Override
public void ProcessSolid(MTKConverter_ProcessData theProcessData, Solid theSolid) {
SheetMetal_Data anSMData = myAnalyzer.Perform(theSolid);
Process(theProcessData, anSMData);
}
@Override
public void ProcessShell(MTKConverter_ProcessData theProcessData, Shell theShell) {
SheetMetal_Data anSMData = myAnalyzer.Perform(theShell);
Process(theProcessData, anSMData);
}
@Override
public void PostProcessPart(Part thePart) {
if (myCurrentUnfoldedBody.Shapes().isEmpty()) {
return;
}
Part anUnfoldedPart = new Part(thePart.Name());
anUnfoldedPart.SetUuid(thePart.Uuid());
anUnfoldedPart.AddBody(myCurrentUnfoldedBody);
myUnfoldedModel.AddRoot(anUnfoldedPart);
myCurrentUnfoldedBody = new SheetBody();
}
public void Process(MTKConverter_ProcessData theProcessData, SheetMetal_Data theData) {
if (theData.IsEmpty()) {
return;
}
MTKConverter_SheetMetalData anSMData = (MTKConverter_SheetMetalData) theProcessData;
anSMData.myIsSheetMetalPart = true;
anSMData.myFeatureList.Append(theData.FeatureList());
SheetMetal_FlatPattern aFlatPattern = theData.FlatPattern();
Shell anUnfoldedShell = aFlatPattern != null ? aFlatPattern.UnfoldedShell() : null;
MTKConverter_UnfoldedPartData anUnfoldedData = anSMData.myUnfoldedPartData;
if (anUnfoldedShell != null) {
myCurrentUnfoldedBody.Append(anUnfoldedShell);
anUnfoldedData.myFlatPatterns.add(aFlatPattern);
SheetMetal_FlatPattern.DrawingParameters aDrawingParams = new SheetMetal_FlatPattern.DrawingParameters();
aDrawingParams.SetIsIgnoreBendingLines(true);
Drawing aFlatPatternDrawing = aFlatPattern.ToDrawing(aDrawingParams);
if (aFlatPatternDrawing != null) {
Drawing.SheetIterator aSheetIt = new Drawing.SheetIterator(aFlatPatternDrawing);
while (aSheetIt.HasNext()) {
Sheet aSheet = aSheetIt.Next();
aSheet.SetUuid(anSMData.myPart.Uuid());
}
Drawing aDrawing = myUnfoldedModel.Drawing();
if (aDrawing == null) {
myUnfoldedModel.SetDrawing(aFlatPatternDrawing);
} else {
aDrawing = MTKConverter_DrawingProcessor.AddSheets(aFlatPatternDrawing, aDrawing);
myUnfoldedModel.SetDrawing(aDrawing);
}
}
}
DFMSheetMetal_Analyzer aDFMAnalyzer = new DFMSheetMetal_Analyzer();
MTKBase_FeatureList anIssueList = aDFMAnalyzer.Perform(theData);
for (long i = 0; i < anIssueList.Size(); ++i) {
MTKBase_Feature anIssue = anIssueList.Feature(i);
if (anUnfoldedData.IsInit() &&
(DFMSheetMetal_FlatPatternInterferenceIssue.CompareType(anIssue) ||
DFMSheetMetal_NonStandardSheetSizeIssue.CompareType(anIssue) ||
DFMSheetMetal_NonStandardSheetThicknessIssue.CompareType(anIssue))) {
anUnfoldedData.myIssueList.Append(anIssue);
} else {
anSMData.myIssueList.Append(anIssue);
}
}
}
private SheetMetal_Analyzer myAnalyzer;
private Model myUnfoldedModel;
private SheetBody myCurrentUnfoldedBody;
}

MTKConverter_NestingProcessor.java

// ****************************************************************************
//
// Copyright (C) 2008-2014, Roman Lygin. All rights reserved.
// Copyright (C) 2014-2026, CADEX. All rights reserved.
//
// This file is part of the Manufacturing Toolkit software.
//
// You may use this file under the terms of the BSD license as follows:
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// ****************************************************************************
import cadex.*;
import cadex.Drawing.*;
import cadex.Geom.*;
import cadex.ModelData.*;
import java.util.ArrayList;
import java.util.UUID;
class MTKConverter_NestingData extends MTKConverter_ProcessData {
public MTKConverter_NestingData(ArrayList<Sheet> theSheets) {
super(theSheets);
myPatterns = new ArrayList<View>();
myResultDrawing = new Drawing(new BaseObject.Initialized());
myNestingResult = new Nesting_Data();
}
public ArrayList<View> myPatterns;
public Drawing myResultDrawing;
public long myPatternCountTotal = 0;
public Nesting_Data myNestingResult;
}
class MTKConverter_NestingProcessor extends MTKConverter_DrawingProcessor {
private static ArrayList<View> ExtractPatternViews(Sheet theSheet) {
ArrayList<View> aPatterns = new ArrayList<View>();
Sheet.ViewIterator aViewIt = new Sheet.ViewIterator(theSheet);
while (aViewIt.HasNext()) {
aPatterns.add(aViewIt.Next());
}
return aPatterns;
}
private static void AssignSheetUuids(Drawing theDrawing) {
Drawing.SheetIterator aSheetIt = new Drawing.SheetIterator(theDrawing);
while (aSheetIt.HasNext()) {
Sheet aSheet = aSheetIt.Next();
aSheet.SetUuid(UUID.randomUUID());
}
}
private static Line2d MakeTrimmedLine(Point2d theStart, Point2d theEnd) {
double aDx = theEnd.X() - theStart.X();
double aDy = theEnd.Y() - theStart.Y();
double aLength = Math.sqrt(aDx * aDx + aDy * aDy);
Line2d aLine = new Line2d(theStart, new Direction2d(aDx, aDy));
aLine.SetTrim(0.0, aLength);
return aLine;
}
private static void AddNestingSheetFrames(Drawing theDrawing) {
Drawing.SheetIterator aSheetIt = new Drawing.SheetIterator(theDrawing);
while (aSheetIt.HasNext()) {
Sheet aSheet = aSheetIt.Next();
double aWidth = aSheet.Width();
double aHeight = aSheet.Height();
Point2d aP1 = new Point2d(0.0, 0.0);
Point2d aP2 = new Point2d(aWidth, 0.0);
Point2d aP3 = new Point2d(aWidth, aHeight);
Point2d aP4 = new Point2d(0.0, aHeight);
PiecewiseContour aFrameContour = new PiecewiseContour();
aFrameContour.AddCurve(MakeTrimmedLine(aP1, aP2));
aFrameContour.AddCurve(MakeTrimmedLine(aP2, aP3));
aFrameContour.AddCurve(MakeTrimmedLine(aP3, aP4));
aFrameContour.AddCurve(MakeTrimmedLine(aP4, aP1));
View aFrameView = new View(new BaseObject.Initialized());
aFrameView.Add(aFrameContour);
aSheet.AddView(aFrameView);
}
}
public MTKConverter_NestingProcessor(
Model theProcessModel,
MTKConverter_NestingParameters theNestingParameters) {
myProcessModel = theProcessModel;
myNestingParameters = theNestingParameters;
}
private MTKConverter_NestingData CreateProcessData(ArrayList<Sheet> theSheets) {
return new MTKConverter_NestingData(theSheets);
}
private void Process(MTKConverter_NestingData theNestingData) {
Nesting_Computer aComputer = new Nesting_Computer();
aComputer.SetParameters(myNestingParameters.myComputerParameters);
aComputer.AddMaterial(
myNestingParameters.myMaterialParameters.myLength,
myNestingParameters.myMaterialParameters.myWidth,
myNestingParameters.myMaterialParameters.myCount);
theNestingData.myPatternCountTotal =
theNestingData.myPatterns.size() * myNestingParameters.myPatternRepeatCount;
for (View aPattern : theNestingData.myPatterns) {
aComputer.AddPattern(aPattern, myNestingParameters.myPatternRepeatCount);
}
theNestingData.myNestingResult = aComputer.Perform();
}
private boolean ProcessAllSheets(ArrayList<Sheet> theSourceSheets) {
MTKConverter_NestingData aNestingData = CreateProcessData(theSourceSheets);
for (Sheet aSourceSheet : theSourceSheets) {
ArrayList<View> aSheetPatterns = ExtractPatternViews(aSourceSheet);
aNestingData.myPatterns.addAll(aSheetPatterns);
}
Process(aNestingData);
Drawing aResultNestingDrawing = aNestingData.myNestingResult.ToDrawing();
if (aResultNestingDrawing != null) {
AddNestingSheetFrames(aResultNestingDrawing);
AssignSheetUuids(aResultNestingDrawing);
aNestingData.myResultDrawing = aResultNestingDrawing;
}
myProcessModel.SetDrawing(aResultNestingDrawing);
myData.add(aNestingData);
return true;
}
private boolean ProcessPerSheet(ArrayList<Sheet> theSourceSheets) {
Drawing aResultNestingDrawing = new Drawing(new BaseObject.Initialized());
for (Sheet aSourceSheet : theSourceSheets) {
ArrayList<Sheet> aSingleSheet = new ArrayList<Sheet>();
aSingleSheet.add(aSourceSheet);
MTKConverter_NestingData aNestingData = CreateProcessData(aSingleSheet);
aNestingData.myPatterns = ExtractPatternViews(aSourceSheet);
Process(aNestingData);
Drawing aSourceNestingDrawing = aNestingData.myNestingResult.ToDrawing();
if (aSourceNestingDrawing != null) {
AddNestingSheetFrames(aSourceNestingDrawing);
AssignSheetUuids(aSourceNestingDrawing);
aNestingData.myResultDrawing = aSourceNestingDrawing;
aResultNestingDrawing = MTKConverter_DrawingProcessor.AddSheets(aSourceNestingDrawing, aResultNestingDrawing);
}
myData.add(aNestingData);
}
myProcessModel.SetDrawing(aResultNestingDrawing);
return true;
}
@Override
public boolean Apply(Drawing theDrawing) {
myData.clear();
ArrayList<Sheet> aSourceSheets = MTKConverter_DrawingProcessor.ExtractDrawingSheets(theDrawing);
if (aSourceSheets.isEmpty()) {
System.out.println("\nERROR: Nesting requires at least one sheet in the source drawing.");
return false;
}
if (myNestingParameters.myMode == MTKConverter_NestingParameters.NestingMode.AllSheets) {
return ProcessAllSheets(aSourceSheets);
}
return ProcessPerSheet(aSourceSheets);
}
private Model myProcessModel;
private MTKConverter_NestingParameters myNestingParameters;
}
Contains classes, types, enums, and functions related to geometric entities.

MTKConverter_WallThicknessProcessor.java

// ****************************************************************************
//
// Copyright (C) 2008-2014, Roman Lygin. All rights reserved.
// Copyright (C) 2014-2026, CADEX. All rights reserved.
//
// This file is part of the Manufacturing Toolkit software.
//
// You may use this file under the terms of the BSD license as follows:
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// ****************************************************************************
import cadex.*;
import cadex.ModelAlgo.MeshGenerator;
import cadex.ModelData.*;
class PointPair {
public PointPair() {
First = new cadex.Geom.Point();
Second = new cadex.Geom.Point();
}
public PointPair(cadex.Geom.Point theFirst, cadex.Geom.Point theSecond) {
First = theFirst;
Second = theSecond;
}
public cadex.Geom.Point First;
public cadex.Geom.Point Second;
}
class MTKConverter_WallThicknessData extends MTKConverter_ProcessData {
public MTKConverter_WallThicknessData(Part thePart) {
super(thePart);
}
public boolean myIsInit = false;
public double myMinThickness = Double.POSITIVE_INFINITY;
public double myMaxThickness = Double.NEGATIVE_INFINITY;
public double myAvgThickness = 0.0;
public long myThicknessPointCount = 0;
public PointPair myMinThicknessPoints = new PointPair();
public PointPair myMaxThicknessPoints = new PointPair();
}
class MTKConverter_WallThicknessProcessor extends MTKConverter_VoidPartProcessor {
public MTKConverter_WallThicknessProcessor(
Model theExtraDataModel,
MTKConverter_WallThicknessParameters theWallThicknessParameters) {
super();
myAnalyzer = new WallThickness_Analyzer(theWallThicknessParameters.myAnalyzerParameters);
myExtraDataModel = theExtraDataModel;
myColorizer = new MeshColorizer(theWallThicknessParameters.myColorSmoothness);
}
@Override
public MTKConverter_ProcessData CreateProcessData(Part thePart) {
return new MTKConverter_WallThicknessData(thePart);
}
private void ProcessResult(MTKConverter_ProcessData theProcessData, IndexedTriangleSet theMesh, WallThickness_Data theResult) {
if (theResult.IsEmpty()) {
return;
}
MTKConverter_WallThicknessData aWTData = (MTKConverter_WallThicknessData) theProcessData;
aWTData.myIsInit = true;
if (aWTData.myMinThickness > theResult.MinThickness()) {
aWTData.myMinThickness = theResult.MinThickness();
cadex.Geom.Point aFirstPoint = new cadex.Geom.Point();
cadex.Geom.Point aSecondPoint = new cadex.Geom.Point();
theResult.PointsOfMinThickness(aFirstPoint, aSecondPoint);
aWTData.myMinThicknessPoints = new PointPair(aFirstPoint, aSecondPoint);
}
if (aWTData.myMaxThickness < theResult.MaxThickness()) {
aWTData.myMaxThickness = theResult.MaxThickness();
cadex.Geom.Point aFirstPoint = new cadex.Geom.Point();
cadex.Geom.Point aSecondPoint = new cadex.Geom.Point();
theResult.PointsOfMaxThickness(aFirstPoint, aSecondPoint);
aWTData.myMaxThicknessPoints = new PointPair(aFirstPoint, aSecondPoint);
}
double aThicknessSum = 0.0;
MTKBase_DoubleList aThicknessList = theResult.ThicknessList();
if (!aThicknessList.IsEmpty()) {
long aThicknessListSize = aThicknessList.Size();
for (long i = 0; i < aThicknessListSize; ++i) {
aThicknessSum += aThicknessList.Value(i);
}
long aPrevThicknessPointCount = aWTData.myThicknessPointCount;
long aTotalThicknessPointCount = aPrevThicknessPointCount + aThicknessListSize;
aWTData.myAvgThickness =
aWTData.myAvgThickness * ((double)aPrevThicknessPointCount / aTotalThicknessPointCount)
+ aThicknessSum / aTotalThicknessPointCount;
aWTData.myThicknessPointCount = aTotalThicknessPointCount;
}
IndexedTriangleSet aColoredITS = myColorizer.Perform(theMesh, theResult);
if (aColoredITS != null) {
if (myColoredITS != null) {
myColoredITS.AddTriangles(aColoredITS);
} else {
myColoredITS = aColoredITS;
}
}
}
@Override
public void ProcessSolid(MTKConverter_ProcessData theProcessData, Solid theSolid) {
WallThickness_Data aData = myAnalyzer.Perform(theSolid);
MeshShape aMesh = new MeshGenerator().Generate(theSolid, false);
if (aMesh != null) {
ProcessResult(theProcessData, IndexedTriangleSet.Cast(aMesh), aData);
}
}
@Override
public void ProcessMesh(MTKConverter_ProcessData theProcessData, IndexedTriangleSet theMesh) {
WallThickness_Data aData = myAnalyzer.Perform(theMesh);
ProcessResult(theProcessData, theMesh, aData);
}
@Override
public void PostProcessPart(Part thePart) {
if (myColoredITS == null) {
return;
}
Part anExtraDataPart = new Part(thePart.Name());
anExtraDataPart.SetUuid(thePart.Uuid());
MeshBody aMeshBody = new MeshBody(myColoredITS);
anExtraDataPart.AddBody(aMeshBody);
myExtraDataModel.AddRoot(anExtraDataPart);
myColoredITS = null;
}
private WallThickness_Analyzer myAnalyzer;
private Model myExtraDataModel;
private IndexedTriangleSet myColoredITS;
private MeshColorizer myColorizer;
}
Contains classes and functions related to model processing.

MTKConverter_Report.java

// ****************************************************************************
//
// Copyright (C) 2008-2014, Roman Lygin. All rights reserved.
// Copyright (C) 2014-2026, CADEX. All rights reserved.
//
// This file is part of the Manufacturing Toolkit software.
//
// You may use this file under the terms of the BSD license as follows:
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// ****************************************************************************
import cadex.*;
import cadex.Drawing.*;
import cadex.Geom.*;
import cadex.ModelData.*;
import cadex.Utilities.JSONSerializer;
import cadex.Utilities.JSONSerializerParameters;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.ArrayList;
import java.util.UUID;
class MTKConverter_Point {
public MTKConverter_Point(double theX, double theY, double theZ) {
X = theX;
Y = theY;
Z = theZ;
}
public String toString() {
return "(" + FormattedString(X) + ", " + FormattedString(Y) + ", " + FormattedString(Z) + ")";
}
private String FormattedString(double theValue) {
DecimalFormatSymbols aDFS = new DecimalFormatSymbols();
aDFS.setDecimalSeparator('.');
DecimalFormat aDF = new DecimalFormat("0.00", aDFS);
return aDF.format(theValue);
}
public double X;
public double Y;
public double Z;
}
class MTKConverter_Report {
public MTKConverter_Report() {
myData = new ArrayList<MTKConverter_ProcessData>();
}
public void AddData(MTKConverter_ProcessData theData) {
myData.add(theData);
}
private <T> void WriteParameter(JSONWriter theWriter, String theParamName, String theParamUnits, T theParamValue) {
theWriter.OpenSection();
theWriter.WriteData("name", theParamName);
theWriter.WriteData("units", theParamUnits);
theWriter.WriteData("value", theParamValue);
theWriter.CloseSection();
}
private boolean WriteFeatures(
JSONWriter theWriter,
String theGroupName,
String theSubgroupName,
MTKBase_FeatureList theFeatures,
String theMessageForEmptyList) {
theWriter.OpenSection(theSubgroupName);
theWriter.WriteData("name", theGroupName);
if (theFeatures.IsEmpty()) {
theWriter.WriteData("message", theMessageForEmptyList);
} else {
JSONSerializerParameters aParams = new JSONSerializerParameters();
aParams.SetStartIndentLevel(theWriter.NestingLevel());
JSONSerializer aJSONSerializer = new JSONSerializer(aParams);
String aFeaturesJSON = aJSONSerializer.Serialize(theFeatures);
theWriter.WriteRawData(aFeaturesJSON);
}
theWriter.CloseSection();
return true;
}
private String MachiningProcessName(Machining_OperationType theOperation) {
switch (theOperation) {
case Machining_OT_Milling:
return "CNC Machining Milling";
case Machining_OT_LatheMilling:
return "CNC Machining Lathe+Milling";
default:
break;
}
return "CNC Machining";
}
private boolean HasShapes(cadex.Collections.BodyList theBodies, ShapeType theType) {
for (Body aBody : theBodies) {
ShapeIterator aShapeIt = new ShapeIterator(aBody, theType);
if (aShapeIt.HasNext()) {
return true;
}
}
return false;
}
private void WriteThicknessNode(
JSONWriter theWriter,
String theParamName,
double theParamValue,
PointPair thePoints,
String theNodeName) {
Point aFirstPoint = thePoints.First;
Point aSecondPoint = thePoints.Second;
theWriter.OpenSection(theNodeName);
theWriter.WriteData("name", theParamName);
theWriter.WriteData("units", "mm");
theWriter.WriteData("value", theParamValue);
theWriter.WriteData("firstPoint", new MTKConverter_Point(aFirstPoint.X(), aFirstPoint.Y(), aFirstPoint.Z()));
theWriter.WriteData("secondPoint", new MTKConverter_Point(aSecondPoint.X(), aSecondPoint.Y(), aSecondPoint.Z()));
theWriter.CloseSection();
}
private void WriteWallThicknessData(JSONWriter theWriter, MTKConverter_WallThicknessData theWTData) {
WriteThicknessNode(
theWriter,
"Minimum Thickness",
theWTData.myMinThickness,
theWTData.myMinThicknessPoints,
"minThickness");
WriteThicknessNode(
theWriter,
"Maximum Thickness",
theWTData.myMaxThickness,
theWTData.myMaxThicknessPoints,
"maxThickness");
theWriter.OpenArraySection("parameters");
WriteParameter(theWriter, "Minimum Thickness", "mm", theWTData.myMinThickness);
WriteParameter(theWriter, "Maximum Thickness", "mm", theWTData.myMaxThickness);
WriteParameter(theWriter, "Average Thickness", "mm", theWTData.myAvgThickness);
theWriter.CloseArraySection();
}
private void WriteUnfoldedPartFeatures(JSONWriter theWriter, MTKConverter_UnfoldedPartData theData) {
theWriter.OpenSection("featureRecognitionUnfolded");
theWriter.WriteData("name", "Feature Recognition");
if (theData.IsInit()) {
JSONSerializerParameters aParams = new JSONSerializerParameters();
aParams.SetStartIndentLevel(4);
JSONSerializer aJSONSerializer = new JSONSerializer(aParams);
String aFeaturesJSON = aJSONSerializer.Serialize(theData.myFlatPatterns.get(0));
theWriter.WriteRawData(aFeaturesJSON);
} else {
theWriter.WriteData("message", "Unfolded part wasn't generated.");
}
theWriter.CloseSection();
}
private void WriteNestingData(
JSONWriter theWriter,
ArrayList<Sheet> theResultSheets,
ArrayList<Double> theFreeSpaces,
long thePatternCountTotal,
ArrayList<Long> theNestedPatternCounts) {
theWriter.OpenSection("nesting");
theWriter.OpenArraySection("sheets");
for (int i = 0; i < theResultSheets.size(); ++i) {
Sheet aResultSheet = theResultSheets.get(i);
double aFreeSpace = i < theFreeSpaces.size() ? theFreeSpaces.get(i) : 0.0;
long aNestedPatternCount = i < theNestedPatternCounts.size() ? theNestedPatternCounts.get(i) : 0;
theWriter.OpenSection();
theWriter.WriteData("sheetId", aResultSheet.Uuid());
theWriter.OpenArraySection("parameters");
WriteParameter(theWriter, "Sheet Length", "mm", aResultSheet.Height());
WriteParameter(theWriter, "Sheet Width", "mm", aResultSheet.Width());
WriteParameter(theWriter, "Free Space", "mm^2", aFreeSpace);
WriteParameter(theWriter, "Requested Pattern Count", "pcs", thePatternCountTotal);
WriteParameter(theWriter, "Nested Pattern Count", "pcs", aNestedPatternCount);
theWriter.CloseArraySection();
theWriter.CloseSection();
}
theWriter.CloseArraySection();
theWriter.CloseSection();
}
private void WriteUuidArray(JSONWriter theWriter, String theName, ArrayList<UUID> theUuids) {
StringBuilder aStream = new StringBuilder();
String aCurrentIndent = new String(new char[theWriter.NestingLevel() * 4]).replace('\0', ' ');
String aArrayValueIndent = new String(new char[(theWriter.NestingLevel() + 1) * 4]).replace('\0', ' ');
aStream.append(aCurrentIndent).append("\"").append(theName).append("\": [");
if (!theUuids.isEmpty()) {
aStream.append("\n");
for (int i = 0; i < theUuids.size(); ++i) {
aStream.append(aArrayValueIndent).append("\"").append(theUuids.get(i)).append("\"");
if (i + 1 < theUuids.size()) {
aStream.append(",");
}
aStream.append("\n");
}
aStream.append(aCurrentIndent);
}
aStream.append("]");
theWriter.WriteRawData(aStream.toString());
}
private boolean IsSheetProcessData(MTKConverter_ProcessData theProcessData) {
return theProcessData instanceof MTKConverter_NestingData;
}
private void WritePartProcessData(JSONWriter theWriter, MTKConverter_ProcessData theProcessData) {
boolean aRes = false;
theWriter.WriteData("partId", theProcessData.myPart.Uuid());
String anErrorMsg = "An error occurred while processing the part.";
if (theProcessData instanceof MTKConverter_MachiningData) {
MTKConverter_MachiningData aMD = (MTKConverter_MachiningData) theProcessData;
theWriter.WriteData("process", MachiningProcessName(aMD.myOperation));
cadex.Collections.BodyList aBodies = aMD.myPart.Bodies();
if (!aMD.myFeatureList.IsEmpty()) {
WriteFeatures(theWriter, "Feature Recognition", "featureRecognition", aMD.myFeatureList, "");
WriteFeatures(
theWriter,
"Design for Manufacturing",
"dfm",
aMD.myIssueList,
"Part contains no DFM improvement suggestions.");
aRes = true;
} else if (aBodies.isEmpty() || !HasShapes(aBodies, ShapeType.Solid)) {
anErrorMsg = "The part can't be analyzed due to lack of: BRep representation or solids in BRep representation.";
}
} else if (theProcessData instanceof MTKConverter_WallThicknessData) {
MTKConverter_WallThicknessData aWTD = (MTKConverter_WallThicknessData) theProcessData;
theWriter.WriteData("process", "Wall Thickness Analysis");
cadex.Collections.BodyList aBodies = aWTD.myPart.Bodies();
if (aWTD.myIsInit) {
WriteWallThicknessData(theWriter, aWTD);
aRes = true;
} else if (aBodies.isEmpty() || !HasShapes(aBodies, ShapeType.Solid)) {
anErrorMsg = "The part can't be analyzed due to lack of: BRep representation, solids in BRep representation.";
}
} else if (theProcessData instanceof MTKConverter_MoldingData) {
MTKConverter_MoldingData aMoldingData = (MTKConverter_MoldingData) theProcessData;
cadex.Collections.BodyList aBodies = aMoldingData.myPart.Bodies();
if (!aMoldingData.myFeatureList.IsEmpty()) {
theWriter.WriteData("process", "Molding Analysis");
WriteFeatures(theWriter, "Feature Recognition", "featureRecognition", aMoldingData.myFeatureList, "");
WriteFeatures(
theWriter,
"Design for Manufacturing",
"dfm",
aMoldingData.myIssueList,
"Part contains no DFM improvement suggestions.");
aRes = true;
} else if (aBodies.isEmpty() || !HasShapes(aBodies, ShapeType.Solid)) {
anErrorMsg = "The part can't be analyzed due to lack of: BRep representation or solids in BRep representation.";
}
} else if (theProcessData instanceof MTKConverter_SheetMetalData) {
MTKConverter_SheetMetalData aSMD = (MTKConverter_SheetMetalData) theProcessData;
theWriter.WriteData("process", "Sheet Metal");
cadex.Collections.BodyList aBodies = aSMD.myPart.Bodies();
if (aSMD.myIsSheetMetalPart) {
WriteFeatures(
theWriter,
"Feature Recognition",
"featureRecognition",
aSMD.myFeatureList,
"Part contains no features.");
WriteFeatures(
theWriter,
"Design for Manufacturing",
"dfm",
aSMD.myIssueList,
"Part contains no DFM improvement suggestions.");
MTKConverter_UnfoldedPartData anUnfoldedPartData = aSMD.myUnfoldedPartData;
WriteUnfoldedPartFeatures(theWriter, anUnfoldedPartData);
if (anUnfoldedPartData.IsInit()) {
WriteFeatures(
theWriter,
"Design for Manufacturing",
"dfmUnfolded",
anUnfoldedPartData.myIssueList,
"Unfolded part contains no DFM improvement suggestions.");
}
aRes = true;
} else if (aBodies.isEmpty() ||
(!HasShapes(aBodies, ShapeType.Solid) && !HasShapes(aBodies, ShapeType.Shell))) {
anErrorMsg = "The part can't be analyzed due to lack of: BRep representation, solids and shells in BRep representation.";
} else {
anErrorMsg = "The part wasn't recognized as a sheet metal part.";
}
} else {
anErrorMsg = "Unrecognized process";
}
if (!aRes) {
theWriter.WriteData("error", anErrorMsg);
}
}
private void WriteSheetProcessData(JSONWriter theWriter, MTKConverter_ProcessData theProcessData) {
boolean aRes = false;
if (theProcessData instanceof MTKConverter_NestingData) {
MTKConverter_NestingData aND = (MTKConverter_NestingData) theProcessData;
ArrayList<UUID> aSourceSheetUuids = new ArrayList<UUID>();
for (Sheet aSheet : aND.mySourceSheets) {
aSourceSheetUuids.add(aSheet.Uuid());
}
WriteUuidArray(theWriter, "sourceIds", aSourceSheetUuids);
ArrayList<Sheet> aResultSheets = MTKConverter_DrawingProcessor.ExtractDrawingSheets(aND.myResultDrawing);
ArrayList<Double> aSheetFreeSpaces = new ArrayList<Double>();
ArrayList<Long> aNestedPatternCounts = new ArrayList<Long>();
for (Nesting_Sheet aSheet : aND.myNestingResult.Sheets()) {
aSheetFreeSpaces.add(aSheet.Scrap() * aSheet.SheetArea());
aNestedPatternCounts.add(aSheet.NestedParts());
}
if (!aResultSheets.isEmpty()) {
theWriter.WriteData("process", "Nesting");
WriteNestingData(
theWriter,
aResultSheets,
aSheetFreeSpaces,
aND.myPatternCountTotal,
aNestedPatternCounts);
aRes = true;
}
}
if (!aRes) {
theWriter.WriteData("error", "An error occurred while processing the sheet.");
}
}
public boolean WriteToJSON(UTF16String thePath) {
String aPath = thePath.toString();
File aFile = new File(aPath);
if (aFile.exists()) {
aFile.delete();
}
try {
PrintWriter aStream = new PrintWriter(new BufferedWriter(new FileWriter(aPath)));
JSONWriter aWriter = new JSONWriter(aStream, 0);
aWriter.OpenSection();
aWriter.WriteData("version", "1");
if (myData.isEmpty()) {
aWriter.WriteData("error", "The model doesn't contain any parts.");
} else {
boolean aHasPartProcessData = false;
boolean aHasSheetProcessData = false;
for (MTKConverter_ProcessData aProcessData : myData) {
if (IsSheetProcessData(aProcessData)) {
aHasSheetProcessData = true;
} else {
aHasPartProcessData = true;
}
}
if (aHasPartProcessData) {
aWriter.OpenArraySection("parts");
for (MTKConverter_ProcessData aProcessData : myData) {
if (IsSheetProcessData(aProcessData)) {
continue;
}
aWriter.OpenSection();
WritePartProcessData(aWriter, aProcessData);
aWriter.CloseSection();
}
aWriter.CloseArraySection();
}
if (aHasSheetProcessData) {
aWriter.OpenArraySection("sheets");
for (MTKConverter_ProcessData aProcessData : myData) {
if (!IsSheetProcessData(aProcessData)) {
continue;
}
aWriter.OpenSection();
WriteSheetProcessData(aWriter, aProcessData);
aWriter.CloseSection();
}
aWriter.CloseArraySection();
}
}
aWriter.CloseSection();
aStream.close();
} catch (Exception anE) {
return false;
}
return true;
}
private ArrayList<MTKConverter_ProcessData> myData;
}
Contains utility classes that can be useful for debugging or configuring global settings.

MTKConverter_Application.java

// ****************************************************************************
//
// Copyright (C) 2008-2014, Roman Lygin. All rights reserved.
// Copyright (C) 2014-2026, CADEX. All rights reserved.
//
// This file is part of the Manufacturing Toolkit software.
//
// You may use this file under the terms of the BSD license as follows:
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// ****************************************************************************
import cadex.*;
import cadex.Drawing.*;
import cadex.Materials.*;
import cadex.ModelData.*;
import cadex.View.*;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
enum MTKConverter_ReturnCode {
// General codes
Ok(0),
UnknownError(1),
GeneralException(2),
NoValidLicense(3),
InvalidArgumentsNumber(4),
InvalidArgument(5),
// Import errors
UnsupportedVersion(100),
UnexpectedFormat(101),
UnsupportedFileVariant(102),
ImportError(103),
// Process errors
ProcessError(200),
// Export errors
ExportError(300);
MTKConverter_ReturnCode(int theValue) {
myValue = theValue;
}
public int GetValue() {
return myValue;
}
private final int myValue;
}
enum MTKConverter_ProcessType {
Undefined(-1),
WallThickness(0),
MachiningMilling(1),
MachiningTurning(2),
Molding(3),
SheetMetal(4),
Nesting(5);
MTKConverter_ProcessType(int theValue) {
myValue = theValue;
}
public int GetValue() {
return myValue;
}
private final int myValue;
}
enum MTKConverter_ArgumentType {
Neutral,
Import,
Process,
Export
}
class MTKConverter_Argument {
public MTKConverter_Argument(MTKConverter_ArgumentType theType, String theValue) {
myArgumentType = theType;
myValue = theValue;
}
public MTKConverter_ArgumentType myArgumentType;
public String myValue;
}
class MTKConverter_ImportParameters {
public MTKConverter_ImportParameters() {
myReaderParameters = new ModelReaderParameters();
myReaderParameters.SetReadPMI(false);
myReaderParameters.SetReadDrawing(false);
myReaderParameters.SetEnableAnalyticalRecognition(true);
}
public ModelReaderParameters myReaderParameters;
}
class MTKConverter_NestingParameters {
enum NestingMode {
PerSheet(0),
AllSheets(1);
NestingMode(int theValue) {
myValue = theValue;
}
public int GetValue() {
return myValue;
}
private final int myValue;
}
static class MaterialParameters {
public double myLength = 500.0;
public double myWidth = 500.0;
public long myCount = 1;
}
public MTKConverter_NestingParameters() {
myComputerParameters = new Nesting_ComputerParameters();
myComputerParameters.SetIterationCount(20);
myComputerParameters.SetGenerationSize(3);
myComputerParameters.SetMutationRate(2.0);
myComputerParameters.SetCurveTolerance(100.0);
myComputerParameters.SetPartToPartDistance(0);
myComputerParameters.SetPartToSheetBoundaryDistance(0);
myComputerParameters.SetRotationCount(4);
myComputerParameters.SetMirrorControl(false);
myComputerParameters.SetNestingInHoles(false);
}
public MaterialParameters myMaterialParameters = new MaterialParameters();
public long myPatternRepeatCount = 4;
public NestingMode myMode = NestingMode.PerSheet;
public Nesting_ComputerParameters myComputerParameters;
}
class MTKConverter_WallThicknessParameters {
public MTKConverter_WallThicknessParameters() {
WallThickness_VoxelizationParameters aVoxelizationParameters = myAnalyzerParameters.VoxelizationParameters();
aVoxelizationParameters.SetResolution (800);
}
public WallThickness_AnalyzerParameters myAnalyzerParameters = new WallThickness_AnalyzerParameters();
public double myColorSmoothness = 0.75;
}
class MTKConverter_ExportParameters {
public boolean myIsScreenshotGenerationEnabled = true;
public boolean myIsExportMTKEnabled = false;
}
class MTKConverter_Parameters {
public MTKConverter_ImportParameters myImportParameters = new MTKConverter_ImportParameters();
public MTKConverter_NestingParameters myNestingParameters = new MTKConverter_NestingParameters();
public MTKConverter_WallThicknessParameters myWallThicknessParameters = new MTKConverter_WallThicknessParameters();
public MTKConverter_ExportParameters myExportParameters = new MTKConverter_ExportParameters();
}
class MTKConverter_Application {
private MTKConverter_ProcessType FindProcessType(String theProcessName) {
HashMap<String, MTKConverter_ProcessType> aProcessMap = new HashMap<String, MTKConverter_ProcessType>();
aProcessMap.put("wall_thickness", MTKConverter_ProcessType.WallThickness);
aProcessMap.put("machining_milling", MTKConverter_ProcessType.MachiningMilling);
aProcessMap.put("machining_turning", MTKConverter_ProcessType.MachiningTurning);
aProcessMap.put("molding", MTKConverter_ProcessType.Molding);
aProcessMap.put("sheet_metal", MTKConverter_ProcessType.SheetMetal);
aProcessMap.put("nesting", MTKConverter_ProcessType.Nesting);
return aProcessMap.getOrDefault(theProcessName, MTKConverter_ProcessType.Undefined);
}
private MTKConverter_ReturnCode Import(
String theFilePath,
Model theModel,
MTKConverter_ImportParameters theImportParameters) {
System.out.print("Importing " + theFilePath + "...");
ModelReader aReader = new ModelReader();
aReader.SetParameters(theImportParameters.myReaderParameters);
if (!aReader.Read(new UTF16String(theFilePath), theModel)) {
System.out.println("\nERROR: Failed to import " + theFilePath + ". Exiting");
return MTKConverter_ReturnCode.ImportError;
}
return MTKConverter_ReturnCode.Ok;
}
private MTKConverter_ReturnCode ApplyPartProcessorToModel(
Model theModel,
MTKConverter_Report theReport,
MTKConverter_PartProcessor theProcessor) {
ModelElementUniqueVisitor aVisitor = new ModelElementUniqueVisitor(theProcessor);
theModel.Accept(aVisitor);
for (MTKConverter_ProcessData i : theProcessor.myData) {
theReport.AddData(i);
}
return MTKConverter_ReturnCode.Ok;
}
private MTKConverter_ReturnCode ApplyDrawingProcessorToModel(
Model theModel,
Model theProcessModel,
MTKConverter_Report theReport,
MTKConverter_DrawingProcessor theProcessor) {
Drawing aDrawing = theProcessModel.Drawing();
if (aDrawing == null) {
aDrawing = theModel.Drawing();
}
if (aDrawing == null) {
System.out.println("\nERROR: Drawing is required, but none was found in the process/source model.");
return MTKConverter_ReturnCode.ProcessError;
}
if (!theProcessor.Apply(aDrawing)) {
return MTKConverter_ReturnCode.ProcessError;
}
for (MTKConverter_ProcessData i : theProcessor.myData) {
theReport.AddData(i);
}
return MTKConverter_ReturnCode.Ok;
}
private MTKConverter_ReturnCode Process(
String theProcess,
Model theModel,
MTKConverter_Report theReport,
Model theProcessModel,
MTKConverter_Parameters theParameters) {
System.out.print("Processing " + theProcess + "...");
switch (FindProcessType(theProcess)) {
case WallThickness: {
theProcessModel.SetName(new UTF16String("extra"));
MTKConverter_WallThicknessProcessor aProcessor = new MTKConverter_WallThicknessProcessor(
theProcessModel,
theParameters.myWallThicknessParameters);
return ApplyPartProcessorToModel(theModel, theReport, aProcessor);
}
case MachiningMilling: {
MTKConverter_MachiningProcessor aProcessor = new MTKConverter_MachiningProcessor(
Machining_OperationType.Machining_OT_Milling);
return ApplyPartProcessorToModel(theModel, theReport, aProcessor);
}
case MachiningTurning: {
MTKConverter_MachiningProcessor aProcessor = new MTKConverter_MachiningProcessor(
Machining_OperationType.Machining_OT_LatheMilling);
return ApplyPartProcessorToModel(theModel, theReport, aProcessor);
}
case Molding: {
theProcessModel.SetName(new UTF16String(theModel.Name() + "_extra"));
MTKConverter_MoldingProcessor aProcessor = new MTKConverter_MoldingProcessor(theProcessModel);
return ApplyPartProcessorToModel(theModel, theReport, aProcessor);
}
case SheetMetal: {
theProcessModel.SetName(new UTF16String(theModel.Name() + "_unfolded"));
MTKConverter_SheetMetalProcessor aProcessor = new MTKConverter_SheetMetalProcessor(theProcessModel);
return ApplyPartProcessorToModel(theModel, theReport, aProcessor);
}
case Nesting: {
theProcessModel.SetName(new UTF16String(theModel.Name() + "_nested"));
MTKConverter_NestingProcessor aProcessor = new MTKConverter_NestingProcessor(
theProcessModel,
theParameters.myNestingParameters);
return ApplyDrawingProcessorToModel(theModel, theProcessModel, theReport, aProcessor);
}
default:
return MTKConverter_ReturnCode.InvalidArgument;
}
}
private boolean CreateOriginModelThumbnail(UTF16String theFilePath, Model theModel) {
ImageWriter aWriter = new ImageWriter();
ImageWriterParameters aParameters = aWriter.Parameters();
aParameters.SetImageHeight(800);
aParameters.SetImageWidth(600);
aParameters.SetViewCameraProjection(CameraProjectionType.Perspective);
aParameters.SetViewCameraPosition(CameraPositionType.Default);
aParameters.SetViewIsFitAll(true);
aParameters.SetViewAntialiasing(AntialiasingMode.High);
aParameters.SetViewBackground(new ColorBackgroundStyle(new Color(255, 255, 255)));
aWriter.SetParameters(aParameters);
return aWriter.WriteFile(theModel, theFilePath);
}
private boolean ExportMTKWEB(String theFolderPath, Model theModelToExport, UTF16String theBaseName) {
UTF16String aPath = new UTF16String(theFolderPath + "/" + theBaseName + ".mtkweb/scenegraph.mtkweb");
if (!theModelToExport.Save(aPath, Model.FileFormatType.MTKWEB)) {
System.out.println("\nERROR: Failed to export " + aPath + ". Exiting");
return false;
}
return true;
}
private boolean ExportMTK(String theFolderPath, Model theModelToExport, UTF16String theBaseName) {
String aSanitizedBaseName = theBaseName.toString().replace('.', '_');
UTF16String aPath = new UTF16String(theFolderPath + "/" + aSanitizedBaseName + "_processed.mtk");
if (!theModelToExport.Save(aPath, Model.FileFormatType.MTK)) {
System.out.println("\nERROR: Failed to save MTK model " + aPath + ". Exiting");
return false;
}
return true;
}
private MTKConverter_ReturnCode Export(
String theFolderPath,
MTKConverter_ExportParameters theExportParameters,
Model theModel,
MTKConverter_Report theReport,
Model theProcessModel) {
System.out.print("Exporting " + theFolderPath + "...");
File aDirectory = new File(theFolderPath);
aDirectory.mkdirs();
UTF16String aModelBaseName = theModel.Name();
UTF16String aProcessedBaseName = theProcessModel.Name();
if (!ExportMTKWEB(theFolderPath, theModel, aModelBaseName)) {
return MTKConverter_ReturnCode.ExportError;
}
UTF16String aThumbnailPath = new UTF16String(theFolderPath + "/thumbnail.png");
if (theExportParameters.myIsScreenshotGenerationEnabled &&
!CreateOriginModelThumbnail(aThumbnailPath, theModel)) {
System.out.println("\nERROR: Failed to create thumbnail " + aThumbnailPath + ". Exiting");
return MTKConverter_ReturnCode.ExportError;
}
Drawing aProcessDrawing = theProcessModel.Drawing();
if (!theProcessModel.IsEmpty() || aProcessDrawing != null) {
if (!ExportMTKWEB(theFolderPath, theProcessModel, aProcessedBaseName)) {
return MTKConverter_ReturnCode.ExportError;
}
if (theExportParameters.myIsExportMTKEnabled &&
!ExportMTK(theFolderPath, theProcessModel, aProcessedBaseName)) {
return MTKConverter_ReturnCode.ExportError;
}
}
UTF16String aJsonPath = new UTF16String(theFolderPath + "/process_data.json");
if (!theReport.WriteToJSON(aJsonPath)) {
System.out.println("\nERROR: Failed to create JSON file " + aJsonPath + ". Exiting");
return MTKConverter_ReturnCode.ExportError;
}
return MTKConverter_ReturnCode.Ok;
}
private MTKConverter_ReturnCode ParseArguments(
String[] args,
MTKConverter_Parameters theParameters,
ArrayList<MTKConverter_Argument> theArguments) {
MTKConverter_ArgumentType anArgumentType = MTKConverter_ArgumentType.Neutral;
for (int i = 0; i < args.length; ++i) {
String anArgument = args[i];
if (anArgument.equals("--no-screenshot")) {
theParameters.myExportParameters.myIsScreenshotGenerationEnabled = false;
} else if (anArgument.equals("--export_mtk")) {
theParameters.myExportParameters.myIsExportMTKEnabled = true;
} else if (anArgument.equals("--sheet_size")) {
if (i + 2 >= args.length) {
System.out.println("ERROR: Missing values for --sheet_size. Use --sheet_size <L> <W> with values > 0.");
return MTKConverter_ReturnCode.InvalidArgument;
}
double aSheetLength;
double aSheetWidth;
try {
aSheetLength = Double.parseDouble(args[++i]);
aSheetWidth = Double.parseDouble(args[++i]);
} catch (NumberFormatException anE) {
System.out.println("ERROR: Invalid sheet size. Use --sheet_size <L> <W> with values > 0.");
return MTKConverter_ReturnCode.InvalidArgument;
}
if (aSheetLength <= 0.0 || aSheetWidth <= 0.0) {
System.out.println("ERROR: Invalid sheet size. Use --sheet_size <L> <W> with values > 0.");
return MTKConverter_ReturnCode.InvalidArgument;
}
theParameters.myNestingParameters.myMaterialParameters.myLength = aSheetLength;
theParameters.myNestingParameters.myMaterialParameters.myWidth = aSheetWidth;
} else if (anArgument.equals("--pattern_count")) {
if (i + 1 >= args.length) {
System.out.println("ERROR: Missing value for --pattern_count. Use --pattern_count <N> with value > 0.");
return MTKConverter_ReturnCode.InvalidArgument;
}
long aPatternRepeatCount;
try {
aPatternRepeatCount = Long.parseLong(args[++i]);
} catch (NumberFormatException anE) {
System.out.println("ERROR: Invalid pattern count. Use --pattern_count <N> with value > 0.");
return MTKConverter_ReturnCode.InvalidArgument;
}
if (aPatternRepeatCount <= 0) {
System.out.println("ERROR: Invalid pattern count. Use --pattern_count <N> with value > 0.");
return MTKConverter_ReturnCode.InvalidArgument;
}
theParameters.myNestingParameters.myPatternRepeatCount = aPatternRepeatCount;
} else if (anArgument.equals("--nesting_mode")) {
if (i + 1 >= args.length) {
System.out.println("ERROR: Missing value for --nesting_mode. Use --nesting_mode per_sheet|all_sheets.");
return MTKConverter_ReturnCode.InvalidArgument;
}
String aNestingModeArg = args[++i];
if (aNestingModeArg.equals("per_sheet")) {
theParameters.myNestingParameters.myMode = MTKConverter_NestingParameters.NestingMode.PerSheet;
} else if (aNestingModeArg.equals("all_sheets")) {
theParameters.myNestingParameters.myMode = MTKConverter_NestingParameters.NestingMode.AllSheets;
} else {
System.out.println("ERROR: Invalid nesting mode \"" + aNestingModeArg +
"\". Use --nesting_mode per_sheet|all_sheets.");
return MTKConverter_ReturnCode.InvalidArgument;
}
} else if (anArgument.equals("-i")) {
anArgumentType = MTKConverter_ArgumentType.Import;
} else if (anArgument.equals("-p")) {
anArgumentType = MTKConverter_ArgumentType.Process;
} else if (anArgument.equals("-e")) {
anArgumentType = MTKConverter_ArgumentType.Export;
} else {
switch (anArgumentType) {
case Import:
theArguments.add(new MTKConverter_Argument(MTKConverter_ArgumentType.Import, anArgument));
break;
case Process: {
MTKConverter_ProcessType aProcessType = FindProcessType(anArgument);
if (aProcessType == MTKConverter_ProcessType.Undefined) {
System.out.println("ERROR: Unknown process \"" + anArgument + "\".");
System.out.println("Type -h for recognized processes.");
return MTKConverter_ReturnCode.InvalidArgument;
}
if (aProcessType == MTKConverter_ProcessType.Nesting) {
theParameters.myImportParameters.myReaderParameters.SetReadDrawing(true);
}
theArguments.add(new MTKConverter_Argument(MTKConverter_ArgumentType.Process, anArgument));
break;
}
case Export:
theArguments.add(new MTKConverter_Argument(MTKConverter_ArgumentType.Export, anArgument));
break;
default:
System.out.println("ERROR!: Invalid argument " + anArgument + ". Exiting");
System.out.println("Type -h for help.");
return MTKConverter_ReturnCode.InvalidArgument;
}
}
}
if (theArguments.isEmpty()) {
System.out.println("ERROR: No commands specified. Use -i/-p/-e.");
return MTKConverter_ReturnCode.InvalidArgument;
}
return MTKConverter_ReturnCode.Ok;
}
private MTKConverter_ReturnCode Execute(
ArrayList<MTKConverter_Argument> theArguments,
MTKConverter_Parameters theParameters) {
Model aModel = new Model();
Model aProcessModel = new Model();
MTKConverter_Report aReport = new MTKConverter_Report();
MTKConverter_ReturnCode aResultCode = MTKConverter_ReturnCode.Ok;
for (MTKConverter_Argument anArgument : theArguments) {
if (aResultCode != MTKConverter_ReturnCode.Ok) {
break;
}
try {
switch (anArgument.myArgumentType) {
case Import:
aProcessModel = new Model();
aResultCode = Import(anArgument.myValue, aModel, theParameters.myImportParameters);
if (aResultCode == MTKConverter_ReturnCode.Ok) {
aModel.AssignUuids();
}
break;
case Process:
aResultCode = Process(anArgument.myValue, aModel, aReport, aProcessModel, theParameters);
break;
case Export:
aResultCode = Export(
anArgument.myValue,
theParameters.myExportParameters,
aModel,
aReport,
aProcessModel);
break;
default:
aResultCode = MTKConverter_ReturnCode.InvalidArgument;
break;
}
if (aResultCode == MTKConverter_ReturnCode.Ok) {
System.out.println("Done.");
}
} catch (Exception anE) {
System.out.println("Failed.\nERROR: Unhandled exception caught.");
return MTKConverter_ReturnCode.GeneralException;
}
}
return aResultCode;
}
public MTKConverter_ReturnCode Run(String[] args) {
if (args.length == 0 ||
args[0].equals("-?") || args[0].equals("/?") ||
args[0].equals("-h") || args[0].equals("--help")) {
PrintUsage();
return MTKConverter_ReturnCode.Ok;
}
if (args.length < 6) {
System.out.println("Invalid number of arguments. Please use \"-h\" or \"--help\" for usage information.");
return MTKConverter_ReturnCode.InvalidArgumentsNumber;
}
MTKConverter_Parameters aParameters = new MTKConverter_Parameters();
ArrayList<MTKConverter_Argument> anArguments = new ArrayList<MTKConverter_Argument>();
MTKConverter_ReturnCode aParseRes = ParseArguments(args, aParameters, anArguments);
if (aParseRes != MTKConverter_ReturnCode.Ok) {
return aParseRes;
}
return Execute(anArguments, aParameters);
}
public void PrintUsage() {
System.out.println("Usage:");
System.out.println("MTKConverter -i <import_file> -p <process> ... -e <export_target> [options]");
System.out.println();
System.out.println("Arguments:");
System.out.println(" <import_file> - import file name");
System.out.println(" <process> - manufacturing process or algorithm name");
System.out.println(" <export_target> - export folder name");
System.out.println();
System.out.println("Export Options:");
System.out.println(" --no-screenshot - disable screenshot generation (optional)");
System.out.println(" --export_mtk - additionally save process model as *.mtk in <export_target>");
System.out.println();
System.out.println("Example:");
System.out.println("MTKConverter -i C:\\models\\test.step -p machining_milling -e C:\\models\\out");
System.out.println("MTKConverter -i C:\\models\\test.step -p nesting -e C:\\models\\out --export_mtk");
System.out.println(
"MTKConverter -i C:\\models\\test.step -p sheet_metal -e C:\\models\\out -p nesting --nesting_mode all_sheets --sheet_size 500 500 --pattern_count 4 -e C:\\models\\out --export_mtk");
System.out.println();
System.out.println("Recognized processes:");
System.out.println(" wall_thickness :\t Wall Thickness analysis");
System.out.println(" machining_milling:\t CNC Machining Milling feature recognition and DFM analysis");
System.out.println(" machining_turning:\t CNC Machining Lathe+Milling feature recognition and DFM analysis");
System.out.println(" molding :\t Molding feature recognition and DFM analysis");
System.out.println(" sheet_metal :\t Sheet Metal feature recognition, unfolding and DFM analysis");
System.out.println(" nesting :\t Nesting using source drawing or sheet metal unfolding drawing");
System.out.println(" parameters :\t --sheet_size <L> <W> (default: 500 500)");
System.out.println(" :\t --pattern_count <N> (default: 4)");
System.out.println(" :\t --nesting_mode per_sheet|all_sheets (default: per_sheet)");
}
}
Contains classes, types, enums, and functions related to image generation.

MTKConverter.java

// ****************************************************************************
//
// Copyright (C) 2008-2014, Roman Lygin. All rights reserved.
// Copyright (C) 2014-2026, CADEX. All rights reserved.
//
// This file is part of the Manufacturing Toolkit software.
//
// You may use this file under the terms of the BSD license as follows:
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// ****************************************************************************
import cadex.*;
public class MTKConverter {
static {
try {
System.loadLibrary("MTKCore");
System.loadLibrary("MTKView");
} catch (UnsatisfiedLinkError e) {
System.err.println("Native code library failed to load.\n" + e);
System.exit(1);
}
}
public static void main(String[] args) {
String aKey = MTKLicenseKey.Value();
// Activate the license (the key must be defined in MTKLicenseKey.java)
if (!LicenseManager.Activate(aKey)) {
System.out.println("Failed to activate Manufacturing Toolkit license.");
System.exit(1);
}
MTKConverter_Application anApp = new MTKConverter_Application();
System.exit(anApp.Run(args).GetValue());
}
}