Wed, 06/21/2017 - 12:32
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);
    }
}
        
Wed, 06/21/2017 - 13:43
Hello David,
Would it be also possible to provide that STEP file for analysis?
Best regards,
Forum supervisor
Wed, 06/21/2017 - 18:14
This is the step file where I want to retrieve a tesselation of the different parts and the related density information.
Regards
David
Thu, 07/06/2017 - 15:36
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;
}