Message Boards Message Boards

[?] Create geometrical regions from STEP (ISO10303)?

Posted 6 years ago

For a student project (doing applied research for a mechanical engineering company) we need to correlate the G-Code statements generated from a CAM System (used by a milling machine or lathe) with the surfaces of the final product produced, which is modelled in a CAD System.

The CAD export format is STEP which is described in the ISO10303 Standard. Unfortunately Mathematica does not provide a STEP Import format for the geometry of the modelled object (which astonishes me as it is a widely used format in mechanical engineering).

As I am a Wolfram Language beginner I am asking for advice on how to transform a STEP file into a geometrical region, allowing then to do computations like which G-code Statement generated which surface.

The STEP content links the standardized geometric objects described in the ISO10303 standard using the EXPRESS language which can be compared to an XML Schema as of today.Here the first few lines of an example STEP file

#10=MECHANICAL_DESIGN_GEOMETRIC_PRESENTATION_REPRESENTATION('',(#218,#215,
#219,#221,#220,#216,#217,#226,#225,#224,#227,#222,#223),#404);
#11=SHAPE_REPRESENTATION_RELATIONSHIP('SRR','None',#411,#12);
#12=ADVANCED_BREP_SHAPE_REPRESENTATION('',(#13),#403);
#13=MANIFOLD_SOLID_BREP('Solid1',#240);
#14=PLANE('',#266);
#15=PLANE('',#267);

I visualized the content using DFS

steps = StringSplit[
   StringReplace[
    ReadList["Documents/G-code/GCODE/Bauteil6_none_AP214.stp", Record,
       RecordSeparators -> {{"HEADER;", "DATA"}, {"ENDSEC;", 
         "ENDSEC;"}}][[2]], "\n" -> ""], ";"];
