Hide menu
Loading...
Searching...
No Matches
MTKConverter/MTKConverter.py

Refer to the MTK Converter Example.

MTKConverter_PartProcessor.py

1# $Id$
2
3# Copyright (C) 2008-2014, Roman Lygin. All rights reserved.
4# Copyright (C) 2014-2025, CADEX. All rights reserved.
5
6# This file is part of the Manufacturing Toolkit software.
7
8# You may use this file under the terms of the BSD license as follows:
9
10# Redistribution and use in source and binary forms, with or without
11# modification, are permitted provided that the following conditions are met:
12# * Redistributions of source code must retain the above copyright notice,
13# this list of conditions and the following disclaimer.
14# * Redistributions in binary form must reproduce the above copyright notice,
15# this list of conditions and the following disclaimer in the documentation
16# and/or other materials provided with the distribution.
17
18# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28# POSSIBILITY OF SUCH DAMAGE.
29
30from abc import abstractmethod
31
32import manufacturingtoolkit.CadExMTK as mtk
33
34class MTKConverter_ProcessData:
35 def __init__(self, thePart: mtk.ModelData_Part):
36 self.myPart = thePart
37
38class MTKConverter_PartProcessor(mtk.ModelData_ModelElementVoidVisitor):
39 def __init__(self):
40 super().__init__()
41 self.myData = []
42
43 def VisitPart(self, thePart: mtk.ModelData_Part):
44 aPartWasProcessed = False
45 aProcessData = self.CreateProcessData(thePart)
46
47 aBodyList = thePart.Bodies()
48 for aBody in aBodyList:
49 aShapeIt = mtk.ModelData_ShapeIterator(aBody)
50 for aShape in aShapeIt:
51 if aShape.Type() == mtk.ShapeType_Solid:
52 self.ProcessSolid(aProcessData, mtk.ModelData_Solid.Cast(aShape))
53 aPartWasProcessed = True
54 elif aShape.Type() == mtk.ShapeType_Shell:
55 self.ProcessShell(thePart, mtk.ModelData_Shell.Cast(aShape))
56 aPartWasProcessed = True
57 if aPartWasProcessed:
58 self.PostProcessPart (thePart)
59 self.myData.append(aProcessData)
60
61 @abstractmethod
62 def CreateProcessData(self, thePart: mtk.ModelData_Part):
63 pass
64
65 @abstractmethod
66 def ProcessSolid(self, theProcessData: MTKConverter_ProcessData, theSolid: mtk.ModelData_Solid):
67 pass
68
69 @abstractmethod
70 def ProcessShell(self, thePart: mtk.ModelData_Part, theShell: mtk.ModelData_Shell):
71 pass
72
73 @abstractmethod
74 def PostProcessPart(self, thePart: mtk.ModelData_Part):
75 pass
76
77class MTKConverter_VoidPartProcessor(MTKConverter_PartProcessor):
78 def __init__(self):
79 super().__init__()
80
81 def ProcessSolid (self, thePart: mtk.ModelData_Part, theSolid: mtk.ModelData_Solid):
82 pass
83
84 def ProcessShell (self, thePart: mtk.ModelData_Part, theShell: mtk.ModelData_Shell):
85 pass
86
87 def PostProcessPart(self, thePart: mtk.ModelData_Part):
88 pass
89

MTKConverter_MachiningProcessor.py

1# $Id$
2#
3# Copyright (C) 2008-2014, Roman Lygin. All rights reserved.
4# Copyright (C) 2014-2025, CADEX. All rights reserved.
5#
6# This file is part of the Manufacturing Toolkit software.
7#
8# You may use this file under the terms of the BSD license as follows:
9#
10# Redistribution and use in source and binary forms, with or without
11# modification, are permitted provided that the following conditions are met:
12# * Redistributions of source code must retain the above copyright notice,
13# this list of conditions and the following disclaimer.
14# * Redistributions in binary form must reproduce the above copyright notice,
15# this list of conditions and the following disclaimer in the documentation
16# and/or other materials provided with the distribution.
17#
18# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28# POSSIBILITY OF SUCH DAMAGE.
29
30import manufacturingtoolkit.CadExMTK as mtk
31
32import MTKConverter_PartProcessor as part_proc
33
34class MTKConverter_MachiningData(part_proc.MTKConverter_ProcessData):
35 def __init__(self, thePart: mtk.ModelData_Part):
36 super().__init__(thePart)
37 self.myFeatureList = mtk.MTKBase_FeatureList()
38 self.myIssueList = mtk.MTKBase_FeatureList()
39 self.myOperation = mtk.Machining_OT_Undefined
40
41class MTKConverter_MachiningProcessor(part_proc.MTKConverter_VoidPartProcessor):
42 def __init__(self, theOperation):
43 super().__init__()
44 self.myOperation = theOperation
45
46 def CreateProcessData(self, thePart: mtk.ModelData_Part):
47 return MTKConverter_MachiningData(thePart)
48
49 def ProcessSolid (self, theMachiningData: MTKConverter_MachiningData, theSolid: mtk.ModelData_Solid):
50 theMachiningData.myOperation = self.myOperation
51
52 aParams = mtk.Machining_FeatureRecognizerParameters()
53 aParams.SetOperation(self.myOperation)
54 aFeatureRecognizer = mtk.Machining_FeatureRecognizer(aParams)
55 anAnalyzer = mtk.Machining_Analyzer()
56 anAnalyzer.AddTool (aFeatureRecognizer)
57 aData = anAnalyzer.Perform(theSolid)
58 if aData.IsEmpty():
59 return
60
61 # Features
62 for i in aData.FeatureList():
63 theMachiningData.myFeatureList.Append(i)
64
65 # Issues
66 aDrillingParameters = mtk.DFMMachining_DrillingAnalyzerParameters()
67 aDrillingAnalyzer = mtk.DFMMachining_Analyzer(aDrillingParameters)
68 theMachiningData.myIssueList.Append(aDrillingAnalyzer.Perform(theSolid, aData))
69
70 aMillingParameters = mtk.DFMMachining_MillingAnalyzerParameters()
71 aMillingAnalyzer = mtk.DFMMachining_Analyzer(aMillingParameters)
72 aMillingIssueList = aMillingAnalyzer.Perform(theSolid, aData)
73 for anIssue in aMillingIssueList:
74 if self.myOperation == mtk.Machining_OT_LatheMilling and not mtk.DFMMachining_DeepPocketIssue.CompareType(anIssue):
75 continue
76 theMachiningData.myIssueList.Append(anIssue)
77
78 if self.myOperation == mtk.Machining_OT_LatheMilling:
79 aTurninigParameters = mtk.DFMMachining_TurningAnalyzerParameters()
80 aTurningAnalyzer = mtk.DFMMachining_Analyzer(aTurninigParameters)
81 aTurningIssueList = aTurningAnalyzer.Perform(theSolid, aData)
82 for anIssue in aTurningIssueList:
83 theMachiningData.myIssueList.Append(anIssue)

MTKConverter_SheetMetalProcessor.py

