tpaviot / pythonocc-core

Python package for 3D geometry CAD/BIM/CAM
GNU Lesser General Public License v3.0
1.38k stars 380 forks source link

Export STEP file with name #482

Closed tnakaicode closed 4 years ago

tnakaicode commented 6 years ago

In my python code, I made one vertex, two planes, and one circle. But, I don't know how to resgister every name. So, opening with CAD Assistant, two planes have same name (named FACE).

root

I want to know how to register every shape's name (these names are difference each other).

I used following code.

import numpy as np
import sys, time, os

from OCC.Display.SimpleGui import init_display
from OCC.XSControl      import XSControl_Writer, XSControl_WorkSession
from OCC.XCAFApp        import XCAFApp_Application
from OCC.XCAFDoc        import (XCAFDoc_DocumentTool_ShapeTool,
                                XCAFDoc_DocumentTool_ColorTool,
                                XCAFDoc_DocumentTool_LayerTool,
                                XCAFDoc_DocumentTool_MaterialTool)
from OCC.STEPCAFControl import STEPCAFControl_Writer
from OCC.STEPControl    import STEPControl_Writer
from OCC.STEPControl    import (STEPControl_AsIs,
                                STEPControl_ManifoldSolidBrep,
                                STEPControl_FacetedBrep,
                                STEPControl_ShellBasedSurfaceModel,
                                STEPControl_GeometricCurveSet)
from OCC.Interface      import Interface_Static_SetCVal
from OCC.IFSelect       import IFSelect_RetDone
from OCC.TDF            import TDF_LabelSequence, TDF_Label, TDF_Tool, TDF_Data
from OCC.TDataStd       import Handle_TDataStd_Name, TDataStd_Name_GetID
from OCC.TDataStd       import TDataStd_Name
from OCC.TCollection    import TCollection_AsciiString
from OCC.TCollection    import TCollection_ExtendedString
from OCC.TDocStd        import TDocStd_Document, Handle_TDocStd_Document

class ExportCAFMethod (object):

    def __init__(self, name="name", tol=1.0E-10):
        self.name = name
        self.step = STEPCAFControl_Writer()
        self.step.SetNameMode(True)
        self.h_doc = Handle_TDocStd_Document()
        self.x_app = XCAFApp_Application.GetApplication().GetObject()
        self.x_app.NewDocument(TCollection_ExtendedString("MDTV-CAF"), self.h_doc)
        self.doc   = self.h_doc.GetObject()
        self.h_shape_tool = XCAFDoc_DocumentTool_ShapeTool(self.doc.Main())
        self.shape_tool   = self.h_shape_tool.GetObject()
        Interface_Static_SetCVal("write.step.schema", "AP214")

    def Add (self, shape, name="name"):
        """
        STEPControl_AsIs                   translates an Open CASCADE shape to its highest possible STEP representation.
        STEPControl_ManifoldSolidBrep      translates an Open CASCADE shape to a STEP manifold_solid_brep or brep_with_voids entity.
        STEPControl_FacetedBrep            translates an Open CASCADE shape into a STEP faceted_brep entity.
        STEPControl_ShellBasedSurfaceModel translates an Open CASCADE shape into a STEP shell_based_surface_model entity.
        STEPControl_GeometricCurveSet      translates an Open CASCADE shape into a STEP geometric_curve_set entity.
        """
        label = self.shape_tool.AddShape(shape)
        self.step.Transfer(self.h_doc, STEPControl_AsIs)

    def Write (self, filename=None):
        if not filename:
            filename = self.name
        path, ext = os.path.splitext(filename)
        if not ext:
            ext = ".stp"
        status = self.step.Write(path + ext)
        assert(status == IFSelect_RetDone)

if __name__ == "__main__":
    from OCC.gp import gp_Pnt
    from OCCUtils.Construct import make_plane, make_vertex, make_circle

    display, start_display, add_menu, add_function_to_menu = init_display()
    display.DisplayShape (gp_Pnt())
    root = ExportCAFMethod (name="root")
    root.Add (make_vertex (gp_Pnt()), name="pnt")
    root.Add (make_plane (center=gp_Pnt(0, 0, 0  )), name="pln0")
    root.Add (make_plane (center=gp_Pnt(0, 0, 100)), name="pln1")
    root.Add (make_circle (gp_Pnt(0, 0, 0), 100), name="circle")
    root.Write()

    display.FitAll()
    #start_display()
