How can I extract Name of Label with python?

Hi all,

I am using the lastest version of pythonocc-core. I just want to extract the name of shape / label and print it out:

        # Get all labels containing shapes
        labels = TDF_LabelSequence()
        shape_tool.GetFreeShapes(labels)

        # Iterate through all labels and print their names
        for i in range(labels.Length()):
            label = labels.Value(i + 1)  # Labels are 1-indexed
            if label.IsNull():
                print("Null label encountered, skipping...")
                continue

            # Use FindAttribute to check for and retrieve the name attribute
            name_attr = TDataStd_Name()
            if label.FindAttribute(TDataStd_Name.GetID(), name_attr):
                name = name_attr.Get()
                print(f"Shape Name: {name}")
            else:
                print("Unnamed Shape")

But then, the following error appeared:

An error occurred: Wrong number or type of arguments for overloaded function 'TDF_Label_FindAttribute'.
  Possible C/C++ prototypes are:
    TDF_Label::FindAttribute(Standard_GUID const &,opencascade::handle< TDF_Attribute > &)
    TDF_Label::FindAttribute(Standard_GUID const &,Standard_Integer const,opencascade::handle< TDF_Attribute > &)

Could you please help me to overcome this issue, as I have not found any example regarding FindAttribute() in python. :-(

Thank you so much!

Dmitrii Pasukhin's picture

Hello.

Please use the handle type as a second argument.

Best regards, Dmitrii.

lanluu's picture

Thank yu @Dmitrii for your tip. Unfortunately, the Handle_TDataStd_Name is not found / cannot be imported from OCC.Core.TDataStd.

from OCC.Core.TDataStd import TDataStd_Name, Handle_TDataStd_Name
ImportError: cannot import name 'Handle_TDataStd_Name' from 'OCC.Core.TDataStd'

Well, I do not know whether I am using the proper class for handle or not. :-(

Following is my full code:

from OCC.Core.STEPCAFControl import STEPCAFControl_Reader
from OCC.Core.TDocStd import TDocStd_Document
from OCC.Core.TDF import TDF_LabelSequence
from OCC.Core.XCAFDoc import XCAFDoc_DocumentTool
from OCC.Core.TDataStd import TDataStd_Name, Handle_TDataStd_Name

def read_step_and_print_names(step_file_path):
    try:
        doc = TDocStd_Document("pythonocc-doc")

        # Get the shape tool for accessing shapes in the document
        shape_tool = XCAFDoc_DocumentTool.ShapeTool(doc.Main())

        # Read the STEP file into the document
        reader = STEPCAFControl_Reader()
        reader.SetColorMode(True)
        reader.SetNameMode(True)
        reader.SetLayerMode(True)

        if reader.ReadFile(step_file_path) != 1:
            print("Error: Unable to read STEP file.")
            return

        if not reader.Transfer(doc):
            print("Error: Unable to transfer STEP data to document.")
            return

        # Get all labels containing shapes
        labels = TDF_LabelSequence()
        shape_tool.GetFreeShapes(labels)

        # Iterate through all labels and print their names
        for i in range(labels.Length()):
            label = labels.Value(i + 1)  # Labels are 1-indexed
            if label.IsNull():
                print("Null label encountered, skipping...")
                continue

            # Use FindAttribute to check for and retrieve the name attribute
            name_attr = Handle_TDataStd_Name()
            if label.FindAttribute(TDataStd_Name.GetID(), name_attr):
                name = name_attr.Get()
                print(f"Shape Name: {name}")
            else:
                print("Unnamed Shape")
    except Exception as e:
        print(f"An error occurred: {e}")

# Example usage with a local STEP file path
step_file_path = "./tests/data/dummy.stp"
read_step_and_print_names(step_file_path)

Dmitrii Pasukhin's picture

Well, look into code, I see that a lot of object that not marked as Handle already handle. shape_tool is a handle, doc is handle. But attribute for some reason - not.

There are some problem from wrapping side, please share bugs with OCC-Py project.

Or try to create variable with basic type and allocate the name attribute:

TDF_Attribute anAttr = TDataStd_Name();

Best regards, Dmitrii. 

 

lanluu's picture
            # Use FindAttribute to check for and retrieve the name attribute
            name_attr: TDF_Attribute = TDataStd_Name()
            if label.FindAttribute(TDataStd_Name.GetID(), name_attr):
                name = name_attr.Get().ToCString()
                print(f"Shape Name: {name}")
            else:
                print("Unnamed Shape")

It did not help with TDF_Attribute :-(.

lanluu's picture

I already submitted an Issue by pythonocc-core at https://github.com/tpaviot/pythonocc-core/issues/1415. But, personally, I think I missed an important point of FindAttribute().

gkv311 n's picture

As a workaround you may try using static method RWMesh::ReadNameAttribute(). It will not allow distinguishing labels without name from labels with an empty name "", though.

aName = rwmesh.ReadNameAttribute(label)
print(f"Shape Name: {aName.ToCString()}")
lanluu's picture

Thank you for your info. How can I find RWMesh Class? As I remember, there is a Package namely e.g. `OCC.Core.RWMesh`.

gkv311 n's picture

lanluu wrote:

How can I find RWMesh Class? As I remember, there is a Package namely e.g. OCC.Core.RWMesh.

from OCC.Core.RWMesh import rwmesh