1# $Id$
2#
3# Copyright (C) 2008-2014, Roman Lygin. All rights reserved.
4# Copyright (C) 2014-2025, CADEX. All rights reserved.
5#
6# This file is part of the Manufacturing Toolkit software.
7#
8# You may use this file under the terms of the BSD license as follows:
9#
10# Redistribution and use in source and binary forms, with or without
11# modification, are permitted provided that the following conditions are met:
12# * Redistributions of source code must retain the above copyright notice,
13# this list of conditions and the following disclaimer.
14# * Redistributions in binary form must reproduce the above copyright notice,
15# this list of conditions and the following disclaimer in the documentation
16# and/or other materials provided with the distribution.
17#
18# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28# POSSIBILITY OF SUCH DAMAGE.
29
30import manufacturingtoolkit.CadExMTK as mtk
31
32import MTKConverter_PartProcessor as part_proc
33
34class MTKConverter_UnfoldedPartData:
35 def __init__(self):
36 self.myIsInit = False
37 self.myLength = 0.0
38 self.myWidth = 0.0
39 self.myThickness = 0.0
40 self.myPerimeter = 0.0
41 self.myIssueList = mtk.MTKBase_FeatureList()
42
43class MTKConverter_SheetMetalData(part_proc.MTKConverter_ProcessData):
44 def __init__(self, thePart: mtk.ModelData_Part):
45 super().__init__(thePart)
46 self.myIsSheetMetalPart = False
47 self.myFeatureList = mtk.MTKBase_FeatureList()
48 self.myIssueList = mtk.MTKBase_FeatureList()
49 self.myUnfoldedPartData = MTKConverter_UnfoldedPartData()
50
51class MTKConverter_SheetMetalProcessor(part_proc.MTKConverter_VoidPartProcessor):
52 def __init__(self, theUnfoldedModel: mtk.ModelData_Model):
53 super().__init__()
54 self.myAnalyzer = mtk.SheetMetal_Analyzer()
55 self.myUnfoldedModel = theUnfoldedModel
56 self.myCurrentUnfoldedBody = mtk.ModelData_SheetBody()
57
58 self.myAnalyzer.AddTool(mtk.SheetMetal_FeatureRecognizer())
59 self.myAnalyzer.AddTool(mtk.SheetMetal_Unfolder())
60
61 def CreateProcessData(self, thePart: mtk.ModelData_Part):
62 return MTKConverter_SheetMetalData(thePart)
63
64 def __Process(self, theSMData: MTKConverter_SheetMetalData, theData: mtk.SheetMetal_Data):
65 if theData.IsEmpty():
66 return
67
68 theSMData.myIsSheetMetalPart = True
69 theSMData.myFeatureList.Append(theData.FeatureList())
70
71 anUnfoldedData = theSMData.myUnfoldedPartData
72 aFlatPattern = theData.FlatPattern()
73 if not aFlatPattern.IsNull():
74 anUnfoldedShell = aFlatPattern.UnfoldedShell()
75 if anUnfoldedShell:
76 self.myCurrentUnfoldedBody.Append(anUnfoldedShell)
77 if not anUnfoldedData.myIsInit:
78 anUnfoldedData.myLength = aFlatPattern.Length()
79 anUnfoldedData.myWidth = aFlatPattern.Width()
80 anUnfoldedData.myThickness = aFlatPattern.Thickness()
81 anUnfoldedData.myPerimeter = aFlatPattern.Perimeter()
82 anUnfoldedData.myIsInit = True
83
84 aDFMAnalyzer = mtk.DFMSheetMetal_Analyzer()
85 anIssueList = aDFMAnalyzer.Perform(theData)
86 for anIssue in anIssueList:
87 if (anUnfoldedData.myIsInit
88 and (mtk.DFMSheetMetal_FlatPatternInterferenceIssue.CompareType(anIssue)
89 or mtk.DFMSheetMetal_NonStandardSheetSizeIssue.CompareType(anIssue)
90 or mtk.DFMSheetMetal_NonStandardSheetThicknessIssue.CompareType(anIssue))):
91 anUnfoldedData.myIssueList.Append(anIssue)
92 else:
93 theSMData.myIssueList.Append(anIssue)
94
95 def ProcessSolid (self, theProcessData: MTKConverter_SheetMetalData, theSolid: mtk.ModelData_Solid):
96 aData = self.myAnalyzer.Perform(theSolid)
97 self.__Process(theProcessData, aData)
98
99 def ProcessShell (self, theMachiningData: MTKConverter_SheetMetalData, theShell: mtk.ModelData_Shell):
100 aData = self.myAnalyzer.Perform(theShell)
101 self.__Process(theProcessData, aData)
102
103 def PostProcessPart(self, thePart: mtk.ModelData_Part):
104 if len(self.myCurrentUnfoldedBody.Shapes()) == 0:
105 return
106
107 anUnfoldedPart = mtk.ModelData_Part(thePart.Name())
108 anUnfoldedPart.SetUuid(thePart.Uuid())
109 anUnfoldedPart.AddBody(self.myCurrentUnfoldedBody)
110
111 self.myUnfoldedModel.AddRoot(anUnfoldedPart)
112 self.myCurrentUnfoldedBody = mtk.ModelData_SheetBody()

MTKConverter_Report.py

