Load STEP-file hierarchy tree

I tried to load structured model from STEP file and get names of its parts using STEPCAFControl_Reader.

But I have a problem.

Real structure of the model has root, root's children and some root's children have their own children.

When I use assembly->GetFreeShapes(freeShapes); and decompose model in OCC, I get root and its children. Some of the children are COMPOUNDs. I can decompose them and draw correct geometry, but I can't get their names.

When I use assembly->GetShapes(shapes);, I get all parts of model with their names, including third level of structure, and I can get their parents. So I can build correct structure tree with names, but I can't draw correct geometry (location of parts is initial).

Is there a way to get both correct locations of part and structure with names as in the CAD Assistant, for example?

Code for loading model:

void CadDocument::loadStepModel(QString path)

{

STEPCAFControl_Reader reader;

IFSelect_ReturnStatus stat = reader.ReadFile(path.toStdString().c_str());

 

if (stat = IFSelect_RetDone)

{

reader.SetNameMode(Standard_True);

reader.SetColorMode(Standard_True);

if (!doc.IsNull())

doc.Nullify();

anApp->NewDocument("MDTV-XCAF", doc);

if (reader.Transfer(doc))

{

m_pcoloredshapeList->Clear(context);

assembly = XCAFDoc_DocumentTool::ShapeTool(doc->Main());

decomposeAssembly();

}

}

}

 

void CadDocument::decomposeAssembly()

{

TDF_LabelSequence freeShapes;

assembly->GetFreeShapes(freeShapes);

int n = freeShapes.Length();

for (int i = 1; i <= n; i++)

{

TDF_Label label = freeShapes.Value(i);

decomposeLabel(label);

}

}

 

void CadDocument::decomposeLabel(TDF_Label &label)

{

if (assembly->IsAssembly(label))

{

Standard_Integer nbc = assembly->NbComponents(label);

if (nbc > 0)

{

TDF_LabelSequence childrenSequence;

assembly->GetComponents(label, childrenSequence);

for (int i = 1; i <= childrenSequence.Length(); i++)

{

TDF_Label newlabel = childrenSequence.Value(i);

decomposeLabel(newlabel);

}

}

else

{

addShapeLabel(label);

}

}

else

{

addShapeLabel(label);

}

}

 

void CadDocument::addShapeLabel(TDF_Label &label)

{

TopoDS_Shape shape = assembly->GetShape(label);

if (shape.ShapeType() == TopAbs_COMPOUND)

{

assembly->Expand(label);

decomposeLabel(label);

}

else

m_pcoloredshapeList->Add(Quantity_NOC_YELLOW, shape, context);

}

Attachments: 
Helena Makarova's picture

I found solution of the problem.

If my label Label isn't assembly, I should check if it is a reference. If it is a reference, I should find referred label Ref and check, if the referred label is assembly.

If it is so, I expand the label Label to make it assembly and delete its components using both RemoveComponent to remove component from tree and tnen RemoveShape to remove its shape from the free shapes list.

Then I iterate components of Ref and add them as components of Label. Also I copy names. If a component of Ref is a reference, I add to Label its referred label.

This is a part of my code to copy components:

TDF_LabelSequence childrenSequence;

assembly->GetComponents(ref, childrenSequence);

for (int i = 1; i <= childrenSequence.Length(); i++)

{

TDF_Label newlabel = childrenSequence.Value(i);

TopLoc_Location location = assembly->GetLocation(label);

location = location.Multiplied(assembly->GetLocation(newlabel));

TDF_Label nextLabel;

if (assembly->IsReference(newlabel))

{

TDF_Label nextRef;

assembly->GetReferredShape(newlabel, nextRef);

nextLabel = assembly->AddComponent(label, nextRef, location);

}

else

nextLabel = assembly->AddComponent(label, newlabel, location);

TDataStd_Name::Set(nextLabel, getLabelName(newlabel).toStdString().c_str());

}

chandrasekhar yammanuri's picture

Could You Please share total code.So that it can help my work which iam doing .Iam also getting unnecesaary things in tree which are not required.I also expecting which is same in cadassistant.

Kadir Canik's picture

Hello Helena,

I new started with OCC.  I can not understand the OCC structure well.

I defined in my application class;

Handle(TDocStd_Application) myApp;

And I defined in my Document class;

Handle(TDocStd_Document) myOcafDoc;

On new document i use OcafApp->NewDocument("BinOcaf", myOcafDoc);

But if i import a step file I need to use anApp->NewDocument("MDTV-XCAF", doc);

I do not understand when to use BinOcaf and when to use MDTV-XCAF.

Is that possible to share your Application class and Document class?

I just want to see what you defined in App class and Doc class and what you do when new document, open document and import.

Thank you.

Kadir Canik kadircanik(at)msn.com