Hide menu
Loading...
Searching...
No Matches
exploring/pmi/pmi.py

Refer to the PMI Example.

1# $Id$
2
3# Copyright (C) 2008-2014, Roman Lygin. All rights reserved.
4# Copyright (C) 2014-2025, mtk. 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
41class TabulatedOutput:
42 myNestingLevel = 0
43
44 @classmethod
45 def WriteLine(cls, theObject: str):
46 cls.PrintTabulation()
47 print(theObject)
48
49 @classmethod
50 def IncreaseIndent(cls):
51 cls.myNestingLevel += 1
52
53 @classmethod
54 def DecreaseIndent(cls):
55 cls.myNestingLevel -= 1
56
57 @classmethod
58 def PrintTabulation(cls):
59 if cls.myNestingLevel <= 0:
60 return
61 # Emulate tabulation like tree.
62 for i in range(cls.myNestingLevel - 1):
63 if i < 2 or i == 3:
64 print("| ", end="")
65 else:
66 print(" ", end="")
67 print("|__", end="")
68 if cls.myNestingLevel > 3:
69 print(" ", end="")
70
71class SceneGraphVisitor(mtk.ModelData_ModelElementVisitor):
72 def VisitPart(self, thePart: mtk.ModelData_Part):
73 self.PrintName("Part", thePart.Name())
74 self.ExplorePMI(thePart)
75
76 def VisitEnterInstance(self, theInstance: mtk.ModelData_Instance):
77 TabulatedOutput.IncreaseIndent()
78 self.PrintName("Instance", theInstance.Name())
79 self.ExplorePMI(theInstance)
80 return True
81
82 def VisitEnterAssembly(self, theAssembly: mtk.ModelData_Assembly):
83 TabulatedOutput.IncreaseIndent()
84 self.PrintName("Assembly", theAssembly.Name())
85 self.ExplorePMI(theAssembly)
86 return True
87
88 def VisitLeaveInstance(self, theInstance: mtk.ModelData_Instance):
89 TabulatedOutput.DecreaseIndent()
90
91 def VisitLeaveAssembly(self, theAssembly: mtk.ModelData_Assembly):
92 TabulatedOutput.DecreaseIndent()
93
94 def ExplorePMI(self, theSGE: mtk.ModelData_ModelElement):
95 aPMIData : mtk.PMI_Data = theSGE.PMI()
96 if aPMIData:
97 TabulatedOutput.WriteLine("PMI Data:")
98 TabulatedOutput.IncreaseIndent()
99
100 if aPMIData.NumberOfElements() == 0:
101 return
102
103 anElements = aPMIData.Elements()
104 for anElement in anElements:
105 TabulatedOutput.WriteLine(f"PMI Element: {anElement.Name()}")
106
107 TabulatedOutput.IncreaseIndent()
108
109 aSemanticRepresentation = anElement.SemanticRepresentation()
110 if aSemanticRepresentation and not aSemanticRepresentation.IsEmpty() :
111 TabulatedOutput.WriteLine("Semantic Representation:")
112 TabulatedOutput.IncreaseIndent()
113 aVisitor = PMISemanticVisitor()
114 aSemanticRepresentation.Accept(aVisitor)
115 TabulatedOutput.DecreaseIndent()
116
117 aGraphicalRepresentation = anElement.GraphicalRepresentation()
118 if aGraphicalRepresentation and not aGraphicalRepresentation.IsEmpty():
119 TabulatedOutput.WriteLine("Graphical Representation:")
120 TabulatedOutput.IncreaseIndent()
121 aVisitor = PMIGraphicalVisitor()
122 aGraphicalRepresentation.Accept(aVisitor)
123 TabulatedOutput.DecreaseIndent()
124
125 TabulatedOutput.DecreaseIndent()
126 TabulatedOutput.DecreaseIndent()
127
128 def PrintName(self, theSGElement: str, theName: str):
129 if theName:
130 TabulatedOutput.WriteLine(f"{theSGElement}: {theName}")
131 else:
132 TabulatedOutput.WriteLine(f"{theSGElement}: <noname>")
133
134class PMISemanticVisitor(mtk.PMI_SemanticComponentVisitor):
135 def VisitDatumComponent(self, theComponent: mtk.PMI_DatumComponent):
136 TabulatedOutput.WriteLine("Datum")
137 TabulatedOutput.IncreaseIndent()
138 TabulatedOutput.WriteLine(f"Label: {theComponent.Label()}")
139 self.PrintAttributes(theComponent)
140 TabulatedOutput.DecreaseIndent()
141
142 def VisitDimensionComponent(self, theComponent: mtk.PMI_DimensionComponent):
143 TabulatedOutput.WriteLine("Dimension")
144 TabulatedOutput.IncreaseIndent()
145 TabulatedOutput.WriteLine(f"Nominal Value: {theComponent.NominalValue()}")
146 TabulatedOutput.WriteLine(f"Type of dimension: {int(theComponent.TypeOfDimension())}")
147 self.PrintAttributes(theComponent)
148 TabulatedOutput.DecreaseIndent()
149
150 def VisitGeometricToleranceComponent(self, theComponent: mtk.PMI_GeometricToleranceComponent):
151 TabulatedOutput.WriteLine("Geometric tolerance")
152 TabulatedOutput.IncreaseIndent()
153 TabulatedOutput.WriteLine(f"Magnitude: {theComponent.Magnitude()}")
154 TabulatedOutput.WriteLine(f"Type of tolerance: {int(theComponent.TypeOfTolerance())}")
155 TabulatedOutput.WriteLine(f"Tolerance zone form: {int(theComponent.ToleranceZoneForm())}")
156 #self.PrintAttributes(theComponent)
157 TabulatedOutput.DecreaseIndent()
158
159 def VisitSurfaceFinishComponent(self, theComponent: mtk.PMI_SurfaceFinishComponent):
160 TabulatedOutput.WriteLine("Surface Finish")
161 TabulatedOutput.IncreaseIndent()
162 TabulatedOutput.WriteLine(f"Material removal: {int(theComponent.MaterialRemoval())}")
163 TabulatedOutput.WriteLine(f"Lay direction: {int(theComponent.LayDirection())}")
164 TabulatedOutput.WriteLine(f"All around flag: {int(theComponent.IsAllAround())}")
165 TabulatedOutput.WriteLine(f"Manufacturing method: {theComponent.ManufacturingMethod()}")
166 self.PrintAttributes(theComponent)
167 TabulatedOutput.DecreaseIndent()
168
169 def PrintAttributes(self, theComponent: mtk.PMI_SemanticComponent):
170 if theComponent.HasAttributes():
171 aVisitor = PMISemanticAttributeVisitor()
172 theComponent.Accept(aVisitor)
173
174class PMISemanticAttributeVisitor(mtk.PMI_SemanticAttributeVisitor):
175 def VisitModifierAttribute(self, theAttribute: mtk.PMI_ModifierAttribute):
176 TabulatedOutput.WriteLine(f"Modifier: {theAttribute.Modifier()}")
177
178 def VisitModifierWithValueAttribute(self, theAttribute: mtk.PMI_ModifierWithValueAttribute):
179 TabulatedOutput.WriteLine(f"ModifierWithValue: modifier={theAttribute.Modifier()}, value={theAttribute.Value()}")
180
181 def VisitQualifierAttribute(self, theAttribute: mtk.PMI_QualifierAttribute):
182 TabulatedOutput.WriteLine(f"Qualifier: {theAttribute.Qualifier()}")
183
184 def VisitPlusMinusBoundsAttribute(self, theAttribute: mtk.PMI_PlusMinusBoundsAttribute):
185 TabulatedOutput.WriteLine(f"PlusMinusBounds: ({theAttribute.LowerBound()}, {theAttribute.UpperBound()})")
186
187 def VisitRangeAttribute(self, theAttribute: mtk.PMI_RangeAttribute):
188 TabulatedOutput.WriteLine(f"Range: [{theAttribute.LowerLimit()}, {theAttribute.UpperLimit()}]")
189
190 def VisitLimitsAndFitsAttribute(self, theAttribute: mtk.PMI_LimitsAndFitsAttribute):
191 TabulatedOutput.WriteLine(f"LimitsAndFits: value={theAttribute.Value()} + {type}={theAttribute.Type()}")
192
193 def VisitDatumTargetAttribute(self, theAttribute: mtk.PMI_DatumTargetAttribute):
194 TabulatedOutput.WriteLine(f"DatumTarget: index={theAttribute.Index()}, description={theAttribute.Description()}")
195
196 def VisitDatumRefAttribute(self, theAttribute: mtk.PMI_DatumRefAttribute):
197 TabulatedOutput.WriteLine(f"DatumRef: precedence={theAttribute.Precedence()}, targetLabel={theAttribute.TargetLabel()}")
198
199 def VisitDatumRefCompartmentAttribute(self, theAttribute: mtk.PMI_DatumRefCompartmentAttribute):
200 TabulatedOutput.WriteLine("DatumRefCompartment:")
201
202 TabulatedOutput.IncreaseIndent()
203
204 aNumberOfReferences = theAttribute.NumberOfReferences()
205 if aNumberOfReferences > 0:
206 TabulatedOutput.WriteLine("References:")
207 TabulatedOutput.IncreaseIndent()
208 for i in range(aNumberOfReferences):
209 theAttribute.Reference(i).Accept(self)
210 TabulatedOutput.DecreaseIndent()
211
212 aNumberOfModifierAttributes = theAttribute.NumberOfModifierAttributes()
213 if aNumberOfModifierAttributes > 0:
214 TabulatedOutput.WriteLine("Modifiers:")
215 TabulatedOutput.IncreaseIndent()
216 for i in range(aNumberOfModifierAttributes):
217 theAttribute.ModifierAttribute(i).Accept(self)
218 TabulatedOutput.DecreaseIndent()
219
220 TabulatedOutput.DecreaseIndent()
221
222 def VisitMaximumValueAttribute(self, theAttribute: mtk.PMI_MaximumValueAttribute):
223 TabulatedOutput.WriteLine(f"MaximumValue: {theAttribute.MaxValue()}")
224
225 def VisitDisplacementAttribute(self, theAttribute: mtk.PMI_DisplacementAttribute):
226 TabulatedOutput.WriteLine(f"Displacement: {theAttribute.Displacement()}")
227
228 def VisitLengthUnitAttribute(self, theAttribute: mtk.PMI_LengthUnitAttribute):
229 TabulatedOutput.WriteLine(f"LengthUnit: {theAttribute.Unit()}")
230
231 def VisitAngleUnitAttribute(self, theAttribute: mtk.PMI_AngleUnitAttribute):
232 TabulatedOutput.WriteLine(f"AngleUnit: {theAttribute.Unit()}")
233
234 def VisitMachiningAllowanceAttribute(self, theAttribute: mtk.PMI_MachiningAllowanceAttribute):
235 TabulatedOutput.WriteLine("Machining allowance")
236 TabulatedOutput.IncreaseIndent()
237 TabulatedOutput.WriteLine(f"Value: {theAttribute.Value()}")
238 TabulatedOutput.WriteLine(f"Upper bound: {theAttribute.UpperBound()}")
239 TabulatedOutput.WriteLine(f"Lower bound: {theAttribute.LowerBound()}")
240 TabulatedOutput.DecreaseIndent()
241
242 def VisitSurfaceTextureRequirementAttribute(self, theAttribute: mtk.PMI_SurfaceTextureRequirementAttribute):
243 TabulatedOutput.WriteLine(f"Surface texture requirement #: {int(theAttribute.Precedence())}")
244 TabulatedOutput.IncreaseIndent()
245 TabulatedOutput.WriteLine(f"Specification limit: {int(theAttribute.SpecificationLimit())}")
246 TabulatedOutput.WriteLine(f"Filter name: {theAttribute.FilterName()}")
247 TabulatedOutput.WriteLine(f"Short wave filter: {theAttribute.ShortWaveFilter()}")
248 TabulatedOutput.WriteLine(f"Long wave filter: {theAttribute.LongWaveFilter()}")
249 TabulatedOutput.WriteLine(f"Surface parameter: {int(theAttribute.SurfaceParameter())}")
250 TabulatedOutput.WriteLine(f"Evaluation length: {theAttribute.EvaluationLength()}")
251 TabulatedOutput.WriteLine(f"Comparison rule: {int(theAttribute.ComparisonRule())}")
252 TabulatedOutput.WriteLine(f"Limit value: {theAttribute.LimitValue()}")
253 TabulatedOutput.DecreaseIndent()
254
255class PMIGraphicalVisitor(mtk.PMI_GraphicalComponentVisitor):
256 def VisitOutlinedComponent(self, theComponent: mtk.PMI_OutlinedComponent):
257 TabulatedOutput.WriteLine("Outline")
258 TabulatedOutput.IncreaseIndent()
259 aVisitor = PMIOutlineVisitor()
260 theComponent.Outline().Accept(aVisitor)
261 TabulatedOutput.DecreaseIndent()
262
263 def VisitTextComponent(self, theComponent: mtk.PMI_TextComponent):
264 TabulatedOutput.WriteLine(f"Text [{theComponent.Text()}]")
265
266 def VisitTriangulatedComponent(self, theComponent: mtk.PMI_TriangulatedComponent):
267 TabulatedOutput.WriteLine(f"Triangulation [{theComponent.TriangleSet().NumberOfTriangles()} triangles]")
268
269class PMIOutlineVisitor(mtk.PMI_OutlineVisitor):
270 def VisitPolyOutline(self, theOutline: mtk.PMI_PolyOutline):
271 TabulatedOutput.WriteLine(f"PolyLine set [{theOutline.LineSet().NumberOfPolylines()} polylines]")
272
273 def VisitPoly2dOutline(self, theOutline: mtk.PMI_Poly2dOutline):
274 TabulatedOutput.WriteLine(f"PolyLine2d set [{theOutline.LineSet().NumberOfPolylines()} polylines]")
275
276 def VisitCurveOutline(self, theOutline: mtk.PMI_CurveOutline):
277 TabulatedOutput.WriteLine(f"Curve set [{theOutline.NumberOfCurves()} curves]")
278
279 def VisitCurve2dOutline(self, theOutline: mtk.PMI_Curve2dOutline):
280 TabulatedOutput.WriteLine(f"Curve2d set [{theOutline.NumberOfCurves()} curves]")
281
282 def VisitEnterCompositeOutline(self, theOutline: mtk.PMI_CompositeOutline):
283 TabulatedOutput.WriteLine("Composite outline:")
284 TabulatedOutput.IncreaseIndent()
285 return True
286
287 def VisitLeaveCompositeOutline(self, theOutline: mtk.PMI_CompositeOutline):
288 TabulatedOutput.DecreaseIndent()
289
290def main(theSource: str):
291 aKey = license.Value()
292
293 if not mtk.LicenseManager.Activate(aKey):
294 print("Failed to activate Manufacturing Toolkit license.")
295 return 1
296
297 aModel = mtk.ModelData_Model()
298 aReader = mtk.ModelData_ModelReader()
299 aParams = mtk.ModelData_ModelReaderParameters()
300 aParams.SetReadPMI(True)
301 aReader.SetParameters(aParams)
302
303 # Reading the file
304 if not aReader.Read(mtk.UTF16String(theSource), aModel):
305 print("Failed to open and convert the file " + theSource)
306 return 1
307
308 print("Model: ", aModel.Name(), "\n", sep="")
309
310 # Create a PMI visitor
311 aVisitor = SceneGraphVisitor()
312 aModel.Accept(aVisitor)
313
314 print("Completed")
315
316 return 0
317
318if __name__ == "__main__":
319 if len(sys.argv) != 2:
320 print("Usage: <input_file>, where:")
321 print(" <input_file> is a name of the file to be read")
322 sys.exit()
323
324 aSource = os.path.abspath(sys.argv[1])
325
326 sys.exit(main(aSource))