Hide menu
Loading...
Searching...
No Matches
sheet_metal/dfm_analyzer/dfm_analyzer.py
Refer to the Sheet Metal DFM Analyzer Example

feature_group.py

1# $Id$
2#
3# Copyright (C) 2008-2014, Roman Lygin. All rights reserved.
4# Copyright (C) 2014-2026, 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 functools import cmp_to_key
31
32import mtk.MTKCore 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 #find or create
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 #update
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)

shape_processor.py

1# $Id$
2#
3# Copyright (C) 2008-2014, Roman Lygin. All rights reserved.
4# Copyright (C) 2014-2026, 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 mtk.MTKCore 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
87
88class SolidAndMeshProcessor(mtk.ModelData_ModelElementVoidVisitor):
89 def __init__(self):
90 super().__init__()
91 self.myPartIndex = 0
92 self.myShapeIndex = 0
93
94 def VisitPart(self, thePart: mtk.ModelData_Part):
95 aPartName = "noname" if thePart.Name().IsEmpty() else thePart.Name()
96
97 myShapeIndex = 0
98 aBodyList = thePart.Bodies()
99 for aBody in aBodyList:
100 if mtk.ModelData_MeshBody.CompareType(aBody):
101 aMeshBody = mtk.ModelData_MeshBody.Cast(aBody)
102 self._ProcessMeshBody(aMeshBody, aPartName)
103 elif mtk.ModelData_SolidBody.CompareType(aBody):
104 aSolid = mtk.ModelData_SolidBody.Cast(aBody).Solid()
105 print("Part #", self.myPartIndex, " [\"", aPartName, "\"] - solid #", myShapeIndex, " has:", sep="")
106 self.ProcessSolid (aSolid, aPartName)
107 self.myShapeIndex += 1
108 self.myPartIndex += 1
109
110 @abstractmethod
111 def ProcessSolid(self, theSolid: mtk.ModelData_Solid, thePartName: mtk.UTF16String):
112 pass
113
114 @abstractmethod
115 def ProcessITS(self, theITS: mtk.ModelData_IndexedTriangleSet, thePartName: mtk.UTF16String):
116 pass
117
118 def _ProcessMeshBody(self, theMeshBody: mtk.ModelData_MeshBody, thePartName: mtk.UTF16String):
119 aMeshShapes = theMeshBody.Shapes()
120 for aMeshShape in aMeshShapes:
121 if(mtk.ModelData_IndexedTriangleSet.CompareType(aMeshShape)):
122 print("Part #", self.myPartIndex, " [\"", thePartName, "\"] - ITS #", self.myShapeIndex, " has:", sep="")
123 anITS = mtk.ModelData_IndexedTriangleSet.Cast(aMeshShape)
124 self.ProcessITS(anITS, thePartName)
125 self.myShapeIndex += 1
126

dfm_analyzer.py

