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 
zealous03's picture

Hello.

I encountered the same problem while using FindAttribute(). Is there any solution to bypass this method while trying to get other attributes like real or array?

Please let me know.

FayazRahman's picture

For anyone coming across this thread, the present solution is to use label.GetLabelName()

        # 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

            name = label.GetLabelName()