1# $Id$
2
3# Copyright (C) 2008-2014, Roman Lygin. All rights reserved.
4# Copyright (C) 2014-2025, CADEX. All rights reserved.
5
6# This file is part of the Manufacturing Toolkit software.
7
8# You may use this file under the terms of the BSD license as follows:
9
10# Redistribution and use in source and binary forms, with or without
11# modification, are permitted provided that the following conditions are met:
12# * Redistributions of source code must retain the above copyright notice,
13# this list of conditions and the following disclaimer.
14# * Redistributions in binary form must reproduce the above copyright notice,
15# this list of conditions and the following disclaimer in the documentation
16# and/or other materials provided with the distribution.
17
18# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28# POSSIBILITY OF SUCH DAMAGE.
29
30import manufacturingtoolkit.CadExMTK as mtk
31
32import MTKConverter_PartProcessor as part_proc
33import MTKConverter_MachiningProcessor as mach_proc
34import MTKConverter_MoldingProcessor as mold_proc
35import MTKConverter_SheetMetalProcessor as sm_proc
36import MTKConverter_WallThicknessProcessor as wt_proc
37
38import io
39import os
40import sys
41
42from pathlib import Path
43
44sys.path.append(os.path.abspath(os.path.dirname(Path(__file__).resolve()) + "/../helpers/"))
45
46from JSONWriter import JSONWriter
47
48class Point:
49 def __init__(self, theX: float, theY: float, theZ: float):
50 self.X = theX
51 self.Y = theY
52 self.Z = theZ
53
54 def __repr__(self):
55 return f"Point({self.X}, {self.Y}, {self.Z})"
56
57 def __str__(self):
58 return f"({self.X:.2f}, {self.Y:.2f}, {self.Z:.2f})"
59
60class MTKConverter_Report:
61 def __init__(self):
62 self.__myData = []
63
64 def AddData(self, theData: part_proc.MTKConverter_ProcessData):
65 self.__myData.append(theData)
66
67 def WriteToJSON(self, thePath: str):
68 aFile = open(thePath, "w", encoding="utf-8")
69 if not aFile:
70 return False
71
72 aWriter = JSONWriter(aFile)
73 aWriter.OpenSection()
74 aWriter.WriteData("version", "1")
75
76 if not self.__myData:
77 aWriter.WriteData("error", "The model doesn't contain any parts.")
78 else:
79 aWriter.OpenArraySection("parts")
80 for aProcessData in self.__myData:
81 aWriter.OpenSection()
82 MTKConverter_Report.__WritePartProcessData(aWriter, aProcessData)
83 aWriter.CloseSection()
84 aWriter.CloseArraySection()
85 aWriter.CloseSection()
86
87 aFile.close()
88 return True
89
90 @staticmethod
91 def __WriteParameter(theWriter: JSONWriter, theParamName: str, theParamUnits: str, theParamValue):
92 theWriter.OpenSection()
93 theWriter.WriteData("name", theParamName)
94 theWriter.WriteData("units", theParamUnits)
95 theWriter.WriteData("value", theParamValue)
96 theWriter.CloseSection()
97
98 @staticmethod
99 def __WriteFeatures(theWriter: JSONWriter, theGroupName: str, theSubgroupName: str,
100 theFeatures: mtk.MTKBase_FeatureList, theMessageForEmptyList: str):
101 theWriter.OpenSection(theSubgroupName)
102 theWriter.WriteData("name", theGroupName)
103
104 if theFeatures.IsEmpty():
105 theWriter.WriteData("message", theMessageForEmptyList)
106 else:
107 aParams = mtk.Utilities_JSONSerializerParameters()
108 aParams.SetStartIndentLevel(theWriter.NestingLevel())
109 aJSONSerializer = mtk.Utilities_JSONSerializer(aParams)
110 aFeaturesJSON = aJSONSerializer.Serialize(theFeatures)
111 theWriter.WriteRawData(aFeaturesJSON)
112
113 theWriter.CloseSection()
114
115 return True
116
117 @staticmethod
118 def __MachiningProcessName(theOperation):
119 aProcessMap = {
120 mtk.Machining_OT_Milling: "CNC Machining Milling",
121 mtk.Machining_OT_LatheMilling: "CNC Machining Lathe+Milling"
122 }
123
124 if theOperation in aProcessMap:
125 return aProcessMap[theOperation]
126 else:
127 return "CNC Machining"
128
129 @staticmethod
130 def __HasShapes(thePart: mtk.ModelData_Part, theType):
131 aBodyList = thePart.Bodies()
132 for aBody in aBodyList:
133 aShapeIt = mtk.ModelData_ShapeIterator(aBody, theType)
134 if aShapeIt.HasNext():
135 return True
136 return False
137
138 @staticmethod
139 def __WriteThicknessNode(theWriter: JSONWriter, theParamName: str, theParamValue: int,
140 thePoints: wt_proc.PointPair, theNodeName: str):
141 aFirstPoint = thePoints.First
142 aSecondPoint = thePoints.Second
143 theWriter.OpenSection(theNodeName)
144 theWriter.WriteData("name", theParamName)
145 theWriter.WriteData("units", "mm")
146 theWriter.WriteData("value", theParamValue)
147 theWriter.WriteData("firstPoint", Point(aFirstPoint.X(), aFirstPoint.Y(), aFirstPoint.Z()))
148 theWriter.WriteData("secondPoint", Point(aSecondPoint.X(), aSecondPoint.Y(), aSecondPoint.Z()))
149 theWriter.CloseSection()
150
151 @staticmethod
152 def __WriteUnfoldedPartFeatures(theWriter: JSONWriter, theData: sm_proc.MTKConverter_UnfoldedPartData):
153 theWriter.OpenSection("featureRecognitionUnfolded")
154 theWriter.WriteData("name", "Feature Recognition")
155
156 if theData.myIsInit:
157 aStream = io.StringIO()
158 aWriter = JSONWriter(aStream, 4)
159
160 aWriter.WriteData("parametersCount", 4)
161 aWriter.OpenArraySection("parameters")
162 MTKConverter_Report.__WriteParameter(aWriter, "Length", "mm", theData.myLength)
163 MTKConverter_Report.__WriteParameter(aWriter, "Width", "mm", theData.myWidth)
164 MTKConverter_Report.__WriteParameter(aWriter, "Thickness", "mm", theData.myThickness)
165 MTKConverter_Report.__WriteParameter(aWriter, "Perimeter", "mm", theData.myPerimeter)
166 aWriter.CloseArraySection()
167
168 theWriter.WriteRawData(aStream.getvalue())
169 aStream.close()
170 else:
171 theWriter.WriteData("message", "Unfolded part wasn't generated.")
172
173 theWriter.CloseSection()
174
175 @staticmethod
176 def __WritePartProcessData(theWriter: JSONWriter, theProcessData):
177 aRes = False
178 theWriter.WriteData("partId", theProcessData.myPart.Uuid())
179
180 anErrorMsg = "An error occurred while processing the part."
181 if type(theProcessData) is mach_proc.MTKConverter_MachiningData:
182 theWriter.WriteData("process", MTKConverter_Report.__MachiningProcessName(theProcessData.myOperation))
183 if not theProcessData.myFeatureList.IsEmpty():
184 MTKConverter_Report.__WriteFeatures(theWriter, "Feature Recognition", "featureRecognition",
185 theProcessData.myFeatureList, "")
186 MTKConverter_Report.__WriteFeatures(theWriter, "Design for Manufacturing", "dfm", theProcessData.myIssueList,
187 "Part contains no DFM improvement suggestions.")
188 aRes = True
189 elif not MTKConverter_Report.__HasShapes(theProcessData.myPart, mtk.ShapeType_Solid):
190 anErrorMsg = "The part can't be analyzed due to lack of: BRep representation or solids in BRep representation."
191 elif type(theProcessData) is mold_proc.MTKConverter_MoldingData:
192 theWriter.WriteData("process", "Molding Analysis")
193 if not theProcessData.myFeatureList.IsEmpty():
194 MTKConverter_Report.__WriteFeatures(theWriter, "Feature Recognition", "featureRecognition",
195 theProcessData.myFeatureList, "")
196 MTKConverter_Report.__WriteFeatures(theWriter, "Design for Manufacturing", "dfm", theProcessData.myIssueList,
197 "Part contains no DFM improvement suggestions.")
198 aRes = True
199 elif not MTKConverter_Report.__HasShapes(theProcessData.myPart, mtk.ShapeType_Solid):
200 anErrorMsg = "The part can't be analyzed due to lack of: BRep representation or solids in BRep representation."
201 elif type(theProcessData) is sm_proc.MTKConverter_SheetMetalData:
202 theWriter.WriteData("process", "Sheet Metal")
203 if theProcessData.myIsSheetMetalPart:
204 MTKConverter_Report.__WriteFeatures(theWriter, "Feature Recognition", "featureRecognition",
205 theProcessData.myFeatureList, "Part contains no features.")
206 MTKConverter_Report.__WriteFeatures(theWriter, "Design for Manufacturing", "dfm", theProcessData.myIssueList,
207 "Part contains no DFM improvement suggestions.")
208
209 anUnfoldedPartData = theProcessData.myUnfoldedPartData
210 MTKConverter_Report.__WriteUnfoldedPartFeatures(theWriter, anUnfoldedPartData)
211 if anUnfoldedPartData.myIsInit:
212 MTKConverter_Report.__WriteFeatures(theWriter, "Design for Manufacturing", "dfmUnfolded",
213 anUnfoldedPartData.myIssueList,
214 "Unfolded part contains no DFM improvement suggestions.")
215 aRes = True
216 elif (not MTKConverter_Report.__HasShapes(theProcessData.myPart, mtk.ShapeType_Solid)
217 and (not MTKConverter_Report.__HasShapes(theProcessData.myPart, mtk.ShapeType_Shell))):
218 anErrorMsg = "The part can't be analyzed due to lack of: BRep representation, solids and shells in BRep representation."
219 else:
220 anErrorMsg = "The part wasn't recognized as a sheet metal part."
221 elif type(theProcessData) is wt_proc.MTKConverter_WallThicknessData:
222 theWriter.WriteData("process", "Wall Thickness Analysis")
223 if theProcessData.myIsInit:
224 MTKConverter_Report.__WriteThicknessNode(theWriter, "Minimum Thickness", theProcessData.myMinThickness,
225 theProcessData.myMinThicknessPoints, "minThickness")
226 MTKConverter_Report.__WriteThicknessNode(theWriter, "Maximum Thickness", theProcessData.myMaxThickness,
227 theProcessData.myMaxThicknessPoints, "maxThickness")
228 aRes = True
229 elif not MTKConverter_Report.__HasShapes(theProcessData.myPart.Bodies(), cadex.ModelData_ST_Solid):
230 anErrorMsg = "The part can't be analyzed due to lack of: BRep representation, solids in BRep representation."
231 else:
232 anErrorMsg = "Unrecognized process"
233
234 if not aRes:
235 theWriter.WriteData("error", anErrorMsg)

