How to parse STP files to obtain a complete hierarchical structure?

I can now obtain Components through STEPCAFControl-Reader, but I cannot obtain SimpleSample included in TopAbs-COMPOUND.

The hierarchical structure I want is shown in 1. png.

My current code is as follows:

void ProcessMesh(const Handle(XCAFDoc_ShapeTool)& ShapeTool, const Handle(XCAFDoc_ColorTool)& ColorTool,
	const TDF_Label& childLabel, const TDF_Label& shapeLabel, TopLoc_Location Location)
{
	Handle(TDataStd_Name) aName;
	if (childLabel.FindAttribute(TDataStd_Name::GetID(), aName))
	{
		Standard_Character* myCharArray = new Standard_Character[aName->Get().LengthOfCString() + 1];
		aName->Get().ToUTF8CString(myCharArray);
		delete[] myCharArray;
	}

	auto trans = Location.Transformation();
	gp_XYZ pos = trans.TranslationPart();
	gp_Quaternion q = trans.GetRotation();
	Standard_Real x = trans.Value(1, 1);
	Standard_Real y = trans.Value(2, 2);
	Standard_Real z = trans.Value(3, 3);

	bool isCompound = false;
	if (ShapeTool->IsShape(shapeLabel))
	{
		TopoDS_Shape aShape;
		//if a shape can be made from the current label, look for the color of that label:
		if (ShapeTool->GetShape(shapeLabel, aShape)) {
			//TopExp_Explorer ex;
			//for (ex.Init(aShape, TopAbs_SOLID); ex.More(); ex.Next())
			{
				auto shape = aShape.ShapeType();

				// get the shape
				if (aShape.ShapeType() == TopAbs_ShapeEnum::TopAbs_SOLID)
				{
					//BRepMesh_IncrementalMesh mesh(aShape, 1);
					TopTools_IndexedMapOfShape faceMap;
					TopExp::MapShapes(aShape, TopAbs_FACE, faceMap);
					TopLoc_Location faceLoc;
					int faceNum = faceMap.Extent();
					int verticesnumber = 0;

					for (int i = 1; i <= faceNum; i++)
					{
						const TopoDS_Face& aFace = TopoDS::Face(faceMap(i));
						bool bGetColor = false;
						Quantity_Color aColor;
						if (ColorTool->GetColor(aFace, XCAFDoc_ColorType::XCAFDoc_ColorSurf, aColor))
						{
							bGetColor = true;
						}

						Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation(aFace, faceLoc);
						if (!aTriangulation.IsNull())
						{
							int number = aTriangulation->NbNodes();
							const gp_Trsf& aTrsf = faceLoc.Transformation();
							// Determinant of transform matrix less then 0 means that mirror transform applied.
							Standard_Boolean isMirrored = aTrsf.VectorialPart().Determinant() < 0;
							// Extracts vertices & normals from nodes
							StdPrs_ToolTriangulatedShape::ComputeNormals(aFace, aTriangulation);

							for (int k = 1; k <= number; k++) {
								//pos
								gp_Pnt aPoint = aTriangulation->Node(k);
								//normal
								gp_Dir aNorm = aTriangulation->Normal(k);
								if ((aFace.Orientation() == TopAbs_REVERSED) ^ isMirrored)
								{
									aNorm.Reverse();
								}
								if (!faceLoc.IsIdentity())
								{
									aPoint.Transform(aTrsf);
									aNorm.Transform(aTrsf);
								}

								verticesnumber++;
							}

							for (Standard_Integer j = 1; j <= aTriangulation->NbTriangles(); j++)
							{

								gp_Pnt  Vertex;
								const Poly_Triangle trian = aTriangulation->Triangle(j); // get Triangle
								Standard_Integer index1, index2, index3;
								if ((aFace.Orientation() == TopAbs_REVERSED))
								{
									trian.Get(index1, index3, index2);
								}
								else
								{
									trian.Get(index1, index2, index3);
								}
								//index
								int finallindex1 = verticesnumber + index1 - number - 1;
								int finallindex2 = verticesnumber + index2 - number - 1;
								int finallindex3 = verticesnumber + index3 - number - 1;
							}

						}
					}

				}
				//else if (aShape.ShapeType() == TopAbs_ShapeEnum::TopAbs_COMPOUND ||
				//	aShape.ShapeType() == TopAbs_ShapeEnum::TopAbs_COMPSOLID)
				//{
				//	isCompound = true;
				//}
			}
		}
	}

	TDF_LabelSequence components;
	if (ShapeTool->GetComponents(shapeLabel, components))
	{
		for (Standard_Integer compIndex = 1; compIndex <= components.Length(); ++compIndex)
		{
			TDF_Label ChildLabel = components.Value(compIndex);
			if (ShapeTool->IsReference(ChildLabel))
			{
				TDF_Label ShapeLabel;
				if (ShapeTool->GetReferredShape(ChildLabel, ShapeLabel))
				{
					TopLoc_Location LocalLocation = ShapeTool->GetLocation(ChildLabel);
					ProcessMesh(ShapeTool, ColorTool, ChildLabel, ShapeLabel, LocalLocation);
				}
			}
		}
	}
	//if (isCompound && ShapeTool->GetSubShapes(shapeLabel, components))
	//{
	//	for (Standard_Integer compIndex = 1; compIndex <= components.Length(); ++compIndex)
	//	{
	//		TDF_Label ChildLabel = components.Value(compIndex);
	//		if (ShapeTool->IsSimpleShape(ChildLabel))
	//		{
	//			TopLoc_Location LocalLocation = ShapeTool->GetLocation(ChildLabel);
	//			ProcessMesh(ShapeTool, ColorTool, ChildLabel, ChildLabel, node, LocalLocation, to_string(compIndex));
	//		}
	//	}
	//}
}

