1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30from functools import cmp_to_key
31
32import manufacturingtoolkit.CadExMTK as mtk
33
34class Pair:
35 def __init__(self, theFirst: float, theSecond: float):
36 self.First = theFirst
37 self.Second = theSecond
38
39 def __repr__(self):
40 return f"Pair({self.First}, {self.Second})"
41
42 def __str__(self):
43 return f"{self.First:.5f} x {self.Second:.5f}"
44
45class Dimension:
46 def __init__(self, theX: float, theY: float, theZ: float):
47 self.X = theX
48 self.Y = theY
49 self.Z = theZ
50
51 def __repr__(self):
52 return f"Dimension({self.X}, {self.Y}, {self.Z})"
53
54 def __str__(self):
55 return f"{self.X:.5f} x {self.Y:.5f} x {self.Z:.5f}"
56
57class Direction:
58 def __init__(self, theX: float, theY: float, theZ: float):
59 self.X = theX
60 self.Y = theY
61 self.Z = theZ
62
63 def __repr__(self):
64 return f"Direction({self.X}, {self.Y}, {self.Z})"
65
66 def __str__(self):
67 return f"({self.X:.2f}, {self.Y:.2f}, {self.Z:.2f})"
68
69def CompareFeatures(theA: mtk.MTKBase_Feature, theB: mtk.MTKBase_Feature):
70 aComparator = mtk.MTKBase_FeatureComparator()
71 anALessThanB = aComparator(theA, theB)
72 if anALessThanB:
73 return -1
74
75 aBLessThanA = aComparator(theB, theA)
76 if aBLessThanA:
77 return 1
78
79 return 0
80
81class FeatureGroupManager:
82 def __init__(self):
83 self.__myGroups = []
84
85 def AddFeature(self, theGroupName: str, theSubgroupName: str, theHasParameters: bool, theFeature: mtk.MTKBase_Feature):
86
87 aRes = -1
88 for i in range(len(self.__myGroups)):
89 aGroup = self.__myGroups[i]
90 if aGroup.myName == theGroupName:
91 aRes = i
92 break
93
94 if aRes == -1:
95 self.__myGroups.append(self.FeatureGroup(theGroupName, theSubgroupName, theHasParameters))
96 aRes = len(self.__myGroups) - 1
97
98
99 aGroup = self.__myGroups[aRes]
100 aSubgroups = aGroup.myFeatureSubgroups
101 aSubgroups.Append(theFeature)
102
103 def Print(self, theFeatureType: str, thePrintFeatureParameters):
104 self.__myGroups.sort(key=cmp_to_key(self.__compare))
105
106 aTotalCount = 0
107 for i in self.__myGroups:
108 aFeatureCount = i.FeatureCount()
109 aTotalCount += aFeatureCount
110
111 print(" ", i.myName, ": ", aFeatureCount, sep="")
112
113 if not i.myHasParameters:
114 continue
115
116 aSubgroupName = i.mySubgroupName
117 for j in range(i.myFeatureSubgroups.Size()):
118 print(" ", i.myFeatureSubgroups.GetFeatureCount(j), " ", aSubgroupName, " with", sep="")
119 thePrintFeatureParameters(i.myFeatureSubgroups.GetFeature(j))
120
121 print("\n Total ", theFeatureType, ": ", aTotalCount, "\n", sep="")
122
123 @staticmethod
124 def PrintFeatureParameter(theName: str, theValue, theUnits: str):
125 print(" ", theName, ": ", theValue, " ", theUnits, sep = "")
126
127 class OrderedFeatureList:
128 def __init__(self):
129 self.__myList = []
130
131 def Append(self, theFeature: mtk.MTKBase_Feature):
132 anInsertIndex = 0
133 for i in self.__myList:
134 aRes = CompareFeatures(theFeature, i.Feature)
135 if aRes == 0:
136 i.Count += 1
137 anInsertIndex = -1
138 break
139 elif aRes < 0:
140 break
141
142 anInsertIndex += 1
143
144 if anInsertIndex >= 0:
145 self.__myList.insert(anInsertIndex, self.FeatureAndCountPair(theFeature))
146
147 def Size(self):
148 return len(self.__myList)
149
150 def GetFeature(self, theIndex: int):
151 return self.__GetFeatureAndCountPair(theIndex).Feature
152
153 def GetFeatureCount(self, theIndex: int):
154 return self.__GetFeatureAndCountPair(theIndex).Count
155
156 def __GetFeatureAndCountPair(self, theIndex: int):
157 return self.__myList[theIndex]
158
159 class FeatureAndCountPair:
160 def __init__(self, theFeature: mtk.MTKBase_Feature):
161 self.Feature = theFeature
162 self.Count = 1
163
164 class FeatureGroup:
165 def __init__(self, theName: str, theSubgroupName: str, theHasParameters: bool):
166 self.myName = theName
167 self.mySubgroupName = theSubgroupName
168 self.myHasParameters = theHasParameters
169 self.myFeatureSubgroups = FeatureGroupManager.OrderedFeatureList()
170
171 def FeatureCount(self):
172 aCount = 0
173 for i in range(self.myFeatureSubgroups.Size()):
174 aCount += self.myFeatureSubgroups.GetFeatureCount(i)
175 return aCount
176
177 @staticmethod
178 def __compare(theA: FeatureGroup, theB: FeatureGroup):
179 anAName = theA.myName
180 aBName = theB.myName
181 if anAName == aBName:
182 return 0
183
184 anAFeatureSubgroups = theA.myFeatureSubgroups
185 aBFeatureSubgroups = theB.myFeatureSubgroups
186 if (not anAFeatureSubgroups) or (not aBFeatureSubgroups):
187 if anAName < aBName:
188 return -1
189 else:
190 return 1
191
192 anAFeature = anAFeatureSubgroups.GetFeature(0)
193 aBFeature = aBFeatureSubgroups.GetFeature(0)
194 return CompareFeatures(anAFeature, aBFeature)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30from abc import abstractmethod
31
32import manufacturingtoolkit.CadExMTK as mtk
33
34class ShapeProcessor(mtk.ModelData_ModelElementVoidVisitor):
35 def __init__(self):
36 super().__init__()
37 self.myPartIndex = 0
38
39 def VisitPart(self, thePart: mtk.ModelData_Part):
40 aPartName = "noname" if thePart.Name().IsEmpty() else thePart.Name()
41
42 aBodyList = thePart.Bodies()
43 i = 0
44 for aBody in aBodyList:
45 aShapeIt = mtk.ModelData_ShapeIterator(aBody)
46 for aShape in aShapeIt:
47 if aShape.Type() == mtk.ShapeType_Solid:
48 print("Part #", self.myPartIndex, " [\"", aPartName, "\"] - solid #", i, " has:", sep="")
49 i += 1
50 self.ProcessSolid(mtk.ModelData_Solid.Cast(aShape))
51 elif aShape.Type() == mtk.ShapeType_Shell:
52 print("Part #", self.myPartIndex, " [\"", aPartName, "\"] - shell #", i, " has:", sep="")
53 i += 1
54 self.ProcessShell(mtk.ModelData_Shell.Cast (aShape))
55 self.myPartIndex += 1
56
57 @abstractmethod
58 def ProcessSolid(self, theSolid: mtk.ModelData_Solid):
59 pass
60
61 @abstractmethod
62 def ProcessShell(self, theShell: mtk.ModelData_Shell):
63 pass
64
65class SolidProcessor(mtk.ModelData_ModelElementVoidVisitor):
66 def __init__(self):
67 super().__init__()
68 self.myPartIndex = 0
69
70 def VisitPart(self, thePart: mtk.ModelData_Part):
71 aPartName = "noname" if thePart.Name().IsEmpty() else thePart.Name()
72
73 aBodyList = thePart.Bodies()
74 i = 0
75 for aBody in aBodyList:
76 aShapeIt = mtk.ModelData_ShapeIterator(aBody)
77 for aShape in aShapeIt:
78 if aShape.Type() == mtk.ShapeType_Solid:
79 print("Part #", self.myPartIndex, " [\"", aPartName, "\"] - solid #", i, " has:", sep="")
80 i += 1
81 self.ProcessSolid (mtk.ModelData_Solid.Cast (aShape))
82 self.myPartIndex += 1
83
84 @abstractmethod
85 def ProcessSolid(self, theSolid: mtk.ModelData_Solid):
86 pass
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30import math
31import os
32import sys
33
34from pathlib import Path
35
36import manufacturingtoolkit.CadExMTK as mtk
37
38sys.path.append(os.path.abspath(os.path.dirname(Path(__file__).resolve()) + "/../../"))
39sys.path.append(os.path.abspath(os.path.dirname(Path(__file__).resolve()) + "/../../helpers/"))
40
41import mtk_license as license
42
43import feature_group
44import shape_processor
45
46def ToDegrees(theAngleRad: float):
47 return theAngleRad * 180.0 / math.pi
48
49def HemTypeToString(theType):
50 aHemTypeMap = {
51 mtk.SheetMetal_HBT_Flattened: "Flattened Hem Bend(s)",
52 mtk.SheetMetal_HBT_Open: "Open Hem Bend(s)",
53 mtk.SheetMetal_HBT_Teardrop: "Teardrop Hem Bend(s)",
54 mtk.SheetMetal_HBT_Rope: "Rope Hem Bend(s)",
55 mtk.SheetMetal_HBT_Rolled: "Rolled Hem Bend(s)"
56 }
57
58 if theType in aHemTypeMap:
59 return aHemTypeMap[theType]
60 else:
61 return "Hem Bend(s)"
62
63def BendName(theBend: mtk.SheetMetal_Bend):
64 if mtk.SheetMetal_HemBend.CompareType(theBend):
65 aHemBend = mtk.SheetMetal_HemBend.Cast(theBend)
66 return HemTypeToString(aHemBend.Type())
67 elif mtk.SheetMetal_CurvedBend.CompareType(theBend):
68 return "Curved Bend(s)"
69 return "Bend(s)"
70
71def HoleName(theHole: mtk.SheetMetal_Hole):
72 if mtk.SheetMetal_ComplexHole.CompareType(theHole):
73 return "Complex Hole(s)"
74 return "Hole(s)"
75
76def NotchName(theNotch: mtk.SheetMetal_Notch):
77 if mtk.SheetMetal_StraightNotch.CompareType(theNotch):
78 return "Straight Notch(es)"
79 elif mtk.SheetMetal_VNotch.CompareType(theNotch):
80 return "V Notch(es)"
81 return "Notch(es)"
82
83
84def GroupByParameters(theFeatureList: mtk.MTKBase_FeatureList, theManager: feature_group.FeatureGroupManager):
85 for aFeature in theFeatureList:
86 if mtk.SheetMetal_FormingFeature.CompareType(aFeature):
87 theManager.AddFeature("Forming Feature(s)", "Forming Feature(s)", True, aFeature)
88 elif mtk.SheetMetal_Bead.CompareType(aFeature):
89 theManager.AddFeature("Bead(s)", "Bead(s)", True, aFeature)
90 elif mtk.SheetMetal_Cutout.CompareType(aFeature):
91 theManager.AddFeature("Cutout(s)", "Cutout(s)", True, aFeature)
92 elif mtk.SheetMetal_Louver.CompareType(aFeature):
93 theManager.AddFeature("Louver(s)", "", True, aFeature)
94 elif mtk.SheetMetal_Bridge.CompareType(aFeature):
95 theManager.AddFeature("Bridge(s)", "Bridge(s)", True, aFeature)
96 elif mtk.SheetMetal_Hole.CompareType(aFeature):
97 aHole = mtk.SheetMetal_Hole.Cast(aFeature)
98 theManager.AddFeature(HoleName(aHole), "Hole(s)", True, aFeature)
99 elif mtk.SheetMetal_Bend.CompareType(aFeature):
100 aBend = mtk.SheetMetal_Bend.Cast(aFeature)
101 theManager.AddFeature(BendName(aBend), "Bend(s)", True, aFeature)
102 elif mtk.SheetMetal_Notch.CompareType(aFeature):
103 aNotch = mtk.SheetMetal_Notch.Cast(aFeature)
104 theManager.AddFeature(NotchName(aNotch), "Notch(es)", True, aFeature)
105 elif mtk.SheetMetal_Tab.CompareType(aFeature):
106 theManager.AddFeature("Tab(s)", "Tab(s)", True, aFeature)
107 elif mtk.SheetMetal_CompoundBend.CompareType(aFeature):
108 aCompoundBend = mtk.SheetMetal_CompoundBend.Cast(aFeature)
109 GroupByParameters(aCompoundBend.FeatureList(), theManager)
110
111def PrintFeatureParameters(theFeature: mtk.MTKBase_Feature):
112 if mtk.SheetMetal_FormingFeature.CompareType(theFeature):
113 aFeature = mtk.SheetMetal_FormingFeature.Cast(theFeature)
114 anAxis = aFeature.Axis().Direction();
115 aDirection = feature_group.Direction(anAxis.X(), anAxis.Y(), anAxis.Z())
116 feature_group.FeatureGroupManager.PrintFeatureParameter("depth", aFeature.Depth(), "mm")
117 feature_group.FeatureGroupManager.PrintFeatureParameter("length", aFeature.Length(), "mm")
118 feature_group.FeatureGroupManager.PrintFeatureParameter("axis", aDirection, "")
119 elif mtk.SheetMetal_Bead.CompareType(theFeature):
120 aBead = mtk.SheetMetal_Bead.Cast(theFeature)
121 feature_group.FeatureGroupManager.PrintFeatureParameter("depth", aBead.Depth(), "mm")
122 elif mtk.SheetMetal_Cutout.CompareType(theFeature):
123 aCutout = mtk.SheetMetal_Cutout.Cast(theFeature)
124 feature_group.FeatureGroupManager.PrintFeatureParameter("perimeter", aCutout.Perimeter(), "mm")
125 elif mtk.SheetMetal_Louver.CompareType(theFeature):
126 aLouver = mtk.SheetMetal_Louver.Cast(theFeature)
127 feature_group.FeatureGroupManager.PrintFeatureParameter("depth", aLouver.Depth(), "mm")
128 elif mtk.SheetMetal_Bridge.CompareType(theFeature):
129 aBridge = mtk.SheetMetal_Bridge.Cast(theFeature)
130 feature_group.FeatureGroupManager.PrintFeatureParameter("length", aBridge.Length(), "mm")
131 feature_group.FeatureGroupManager.PrintFeatureParameter("depth", aBridge.Depth(), "mm")
132 elif mtk.SheetMetal_Hole.CompareType(theFeature):
133 aHole = mtk.SheetMetal_Hole.Cast(theFeature)
134 anAxis = aHole.Axis().Axis()
135 aDirection = feature_group.Direction(anAxis.X(), anAxis.Y(), anAxis.Z())
136 feature_group.FeatureGroupManager.PrintFeatureParameter("radius", aHole.Radius(), "mm")
137 feature_group.FeatureGroupManager.PrintFeatureParameter("depth", aHole.Depth(), "mm")
138 feature_group.FeatureGroupManager.PrintFeatureParameter("axis", aDirection, "")
139 elif mtk.SheetMetal_Bend.CompareType(theFeature):
140 aBend = mtk.SheetMetal_Bend.Cast(theFeature)
141 feature_group.FeatureGroupManager.PrintFeatureParameter("radius", aBend.Radius(), "mm")
142 feature_group.FeatureGroupManager.PrintFeatureParameter("angle", ToDegrees (aBend.Angle()), "deg")
143 feature_group.FeatureGroupManager.PrintFeatureParameter("length", aBend.Length(), "mm")
144 feature_group.FeatureGroupManager.PrintFeatureParameter("width", aBend.Width(), "mm")
145 elif mtk.SheetMetal_Notch.CompareType(theFeature):
146 aNotch = mtk.SheetMetal_Notch.Cast(theFeature)
147 feature_group.FeatureGroupManager.PrintFeatureParameter("length", aNotch.Length(), "mm")
148 feature_group.FeatureGroupManager.PrintFeatureParameter("width", aNotch.Width(), "mm")
149 if mtk.SheetMetal_StraightNotch.CompareType(aNotch):
150 aStraightNotch = mtk.SheetMetal_StraightNotch.Cast(aNotch)
151 feature_group.FeatureGroupManager.PrintFeatureParameter ("corner fillet radius", aStraightNotch.CornerFilletRadius(), "mm")
152 elif mtk.SheetMetal_VNotch.CompareType(aNotch):
153 aVNotch = mtk.SheetMetal_VNotch.Cast(aNotch)
154 feature_group.FeatureGroupManager.PrintFeatureParameter ("angle", ToDegrees (aVNotch.Angle()), "deg")
155 elif mtk.SheetMetal_Tab.CompareType(theFeature):
156 aTab = mtk.SheetMetal_Tab.Cast(theFeature)
157 feature_group.FeatureGroupManager.PrintFeatureParameter("length", aTab.Length(), "mm")
158 feature_group.FeatureGroupManager.PrintFeatureParameter("width", aTab.Width(), "mm")
159
160def PrintFeatures(theFeatureList: mtk.MTKBase_FeatureList):
161 aManager = feature_group.FeatureGroupManager()
162 GroupByParameters (theFeatureList, aManager)
163 aManager.Print ("features", PrintFeatureParameters)
164
165class PartProcessor(shape_processor.ShapeProcessor):
166 def __init__(self):
167 super().__init__()
168 self.myRecognizer = mtk.SheetMetal_FeatureRecognizer()
169
170 def ProcessSolid(self, theSolid: mtk.ModelData_Solid):
171 aFeatureList = self.myRecognizer.Perform(theSolid)
172 PrintFeatures(aFeatureList)
173
174 def ProcessShell(self, theShell: mtk.ModelData_Shell):
175 aFeatureList = self.myRecognizer.Perform(theShell)
176 PrintFeatures(aFeatureList)
177
178def main(theSource: str):
179 aKey = license.Value()
180
181 if not mtk.LicenseManager.Activate(aKey):
182 print("Failed to activate Manufacturing Toolkit license.")
183 return 1
184
185 aModel = mtk.ModelData_Model()
186 aReader = mtk.ModelData_ModelReader()
187
188
189 if not aReader.Read(mtk.UTF16String(theSource), aModel):
190 print("Failed to open and convert the file " + theSource)
191 return 1
192
193 print("Model: ", aModel.Name(), "\n", sep="")
194
195
196 aPartProcessor = PartProcessor()
197 aVisitor = mtk.ModelData_ModelElementUniqueVisitor(aPartProcessor)
198 aModel.Accept(aVisitor)
199
200 return 0
201
202if __name__ == "__main__":
203 if len(sys.argv) != 2:
204 print("Usage: <input_file>, where:")
205 print(" <input_file> is a name of the file to be read")
206 sys.exit()
207
208 aSource = os.path.abspath(sys.argv[1])
209
210 sys.exit(main(aSource))