Import Step Mesh and density information

Hi Forum,

I actually try to import mesh data out of a step file. The task is to convert the step geometry to an internal format which can be used for some visualization. Beside the tesselation I need a possibility to read the density information of the step file. I the code which is attached to this post, but I always get a density value of zero. Can somebody help me to solve this issue?

Best Regards

Code:

void analyzeLabel(TDF_Label &lbl, int number = 0) {
    
    // Get name
    Handle(TDataStd_Name) nm;
    TCollection_AsciiString ascii_name;
    std::string nameOfShape;
    Handle_TDF_Attribute att;
    if (lbl.FindAttribute(TDataStd_Name::GetID(), att)) {
        nm = Handle(TDataStd_Name)::DownCast(att);            
        ascii_name = nm->Get();
        nameOfShape = ascii_name.ToCString();
    }

    // Get shape
    TopoDS_Shape shape;
    XCAFDoc_ShapeTool::GetShape(lbl, shape);

    // Determine whether an assembly
    if (XCAFDoc_ShapeTool::IsAssembly(lbl)) {
    }
    else if (XCAFDoc_ShapeTool::IsCompound(lbl)) {
    } // If not, see if it has a color
    else {
        Handle(XCAFDoc_MaterialTool) materialTool = XCAFDoc_MaterialTool::Set(lbl);
        if (materialTool->GetDensityForShape(lbl) != 0.0) {
            cout << "materialTool->GetDensityForShape(lbl): " << materialTool->GetDensityForShape(lbl) << endl;
        }
        
    }

    // Write shape type
    switch (shape.ShapeType()) {
    case TopAbs_COMPOUND: {
        break;
    }
    case TopAbs_COMPSOLID: {
        break;
    }
    case TopAbs_SOLID: {

        BRepMesh_IncrementalMesh(shape, 0.1);
        //Write directly to STL
        StlAPI_Writer writer;
        nameOfShape = nameOfShape + ".stl";
        writer.Write(shape, nameOfShape.c_str());

        break;
    }
    default: {
        break;
    }
    }

    // Count subshapes
    TopoDS_Iterator anIt(shape);
    int ns = 0;
    for (; anIt.More(); anIt.Next()) {
        ++ns;
    }

    // Count children
    TDF_ChildIterator childIter = TDF_ChildIterator(lbl);
    int nc = 0;
    for (; childIter.More(); childIter.Next()) {
        ++nc;
    }

    // Get subshapes
    TDF_LabelSequence subLabels;
    XCAFDoc_ShapeTool::GetSubShapes(lbl, subLabels);
    unsigned int nsubs = subLabels.Length();

    // Analyze children
    childIter.Initialize(lbl);
    for (; childIter.More(); childIter.Next()) {
        TDF_Label childLabel = childIter.Value();            
        analyzeLabel(childLabel, number);
    }
    
}

void main(){
    Handle(TDocStd_Document) aDoc;
    Handle(XCAFApp_Application) anApp = XCAFApp_Application::GetApplication();
    anApp->NewDocument("MDTV-XCAF", aDoc);
    STEPCAFControl_Reader aReader;
    aReader.SetNameMode(true);
    aReader.SetMatMode(true); //this should be the important thing for density true?

    IFSelect_ReturnStatus status = aReader.ReadFile(filename.c_str());
    if (status != IFSelect_RetDone)
        return 0;
    if (!aReader.Transfer(aDoc))
    {
        return 0;
    }
    Handle(XCAFDoc_ShapeTool) myAssembly = XCAFDoc_DocumentTool::ShapeTool(aDoc->Main());
    Handle(XCAFDoc_MaterialTool) myMaterials = XCAFDoc_DocumentTool::MaterialTool(aDoc->Main());
    
    TDF_LabelSequence frshapes;
    TDF_LabelSequence materialLabels;
    myAssembly->GetShapes(frshapes);
    myMaterials->GetMaterialLabels(materialLabels);
    
    unsigned int nRoots = frshapes.Length();
    for (unsigned int i = 1; i <= nRoots; ++i){
        TDF_Label lbl = frshapes.Value(i);
        analyzeLabel(lbl);
    }
}

Forum supervisor's picture

Hello David,

Would it be also possible to provide that STEP file for analysis?

Best regards,

Forum supervisor