void readFile(std::string filePath)
{
	STEPCAFControl_Reader* m_StpImporter = new STEPCAFControl_Reader();
	m_StpImporter->SetColorMode(true);
	m_StpImporter->SetNameMode(true);
	if (m_StpImporter->ReadFile(Standard_CString(filePath.c_str())) != IFSelect_RetDone)
	{
		return;
	}

	Handle(XCAFApp_Application) anApp = XCAFApp_Application::GetApplication();
	Handle(TDocStd_Document) doc;
	anApp->NewDocument("MDTV-XCAF", doc);
	bool yes = m_StpImporter->Transfer(doc);
	if (yes)
	{
		TDF_Label mainLabel = doc->Main();
		Handle(XCAFDoc_ShapeTool) ShapeTool = XCAFDoc_DocumentTool::ShapeTool(mainLabel);
		Handle(XCAFDoc_ColorTool) ColorTool = XCAFDoc_DocumentTool::ColorTool(mainLabel);

		{
			TDF_LabelSequence tdfLabels;
			ShapeTool->GetFreeShapes(tdfLabels);   //获取装配体和组件对应名称
			int Roots = tdfLabels.Length();
			for (int index = 1; index <= Roots; index++)
			{
				TDF_Label Label = tdfLabels.Value(index);
				if (ShapeTool->IsShape(Label))
				{
					TopoDS_Shape aShape;
					//if a shape can be made from the current label, look for the color of that label:
					if (ShapeTool->GetShape(Label, aShape)) {
						BRepMesh_IncrementalMesh mesh(aShape, 1);
					}
				}
				ProcessMesh(ShapeTool, ColorTool, Label, Label, TopLoc_Location());
			}
		}
	}
}
Attachments: 
Dmitrii Pasukhin's picture

Hello, the code looks like as not process assembly structure and references. Please have a look into https://dev.opencascade.org/doc/overview/html/occt_user_guides__xde.html

And https://www.youtube.com/watch?v=NMs7GtvsJ6g

Best regards, Dmitrii.

龙 柳州's picture

Dmitrii, Thank you very much. I will learn from it.

Dmitrii Pasukhin's picture

If you want to check the source code as sample. I recommend to check the CAD Writers.

For Example: STEPCAFControl_Writer::transfer

Best regards, Dmitrii