MTKConverter_Application.py

1# $Id$
2
3# Copyright (C) 2008-2014, Roman Lygin. All rights reserved.
4# Copyright (C) 2014-2025, CADEX. All rights reserved.
5
6# This file is part of the Manufacturing Toolkit software.
7
8# You may use this file under the terms of the BSD license as follows:
9
10# Redistribution and use in source and binary forms, with or without
11# modification, are permitted provided that the following conditions are met:
12# * Redistributions of source code must retain the above copyright notice,
13# this list of conditions and the following disclaimer.
14# * Redistributions in binary form must reproduce the above copyright notice,
15# this list of conditions and the following disclaimer in the documentation
16# and/or other materials provided with the distribution.
17
18# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28# POSSIBILITY OF SUCH DAMAGE.
29
30from enum import Enum
31
32import os
33import manufacturingtoolkit.CadExMTK as mtk
34import manufacturingtoolkit.MTKView as view
35
36import MTKConverter_PartProcessor as part_proc
37
38from MTKConverter_Report import MTKConverter_Report
39from MTKConverter_MachiningProcessor import MTKConverter_MachiningProcessor
40from MTKConverter_MoldingProcessor import MTKConverter_MoldingProcessor
41from MTKConverter_SheetMetalProcessor import MTKConverter_SheetMetalProcessor
42from MTKConverter_WallThicknessProcessor import MTKConverter_WallThicknessProcessor
43
44class MTKConverter_ProcessType(Enum):
45 MTKConverter_PT_Undefined = -1
46 MTKConverter_PT_WallThickness = 0
47 MTKConverter_PT_MachiningMilling = 1
48 MTKConverter_PT_MachiningTurning = 2
49 MTKConverter_PT_Molding = 3
50 MTKConverter_PT_SheetMetal = 4
51
52class MTKConverter_ReturnCode(Enum):
53 # General codes
54 MTKConverter_RC_OK = 0
55 MTKConverter_RC_UnknownError = 1
56 MTKConverter_RC_GeneralException = 2
57 MTKConverter_RC_NoValidLicense = 3
58 MTKConverter_RC_InvalidArgumentsNumber = 4
59 MTKConverter_RC_InvalidArgument = 5
60
61 # Import errors
62 MTKConverter_RC_UnsupportedVersion = 100
63 MTKConverter_RC_UnexpectedFormat = 101
64 MTKConverter_RC_UnsupportedFileVariant = 102
65 MTKConverter_RC_ImportError = 103
66
67 # Process errors
68 MTKConverter_RC_ProcessError = 200
69
70 # Export errors
71 MTKConverter_RC_ExportError = 300
72
73class MTKConverter_Application:
74 def __init__(self):
75 pass
76
77 @staticmethod
78 def __ProcessType(theProcessName: str):
79 aProcessMap = {
80 "wall_thickness": MTKConverter_ProcessType.MTKConverter_PT_WallThickness,
81 "machining_milling": MTKConverter_ProcessType.MTKConverter_PT_MachiningMilling,
82 "machining_turning": MTKConverter_ProcessType.MTKConverter_PT_MachiningTurning,
83 "molding": MTKConverter_ProcessType.MTKConverter_PT_Molding,
84 "sheet_metal": MTKConverter_ProcessType.MTKConverter_PT_SheetMetal
85 }
86
87 if theProcessName in aProcessMap:
88 return aProcessMap[theProcessName]
89 else:
90 return MTKConverter_ProcessType.MTKConverter_PT_Undefined
91
92 @staticmethod
93 def __Import(theFilePath: str, theModel: mtk.ModelData_Model):
94 print("Importing ", theFilePath, "...", sep="", end="")
95
96 aReader = mtk.ModelData_ModelReader()
97 if not aReader.Read(mtk.UTF16String(theFilePath), theModel):
98 print("\nERROR: Failed to import ", theFilePath, ". Exiting", sep="")
99 return MTKConverter_ReturnCode.MTKConverter_RC_ImportError
100
101 return MTKConverter_ReturnCode.MTKConverter_RC_OK
102
103 @staticmethod
104 def __CreateOriginModelThumbnail (theFilePath: mtk.UTF16String, theModel: mtk.ModelData_Model):
105 aWriter = view.View_ImageWriter()
106 aParameters = aWriter.Parameters()
107 aParameters.SetImageHeight (800)
108 aParameters.SetImageWidth (600)
109 aParameters.SetViewCameraProjection (view.CameraProjectionType_Perspective)
110 aParameters.SetViewCameraPosition (view.CameraPositionType_Default)
111 aParameters.SetViewIsFitAll (True)
112 aParameters.SetViewAntialiasing (view.AntialiasingMode_High)
113 aParameters.SetViewBackground (view.View_ColorBackgroundStyle (view.View_Color (255, 255, 255)))
114 aWriter.SetParameters (aParameters)
115
116 aRes = aWriter.WriteFile (theModel, theFilePath)
117 return aRes
118
119 @staticmethod
120 def __ApplyProcessorToModel (theProcessor: part_proc.MTKConverter_PartProcessor,
121 theModel: mtk.ModelData_Model,
122 theReport: MTKConverter_Report):
123
124 aVisitor = mtk.ModelData_ModelElementUniqueVisitor(theProcessor)
125 theModel.Accept(aVisitor)
126 for i in theProcessor.myData:
127 theReport.AddData(i)
128
129 @staticmethod
130 def __Process (theProcess: str,
131 theModel: mtk.ModelData_Model,
132 theReport: MTKConverter_Report,
133 theProcessModel: mtk.ModelData_Model):
134 print("Processing ", theProcess, "... ", sep="", end="")
135
136 theModel.AssignUuids()
137
138 aProcessType = MTKConverter_Application.__ProcessType(theProcess)
139 if aProcessType == MTKConverter_ProcessType.MTKConverter_PT_MachiningMilling:
140 aProcessor = MTKConverter_MachiningProcessor(mtk.Machining_OT_Milling)
141 MTKConverter_Application.__ApplyProcessorToModel(aProcessor, theModel, theReport)
142 elif aProcessType == MTKConverter_ProcessType.MTKConverter_PT_MachiningTurning:
143 aProcessor = MTKConverter_MachiningProcessor(mtk.Machining_OT_LatheMilling)
144 MTKConverter_Application.__ApplyProcessorToModel(aProcessor, theModel, theReport)
145 elif aProcessType == MTKConverter_ProcessType.MTKConverter_PT_Molding:
146 anExtraDataName = str(theModel.Name()) + "_extra"
147 theProcessModel.SetName(mtk.UTF16String(anExtraDataName))
148 aProcessor = MTKConverter_MoldingProcessor(theProcessModel)
149 MTKConverter_Application.__ApplyProcessorToModel(aProcessor, theModel, theReport)
150 elif aProcessType == MTKConverter_ProcessType.MTKConverter_PT_SheetMetal:
151 anUnfoldedName = str(theModel.Name()) + "_unfolded"
152 theProcessModel.SetName(mtk.UTF16String(anUnfoldedName))
153 aProcessor = MTKConverter_SheetMetalProcessor(theProcessModel)
154 MTKConverter_Application.__ApplyProcessorToModel(aProcessor, theModel, theReport)
155 elif aProcessType == MTKConverter_ProcessType.MTKConverter_PT_WallThickness:
156 aProcessor = MTKConverter_WallThicknessProcessor(800)
157 MTKConverter_Application.__ApplyProcessorToModel(aProcessor, theModel, theReport)
158 else:
159 return MTKConverter_ReturnCode.MTKConverter_RC_InvalidArgument
160
161 return MTKConverter_ReturnCode.MTKConverter_RC_OK
162
163 @staticmethod
164 def __Export(theFolderPath: mtk.UTF16String,
165 theModel: mtk.ModelData_Model,
166 theToGenerateScreenshot: bool,
167 theReport: MTKConverter_Report,
168 theProcessModel: mtk.ModelData_Model):
169 print("Exporting ", theFolderPath, "...", sep="", end="")
170
171 os.mkdir(theFolderPath)
172
173 aModelPath = theFolderPath + "/" + str(theModel.Name()) + ".mtkweb" + "/scenegraph.mtkweb"
174 if not theModel.Save(mtk.UTF16String(aModelPath), mtk.ModelData_Model.FileFormatType_MTKWEB):
175 print("\nERROR: Failed to export ", aModelPath, ". Exiting", sep="")
176 return MTKConverter_ReturnCode.MTKConverter_RC_ExportError
177
178 aThumbnailPath = theFolderPath + "/thumbnail.png"
179 if theToGenerateScreenshot and not MTKConverter_Application.__CreateOriginModelThumbnail(mtk.UTF16String(aThumbnailPath), theModel):
180 print("\nERROR: Failed to create thumbnail ", aThumbnailPath, ". Exiting", sep="")
181 return MTKConverter_ReturnCode.ExportError
182
183 if not theProcessModel.IsEmpty():
184 aProcessModelPath = theFolderPath + "/" + str(theProcessModel.Name()) + ".mtkweb" + "/scenegraph.mtkweb"
185 if not theProcessModel.Save(mtk.UTF16String(aProcessModelPath), mtk.ModelData_Model.FileFormatType_MTKWEB):
186 print("\nERROR: Failed to export ", aProcessModelPath, ". Exiting", sep="")
187 return MTKConverter_ReturnCode.MTKConverter_RC_ExportError
188
189 aJsonPath = theFolderPath + "\\process_data.json"
190 if not theReport.WriteToJSON (aJsonPath):
191 print("\nERROR: Failed to create JSON file ", aJsonPath, ". Exiting", sep="")
192 return MTKConverter_ReturnCode.MTKConverter_RC_ExportError
193
194 return MTKConverter_ReturnCode.MTKConverter_RC_OK
195
196 def Run(self, theSource: str, theProcess: str, theTarget: str, theToGenerateScreenshot: str = ""):
197 aModel = mtk.ModelData_Model()
198 aProcessModel = mtk.ModelData_Model()
199 aReport = MTKConverter_Report()
200 aToGenerateScreenshot = True
201
202 if theToGenerateScreenshot == "--no-screenshot":
203 aToGenerateScreenshot = False
204 aRes = MTKConverter_ReturnCode.MTKConverter_RC_OK
205 try:
206 aRes = MTKConverter_Application.__Import (theSource, aModel)
207 print("Done.")
208 if aRes == MTKConverter_ReturnCode.MTKConverter_RC_OK:
209 aRes = MTKConverter_Application.__Process (theProcess, aModel, aReport, aProcessModel)
210 print("Done.")
211 if aRes == MTKConverter_ReturnCode.MTKConverter_RC_OK:
212 aRes = MTKConverter_Application.__Export (theTarget, aModel, aToGenerateScreenshot, aReport, aProcessModel)
213 print("Done.")
214 except Exception as anE:
215 print("Failed.\nERROR: ", anE, sep="")
216 return MTKConverter_ReturnCode.MTKConverter_RC_GeneralException
217 except:
218 print("Failed.\nERROR: Unhandled exception caught.")
219 return MTKConverter_ReturnCode.MTKConverter_RC_GeneralException
220
221 return aRes