David Neu's picture

This is the step file where I want to retrieve a tesselation of the different parts and the related density information.

Regards

David

Attachments: 
David Neu's picture

Hi Forum,

I am now able to read all the geometry information. Nevertheless I have now the problem that the shapes aren't located correctly in the scene. I think all the shapes are displayed in their own local coordinate system and not in the global one. So I need some kind of transformation to the global coordinate system.

I would be really thankfull if somebody could have a look at my code and help could me with this problem! Is there any standard example which transfers a step file assembly to a subdivided triangle mesh?

 void analyzeLabel(const TDF_Label &lbl, bgeo::Polyhedron_3D * poly, int number, gp_Trsf trsf) {
        number++;

        // Get shape
        TopoDS_Shape shape;
        XCAFDoc_ShapeTool::GetShape(lbl, shape);

        // Write shape type
        switch (shape.ShapeType()) {
        case TopAbs_COMPOUND: {
            break;
        }
        case TopAbs_COMPSOLID: {
            break;
        }
        case TopAbs_SOLID: {

            Handle(XCAFDoc_MaterialTool) materialTool = XCAFDoc_MaterialTool::Set(lbl);

            Handle(TDataStd_Name) nm;
            TCollection_AsciiString ascii_name;
            std::string nameOfShape;
            Handle_TDF_Attribute att;
            if (lbl.FindAttribute(TDataStd_Name::GetID(), att)) {
                nm = Handle(TDataStd_Name)::DownCast(att);
                ascii_name = nm->Get();
                nameOfShape = ascii_name.ToCString();
            }

            Handle(XCAFDoc_Location) attribute;
            lbl.FindAttribute(XCAFDoc_Location::GetID(), attribute);
            if (attribute.IsNull() == Standard_False)
            {
                TopLoc_Location location = attribute->Get();
                trsf.Multiply(location.Transformation());
            }
            shape.Move(trsf);

            StlAPI_Writer writer;
            writer.ASCIIMode() = false;
            BRepMesh_IncrementalMesh(shape, 0.1);

            break;

        }
        default: {
            break;
        }
        }

        // Count subshapes
        TopoDS_Iterator anIt(shape);
        int ns = 0;
        for (; anIt.More(); anIt.Next()) {
            ++ns;
        }

        // Count children
        TDF_ChildIterator childIter = TDF_ChildIterator(lbl);
        int nc = 0;
        for (; childIter.More(); childIter.Next()) {
            ++nc;
        }

        // Analyze children
        childIter.Initialize(lbl);
        for (; childIter.More(); childIter.Next()) {
            TDF_Label childLabel = childIter.Value();
            analyzeLabel(childLabel, poly, number, trsf);
        }
    }

    bool loadByFileName(const std::string & filename) {

        //Create Document
        Handle(TDocStd_Document) aDoc;
        Handle(XCAFApp_Application) anApp = XCAFApp_Application::GetApplication();
        anApp->NewDocument("MDTV-XCAF", aDoc);

        STEPCAFControl_Reader aReader;
        aReader.SetNameMode(true);
        aReader.SetMatMode(true); //this should be the important thing for density true?
        aReader.SetLayerMode(true);

        IFSelect_ReturnStatus status = aReader.ReadFile(filename.c_str());
        if (status != IFSelect_RetDone)
            return 0;
        if (!aReader.Transfer(aDoc))
        {
            return 0;
        }
        
        _assembly = XCAFDoc_DocumentTool::ShapeTool(aDoc->Main());

        TDF_LabelSequence frshapes;
        TDF_LabelSequence materialLabels;
        gp_Trsf transformation;

        _assembly->GetShapes(frshapes);

        int i = 1;

        unsigned int nRoots = frshapes.Length();
        for (unsigned int i = 1; i <= nRoots; ++i) {
           
            TDF_Label lbl = frshapes.Value(i);

            Handle(XCAFDoc_Location) attribute;
            gp_Trsf transformation;
            lbl.FindAttribute(XCAFDoc_Location::GetID(), attribute);
            if (attribute.IsNull() == Standard_False)
            {
                TopLoc_Location location = attribute->Get();
                transformation = location.Transformation();
            }
            
           analyzeLabel(lbl, &_resultPolyhedron, i, transformation);
        }

        return 1;
    }