Sat, 12/02/2017 - 17:03
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
Tue, 12/05/2017 - 16:33
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.
Tue, 12/05/2017 - 17:48
Ok Thanks
Walter Steffe