exploring a compound

Hello forum,

I known that this topic was already discussed in the past, but I have not been able to find a clear answer to my question,

apart from "read the documentation"; which honestly is very clear.

I generated with an external tool a step file containing a cube (TopoDS_Solid), a shell (TopoDS_Shell), a face (TopoDS_Face),

a wire (TopoDS_Wire), and finally an edge (TopoDS_Edge).

The shapes are separated in space, not connected in any way: I attached a skectch and the .step file.

When reading the file using the STEPControl_ reader::oneShape I get one shape, which is of TopoDS_Compound type (type 0).

Then I would like to explore it, and retrieve the list of "main" shapes, that is the original solid, shell, face, wire, edge.

It seems that the ShapeExtend_Explorer is the right tool, since documentation claims:

"This class is intended to explore shapes and convert different representations (list, sequence, compound)

of complex shapes. It provides tools for:obtaining type of the shapes in context of TopoDS_Compoung [...]"​

So I tried the following simple code,

#define FILENAME "D:\\000000000_mixed.stp"

 
//! OCC
#include <STEPControl_Reader.hxx>
#include <TopoDS_Shape.hxx>
#include <IFSelect_ReturnStatus.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Shape.hxx>
#include <TopTools_HSequenceOfShape.hxx>
#include <ShapeExtend_Explorer.hxx>

 
//! C++
#include <iostream>
using namespace std;

 
//! Qt
#include <QString>

 
int main()
{
    //! ------------------------
    //! load the file from disk
    //! ------------------------
    STEPControl_Reader aReader;
    IFSelect_ReturnStatus stat = aReader.ReadFile(FILENAME);

 
    if(stat!=IFSelect_RetDone)
    {
        cout<<"____error in loading the file____"<<endl;
        return 1;
    }

 
    aReader.TransferRoots();
    TopoDS_Shape aShape = aReader.OneShape();
    if(!aShape.IsNull())
    {
        cout<<"____shape type: "<<aShape.ShapeType()<<"____"<<endl;

 
        Handle(TopTools_HSequenceOfShape) seqShape = new TopTools_HSequenceOfShape;
        Handle(TopTools_HSequenceOfShape) compounds, compsolids, solids, shells, faces, wires, edges, vertices;

 
        ShapeExtend_Explorer anExp;

 
        anExp.SeqFromCompound(aShape,false);
        anExp.DispatchList(seqShape,vertices,edges,wires,faces,shells,solids,compsolids,compounds);
        cout<<"____Nb compounds: "<<compounds->Length()<<"____"<<endl;
        cout<<"____Nb compsolids: "<<compsolids->Length()<<"____"<<endl;
        cout<<"____Nb solids: "<<solids->Length()<<"____"<<endl;
        cout<<"____Nb shells: "<<shells->Length()<<"____"<<endl;
        cout<<"____Nb faces: "<<faces->Length()<<"____"<<endl;
        cout<<"____Nb wires: "<<wires->Length()<<"____"<<endl;
        cout<<"____Nb edges: "<<edges->Length()<<"____"<<endl;
        cout<<"____Nb vertices: "<<vertices->Length()<<"____"<<endl;
    }
}

The output is

____shape type: 0____
____Nb compounds: 0____
____Nb compsolids: 0____
____Nb solids: 0____
____Nb shells: 0____
____Nb faces: 0____
____Nb wires: 0____
____Nb edges: 0____
____Nb vertices: 0____

which is not correct.

Were did I wrong?

Any help is strongly appreciated

Giovanni

Any help 

 

 

Giovanni Bettega's picture

Hello

I would like to share my solution.

