TDF_Label from "TCollection_AsciiString" and modifying sub-assemblies

Jonathan

CAD community veteran
Hi,

I know that using TDF_Tool::Entry it is possible to obtain the ascii representation of the label , ie: "0:1:1:2:4"
Is there a tool that goes backward? Give the label from the string representation ?

I am currently using a map(ais,string) to keep track of what AIS is representing in the document..
I had (ais,label) but then when there are multiple instance of a specific object it is not working so well..

Another question,

how to delete an instance in a sub assembly that is referenced multiple times.. for instance in as1-oc-214.stp , if I would like to remove one of the bolt, but leave the nut alone... Since the "bolt-nut" sub assembly is present 6 times, how do I update the one assembly without affecting all the other instance ? I guess I would have to create a version of the assembly without the bolt and replace the instance that has both the bolt and the nut.. but I have no idea how to do this, it's very unintuitive to me.

thank you!
 

JSlyadne

Administrator
Staff member
Hi,

I know that using TDF_Tool::Entry it is possible to obtain the ascii representation of the label , ie: "0:1:1:2:4"
Is there a tool that goes backward? Give the label from the string representation ?

I am currently using a map(ais,string) to keep track of what AIS is representing in the document..
I had (ais,label) but then when there are multiple instance of a specific object it is not working so well..

Another question,

how to delete an instance in a sub assembly that is referenced multiple times.. for instance in as1-oc-214.stp , if I would like to remove one of the bolt, but leave the nut alone... Since the "bolt-nut" sub assembly is present 6 times, how do I update the one assembly without affecting all the other instance ? I guess I would have to create a version of the assembly without the bolt and replace the instance that has both the bolt and the nut.. but I have no idea how to do this, it's very unintuitive to me.

thank you!
Hey, Jonathan,

Regarding the first point, I guess TDF_Tool::Label(...) is what you're looking for. The first parameter there should be GetData(...) of the instance of OCAF document in your app.
 

Quaoar

Administrator
Staff member
how to delete an instance in a sub assembly that is referenced multiple times.. for instance in as1-oc-214.stp , if I would like to remove one of the bolt, but leave the nut alone... Since the "bolt-nut" sub assembly is present 6 times, how do I update the one assembly without affecting all the other instance ? I
That's surprisingly not easy to do in XDE. Back in the days, we implemented a function named "break sharing" to isolate an occurrence of interest in the assembly document (you may want to read Sec. 4 here). Unfortunately, it was not open sourced, but we'll definitely reimplement and publish it in the next few months because we need it for another project.
 

Jonathan

CAD community veteran
Hey, Jonathan,

Regarding the first point, I guess TDF_Tool::Label(...) is what you're looking for. The first parameter there should be GetData(...) of the instance of OCAF document in your app.
Yes, thank you, that worked well! much less convoluted than what I came up with haha :)

I made some progress on part #2 but it's not working right just yet..
 

Jonathan

CAD community veteran
That's surprisingly not easy to do in XDE. Back in the days, we implemented a function named "break sharing" to isolate an occurrence of interest in the assembly document (you may want to read Sec. 4 here). Unfortunately, it was not open sourced, but we'll definitely reimplement and publish it in the next few months because we need it for another project.
that's great news!

In the case of the wheel chassis.. let say user wants to delete front left wheel..

I would replace the wheel - axle - wheel assembly by a new assembly axle - wheel

I can't figure a clean way to do this.. I end up loosing a lot of the attributes like colors.. ..etc.

C++:
                TDF_Label theDadref;
                shapeTool->GetReferredShape(theDad, theDadref);
                if (!shapeTool->IsAssembly(theDadref)) {
                    return;
                }

                TopLoc_Location location = shapeTool->GetLocation(theDad);
                TDF_LabelSequence myBros;
                myBros.Clear();

                shapeTool->GetComponents(theDadref, myBros, false);
               
                Standard_Boolean isRemoved = false;
                TopoDS_ListOfShape shapes;
                for (size_t i = 1; i <= myBros.Length(); i++)
                {
                    if (myBros(i).IsEqual(me)) {
                        myBros.Remove(i);
                        isRemoved = true;
                        i--;
                    }
                    else {
                        if (shapeTool->IsShape(myBros(i))) {
                            shapes.Append(shapeTool->GetShape(myBros(i)));
                        }
                    }
                }
                if (!isRemoved) {
                    theApp.MsgDebugWnd("Couldnt find me in the list, aborting.");
                    return;
                }
       
                TopoDS_Compound aRes;
                BRep_Builder aBuilder;
                aBuilder.MakeCompound(aRes);
               
                for each (TopoDS_Shape shape in shapes)
                {
                   
                    try
                    {
                        aBuilder.Add(aRes, shape);
                    }
       
                    catch (const TopoDS_FrozenShape) {
                        theApp.MsgDebugWnd("Frozen shape, can't modify");
                    }
                    catch (const TopoDS_UnCompatibleShapes) {
                        theApp.MsgDebugWnd("shapes are incompatible.");
                    }
                }

                Handle(TNaming_NamedShape) NS;
                TDF_Label& lbl = shapeTool->NewShape();
                TNaming_Builder builder(lbl);
                builder.Generated(aRes);
                std::stringstream* stream = new std::stringstream();
               
                XCAFDoc_Location::Set(lbl, location);
please excuse the million MsgDebugWnd calls :)
 

JSlyadne

Administrator
Staff member
I can't figure a clean way to do this.. I end up loosing a lot of the attributes like colors.. ..etc.
I think you're on the right way. The attributes must be copied manually since OCCT doesn't provide ready-to-go methods for that.

For colors you should get XCAFDoc_DocumentTool::ColorTool(...) for original and new labels to transfer all the colors (surface, curve, etc.)
For layers you should do almost the same but through XCAFDoc_LayerTool::LayerTool(...).
For materials - XCAFDoc_DocumentTool::MaterialTool(...).

For other attributes if any you should iterate the original part using TDF_AttributeIterator and do smth like:

C++:
Handle(TDF_Attribute) newAttr;

id = oldAttr->ID();

if (!newLabel.FindAttribute(...))
{
    newAttr = oldAttr->NewEmpty();
    newLabel.AddAttribute(newAttr);
}

Handle(TDF_RelocationTable) rt = new TDF_RelocationTable();
oldAttr->Paste(newAttr, rt);
 
Top