DiscussionsIssue archiveOCCT:Modeling Data

Archived issue #0027790

Location not read for root TopoDS_Shape from BRepTools_ShapeSet

CommunityOCCT:Modeling Dataclosed4 public notes

Search issues

Description

Consider the C++ code below. I would expect the TopoDS_Face to be read back from a BRepTools_ShapeSet including the location. However, the location for a root shape is not automatically applied. Only for child shapes, e.g. when the face is added to a compound, the location is restored.

The script outputs:

Original plane at:
(0 0 1)
Read plane at:
(0 0 0)
Read plane from compound at:
(0 0 1)

Whereas I would expect:

Original plane at:
(0 0 1)
Read plane at:
(0 0 1)
Read plane from compound at:
(0 0 1)

If one knows the index in the BRepTools_ShapeSet::Locations() one can restore the location manually. But only in trivial cases I am able to find the correct location from the set.

#include <gp_Pln.hxx>
#include <Geom_Plane.hxx>
#include <BRep_Tool.hxx>
#include <BRepTools_ShapeSet.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Compound.hxx>
#include <TopoDS_Iterator.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>

int main(int argc, char** argv) {
    TopoDS_Face face = BRepBuilderAPI_MakeFace(gp_Pln()).Face();
    gp_Trsf trsf;
    trsf.SetTranslation(gp::DZ());
    face.Move(trsf);

    std::cerr << "Original plane at:" << std::endl;
    const gp_Pnt& p = Handle_Geom_Plane::DownCast(
        BRep_Tool::Surface(face)
        )->Pln().Location();
    std::cerr << "(" << p.X() << " " << p.Y() << " " << p.Z() << ")" << std::endl;

    {
        std::stringstream stream;
        {
            BRepTools_ShapeSet shapes;
            shapes.Add(face);
            shapes.Write(stream);
        }
        {
            BRepTools_ShapeSet shapes;
            shapes.Read(stream);
            std::cerr << "Read plane at:" << std::endl;
            const gp_Pnt& p = Handle_Geom_Plane::DownCast(
                BRep_Tool::Surface(TopoDS::Face(shapes.Shape(1)))
                )->Pln().Location();
            std::cerr << "(" << p.X() << " " << p.Y() << " " << p.Z() << ")" << std::endl;
        }
    }

    {
        BRep_Builder b;
        TopoDS_Compound compound;
        b.MakeCompound(compound);
        b.Add(compound, face);

        std::stringstream stream;
        {
            BRepTools_ShapeSet shapes;
            shapes.Add(compound);
            shapes.Write(stream);
        }
        {
            BRepTools_ShapeSet shapes;
            shapes.Read(stream);
            TopoDS_Face face = TopoDS::Face(TopoDS_Iterator(shapes.Shape(2)).Value());
            std::cerr << "Read plane from compound at:" << std::endl;
            const gp_Pnt& p = Handle_Geom_Plane::DownCast(
                BRep_Tool::Surface(face)
                )->Pln().Location();
            std::cerr << "(" << p.X() << " " << p.Y() << " " << p.Z() << ")" << std::endl;
        }
    }

    std::cin.get();
}

Steps to reproduce

Run the attached C++ code and observe that the face location is not restored. The executable will output:

Original plane at:
(0 0 1)
Read plane at:
(0 0 0)
Read plane from compound at:
(0 0 1)

Additional information

If this is the intended behaviour, documentation needs to be more clearly updated on this fact and a reference on how to find the original location from the TopTools_LocationSet would be beneficial.

Public activity

4 archived notes

Participants are labeled by their role within this record.

01Commenter 1
BRepTools_ShapeSet is a low-level tool that is used for serialization of a TopoDS_Shape to/from a stream in the user-level API provided by the static methods Read/Write of the class BRepTools.

I wonder why don't you use BRepTools::Read and Write. Do you have any serious reason to use low-level methods?
02Commenter 2
BTW, of course you are getting wrong result because of you are using the class BRepTools_ShapeSet in a wrong way.
03Author
Thanks for clarifying. While I was aware of BRepTools::Read and Write I didn't know that BRepTools_ShapeSet was considered more low level. I can confirm that with your suggestion the code works as expected.

#include <gp_Pln.hxx>
#include <Geom_Plane.hxx>
#include <BRep_Tool.hxx>
#include <BRepTools.hxx>
#include <BRepTools_ShapeSet.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Compound.hxx>
#include <TopoDS_Iterator.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>


int main(int argc, char** argv) {
    TopoDS_Face face = BRepBuilderAPI_MakeFace(gp_Pln()).Face();
    gp_Trsf trsf;
    trsf.SetTranslation(gp::DZ());
    face.Move(trsf);

    std::cerr << "Original plane at:" << std::endl;
    const gp_Pnt& p = Handle_Geom_Plane::DownCast(
        BRep_Tool::Surface(face)
        )->Pln().Location();
    std::cerr << "(" << p.X() << " " << p.Y() << " " << p.Z() << ")" << std::endl;

    {
        std::stringstream stream;
        {
            // BRepTools_ShapeSet shapes;
            // shapes.Add(face);
            // shapes.Write(stream);

            BRepTools::Write(face, stream);
        }
        {
            // BRepTools_ShapeSet shapes;
            // shapes.Read(stream);
            // TopoDS_Face face = TopoDS::Face(shapes.Shape(1));

            BRep_Builder B;
            TopoDS_Face face;
            BRepTools::Read(face, stream, B);

            std::cerr << "Read plane at:" << std::endl;
            const gp_Pnt& p = Handle_Geom_Plane::DownCast(
                BRep_Tool::Surface(face)
                )->Pln().Location();
            std::cerr << "(" << p.X() << " " << p.Y() << " " << p.Z() << ")" << std::endl;
        }
    }

    {
        BRep_Builder b;
        TopoDS_Compound compound;
        b.MakeCompound(compound);
        b.Add(compound, face);

        std::stringstream stream;
        {
            // BRepTools_ShapeSet shapes;
            // shapes.Add(face);
            // shapes.Write(stream);

            BRepTools::Write(compound, stream);
        }
        {
            // BRepTools_ShapeSet shapes;
            // shapes.Read(stream);
            // TopoDS_Face face = TopoDS::Face(TopoDS_Iterator(shapes.Shape(2)).Value());
            
            BRep_Builder B;
            TopoDS_Compound compound;
            BRepTools::Read(compound, stream, B);
            TopoDS_Face face = TopoDS::Face(TopoDS_Iterator(compound).Value());

            std::cerr << "Read plane from compound at:" << std::endl;
            const gp_Pnt& p = Handle_Geom_Plane::DownCast(
                BRep_Tool::Surface(face)
                )->Pln().Location();
            std::cerr << "(" << p.X() << " " << p.Y() << " " << p.Z() << ")" << std::endl;
        }
    }

    std::cin.get();
}
04Author
Can be closed.