Archived issue #0027790
Location not read for root TopoDS_Shape from BRepTools_ShapeSet
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();
}
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)
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.
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?
I wonder why don't you use BRepTools::Read and Write. Do you have any serious reason to use low-level methods?
BTW, of course you are getting wrong result because of you are using the class BRepTools_ShapeSet in a wrong way.
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();
}
#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();
}
Can be closed.