Creating an Assembly out of multiple of the same Shape

Hello I am trying to create an assembly with components that have the same TopoDS_Shape, but at different locations.
Then I want to write this assembly to a step file. The step file only shows the Shape once at a single location though.

my code looks like the following:

TopoDS_Shape shape = ...
std::vector<TopLoc_Location> locations = ...

Handle(TDocStd_Application) app = new TDocStd_Application;
BinXCAFDrivers::DefineFormat(app);

Handle(TDocStd_Document) doc;
app->NewDocument("BinXCAF", doc);

Handle(XCAFDoc_ShapeTool) ShapeTool= XCAFDoc_DocumentTool::ShapeTool( doc->Main() );

// add all the components to the document
for(int i = 0; i<locations.size(); i++){
    ShapeTool->AddShape(shape);
    ShapeTool->AddComponent(doc->Main(), ShapeTool->FindShape(shape), locations[i]);
    ShapeTool->UpdateAssemblies();
}

// Write the assembly to Step
STEPCAFControl_Writer writer;
writer.Transfer(doc);
std::string writePath = "assembly.stp";
writer.Write(writePath.c_str());

I am unsure what arguments to pass to AddComponent(). Since I only want a single assembly, I use doc->Main() as my assembly label. I am also unsure whether the second argument ShapeTool->FindShape(shape) is correct.

Any help is greatly appreciated. Thank you!

Best Regards
Kaiwen

Dmitrii Pasukhin's picture

Hello.

As I understand. You need to create assembly with single simple shape that just moved into different location as a parts of assembly. It is a trivial task. Let me present a sample(i dont check it out, you need to debug).

  Handle(XCAFDoc_ShapeTool) aShTool = this;
  const TopoDS_Shape anOriginShape = TopoDS_Shape();
  std::vector<TopLoc_Location> aLocations(10, TopLoc_Location());
  const TDF_Label aRootL = aShTool->NewShape();
  const TDF_Label anOriginSh = aShTool->AddShape(anOriginShape, false, false);
  for (const auto& aLoc : aLocations)
  {
    aShTool->AddComponent(aRootL, anOriginSh, aLoc);
  }
  aShTool->UpdateAssemblies();

Best regards, Dmitrii.

Kaiwen He's picture

Hello, Thank you for your answer.

I applied your sample and tried to use it analogously for a case with multiple different simple shapes.
In each pass through of the loop I pass a different anOriginSh to AddComponent(aRootL, anOriginSh, aLoc),but my code aborts at that line with terminate called after throwing an instance of 'Standard_NullObject'.

However the debugger shows that neither inputs are null, so assume the problem are not inputs

For context: The goal of my program is to take certain components from an assembly and reassemble the resulting subassembly in a new TDocStd_Document and output it as a STEP file.
So far the program works only for an assembly made of a single simple shape at different locations.

Do I need to adjust my program otherwise to process assemblies with different shapes or are the inputs faulty after all.

Sorry if this is a noobish question.

Best Regards
Kaiwen

Dmitrii Pasukhin's picture

I don't know a problem, but you need to check aLabel.IsNull() before working with thin label.

I think that one of your simple shapes was not Added. Please check that each AddShape return !IsNull() object. ::IsNull()

Best regards, Dmitrii.