MainWindow::MainWindow(QMainWindow *parent):QMainWindow(parent)
{
    //! ---------
    //! a viewer
    //! ---------
    occViewPort aViewer = new occViewPort(this);
    if(aViewer->getContext().IsNull()) aViewer->init();
    this->setCentralWidget(aViewer);

    //! ------------------------
    //! load the file from disk
    //! ------------------------
    STEPControl_Reader aReader;
    IFSelect_ReturnStatus stat = aReader.ReadFile(FILENAME);

    if(stat!=IFSelect_RetDone) exit(1);

    aReader.TransferRoots();
    TopoDS_Shape aShape = aReader.OneShape();

    //! ----------------
    //! list of shapes
    //! ----------------
    QList<TopoDS_Shape> csolids;
    QList<TopoDS_Shape> solids;
    QList<TopoDS_Shape> wires;
    QList<TopoDS_Shape> edges;
    QList<TopoDS_Shape> shells;
    QList<TopoDS_Shape> faces;

    for(TopoDS_Iterator anIt(aShape); anIt.More(); anIt.Next())
    {
        const TopoDS_Shape &curShape = anIt.Value();
        TopAbs_ShapeEnum type = curShape.ShapeType();

        if(type==TopAbs_COMPOUND)
        {
            cout<<"____COMPOUND____"<<endl;

            TopoDS_Builder aShellBuilder;
            TopoDS_Shell aShell;

            TopoDS_Builder aWireBuilder;
            TopoDS_Wire aWire;

            aShellBuilder.MakeShell(aShell);
            aWireBuilder.MakeWire(aWire);

            int faceCount = 0;
            int edgeCount = 0;

            for(TopoDS_Iterator anExp(curShape); anExp.More(); anExp.Next())
            {
                const TopoDS_Shape &curShape1 = anExp.Value();
                TopAbs_ShapeEnum type1 = curShape1.ShapeType();

                if(type1==TopAbs_SHELL)
                {
                    for(TopExp_Explorer anExp(curShape1,TopAbs_FACE);anExp.More();anExp.Next())
                    {
                        const TopoDS_Shape &curShape2 = anExp.Current();
                        aShellBuilder.Add(aShell,curShape2);
                        faceCount++;
                    }
                }

                if(type1==TopAbs_EDGE)
                {
                    aWireBuilder.Add(aWire,curShape1);
                    edgeCount++;
                }
            }

            if(faceCount>1) shells<<aShell;
            if(edgeCount>1) wires<<aWire;
            else if(edgeCount==1)
            {
                //! --------------------------------------
                //! remove "aWire" from the list of wires
                //! --------------------------------------
                wires.removeOne(aWire);
                for(TopExp_Explorer anExp(aWire,TopAbs_EDGE); anExp.More(); anExp.Next())
                {
                    const TopoDS_Shape &curEdge = anExp.Current();
                    edges<<curEdge;
                }
            }
        }

        //! -----------------
        //! composite solids
        //! -----------------
        if(type==TopAbs_COMPSOLID)
        {
            cout<<"____COMPSOLID____"<<endl;
            csolids<<curShape;
        }

        //! -------
        //! solids
        //! -------
        if(type==TopAbs_SOLID)
        {
            solids<<curShape;
        }

        //! ------
        //! faces
        //! ------
        if(type==TopAbs_SHELL)
        {
            for(TopExp_Explorer anExp(curShape,TopAbs_FACE);anExp.More();anExp.Next())
            {
                const TopoDS_Shape &curShape1 = anExp.Current();
                faces<<curShape1;
            }
        }
    }

    cout<<"____Nb solids: "<<solids.length()<<"____"<<endl;
    cout<<"____Nb shells: "<<shells.length()<<"____"<<endl;
    cout<<"____Nb faces: "<<faces.length()<<"____"<<endl;
    cout<<"____Nb wires: "<<wires.length()<<"____"<<endl;
    cout<<"____Nb edges: "<<edges.length()<<"____"<<endl;

    //! --------
    //! display
    //! --------
    QList<TopoDS_Shape> listOfShapes;
    listOfShapes<<csolids<<solids<<shells<<faces<<wires<<edges;
    for(int i=0; i<listOfShapes.length(); i++)
    {
        const Handle(AIS_Shape) &anAIS_Shape = new AIS_Shape(listOfShapes.at(i));
        aViewer->getContext()->Display(anAIS_Shape,AIS_Shaded,-1,true,false);
    }
    aViewer->FitAll();
    aViewer->setAction3D_Rotation();
}

It gives

____Nb solids: 1____
____Nb shells: 2____
____Nb faces: 1____
____Nb wires: 1____
____Nb edges: 1____

for file 000000000_mixed_1

and

____Nb solids: 1____
____Nb shells: 1____
____Nb faces: 3____
____Nb wires: 1____
____Nb edges: 1____

for 000000000_mixed_2.stp

Giovanni