1# $Id$
2#
3# Copyright (C) 2008-2014, Roman Lygin. All rights reserved.
4# Copyright (C) 2014-2026, 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 mtk.MTKCore as mtk
36
37sys.path.append(os.path.abspath(os.path.dirname(Path(__file__).resolve()) + "/../../"))
38sys.path.append(os.path.abspath(os.path.dirname(Path(__file__).resolve()) + "/../../helpers/"))
39
40import mtk_license as license
41
42import LicenseHelper
43import feature_group
44import shape_processor
45
46def SmallDistanceIssueName(theIssue: mtk.DFMSheetMetal_SmallDistanceBetweenFeaturesIssue):
47 if mtk.DFMSheetMetal_SmallDistanceBetweenBendAndLouverIssue.CompareType(theIssue):
48 return "Small Distance Between Bend And Louver Issue(s)"
49 elif mtk.DFMSheetMetal_SmallDistanceBetweenExtrudedHoleAndBendIssue.CompareType(theIssue):
50 return "Small Distance Between Extruded Hole And Bend Issue(s)"
51 elif mtk.DFMSheetMetal_SmallDistanceBetweenExtrudedHoleAndEdgeIssue.CompareType(theIssue):
52 return "Small Distance Between Extruded Hole And Edge Issue(s)"
53 elif mtk.DFMSheetMetal_SmallDistanceBetweenExtrudedHolesIssue.CompareType(theIssue):
54 return "Small Distance Between Extruded Holes Issue(s)"
55 elif mtk.DFMSheetMetal_SmallDistanceBetweenHoleAndBendIssue.CompareType(theIssue):
56 return "Small Distance Between Hole And Bend Issue(s)"
57 elif mtk.DFMSheetMetal_SmallDistanceBetweenHoleAndCutoutIssue.CompareType(theIssue):
58 return "Small Distance Between Hole And Cutout Issue(s)"
59 elif mtk.DFMSheetMetal_SmallDistanceBetweenHoleAndEdgeIssue.CompareType(theIssue):
60 return "Small Distance Between Hole And Edge Issue(s)"
61 elif mtk.DFMSheetMetal_SmallDistanceBetweenHoleAndLouverIssue.CompareType(theIssue):
62 return "Small Distance Between Hole And Louver Issue(s)"
63 elif mtk.DFMSheetMetal_SmallDistanceBetweenHoleAndNotchIssue.CompareType(theIssue):
64 return "Small Distance Between Hole And Notch Issue(s)"
65 elif mtk.DFMSheetMetal_SmallDistanceBetweenHolesIssue.CompareType(theIssue):
66 return "Small Distance Between Holes Issue(s)"
67 elif mtk.DFMSheetMetal_SmallDistanceBetweenNotchAndBendIssue.CompareType(theIssue):
68 return "Small Distance Between Notch And Bend Issue(s)"
69 elif mtk.DFMSheetMetal_SmallDistanceBetweenNotchesIssue.CompareType(theIssue):
70 return "Small Distance Between Notches Issue(s)"
71 elif mtk.DFMSheetMetal_SmallDistanceBetweenTabsIssue.CompareType(theIssue):
72 return "Small Distance Between Tabs Issue(s)"
73 return "Small Distance Between Feature(s)"
74
75def PrintFeatureParameters(theIssue: mtk.MTKBase_Feature):
76 if mtk.DFMSheetMetal_SmallRadiusBendIssue.CompareType(theIssue):
77 aSRBIssue = mtk.DFMSheetMetal_SmallRadiusBendIssue.Cast(theIssue)
78 feature_group.FeatureGroupManager.PrintFeatureParameter("expected min radius", aSRBIssue.ExpectedMinRadius(), "mm")
79 feature_group.FeatureGroupManager.PrintFeatureParameter("actual radius", aSRBIssue.ActualRadius(), "mm")
80 elif mtk.DFMSheetMetal_SmallDiameterHoleIssue.CompareType(theIssue):
81 aSDHIssue = mtk.DFMSheetMetal_SmallDiameterHoleIssue.Cast(theIssue)
82 feature_group.FeatureGroupManager.PrintFeatureParameter("expected min diameter", aSDHIssue.ExpectedMinDiameter(), "mm")
83 feature_group.FeatureGroupManager.PrintFeatureParameter("actual diameter", aSDHIssue.ActualDiameter(), "mm")
84 elif mtk.DFMSheetMetal_SmallDistanceBetweenFeaturesIssue.CompareType(theIssue):
85 aSDBFIssue = mtk.DFMSheetMetal_SmallDistanceBetweenFeaturesIssue.Cast(theIssue)
86 feature_group.FeatureGroupManager.PrintFeatureParameter(
87 "expected min distance", aSDBFIssue.ExpectedMinDistanceBetweenFeatures(), "mm")
88 feature_group.FeatureGroupManager.PrintFeatureParameter(
89 "actual distance", aSDBFIssue.ActualDistanceBetweenFeatures(), "mm")
90 elif mtk.DFMSheetMetal_FlatPatternInterferenceIssue.CompareType(theIssue):
91 pass #no parameters
92 elif mtk.DFMSheetMetal_IrregularCornerFilletRadiusNotchIssue.CompareType(theIssue):
93 aICFRNIssue = mtk.DFMSheetMetal_IrregularCornerFilletRadiusNotchIssue.Cast(theIssue)
94 feature_group.FeatureGroupManager.PrintFeatureParameter("expected corner fillet radius", aICFRNIssue.ExpectedCornerFilletRadius(), "mm")
95 feature_group.FeatureGroupManager.PrintFeatureParameter("actual corner fillet radius", aICFRNIssue.ActualCornerFilletRadius(), "mm")
96 elif mtk.DFMSheetMetal_IrregularDepthExtrudedHoleIssue.CompareType(theIssue):
97 aIDEHIssue = mtk.DFMSheetMetal_IrregularDepthExtrudedHoleIssue.Cast(theIssue)
98 feature_group.FeatureGroupManager.PrintFeatureParameter("expected min extruded height", aIDEHIssue.ExpectedMinExtrudedHeight(), "mm")
99 feature_group.FeatureGroupManager.PrintFeatureParameter("expected max extruded height", aIDEHIssue.ExpectedMaxExtrudedHeight(), "mm")
100 feature_group.FeatureGroupManager.PrintFeatureParameter("actual extruded height", aIDEHIssue.ActualExtrudedHeight(), "mm")
101 elif mtk.DFMSheetMetal_IrregularRadiusOpenHemBendIssue.CompareType(theIssue):
102 aIROHBIssue = mtk.DFMSheetMetal_IrregularRadiusOpenHemBendIssue.Cast(theIssue)
103 feature_group.FeatureGroupManager.PrintFeatureParameter("expected radius", aIROHBIssue.ExpectedRadius(), "mm")
104 feature_group.FeatureGroupManager.PrintFeatureParameter("actual radius", aIROHBIssue.ActualRadius(), "mm")
105 elif mtk.DFMSheetMetal_IrregularSizeBendReliefIssue.CompareType(theIssue):
106 aISBRIssue = mtk.DFMSheetMetal_IrregularSizeBendReliefIssue.Cast(theIssue)
107 anExpectedRelief = aISBRIssue.ExpectedMinBendRelief()
108 aFirstActualRelief = aISBRIssue.FirstActualRelief()
109 aSecondActualRelief = aISBRIssue.SecondActualRelief()
110
111 feature_group.FeatureGroupManager.PrintFeatureParameter (
112 "expected min relief size (LxW)",
113 feature_group.Pair (anExpectedRelief.Length(), anExpectedRelief.Width()),
114 "mm")
115 if aFirstActualRelief and aSecondActualRelief:
116 feature_group.FeatureGroupManager.PrintFeatureParameter (
117 "first actual relief size (LxW)",
118 feature_group.Pair(aFirstActualRelief.Length(), aFirstActualRelief.Width()),
119 "mm")
120 feature_group.FeatureGroupManager.PrintFeatureParameter (
121 "second actual relief size (LxW)",
122 feature_group.Pair(aSecondActualRelief.Length(), aSecondActualRelief.Width()),
123 "mm")
124 elif not aFirstActualRelief:
125 feature_group.FeatureGroupManager.PrintFeatureParameter (
126 "actual relief size (LxW)",
127 feature_group.Pair(aSecondActualRelief.Length(), aSecondActualRelief.Width()),
128 "mm")
129 else:
130 feature_group.FeatureGroupManager.PrintFeatureParameter (
131 "actual relief size (LxW)",
132 feature_group.Pair(aFirstActualRelief.Length(), aFirstActualRelief.Width()),
133 "mm")
134 elif mtk.DFMSheetMetal_LargeDepthBeadIssue.CompareType(theIssue):
135 anIssue = mtk.DFMSheetMetal_LargeDepthBeadIssue.Cast(theIssue)
136 feature_group.FeatureGroupManager.PrintFeatureParameter("expected max depth", anIssue.ExpectedMaxDepth(), "mm")
137 feature_group.FeatureGroupManager.PrintFeatureParameter("actual depth", anIssue.ActualDepth(), "mm")
138 elif mtk.DFMSheetMetal_LargeDepthCountersinkIssue.CompareType(theIssue):
139 anIssue = mtk.DFMSheetMetal_LargeDepthCountersinkIssue.Cast(theIssue)
140 feature_group.FeatureGroupManager.PrintFeatureParameter("expected max depth", anIssue.ExpectedMaxDepth(), "mm")
141 feature_group.FeatureGroupManager.PrintFeatureParameter("actual depth", anIssue.ActualDepth(), "mm")
142 elif mtk.DFMSheetMetal_NarrowCutoutIssue.CompareType(theIssue):
143 anIssue = mtk.DFMSheetMetal_NarrowCutoutIssue.Cast(theIssue)
144 feature_group.FeatureGroupManager.PrintFeatureParameter("expected min width", anIssue.ExpectedMinWidth(), "mm")
145 feature_group.FeatureGroupManager.PrintFeatureParameter("actual width", anIssue.ActualWidth(), "mm")
146 elif mtk.DFMSheetMetal_SmallDepthLouverIssue.CompareType(theIssue):
147 aSDLIssue = mtk.DFMSheetMetal_SmallDepthLouverIssue.Cast(theIssue)
148 feature_group.FeatureGroupManager.PrintFeatureParameter("expected min depth", aSDLIssue.ExpectedMinDepth(), "mm")
149 feature_group.FeatureGroupManager.PrintFeatureParameter("actual depth", aSDLIssue.ActualDepth(), "mm")
150 elif mtk.DFMSheetMetal_InconsistentRadiusBendIssue.CompareType(theIssue):
151 aIRBIssue = mtk.DFMSheetMetal_InconsistentRadiusBendIssue.Cast(theIssue)
152 feature_group.FeatureGroupManager.PrintFeatureParameter("expected max radius", aIRBIssue.ExpectedRadius(), "mm")
153 feature_group.FeatureGroupManager.PrintFeatureParameter("actual radius", aIRBIssue.ActualRadius(), "mm")
154 elif mtk.DFMSheetMetal_SmallLengthFlangeIssue.CompareType(theIssue):
155 aSLFIssue = mtk.DFMSheetMetal_SmallLengthFlangeIssue.Cast(theIssue)
156 feature_group.FeatureGroupManager.PrintFeatureParameter("expected min length", aSLFIssue.ExpectedMinLength(), "mm")
157 feature_group.FeatureGroupManager.PrintFeatureParameter("actual length", aSLFIssue.ActualLength(), "mm")
158 elif mtk.DFMSheetMetal_SmallLengthHemBendFlangeIssue.CompareType(theIssue):
159 aSLHBFIssue = mtk.DFMSheetMetal_SmallLengthHemBendFlangeIssue.Cast(theIssue)
160 feature_group.FeatureGroupManager.PrintFeatureParameter("expected min length", aSLHBFIssue.ExpectedMinLength(), "mm")
161 feature_group.FeatureGroupManager.PrintFeatureParameter("actual length", aSLHBFIssue.ActualLength(), "mm")
162 elif mtk.DFMSheetMetal_IrregularSizeNotchIssue.CompareType(theIssue):
163 aISNIssue = mtk.DFMSheetMetal_IrregularSizeNotchIssue.Cast(theIssue)
164 feature_group.FeatureGroupManager.PrintFeatureParameter(
165 "expected size (LxW)",
166 feature_group.Pair(aISNIssue.ExpectedLength(), aISNIssue.ExpectedWidth()),
167 "mm")
168 feature_group.FeatureGroupManager.PrintFeatureParameter(
169 "actual size (LxW)",
170 feature_group.Pair(aISNIssue.ActualLength(), aISNIssue.ActualWidth()),
171 "mm")
172 elif mtk.DFMSheetMetal_IrregularSizeTabIssue.CompareType(theIssue):
173 aISTIssue = mtk.DFMSheetMetal_IrregularSizeTabIssue.Cast(theIssue)
174 feature_group.FeatureGroupManager.PrintFeatureParameter(
175 "expected size (LxW)",
176 feature_group.Pair(aISTIssue.ExpectedLength(), aISTIssue.ExpectedWidth()),
177 "mm")
178 feature_group.FeatureGroupManager.PrintFeatureParameter(
179 "actual size (LxW)",
180 feature_group.Pair(aISTIssue.ActualLength(), aISTIssue.ActualWidth()),
181 "mm")
182 elif mtk.DFMSheetMetal_NonStandardSheetThicknessIssue.CompareType(theIssue):
183 aNSSTIssue = mtk.DFMSheetMetal_NonStandardSheetThicknessIssue.Cast(theIssue)
184 feature_group.FeatureGroupManager.PrintFeatureParameter(
185 "nearest standard sheet thickness", aNSSTIssue.NearestStandardSheetThickness(), "mm")
186 feature_group.FeatureGroupManager.PrintFeatureParameter(
187 "actual sheet thickness", aNSSTIssue.ActualSheetThickness(), "mm")
188 elif mtk.DFMSheetMetal_NonStandardSheetSizeIssue.CompareType(theIssue):
189 aNSSSIssue = mtk.DFMSheetMetal_NonStandardSheetSizeIssue.Cast(theIssue)
190 aNearestStandardSize = aNSSSIssue.NearestStandardSheetSize()
191 anActualSize = aNSSSIssue.ActualSheetSize()
192 feature_group.FeatureGroupManager.PrintFeatureParameter(
193 "nearest standard sheet size (LxW)",
194 feature_group.Pair(aNearestStandardSize.Length(), aNearestStandardSize.Width()),
195 "mm")
196 feature_group.FeatureGroupManager.PrintFeatureParameter(
197 "actual sheet size (LxW)",
198 feature_group.Pair(anActualSize.Length(), anActualSize.Width()),
199 "mm")
200
201def PrintIssues(theIssueList: mtk.MTKBase_FeatureList):
202 aManager = feature_group.FeatureGroupManager()
203
204 #group by parameters to provide more compact information about features
205 for anIssue in theIssueList:
206 if mtk.DFMSheetMetal_SmallRadiusBendIssue.CompareType(anIssue):
207 aManager.AddFeature("Small Radius Bend Issue(s)", "Bend(s)", True, anIssue)
208 elif mtk.DFMSheetMetal_SmallDiameterHoleIssue.CompareType(anIssue):
209 aManager.AddFeature("Small Diameter Hole Issue(s)", "Hole(s)", True, anIssue)
210 elif mtk.DFMSheetMetal_FlatPatternInterferenceIssue.CompareType(anIssue):
211 aManager.AddFeature("Flat Pattern Interference Issue(s)", "", False, anIssue)
212 elif mtk.DFMSheetMetal_IrregularCornerFilletRadiusNotchIssue.CompareType(anIssue):
213 aManager.AddFeature("Irregular Corner Fillet Radius Notch Issue(s)", "Notch(es)", True, anIssue)
214 elif mtk.DFMSheetMetal_IrregularDepthExtrudedHoleIssue.CompareType(anIssue):
215 aManager.AddFeature("Irregular Depth Extruded Hole Issue(s)", "Hole(s)", True, anIssue)
216 elif mtk.DFMSheetMetal_IrregularRadiusOpenHemBendIssue.CompareType(anIssue):
217 aManager.AddFeature("Irregular Radius Open Hem Bend Issue(s)", "Bend(s)", True, anIssue)
218 elif mtk.DFMSheetMetal_IrregularSizeBendReliefIssue.CompareType(anIssue):
219 aManager.AddFeature("Irregular Size Bend Relief Issue(s)", "Bend(s)", True, anIssue)
220 elif mtk.DFMSheetMetal_LargeDepthBeadIssue.CompareType(anIssue):
221 aManager.AddFeature("Large Depth Bead Issue(s)", "Bead(s)", True, anIssue)
222 elif mtk.DFMSheetMetal_LargeDepthCountersinkIssue.CompareType(anIssue):
223 aManager.AddFeature("Large Depth Countersink Issue(s)", "Countersink(s)", True, anIssue)
224 elif mtk.DFMSheetMetal_NarrowCutoutIssue.CompareType(anIssue):
225 aManager.AddFeature("Narrow Cutout Issue(s)", "Cutout(s)", True, anIssue)
226 elif mtk.DFMSheetMetal_SmallDepthLouverIssue.CompareType(anIssue):
227 aManager.AddFeature("Small Depth Louver Issue(s)", "Louver(s)", True, anIssue)
228 elif mtk.DFMSheetMetal_InconsistentRadiusBendIssue.CompareType(anIssue):
229 aManager.AddFeature("Inconsistent Radius Bend Issue(s)", "Bend(s)", True, anIssue)
230 elif mtk.DFMSheetMetal_SmallLengthFlangeIssue.CompareType(anIssue):
231 aManager.AddFeature("Small Length Flange Issue(s)", "Flange(s)", True, anIssue)
232 elif mtk.DFMSheetMetal_SmallLengthHemBendFlangeIssue.CompareType(anIssue):
233 aManager.AddFeature("Small Length Hem Bend Flange Issue(s)", "Flange(s)", True, anIssue)
234 elif mtk.DFMSheetMetal_IrregularSizeNotchIssue.CompareType(anIssue):
235 aManager.AddFeature("Irregular Size Notch Issue(s)", "Notch(s)", True, anIssue)
236 elif mtk.DFMSheetMetal_IrregularSizeTabIssue.CompareType(anIssue):
237 aManager.AddFeature("Irregular Size Tab Issue(s)", "Tab(s)", True, anIssue)
238 elif mtk.DFMSheetMetal_SmallDistanceBetweenFeaturesIssue.CompareType(anIssue):
239 aSDBFIssue = mtk.DFMSheetMetal_SmallDistanceBetweenFeaturesIssue.Cast(anIssue)
240 aManager.AddFeature(SmallDistanceIssueName (aSDBFIssue), "Distance(s)", True, anIssue)
241 elif mtk.DFMSheetMetal_NonStandardSheetThicknessIssue.CompareType(anIssue):
242 aManager.AddFeature("Non Standard Sheet Thickness Issue(s)", "Sheet Thickness(s)", True, anIssue)
243 elif mtk.DFMSheetMetal_NonStandardSheetSizeIssue.CompareType(anIssue):
244 aManager.AddFeature("Non Standard Sheet Size Issue(s)", "Sheet Size(s)", True, anIssue)
245
246 aManager.Print ("issues", PrintFeatureParameters)
247
248class PartProcessor(shape_processor.ShapeProcessor):
249 def __init__(self):
250 super().__init__()
251 self.myAnalyzer = mtk.DFMSheetMetal_Analyzer()
252
253 def ProcessSolid(self, theSolid: mtk.ModelData_Solid):
254 anIssueList = self.myAnalyzer.Perform(theSolid)
255 PrintIssues(anIssueList)
256
257 def ProcessShell(self, theShell: mtk.ModelData_Shell):
258 anIssueList = self.myAnalyzer.Perform(theShell)
259 PrintIssues(anIssueList)
260
261def main(theSource: str):
262 aKey = license.Value()
263
264 if not LicenseHelper.SetupRuntimeKey() :
265 return 1
266
267 try:
268 mtk.LicenseManager.Activate(aKey)
269 except mtk.LicenseError as anException:
270 mtk.LicenseManager.Deactivate()
271 print("Failed to activate Manufacturing Toolkit license: " + anException.what())
272 return 1
273
274 aModel = mtk.ModelData_Model()
275 aReader = mtk.ModelData_ModelReader()
276
277 # Reading the file
278 if not aReader.Read(mtk.UTF16String(theSource), aModel):
279 mtk.LicenseManager.Deactivate()
280 print("Failed to open and convert the file " + theSource)
281 return 1
282
283 print("Model: ", aModel.Name(), "\n", sep="")
284
285 # Processing
286 aPartProcessor = PartProcessor()
287 aVisitor = mtk.ModelData_ModelElementUniqueVisitor(aPartProcessor)
288 aModel.Accept(aVisitor)
289
290 mtk.LicenseManager.Deactivate()
291
292 return 0
293
294if __name__ == "__main__":
295 if len(sys.argv) != 2:
296 print( "Usage: <input_file>, where:")
297 print( " <input_file> is a name of the file to be read")
298 sys.exit()
299
300 aSource = os.path.abspath(sys.argv[1])
301
302 sys.exit(main(aSource))