MTKConverter.py

1# $Id$
2
3# Copyright (C) 2008-2014, Roman Lygin. All rights reserved.
4# Copyright (C) 2014-2025, CADEX. All rights reserved.
5
6# This file is part of the Manufacturing Toolkit software.
7
8# You may use this file under the terms of the BSD license as follows:
9
10# Redistribution and use in source and binary forms, with or without
11# modification, are permitted provided that the following conditions are met:
12# * Redistributions of source code must retain the above copyright notice,
13# this list of conditions and the following disclaimer.
14# * Redistributions in binary form must reproduce the above copyright notice,
15# this list of conditions and the following disclaimer in the documentation
16# and/or other materials provided with the distribution.
17
18# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28# POSSIBILITY OF SUCH DAMAGE.
29
30import os
31import sys
32
33from pathlib import Path
34
35import manufacturingtoolkit.CadExMTK as mtk
36
37sys.path.append(os.path.abspath(os.path.dirname(Path(__file__).resolve()) + "/../"))
38
39import mtk_license as license
40
41import MTKConverter_Application as app
42
43def PrintUsage():
44 print ("Usage:")
45 print ("MTKConverter -i <import_file> -p <process> --no-screenshot -e <export_folder>\n")
46 print ("Arguments:")
47 print (" <import_file> - import file name")
48 print (" <process> - manufacturing process or algorithm name")
49 print (" <export_folder> - export folder name")
50 print (" --no-screenshot - disable screenshot generation (optional)")
51 print ("Example:")
52 print ("MTKConverter -i C:\\models\\test.step -p machining_milling -e C:\\models\\test")
53
54 print ("\nRecognized processes:")
55 print (" wall_thickness :\t Wall Thickness analysis")
56 print (" machining_milling:\t CNC Machining Milling feature recognition and DFM analyzis")
57 print (" machining_turning:\t CNC Machining Lathe+Milling feature recognition and DFM analyzis")
58 print (" molding :\t Molding feature recognition and DFM analyzis")
59 print (" sheet_metal :\t Sheet Metal feature recognition, unfolding and DFM analysis")
60
61def main (theSource: str, theProcess: str, theTarget: str, theToGenerateScreenshot: str = ""):
62 aKey = license.Value()
63
64 if not mtk.LicenseManager.Activate(aKey):
65 print("Failed to activate Manufacturing Toolkit license.")
66 return 1
67
68 anApp = app.MTKConverter_Application()
69 aRes = anApp.Run (theSource, theProcess, theTarget)
70 return aRes.value
71
72if __name__ == "__main__":
73 if (len(sys.argv) == 1
74 or sys.argv[1] == "-?" or sys.argv[1] == "/?"
75 or sys.argv[1] == "-h" or sys.argv[1] == "--help"):
76 PrintUsage()
77 sys.exit()
78
79 if len(sys.argv) < 6 :
80 print("Invalid number of arguments. Please use \"-h\" or \"--help\" for usage information.")
81 sys.exit(app.MTKConverter_ReturnCode.MTKConverter_RC_InvalidArgumentsNumber.value)
82
83 aSource = os.path.abspath(sys.argv[2])
84 aProcess = sys.argv[4]
85 aTarget = os.path.abspath(sys.argv[6])
86
87 sys.exit(main(aSource, aProcess, aTarget))