trelau commented 6 years ago

I tried to write a pythonocc script to do this, but it seems a few types are not wrapped. I'll register a separate issue for this.

tpaviot commented 4 years ago

@tnakaicode Please close this issue if it's fixed, or report any new feedback.

Krande commented 4 years ago

Hello, I remember looking into this for some time ago myself but at that time I found nothing. I took another look now and found a way of adding names to my various shapes using the following code (based on snippets from various examples found online):

Note! I am using pythonocc-core 7.4.0rc1

from OCC.Core.IFSelect import IFSelect_RetError
from OCC.Core.Interface import Interface_Static_SetCVal
from OCC.Core.STEPConstruct import stepconstruct_FindEntity
from OCC.Core.STEPControl import (STEPControl_AsIs, STEPControl_Writer)
from OCC.Core.TCollection import TCollection_HAsciiString
from OCC.Core.BRepPrimAPI import BRepPrimAPI_MakeBox
from OCC.Extend.DataExchange import read_step_file_with_names_colors

schema = 'AP203'
assembly_mode = 1

writer = STEPControl_Writer()
fp = writer.WS().TransferWriter().FinderProcess()
Interface_Static_SetCVal('write.step.schema', schema)
Interface_Static_SetCVal('write.step.unit', 'M')
Interface_Static_SetCVal('write.step.assembly', str(assembly_mode))

my_box1 = BRepPrimAPI_MakeBox(10., 20., 30.).Shape()
my_box2 = BRepPrimAPI_MakeBox(20., 1., 30.).Shape()

components = [my_box1, my_box2]
comp_names = ['PartA',  'PartB']
for i, comp in enumerate(components):
    Interface_Static_SetCVal('write.step.product.name', comp_names[i])
    status = writer.Transfer(comp, STEPControl_AsIs)
    if int(status) > int(IFSelect_RetError):
        raise Exception('Some Error occurred')

    # This portion is not working as I hoped
    item = stepconstruct_FindEntity(fp, comp)
    if not item:
        raise Exception('Item not found')

    item.SetName(TCollection_HAsciiString(comp_names[i]))

status = writer.Write('my_stepfile.stp')
if int(status) > int(IFSelect_RetError):
    raise Exception('Something bad happened')

read_step_file_with_names_colors('my_stepfile.stp')

this results in the output:

>>> Number of shapes at root : 2
>>> 
>>> Name : PartA 1
>>> Name : PartB 2
>>> 
>>> Process finished with exit code 0

And if I view it in for example FreeCAD it shows up as bilde

However, what I really wanted was a way to build an Assembly structure using

Interface_Static_SetCVal('write.step.product.name', 'my_root_compound')

to set the name of the "top" layer of a compound, and then use

    item = stepconstruct_FindEntity(fp, comp)
    if not item:
        raise Exception('Item not found')
    item.SetName(TCollection_HAsciiString(comp_names[i]))

to set the name of each individual entity. However, this latter approach seems to do nothing.

I have started trying to find what I am looking for in the OCC docs here: https://www.opencascade.com/doc/occt-7.4.0/overview/html/occt_user_guides__step.html#occt_step_3_4

and here https://www.opencascade.com/doc/occt-7.4.0/overview/html/occt_user_guides__xde.html

The latter (Extended Data Exchange (XDE) ) seems like it offers what I'm after, but it will take me some time to understand how to make use of it.

In my personal opinion I think a implementation of "entity naming" (and potentially assembly structure) would be great! That would provide some extra control when exporting created step files to other applications that could use the entity name for identification and lookup of metadata not embedded in the step file itself.

However, if the approach I describe is the only way of providing names to step entities I guess you can close this issue?

mlaura1996 commented 2 years ago

Hi, did someone use this command to set the colors in stead of names?