edge[n_] := Module[{instances = {}},
  instances = StringCases[n, "#" ~~ DigitCharacter ..];
  Drop[Map[DirectedEdge[First[instances], #] &, instances], 1]
  ]
vertex[p_] := Module[{instances = {}},
  instances = StringCases[p, "#" ~~ DigitCharacter ..];
  Property[First[instances], "Content" -> p]
  ]
edges = Map[edge[#] &, steps];
properties = Map[vertex[#] &, steps];
g = Graph[properties, Flatten[edges, 2]];
DepthFirstScan[g, 
  "#10", {"DiscoverVertex" -> ((depthval[#1] = #3) &), 
   "PrevisitVertex" -> (If[depthval[#] > -1, 
       Print @@ 
        Append[Table["    ", depthval[#]], 
         StringReplace[PropertyValue[{g, #}, "Content"], 
          "\n" -> ""]]] &)}];
10=MECHANICAL_DESIGN_GEOMETRIC_PRESENTATION_REPRESENTATION('',(#218,#215,#219,#221,#220,#216,#217,#226,#225,#224,#227,#222,#223),#404)
    #218=STYLED_ITEM('',(#421),#231)
        #421=PRESENTATION_STYLE_ASSIGNMENT((#423))
            #423=SURFACE_STYLE_USAGE(.BOTH.,#425)
                #425=SURFACE_SIDE_STYLE('',(#427))
                    #427=SURFACE_STYLE_FILL_AREA(#429)
                        #429=FILL_AREA_STYLE('',(#431))
                            #431=FILL_AREA_STYLE_COLOUR('',#433)
                                #433=COLOUR_RGB('',0.274509803921569,0.619607843137255,0.254901960784314)
        #231=ADVANCED_FACE('',(#75),#15,.T.)
            #75=FACE_OUTER_BOUND('',#89,.T.)
                #89=EDGE_LOOP('',(#166,#167,#168,#169))
                    #166=ORIENTED_EDGE('',*,*,#128,.F.)
                        #128=EDGE_CURVE('',#108,#109,#23,.T.)
                            #108=VERTEX_POINT('',#347)
                                #347=CARTESIAN_POINT('',(20.,-30.,40.))
                            #109=VERTEX_POINT('',#349)
                                #349=CARTESIAN_POINT('',(20.,-30.,0.))
                            #23=LINE('',#350,#46)
                                #350=CARTESIAN_POINT('',(20.,-30.,0.))
                                #46=VECTOR('',#290,10.)
                                    #290=DIRECTION('',(0.,0.,-1.))
                    #167=ORIENTED_EDGE('',*,*,#135,.F.)
                        #135=EDGE_CURVE('',#114,#108,#29,.T.)
                            #114=VERTEX_POINT('',#363)
                                #363=CARTESIAN_POINT('',(-50.,-30.,40.))
                            #29=LINE('',#364,#52)
                                #364=CARTESIAN_POINT('',(50.,-30.,40.))
                                #52=VECTOR('',#302,10.)
                                    #302=DIRECTION('',(1.,1.33226762955019E-16,0.))
                    #168=ORIENTED_EDGE('',*,*,#136,.F.)
                        #136=EDGE_CURVE('',#111,#114,#30,.T.)
                            #111=VERTEX_POINT('',#355)
                                #355=CARTESIAN_POINT('',(-50.,-30.,0.))
                            #30=LINE('',#365,#53)
                                #365=CARTESIAN_POINT('',(-50.,-30.,0.))
                                #53=VECTOR('',#303,10.)
                                    #303=DIRECTION('',(0.,0.,1.))
                    #169=ORIENTED_EDGE('',*,*,#131,.F.)
                        #131=EDGE_CURVE('',#109,#111,#25,.T.)
                            #25=LINE('',#356,#48)
                                #356=CARTESIAN_POINT('',(50.,-30.,0.))
                                #48=VECTOR('',#296,10.)
                                    #296=DIRECTION('',(-1.,-1.33226762955019E-16,0.))
            #15=PLANE('',#267)
                #267=AXIS2_PLACEMENT_3D('',#362,#300,#301)
                    #362=CARTESIAN_POINT('Origin',(-50.,-30.,0.))
                    #300=DIRECTION('center_axis',(1.33226762955019E-16,-1.,0.))

One can see that index #10 references #218 which in turn then references #421 and #231 and so on.

ADVANCED_FACE in this example could be modelled as a RegionUnion of a LINE with an InfinitePlane.

But how to do this in Wolfram Language? Shall I transform the STEP content into nested expressions like

advancedFace[{faceOuterBound[{edgeLoop[{orientedEdge[ ...]}], ...}, TRUE], plane[]}, TRUE] and then transforming the expressions into a list of basic geometric regions, meshes, combinded regions?

Any thought on how to best approach this problem is much appreciated. Regards Markus

2 Replies

STEP may be a widely used system in the manufacturing world, but you should not be "astonished" that it is not currently supported by Wolfram. Getting a STEP import capability will be costly. After you purchase the rather pricey ISO10303 standard you will find other ISO documents are also required. Eventually you will discover that the Express modeling language is a can of worms that needs a very complete Object Oriented Programming language to parse. The last time I looked at this, none of the existing OOP systems for Mathematica had all the required bells and whistles. So to summarize, I believe that to get STEP import into Mathematica, (1) you need a very complete and high performance OOP system coded in the Wolfram Language, (2) then you need to build an Express parser using that OOP system, (3) then you need to translate the ISO10303 standard for STEP into a form that your Express parser can handle. As a wild guess, a $1M budget would be a ROM cost for this. Someone please prove me wrong, since I have needed this capability for years.

Proven wrong again. The latest version 12.1 contains an add-on package named OpenCascadeLink which provides a function OpenCascadeShapeImport which can import an ISO-10303-21 STEP file into Mathematica. It appears to do what Markus Sonderegger is asking for above. This approach (of linking to an existing external package with the desired functionality) avoids the costly reinvention of the wheel I alluded to earlier. Most of the 29 functions in the OpenCascadeLink package have rather skimpy documentation but there is a useful tutorial with examples. Nice to see more support for mechanical engineering coming to Mathematica.

I would not have found this except for this mention on stack exchange. There was no hint of this in the Summary of New Features in 12.1 in the Mar 18, 2020 Wolfram Blog announcing the 12.1 release so maybe OpenCascadeLink is still considered in development.

Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract