For all issues regarding the Forums use, please, refer to the Forum Rules.

Our Solutions

Need professional assistance?
Consider our:

Support Offerings

 

Need to speed up your development?
Have a look at our:

Samples & Tools

 

Need some functionality extending standard OCCT capabilities?
Check out our:

Adv. Components

Related pages

TDF_Label::FindAttribute strange bahaviour in OCC7.2

walter steffe's picture
Forums: 

With OCC 6.9.1 I was using the function "void MwOCAF::setMissingNames(TDF_Label root))" (code shown in the last part of this message)

to assign names (taken from shape types) to OCAF labels without a yet assigned name attribute.

But this  function does not work any more with OCC 7.2.

The problem occurs because  root.FindAttribute(TDataStd_Name::GetID(),nameAtt) returns false so that the code enters into the lines

        nameAtt= new TDataStd_Name();

        root.AddAttribute(nameAtt);

But  then TDF_Label::AddToNode(), which is called by TDF_Label::AddAttribute() makes a different test:

  Handle(TDF_Attribute) dummyAtt;
  //if (Find(anAttribute->ID(),dummyAtt))  
  if (FindAttribute(anAttribute->ID(),dummyAtt))
    throw Standard_DomainError("This label has already such an attribute.");

And this exception is thrown because this test evaluates to true.

The main difference with respect to the test done in my function is that in this one

the first argument of TDF_Label::FindAttribute is just TDataStd_Name::GetID()

while in TDF_Label::AddAttribute() the first argument of TDF_Label::FindAttribute is

anAttribute->ID()=nameAtt->ID()

where nameAtt was declared as Handle(TDataStd_Name) and passed to TDF_Label::AddAttribute() 

Using GDB I have also verified that the two arguments actually have different values:

(gdb) p nameAtt->ID()
[Thread 0x7fffcac9e700 (LWP 21661) exited]
$1 = (const Standard_GUID &) @0x1c51778: {my32b = 0, my16b1 = 0 u'\000', my16b2 = 0 u'\000', my16b3 = 0 u'\000', 
  my8b1 = 0 '\000', my8b2 = 0 '\000', my8b3 = 0 '\000', my8b4 = 0 '\000', my8b5 = 0 '\000', my8b6 = 0 '\000'}

(gdb) p TDataStd_Name::GetID()
$2 = (const Standard_GUID &) @0x7ffff3d96ec0: {my32b = 714520072, my16b1 = 60555 u'', my16b2 = 4560 u'ᇐ', 
  my16b3 = 48871 u'뻧', my8b1 = 8 '\b', my8b2 = 0 '\000', my8b3 = 9 '\t', my8b4 = 220 '\334', my8b5 = 51 '3', my8b6 = 51 '3'}

But it is not clear to me which of the two tests is the good one.

Following the relevant lines of the calling function:

void MwOCAF::setMissingNames(TDF_Label root)

{

  TCollection_AsciiString name;

  Handle(TDataStd_Name) nameAtt;

  bool hasNameAtt=root.FindAttribute(TDataStd_Name::GetID(),nameAtt);

  if(hasNameAtt) name=nameAtt->Get();

  bool missingName=name.IsEmpty() || (name==TCollection_AsciiString("NONE"));

  if(missingName) {

       if(!hasNameAtt){

        nameAtt= new TDataStd_Name();

        root.AddAttribute(nameAtt);

       }

Thanks in advance for your help

Walter

Mikhail MPV's picture

Since OCCT 7.1.0 same type attributes may have different GUIDs. Because of this the attribute constructor does not initialize GUID. See a chapter "Support of several attributes of one type at the same label" in Release Notes.

So, before AddAttribute you should call

  nameAtt->SetID(TDataStd_Name::GetID())

Anyway, the standard way to create and attach attribute to a label is to use "Set" method of the attribute. It works well on any version of OCCT.

I registered an issue 29371 in the bugtracker to avoid such a problem later.

walter steffe's picture

Ok Thanks

Walter Steffe