- Refer to the MTK Converter Example.
MTKConverter_PartProcessor.cs
using System.Collections.Generic;
namespace mtkconverter
{
class MTKConverter_ProcessData
{
protected MTKConverter_ProcessData(Part thePart)
{
myPart = thePart;
mySourceSheets = new List<Sheet>();
}
protected MTKConverter_ProcessData(List<Sheet> theSheets)
{
myPart = new Part(new UTF16String(""));
mySourceSheets = theSheets;
}
public Part myPart;
public List<Sheet> mySourceSheets;
}
abstract class MTKConverter_PartProcessor : ModelElementVoidVisitor
{
protected MTKConverter_PartProcessor()
{
myData = new List<MTKConverter_ProcessData>();
}
public List<MTKConverter_ProcessData> myData;
public override void Apply(Part thePart)
{
bool aPartWasProcessed = false;
var aProcessData = CreateProcessData(thePart);
foreach (var aBody in 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 bool ProcessBRepBody(MTKConverter_ProcessData theProcessData, Body theBody)
{
bool aBodyWasProcessed = false;
var aShapeIt = new ShapeIterator(theBody);
foreach (var aShape in aShapeIt)
{
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 bool ProcessMeshBody(MTKConverter_ProcessData theProcessData, MeshBody theBody)
{
bool aBodyWasProcessed = false;
foreach (var aMeshShape in 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);
}
abstract class MTKConverter_VoidPartProcessor : MTKConverter_PartProcessor
{
public MTKConverter_VoidPartProcessor() : base() { }
public override void ProcessSolid(MTKConverter_ProcessData theProcessData, Solid theSolid) { }
public override void ProcessShell(MTKConverter_ProcessData theProcessData, Shell theShell) { }
public override void ProcessMesh(MTKConverter_ProcessData theProcessData, IndexedTriangleSet theMesh) { }
public override 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.cs
using System.Collections.Generic;
namespace mtkconverter
{
abstract class MTKConverter_DrawingProcessor
{
protected MTKConverter_DrawingProcessor()
{
myData = new List<MTKConverter_ProcessData>();
}
public abstract bool Apply(Drawing theDrawing);
public static List<Sheet> ExtractDrawingSheets(Drawing theDrawing)
{
List<Sheet> aSheets = new List<Sheet>();
Drawing.SheetIterator aSheetIt = new Drawing.SheetIterator(theDrawing);
while (aSheetIt.HasNext())
{
aSheets.Add(aSheetIt.Next());
}
return aSheets;
}
public static void AddSheets(Drawing theSrc, ref Drawing theDst)
{
if (theSrc == null)
{
return;
}
if (theDst == null)
{
theDst = theSrc;
return;
}
Drawing.SheetIterator anIt = new Drawing.SheetIterator(theSrc);
while (anIt.HasNext())
{
theDst.AddSheet(anIt.Next());
}
}
public List<MTKConverter_ProcessData> myData;
}
}
MTKConverter_MachiningProcessor.cs
namespace mtkconverter
{
class MTKConverter_MachiningData : MTKConverter_ProcessData
{
public MTKConverter_MachiningData(Part thePart) : base(thePart)
{
myFeatureList = new MTKBase_FeatureList();
myIssueList = new MTKBase_FeatureList();
}
public MTKBase_FeatureList myFeatureList;
public MTKBase_FeatureList myIssueList;
public Machining_OperationType myOperation;
}
class MTKConverter_MachiningProcessor : MTKConverter_VoidPartProcessor
{
public MTKConverter_MachiningProcessor(Machining_OperationType theOperation) : base()
{
myOperation = theOperation;
}
private Machining_OperationType myOperation;
public override MTKConverter_ProcessData CreateProcessData(Part thePart)
{
return new MTKConverter_MachiningData(thePart);
}
public override void ProcessSolid(MTKConverter_ProcessData theProcessData, Solid theSolid)
{
var aMachiningData = theProcessData as MTKConverter_MachiningData;
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;
}
aMachiningData.myFeatureList.Append(aData.FeatureList());
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 (uint 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 (uint i = 0; i < aTurningIssueList.Size(); ++i)
{
MTKBase_Feature anIssue = aTurningIssueList.Feature(i);
aMachiningData.myIssueList.Append(anIssue);
}
}
}
}
}
MTKConverter_MoldingProcessor.cs
using System.Collections.Generic;
namespace mtkconverter
{
class MTKConverter_MoldingData : MTKConverter_ProcessData
{
public MTKConverter_MoldingData(Part thePart) : base(thePart)
{
myFeatureList = new MTKBase_FeatureList();
myIssueList = new MTKBase_FeatureList();
}
public MTKBase_FeatureList myFeatureList;
public MTKBase_FeatureList myIssueList;
}
class MTKConverter_MoldingProcessor : MTKConverter_VoidPartProcessor
{
public MTKConverter_MoldingProcessor(Model theExtraDataModel) : base()
{
myExtraDataModel = theExtraDataModel;
myCurrentNewFaces = new SheetBody();
}
private Model myExtraDataModel;
private SheetBody myCurrentNewFaces;
public override MTKConverter_ProcessData CreateProcessData(Part thePart)
{
return new MTKConverter_MoldingData(thePart);
}
private void AddNewFacesFromFeatures(MTKBase_FeatureList theFeatureList, Solid theSolid)
{
var aFaceIdSet = new HashSet<ulong>();
{
ShapeIterator aFaceIt = new ShapeIterator(theSolid, ShapeType.Face);
foreach (var aFace in aFaceIt)
{
aFaceIdSet.Add(aFace.Id());
}
}
for (uint i = 0; i < theFeatureList.Size(); ++i)
{
var aFeature = MTKBase_ShapeFeature.Cast(theFeatureList.Feature(i));
ShapeIterator aFaceIt = new ShapeIterator(aFeature.Shape(), ShapeType.Face);
foreach (var aFace in aFaceIt)
{
if (!aFaceIdSet.Contains(aFace.Id()))
{
myCurrentNewFaces.Append(Face.Cast(aFace));
}
}
}
}
public override void ProcessSolid(MTKConverter_ProcessData theProcessData, Solid theSolid)
{
var aMoldingData = theProcessData as MTKConverter_MoldingData;
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;
}
var aFeatureList = aData.FeatureList();
AddNewFacesFromFeatures(aFeatureList, theSolid);
aMoldingData.myFeatureList.Append(aFeatureList);
DFMMolding_AnalyzerParameters aParameters = new DFMMolding_AnalyzerParameters();
DFMMolding_Analyzer aAnalyzer = new DFMMolding_Analyzer(aParameters);
aMoldingData.myIssueList.Append(aAnalyzer.Perform(aData));
}
public override void PostProcessPart(Part thePart)
{
if (myCurrentNewFaces.Shapes().Count == 0)
{
return;
}
Part anExtraDataPart = new Part(thePart.Name());
anExtraDataPart.SetUuid(thePart.Uuid());
anExtraDataPart.AddBody(myCurrentNewFaces);
myExtraDataModel.AddRoot(anExtraDataPart);
myCurrentNewFaces = new SheetBody();
}
}
}
MTKConverter_SheetMetalProcessor.cs
using System;
using System.Collections.Generic;
namespace mtkconverter
{
class MTKConverter_UnfoldedPartData
{
public MTKConverter_UnfoldedPartData()
{
myFlatPatterns = new List<SheetMetal_FlatPattern>();
myIssueList = new MTKBase_FeatureList();
}
public bool IsInit() { return myFlatPatterns.Count > 0; }
public List<SheetMetal_FlatPattern> myFlatPatterns;
public MTKBase_FeatureList myIssueList;
}
class MTKConverter_SheetMetalData : MTKConverter_ProcessData
{
public MTKConverter_SheetMetalData(Part thePart) : base(thePart)
{
myFeatureList = new MTKBase_FeatureList();
myIssueList = new MTKBase_FeatureList();
myUnfoldedPartData = new MTKConverter_UnfoldedPartData();
}
public bool myIsSheetMetalPart = false;
public MTKBase_FeatureList myFeatureList;
public MTKBase_FeatureList myIssueList;
public MTKConverter_UnfoldedPartData myUnfoldedPartData;
}
class MTKConverter_SheetMetalProcessor : MTKConverter_VoidPartProcessor
{
public MTKConverter_SheetMetalProcessor(Model theUnfoldedModel) : base()
{
myAnalyzer = new SheetMetal_Analyzer();
myAnalyzer.AddTool(new SheetMetal_FeatureRecognizer());
myAnalyzer.AddTool(new SheetMetal_Unfolder());
myUnfoldedModel = theUnfoldedModel;
myCurrentUnfoldedBody = new SheetBody();
}
private SheetMetal_Analyzer myAnalyzer;
private Model myUnfoldedModel;
private SheetBody myCurrentUnfoldedBody;
public override MTKConverter_ProcessData CreateProcessData(Part thePart)
{
return new MTKConverter_SheetMetalData(thePart);
}
public override void ProcessSolid(MTKConverter_ProcessData theProcessData, Solid theSolid)
{
SheetMetal_Data anSMData = myAnalyzer.Perform(theSolid);
Process(theProcessData, anSMData);
}
public override void ProcessShell(MTKConverter_ProcessData theProcessData, Shell theShell)
{
SheetMetal_Data anSMData = myAnalyzer.Perform(theShell);
Process(theProcessData, anSMData);
}
public override void PostProcessPart(Part thePart)
{
if (myCurrentUnfoldedBody.Shapes().Count == 0)
{
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;
}
var anSMData = theProcessData as MTKConverter_SheetMetalData;
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
{
MTKConverter_DrawingProcessor.AddSheets(aFlatPatternDrawing, ref aDrawing);
myUnfoldedModel.SetDrawing(aDrawing);
}
}
}
DFMSheetMetal_Analyzer aDFMAnalyzer = new DFMSheetMetal_Analyzer();
MTKBase_FeatureList anIssueList = aDFMAnalyzer.Perform(theData);
for (uint 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);
}
}
}
}
}
MTKConverter_NestingProcessor.cs
using System;
using System.Collections.Generic;
namespace mtkconverter
{
class MTKConverter_NestingData : MTKConverter_ProcessData
{
public MTKConverter_NestingData(List<Sheet> theSheets) : base(theSheets)
{
myPatterns = new List<View>();
myResultDrawing = new Drawing(new BaseObject.Initialized());
myNestingResult = new Nesting_Data();
}
public List<View> myPatterns;
public Drawing myResultDrawing;
public uint myPatternCountTotal = 0;
public Nesting_Data myNestingResult;
}
class MTKConverter_NestingProcessor : MTKConverter_DrawingProcessor
{
private static List<View> ExtractPatternViews(Sheet theSheet)
{
List<View> aPatterns = new List<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(Guid.NewGuid());
}
}
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) : base()
{
myProcessModel = theProcessModel;
myNestingParameters = theNestingParameters;
}
private MTKConverter_NestingData CreateProcessData(List<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 =
(uint)(theNestingData.myPatterns.Count * myNestingParameters.myPatternRepeatCount);
foreach (View aPattern in theNestingData.myPatterns)
{
aComputer.AddPattern(aPattern, myNestingParameters.myPatternRepeatCount);
}
theNestingData.myNestingResult = aComputer.Perform();
}
private bool ProcessAllSheets(List<Sheet> theSourceSheets)
{
MTKConverter_NestingData aNestingData = CreateProcessData(theSourceSheets);
foreach (Sheet aSourceSheet in theSourceSheets)
{
List<View> aSheetPatterns = ExtractPatternViews(aSourceSheet);
aNestingData.myPatterns.AddRange(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 bool ProcessPerSheet(List<Sheet> theSourceSheets)
{
Drawing aResultNestingDrawing = new Drawing(new BaseObject.Initialized());
foreach (Sheet aSourceSheet in theSourceSheets)
{
MTKConverter_NestingData aNestingData = CreateProcessData(new List<Sheet> { aSourceSheet });
aNestingData.myPatterns = ExtractPatternViews(aSourceSheet);
Process(aNestingData);
Drawing aSourceNestingDrawing = aNestingData.myNestingResult.ToDrawing();
if (aSourceNestingDrawing != null)
{
AddNestingSheetFrames(aSourceNestingDrawing);
AssignSheetUuids(aSourceNestingDrawing);
aNestingData.myResultDrawing = aSourceNestingDrawing;
MTKConverter_DrawingProcessor.AddSheets(aSourceNestingDrawing, ref aResultNestingDrawing);
}
myData.Add(aNestingData);
}
myProcessModel.SetDrawing(aResultNestingDrawing);
return true;
}
public override bool Apply(Drawing theDrawing)
{
myData.Clear();
List<Sheet> aSourceSheets = MTKConverter_DrawingProcessor.ExtractDrawingSheets(theDrawing);
if (aSourceSheets.Count == 0)
{
Console.WriteLine("\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.cs
using mesh_colorizer;
using PointPairType = System.Collections.Generic.KeyValuePair<
cadex.
Geom.Point,
cadex.
Geom.Point>;
namespace mtkconverter
{
class MTKConverter_WallThicknessData : MTKConverter_ProcessData
{
public MTKConverter_WallThicknessData(Part thePart) : base(thePart)
{
}
public bool myIsInit = false;
public double myMinThickness = double.MaxValue;
public double myMaxThickness = -double.MaxValue;
public double myAvgThickness = 0.0;
public uint myThicknessPointCount = 0;
public PointPairType myMinThicknessPoints;
public PointPairType myMaxThicknessPoints;
}
class MTKConverter_WallThicknessProcessor : MTKConverter_VoidPartProcessor
{
public MTKConverter_WallThicknessProcessor(
Model theExtraDataModel,
MTKConverter_WallThicknessParameters theWallThicknessParameters) : base()
{
myAnalyzer = new WallThickness_Analyzer(theWallThicknessParameters.myAnalyzerParameters);
myColorizer = new MeshColorizer(theWallThicknessParameters.myColorSmoothness);
myExtraDataModel = theExtraDataModel;
}
private WallThickness_Analyzer myAnalyzer;
private MeshColorizer myColorizer;
private Model myExtraDataModel;
private IndexedTriangleSet myColoredITS;
public override 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;
}
var aWTData = theProcessData as MTKConverter_WallThicknessData;
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 PointPairType(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 PointPairType(aFirstPoint, aSecondPoint);
}
double aThicknessSum = 0.0;
MTKBase_DoubleList aThicknessList = theResult.ThicknessList();
if (!aThicknessList.IsEmpty())
{
uint aThicknessListSize = aThicknessList.Size();
for (uint i = 0; i < aThicknessListSize; ++i)
{
aThicknessSum += aThicknessList.Value(i);
}
uint aPrevThicknessPointCount = aWTData.myThicknessPointCount;
uint aTotalThicknessPointCount = aPrevThicknessPointCount + aThicknessListSize;
aWTData.myAvgThickness =
aWTData.myAvgThickness * ((double)aPrevThicknessPointCount / aTotalThicknessPointCount)
+ aThicknessSum / aTotalThicknessPointCount;
aWTData.myThicknessPointCount = aTotalThicknessPointCount;
}
var aColoredITS = myColorizer.Perform (theMesh, theResult);
if (myColoredITS != null)
{
myColoredITS.AddTriangles(aColoredITS);
}
else
{
myColoredITS = aColoredITS;
}
}
public override void ProcessSolid(MTKConverter_ProcessData theProcessData, Solid theSolid)
{
WallThickness_Data aWTData = myAnalyzer.Perform(theSolid);
var aMesh = new MeshGenerator().Generate(theSolid, false);
if (aMesh != null)
{
ProcessResult(theProcessData, IndexedTriangleSet.Cast(aMesh), aWTData);
}
}
public override void ProcessMesh(MTKConverter_ProcessData theProcessData, IndexedTriangleSet theMesh)
{
WallThickness_Data aWTData = myAnalyzer.Perform(theMesh);
ProcessResult(theProcessData, theMesh, aWTData);
}
public override void PostProcessPart(Part thePart)
{
if (myColoredITS == null) {
return;
}
var anExtraDataPart = new Part(thePart.Name());
anExtraDataPart.SetUuid (thePart.Uuid());
var aMeshBody = new MeshBody(myColoredITS);
anExtraDataPart.AddBody(aMeshBody);
myExtraDataModel.AddRoot(anExtraDataPart);
myColoredITS = null;
}
}
}
Contains classes and functions related to model processing.
MTKConverter_Report.cs
using System.Collections.Generic;
using System.IO;
using System.Text;
using PointPairType = System.Collections.Generic.KeyValuePair<
cadex.
Geom.Point,
cadex.
Geom.Point>;
namespace mtkconverter
{
public struct Point
{
public Point(double theX, double theY, double theZ)
{
X = theX;
Y = theY;
Z = theZ;
}
public double X { get; }
public double Y { get; }
public double Z { get; }
public override string ToString() => $"({FormattedString(X)}, {FormattedString(Y)}, {FormattedString(Z)})";
private string FormattedString(double theValue)
{
System.Globalization.CultureInfo aCI = new System.Globalization.CultureInfo("en-US");
return string.Format(aCI, "{0:0.00}", theValue);
}
}
class MTKConverter_Report
{
public MTKConverter_Report()
{
myData = new List<MTKConverter_ProcessData>();
}
private List<MTKConverter_ProcessData> myData;
public void AddData(MTKConverter_ProcessData theData)
{
myData.Add(theData);
}
private void WriteParameter<T>(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 bool 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_OperationType.Machining_OT_Milling: return "CNC Machining Milling";
case Machining_OperationType.Machining_OT_LatheMilling: return "CNC Machining Lathe+Milling";
default: break;
}
return "CNC Machining";
}
private bool HasShapes(
cadex.Collections.BodyList theBodies, ShapeType theType)
{
for (int i = 0, n = theBodies.Count; i < n; ++i)
{
Body aBody = theBodies[i];
ShapeIterator aShapeIt = new ShapeIterator(aBody, theType);
if (aShapeIt.HasNext())
{
return true;
}
}
return false;
}
private void WriteThicknessNode(
JSONWriter theWriter,
string theParamName,
double theParamValue,
PointPairType thePoints,
string theNodeName)
{
cadex.Geom.Point aFirstPoint = thePoints.Key;
cadex.Geom.Point aSecondPoint = thePoints.Value;
theWriter.OpenSection(theNodeName);
theWriter.WriteData("name", theParamName);
theWriter.WriteData("units", "mm");
theWriter.WriteData("value", theParamValue);
theWriter.WriteData("firstPoint", new Point(aFirstPoint.X(), aFirstPoint.Y(), aFirstPoint.Z()));
theWriter.WriteData("secondPoint", new Point(aSecondPoint.X(), aSecondPoint.Y(), aSecondPoint.Z()));
theWriter.CloseSection();
}
private void WriteWallThicknessData(JSONWriter theWriter, MTKConverter_WallThicknessData theData)
{
WriteThicknessNode(theWriter, "Minimum Thickness", theData.myMinThickness, theData.myMinThicknessPoints, "minThickness");
WriteThicknessNode(theWriter, "Maximum Thickness", theData.myMaxThickness, theData.myMaxThicknessPoints, "maxThickness");
theWriter.OpenArraySection("parameters");
WriteParameter(theWriter, "Minimum Thickness", "mm", theData.myMinThickness);
WriteParameter(theWriter, "Maximum Thickness", "mm", theData.myMaxThickness);
WriteParameter(theWriter, "Average Thickness", "mm", theData.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[0]);
theWriter.WriteRawData(aFeaturesJSON);
}
else
{
theWriter.WriteData("message", "Unfolded part wasn't generated.");
}
theWriter.CloseSection();
}
private void WriteNestingData(
JSONWriter theWriter,
List<Sheet> theResultSheets,
List<double> theFreeSpaces,
uint thePatternCountTotal,
List<uint> theNestedPatternCounts)
{
theWriter.OpenSection("nesting");
theWriter.OpenArraySection("sheets");
for (int i = 0; i < theResultSheets.Count; ++i)
{
Sheet aResultSheet = theResultSheets[i];
double aFreeSpace = i < theFreeSpaces.Count ? theFreeSpaces[i] : 0.0;
uint aNestedPatternCount = i < theNestedPatternCounts.Count ? theNestedPatternCounts[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, List<System.Guid> theUuids)
{
StringBuilder aStream = new StringBuilder();
string aCurrentIndent = new string(' ', theWriter.NestingLevel() * 4);
string aArrayValueIndent = new string(' ', (theWriter.NestingLevel() + 1) * 4);
aStream.Append(aCurrentIndent).Append('"').Append(theName).Append("\": [");
if (theUuids.Count > 0)
{
aStream.AppendLine();
for (int i = 0; i < theUuids.Count; ++i)
{
aStream.Append(aArrayValueIndent).Append('"').Append(theUuids[i]).Append('"');
if (i + 1 < theUuids.Count)
{
aStream.Append(",");
}
aStream.AppendLine();
}
aStream.Append(aCurrentIndent);
}
aStream.Append("]");
theWriter.WriteRawData(aStream.ToString());
}
private bool IsSheetProcessData(MTKConverter_ProcessData theProcessData)
{
return theProcessData is MTKConverter_NestingData;
}
private void WritePartProcessData(JSONWriter theWriter, MTKConverter_ProcessData theProcessData)
{
bool aRes = false;
theWriter.WriteData("partId", theProcessData.myPart.Uuid());
string anErrorMsg = "An error occurred while processing the part.";
if (theProcessData is 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 (!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 is 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 (!HasShapes(aBodies, ShapeType.Solid))
{
anErrorMsg =
"The part can't be analyzed due to lack of: " +
"BRep representation, solids in BRep representation.";
}
}
else if (theProcessData is 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 (!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 is 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 (!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)
{
bool aRes = false;
if (theProcessData is MTKConverter_NestingData)
{
MTKConverter_NestingData aND = (MTKConverter_NestingData)theProcessData;
List<System.Guid> aSourceSheetUuids = new List<System.Guid>();
foreach (Sheet aSheet in aND.mySourceSheets)
{
aSourceSheetUuids.Add(aSheet.Uuid());
}
WriteUuidArray(theWriter, "sourceIds", aSourceSheetUuids);
List<Sheet> aResultSheets = MTKConverter_DrawingProcessor.ExtractDrawingSheets(aND.myResultDrawing);
List<double> aSheetFreeSpaces = new List<double>();
List<uint> aNestedPatternCounts = new List<uint>();
cadex.Collections.Nesting_SheetList aSheets = aND.myNestingResult.Sheets();
for (int i = 0; i < aSheets.Count; ++i)
{
var aSheet = aSheets[i];
aSheetFreeSpaces.Add(aSheet.Scrap() * aSheet.SheetArea());
aNestedPatternCounts.Add(aSheet.NestedParts());
}
if (aResultSheets.Count > 0)
{
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 bool WriteToJSON(UTF16String thePath)
{
string aPath = thePath.ToString();
if (File.Exists(aPath))
{
File.Delete(aPath);
}
try
{
using (StreamWriter aStream = File.CreateText(aPath))
{
JSONWriter aWriter = new JSONWriter(aStream);
aWriter.OpenSection();
aWriter.WriteData("version", "1");
if (myData.Count == 0)
{
aWriter.WriteData("error", "The model doesn't contain any parts.");
}
else
{
bool aHasPartProcessData = false;
bool aHasSheetProcessData = false;
foreach (MTKConverter_ProcessData aProcessData in myData)
{
if (IsSheetProcessData(aProcessData))
{
aHasSheetProcessData = true;
}
else
{
aHasPartProcessData = true;
}
}
if (aHasPartProcessData)
{
aWriter.OpenArraySection("parts");
foreach (MTKConverter_ProcessData aProcessData in myData)
{
if (IsSheetProcessData(aProcessData))
{
continue;
}
aWriter.OpenSection();
WritePartProcessData(aWriter, aProcessData);
aWriter.CloseSection();
}
aWriter.CloseArraySection();
}
if (aHasSheetProcessData)
{
aWriter.OpenArraySection("sheets");
foreach (MTKConverter_ProcessData aProcessData in myData)
{
if (!IsSheetProcessData(aProcessData))
{
continue;
}
aWriter.OpenSection();
WriteSheetProcessData(aWriter, aProcessData);
aWriter.CloseSection();
}
aWriter.CloseArraySection();
}
}
aWriter.CloseSection();
}
}
catch
{
return false;
}
return true;
}
}
}
Contains utility classes that can be useful for debugging or configuring global settings.
MTKConverter_Application.cs
using cadex.Materials;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
namespace mtkconverter
{
enum MTKConverter_ReturnCode
{
Ok = 0,
UnknownError = 1,
GeneralException = 2,
NoValidLicense = 3,
InvalidArgumentsNumber = 4,
InvalidArgument = 5,
UnsupportedVersion = 100,
UnexpectedFormat = 101,
UnsupportedFileVariant = 102,
ImportError = 103,
ProcessError = 200,
ExportError = 300
}
enum MTKConverter_ProcessType
{
Undefined = -1,
WallThickness = 0,
MachiningMilling,
MachiningTurning,
Molding,
SheetMetal,
Nesting
}
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
{
public enum NestingMode
{
PerSheet = 0,
AllSheets = 1
}
public class MaterialParameters
{
public double myLength = 500.0;
public double myWidth = 500.0;
public uint 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 uint myPatternRepeatCount = 4;
public NestingMode myMode = NestingMode.PerSheet;
public Nesting_ComputerParameters myComputerParameters;
}
class MTKConverter_WallThicknessParameters
{
public MTKConverter_WallThicknessParameters() {
var aVoxelizationParameters = myAnalyzerParameters.VoxelizationParameters();
aVoxelizationParameters.SetResolution (800);
}
public WallThickness_AnalyzerParameters myAnalyzerParameters = new WallThickness_AnalyzerParameters();
public double myColorSmoothness = 0.75;
}
class MTKConverter_ExportParameters
{
public bool myIsScreenshotGenerationEnabled = true;
public bool 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)
{
var aProcessDictionary = new Dictionary<string, MTKConverter_ProcessType>()
{
{ "wall_thickness", MTKConverter_ProcessType.WallThickness },
{ "machining_milling", MTKConverter_ProcessType.MachiningMilling },
{ "machining_turning", MTKConverter_ProcessType.MachiningTurning },
{ "molding", MTKConverter_ProcessType.Molding },
{ "sheet_metal", MTKConverter_ProcessType.SheetMetal },
{ "nesting", MTKConverter_ProcessType.Nesting }
};
MTKConverter_ProcessType aProcessType;
if (aProcessDictionary.TryGetValue(theProcessName, out aProcessType))
{
return aProcessType;
}
return MTKConverter_ProcessType.Undefined;
}
private MTKConverter_ReturnCode Import(
string theFilePath,
Model theModel,
MTKConverter_ImportParameters theImportParameters)
{
UTF16String aFilePath = new UTF16String(theFilePath);
Console.Write($"Importing {theFilePath}...");
ModelReader aReader = new ModelReader();
aReader.SetParameters(theImportParameters.myReaderParameters);
if (!aReader.Read(aFilePath, theModel))
{
Console.WriteLine($"\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);
foreach (MTKConverter_ProcessData i in 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)
{
Console.WriteLine("\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;
}
foreach (MTKConverter_ProcessData i in 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)
{
Console.Write($"Processing {theProcess}...");
switch (FindProcessType(theProcess))
{
case MTKConverter_ProcessType.WallThickness:
{
theProcessModel.SetName(new UTF16String("extra"));
MTKConverter_WallThicknessProcessor aProcessor =
new MTKConverter_WallThicknessProcessor(
theProcessModel,
theParameters.myWallThicknessParameters);
return ApplyPartProcessorToModel(theModel, theReport, aProcessor);
}
case MTKConverter_ProcessType.MachiningMilling:
{
MTKConverter_MachiningProcessor aProcessor =
new MTKConverter_MachiningProcessor(Machining_OperationType.Machining_OT_Milling);
return ApplyPartProcessorToModel(theModel, theReport, aProcessor);
}
case MTKConverter_ProcessType.MachiningTurning:
{
MTKConverter_MachiningProcessor aProcessor =
new MTKConverter_MachiningProcessor(Machining_OperationType.Machining_OT_LatheMilling);
return ApplyPartProcessorToModel(theModel, theReport, aProcessor);
}
case MTKConverter_ProcessType.Molding:
{
theProcessModel.SetName(new UTF16String(theModel.Name() + "_extra"));
MTKConverter_MoldingProcessor aProcessor = new MTKConverter_MoldingProcessor(theProcessModel);
return ApplyPartProcessorToModel(theModel, theReport, aProcessor);
}
case MTKConverter_ProcessType.SheetMetal:
{
theProcessModel.SetName(new UTF16String(theModel.Name() + "_unfolded"));
MTKConverter_SheetMetalProcessor aProcessor = new MTKConverter_SheetMetalProcessor(theProcessModel);
return ApplyPartProcessorToModel(theModel, theReport, aProcessor);
}
case MTKConverter_ProcessType.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 bool 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 bool ExportMTKWEB(
string theFolderPath,
Model theModelToExport,
UTF16String theBaseName)
{
UTF16String aPath = new UTF16String(theFolderPath + "/" + theBaseName + ".mtkweb/scenegraph.mtkweb");
if (!theModelToExport.Save(aPath, Model.FileFormatType.MTKWEB))
{
Console.WriteLine($"\nERROR: Failed to export {aPath}. Exiting");
return false;
}
return true;
}
private bool 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))
{
Console.WriteLine($"\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)
{
Console.Write($"Exporting {theFolderPath}...");
Directory.CreateDirectory(theFolderPath);
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))
{
Console.WriteLine($"\nERROR: Failed to create thumbnail {aThumbnailPath}. Exiting");
return MTKConverter_ReturnCode.ExportError;
}
if (!theProcessModel.IsEmpty() || theProcessModel.Drawing() != null)
{
if (!ExportMTKWEB(theFolderPath, theProcessModel, aProcessedBaseName))
{
return MTKConverter_ReturnCode.ExportError;
}
if (theExportParameters.myIsExportMTKEnabled)
{
if (!ExportMTK(theFolderPath, theProcessModel, aProcessedBaseName))
{
return MTKConverter_ReturnCode.ExportError;
}
}
}
UTF16String aJsonPath = new UTF16String(theFolderPath + "/process_data.json");
if (!theReport.WriteToJSON(aJsonPath))
{
Console.WriteLine($"\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,
List<MTKConverter_Argument> theArguments)
{
MTKConverter_ArgumentType anArgumentType = MTKConverter_ArgumentType.Neutral;
for (int i = 0; i < args.Length; ++i)
{
string anArgument = args[i];
if (anArgument == "--no-screenshot")
{
theParameters.myExportParameters.myIsScreenshotGenerationEnabled = false;
}
else if (anArgument == "--export_mtk")
{
theParameters.myExportParameters.myIsExportMTKEnabled = true;
}
else if (anArgument == "--sheet_size")
{
if (i + 2 >= args.Length)
{
Console.WriteLine("ERROR: Missing values for --sheet_size. Use --sheet_size <L> <W> with values > 0.");
return MTKConverter_ReturnCode.InvalidArgument;
}
double aSheetLength;
double aSheetWidth;
if (!double.TryParse(args[++i], NumberStyles.Float, CultureInfo.InvariantCulture, out aSheetLength) ||
!double.TryParse(args[++i], NumberStyles.Float, CultureInfo.InvariantCulture, out aSheetWidth) ||
aSheetLength <= 0.0 || aSheetWidth <= 0.0)
{
Console.WriteLine("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 == "--pattern_count")
{
if (i + 1 >= args.Length)
{
Console.WriteLine("ERROR: Missing value for --pattern_count. Use --pattern_count <N> with value > 0.");
return MTKConverter_ReturnCode.InvalidArgument;
}
int aPatternRepeatCount;
if (!int.TryParse(args[++i], NumberStyles.Integer, CultureInfo.InvariantCulture, out aPatternRepeatCount) ||
aPatternRepeatCount <= 0)
{
Console.WriteLine("ERROR: Invalid pattern count. Use --pattern_count <N> with value > 0.");
return MTKConverter_ReturnCode.InvalidArgument;
}
theParameters.myNestingParameters.myPatternRepeatCount = (uint)aPatternRepeatCount;
}
else if (anArgument == "--nesting_mode")
{
if (i + 1 >= args.Length)
{
Console.WriteLine("ERROR: Missing value for --nesting_mode. Use --nesting_mode per_sheet|all_sheets.");
return MTKConverter_ReturnCode.InvalidArgument;
}
string aModeArg = args[++i];
if (aModeArg == "per_sheet")
{
theParameters.myNestingParameters.myMode = MTKConverter_NestingParameters.NestingMode.PerSheet;
}
else if (aModeArg == "all_sheets")
{
theParameters.myNestingParameters.myMode = MTKConverter_NestingParameters.NestingMode.AllSheets;
}
else
{
Console.WriteLine($"ERROR: Invalid nesting mode \"{aModeArg}\". Use --nesting_mode per_sheet|all_sheets.");
return MTKConverter_ReturnCode.InvalidArgument;
}
}
else if (anArgument == "-i")
{
anArgumentType = MTKConverter_ArgumentType.Import;
}
else if (anArgument == "-p")
{
anArgumentType = MTKConverter_ArgumentType.Process;
}
else if (anArgument == "-e")
{
anArgumentType = MTKConverter_ArgumentType.Export;
}
else
{
switch (anArgumentType)
{
case MTKConverter_ArgumentType.Import:
theArguments.Add(new MTKConverter_Argument(MTKConverter_ArgumentType.Import, anArgument));
break;
case MTKConverter_ArgumentType.Process:
{
MTKConverter_ProcessType aProcessType = FindProcessType(anArgument);
if (aProcessType == MTKConverter_ProcessType.Undefined)
{
Console.WriteLine($"ERROR: Unknown process \"{anArgument}\".");
Console.WriteLine("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 MTKConverter_ArgumentType.Export:
theArguments.Add(new MTKConverter_Argument(MTKConverter_ArgumentType.Export, anArgument));
break;
default:
Console.WriteLine($"ERROR!: Invalid argument {anArgument}. Exiting");
Console.WriteLine("Type -h for help.");
return MTKConverter_ReturnCode.InvalidArgument;
}
}
}
if (theArguments.Count == 0)
{
Console.WriteLine("ERROR: No commands specified. Use -i/-p/-e.");
return MTKConverter_ReturnCode.InvalidArgument;
}
return MTKConverter_ReturnCode.Ok;
}
private MTKConverter_ReturnCode Execute(
List<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;
foreach (MTKConverter_Argument anArgument in theArguments)
{
if (aResultCode != MTKConverter_ReturnCode.Ok)
{
break;
}
try
{
switch (anArgument.myArgumentType)
{
case MTKConverter_ArgumentType.Import:
aProcessModel = new Model();
aResultCode = Import(anArgument.myValue, aModel, theParameters.myImportParameters);
if (aResultCode == MTKConverter_ReturnCode.Ok)
{
aModel.AssignUuids();
}
break;
case MTKConverter_ArgumentType.Process:
aResultCode = Process(anArgument.myValue, aModel, aReport, aProcessModel, theParameters);
break;
case MTKConverter_ArgumentType.Export:
aResultCode = Export(
anArgument.myValue,
theParameters.myExportParameters,
aModel,
aReport,
aProcessModel);
break;
default:
aResultCode = MTKConverter_ReturnCode.InvalidArgument;
break;
}
if (aResultCode == MTKConverter_ReturnCode.Ok)
{
Console.WriteLine("Done.");
}
}
catch
{
Console.WriteLine("Failed.\nERROR: Unhandled exception caught.");
return MTKConverter_ReturnCode.GeneralException;
}
}
return aResultCode;
}
public MTKConverter_ReturnCode Run(string[] args)
{
if (args.Length == 0 ||
args[0] == "-?" || args[0] == "/?" || args[0] == "-h" || args[0] == "--help")
{
PrintUsage();
return MTKConverter_ReturnCode.Ok;
}
if (args.Length < 6)
{
Console.WriteLine("Invalid number of arguments. Please use \"-h\" or \"--help\" for usage information.");
return MTKConverter_ReturnCode.InvalidArgumentsNumber;
}
MTKConverter_Parameters aParameters = new MTKConverter_Parameters();
List<MTKConverter_Argument> anArguments = new List<MTKConverter_Argument>();
MTKConverter_ReturnCode aParseRes = ParseArguments(args, aParameters, anArguments);
if (aParseRes != MTKConverter_ReturnCode.Ok)
{
return aParseRes;
}
return Execute(anArguments, aParameters);
}
public void PrintUsage()
{
Console.WriteLine("Usage:");
Console.WriteLine("MTKConverter -i <import_file> -p <process> ... -e <export_target> [options]");
Console.WriteLine();
Console.WriteLine("Arguments:");
Console.WriteLine(" <import_file> - import file name");
Console.WriteLine(" <process> - manufacturing process or algorithm name");
Console.WriteLine(" <export_target> - export folder name");
Console.WriteLine();
Console.WriteLine("Export Options:");
Console.WriteLine(" --no-screenshot - disable screenshot generation (optional)");
Console.WriteLine(" --export_mtk - additionally save process model as *.mtk in <export_target>");
Console.WriteLine();
Console.WriteLine("Example:");
Console.WriteLine("MTKConverter -i C:\\models\\test.step -p machining_milling -e C:\\models\\out");
Console.WriteLine("MTKConverter -i C:\\models\\test.step -p nesting -e C:\\models\\out --export_mtk");
Console.WriteLine(
"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");
Console.WriteLine();
Console.WriteLine("Recognized processes:");
Console.WriteLine(" wall_thickness :\t Wall Thickness analysis");
Console.WriteLine(" machining_milling:\t CNC Machining Milling feature recognition and DFM analysis");
Console.WriteLine(" machining_turning:\t CNC Machining Lathe+Milling feature recognition and DFM analysis");
Console.WriteLine(" molding :\t Molding feature recognition and DFM analysis");
Console.WriteLine(" sheet_metal :\t Sheet Metal feature recognition, unfolding and DFM analysis");
Console.WriteLine(" nesting :\t Nesting using source drawing or sheet metal unfolding drawing");
Console.WriteLine(" parameters :\t --sheet_size <L> <W> (default: 500 500)");
Console.WriteLine(" :\t --pattern_count <N> (default: 4)");
Console.WriteLine(" :\t --nesting_mode per_sheet|all_sheets (default: per_sheet)");
}
}
}
Contains classes, types, enums, and functions related to image generation.
Program.cs
using System;
namespace mtkconverter
{
class Program
{
static int Main(string[] args)
{
string aKey = MTKLicenseKey.Value();
if (!LicenseManager.Activate(aKey))
{
Console.WriteLine("Failed to activate Manufacturing Toolkit license.");
return 1;
}
MTKConverter_Application anApp = new MTKConverter_Application();
return (int)anApp.Run(args);
}
}
}