Part: Use TopoShape instead of TopoDS_Shape

This changes Attacher to use more our own TopoShape class which is more
information rich.
This commit is contained in:
Kacper Donat
2024-11-11 17:57:19 +01:00
parent 431f46a4fe
commit a71a67408b
3 changed files with 65 additions and 64 deletions

View File

@@ -388,8 +388,8 @@ void AttachEngine::suggestMapModes(SuggestResult &result) const
result.message = SuggestResult::srLinkBroken;
result.bestFitMode = mmDeactivated;
std::vector<const TopoDS_Shape*> shapes;
std::vector<TopoDS_Shape> shapeStorage;
std::vector<const TopoShape*> shapes;
std::vector<TopoShape> shapeStorage;
std::vector<eRefType> typeStr;
try{
readLinks(getRefObjects(),subnames, shapes, shapeStorage, typeStr);
@@ -578,8 +578,8 @@ eRefType AttachEngine::getShapeType(const App::DocumentObject *obj, const std::s
//const_cast is worth here, to keep obj argument const. We are not going to write anything to obj through this temporary link.
tmpLink.setValue(const_cast<App::DocumentObject*>(obj), subshape.c_str());
std::vector<const TopoDS_Shape*> shapes;
std::vector<TopoDS_Shape> copiedShapeStorage;
std::vector<const TopoShape*> shapes;
std::vector<TopoShape> copiedShapeStorage;
std::vector<eRefType> types;
readLinks(tmpLink.getValues(), tmpLink.getSubValues(), shapes, copiedShapeStorage, types);
@@ -740,13 +740,14 @@ eRefType AttachEngine::getRefTypeByName(const std::string& typeName)
throw AttachEngineException(errmsg.str());
}
GProp_GProps AttachEngine::getInertialPropsOfShape(const std::vector<const TopoDS_Shape*> &shapes)
GProp_GProps AttachEngine::getInertialPropsOfShape(const std::vector<const TopoShape*> &shapes)
{
//explode compounds
TopTools_HSequenceOfShape totalSeq;
for (const TopoDS_Shape* pSh : shapes) {
for (auto tSh : shapes) {
auto pSh = tSh->getShape();
ShapeExtend_Explorer xp;
totalSeq.Append( xp.SeqFromCompound(*pSh, /*recursive=*/true));
totalSeq.Append( xp.SeqFromCompound(pSh, /*recursive=*/true));
}
if (totalSeq.Length() == 0)
throw AttachEngineException("AttachEngine::getInertialPropsOfShape: no geometry provided");
@@ -820,8 +821,8 @@ GProp_GProps AttachEngine::getInertialPropsOfShape(const std::vector<const TopoD
*/
void AttachEngine::readLinks(const std::vector<App::DocumentObject*>& objs,
const std::vector<std::string> &subs,
std::vector<const TopoDS_Shape*> &shapes,
std::vector<TopoDS_Shape> &storage,
std::vector<const TopoShape*> &shapes,
std::vector<TopoShape> &storage,
std::vector<eRefType> &types)
{
storage.reserve(objs.size());
@@ -837,12 +838,11 @@ void AttachEngine::readLinks(const std::vector<App::DocumentObject*>& objs,
"AttachEngine3D: attached to a non App::GeoFeature '" << objs[i]->getNameInDocument() << "'");
}
}
TopoDS_Shape myShape;
Part::TopoShape shape;
try {
// getTopoShape support fully qualified subnames and should return shape with correct
// global placement.
Part::TopoShape shape = Part::Feature::getTopoShape(objs[i], subs[i].c_str(), true);
shape = Part::Feature::getTopoShape(objs[i], subs[i].c_str(), true);
for (;;) {
if (shape.isNull()) {
FC_THROWM(AttachEngineException,
@@ -856,8 +856,6 @@ void AttachEngine::readLinks(const std::vector<App::DocumentObject*>& objs,
// auto extract the single sub-shape from a compound
shape = shape.getSubTopoShape(TopAbs_SHAPE, 1);
}
myShape = shape.getShape();
}
catch (Standard_Failure& e) {
FC_THROWM(AttachEngineException,
@@ -871,18 +869,19 @@ void AttachEngine::readLinks(const std::vector<App::DocumentObject*>& objs,
<< '.' << subs[i] << std::endl
<< e.what());
}
if (myShape.IsNull()) {
if (shape.isNull()) {
FC_THROWM(AttachEngineException,
"AttachEngine3D: null subshape " << objs[i]->getNameInDocument() << '.'
<< subs[i]);
}
storage.emplace_back(myShape);
storage.emplace_back(shape);
shapes[i] = &(storage.back());
// FIXME: unpack single-child compounds here? Compounds are not used so far, so it should be
// considered later, when the need arises.
types[i] = getShapeType(*(shapes[i]));
types[i] = getShapeType(shapes[i]->getShape());
if (subs[i].length() == 0) {
types[i] = eRefType(types[i] | rtFlagHasPlacement);
}
@@ -1140,8 +1139,8 @@ AttachEngine3D::_calculateAttachedPlacement(const std::vector<App::DocumentObjec
throw ExceptionCancel(); // to be handled in positionBySupport, to not do anything if
// disabled
}
std::vector<const TopoDS_Shape*> shapes;
std::vector<TopoDS_Shape> copiedShapeStorage;
std::vector<const TopoShape*> shapes;
std::vector<TopoShape> copiedShapeStorage;
std::vector<eRefType> types;
readLinks(objs, subs, shapes, copiedShapeStorage, types);
@@ -1172,7 +1171,7 @@ AttachEngine3D::_calculateAttachedPlacement(const std::vector<App::DocumentObjec
throw Base::ValueError("AttachEngine3D::calculateAttachedPlacement: no subobjects "
"specified (need one vertex).");
}
const TopoDS_Shape& sh = *shapes[0];
const TopoDS_Shape& sh = shapes[0]->getShape();
if (sh.IsNull()) {
throw Base::ValueError(
"Null shape in AttachEngine3D::calculateAttachedPlacement()!");
@@ -1207,7 +1206,7 @@ AttachEngine3D::_calculateAttachedPlacement(const std::vector<App::DocumentObjec
gp_Pnt(Place.getPosition().x, Place.getPosition().y, Place.getPosition().z);
}
else if (isShapeOfType(types[0], rtConic) > 0) {
const TopoDS_Edge& e = TopoDS::Edge(*shapes[0]);
const TopoDS_Edge& e = TopoDS::Edge(shapes[0]->getShape());
BRepAdaptor_Curve adapt(e);
gp_Ax3 pos;
switch (adapt.GetType()) {
@@ -1259,7 +1258,7 @@ AttachEngine3D::_calculateAttachedPlacement(const std::vector<App::DocumentObjec
TopoDS_Vertex vertex;
try {
vertex = TopoDS::Vertex(*(shapes[1]));
vertex = TopoDS::Vertex(shapes[1]->getShape());
}
catch (...) {
}
@@ -1330,7 +1329,7 @@ AttachEngine3D::_calculateAttachedPlacement(const std::vector<App::DocumentObjec
gp_Pln plane;
bool Reverse = false;
try {
face = TopoDS::Face(*(shapes[0]));
face = TopoDS::Face(shapes[0]->getShape());
}
catch (...) {
}
@@ -1387,14 +1386,14 @@ AttachEngine3D::_calculateAttachedPlacement(const std::vector<App::DocumentObjec
}
bool bThruVertex = false;
if (shapes[0]->ShapeType() == TopAbs_VERTEX) {
if (shapes[0]->shapeType() == TopAbs_VERTEX) {
std::swap(shapes[0], shapes[1]);
bThruVertex = true;
}
TopoDS_Face face;
try {
face = TopoDS::Face(*(shapes[0]));
face = TopoDS::Face(shapes[0]->getShape());
}
catch (...) {
}
@@ -1405,7 +1404,7 @@ AttachEngine3D::_calculateAttachedPlacement(const std::vector<App::DocumentObjec
TopoDS_Vertex vertex;
try {
vertex = TopoDS::Vertex(*(shapes[1]));
vertex = TopoDS::Vertex(shapes[1]->getShape());
}
catch (...) {
}
@@ -1472,14 +1471,14 @@ AttachEngine3D::_calculateAttachedPlacement(const std::vector<App::DocumentObjec
}
bool bThruVertex = false;
if (shapes[0]->ShapeType() == TopAbs_VERTEX && shapes.size() >= 2) {
if (shapes[0]->shapeType() == TopAbs_VERTEX && shapes.size() >= 2) {
std::swap(shapes[0], shapes[1]);
bThruVertex = true;
}
TopoDS_Edge path;
try {
path = TopoDS::Edge(*(shapes[0]));
path = TopoDS::Edge(shapes[0]->getShape());
}
catch (...) {
}
@@ -1506,7 +1505,7 @@ AttachEngine3D::_calculateAttachedPlacement(const std::vector<App::DocumentObjec
if (shapes.size() >= 2) {
TopoDS_Vertex vertex;
try {
vertex = TopoDS::Vertex(*(shapes[1]));
vertex = TopoDS::Vertex(shapes[1]->getShape());
}
catch (...) {
}
@@ -1633,7 +1632,7 @@ AttachEngine3D::_calculateAttachedPlacement(const std::vector<App::DocumentObjec
std::vector<gp_Pnt> points;
for (const auto & shape : shapes) {
const TopoDS_Shape &sh = *shape;
const TopoDS_Shape &sh = shape->getShape();
if (sh.IsNull()) {
throw Base::ValueError(
"Null shape in AttachEngine3D::calculateAttachedPlacement()!");
@@ -1725,7 +1724,7 @@ AttachEngine3D::_calculateAttachedPlacement(const std::vector<App::DocumentObjec
gp_Lin lines[4];
for (int i = 0; i < 4; i++) {
try {
edges[i] = &TopoDS::Edge(*(shapes[i]));
edges[i] = &TopoDS::Edge(shapes[i]->getShape());
}
catch (...) {
}
@@ -1845,28 +1844,28 @@ AttachEngine3D::_calculateAttachedPlacement(const std::vector<App::DocumentObjec
gp_Vec dirs[3];
// read out origin
if (shapes[0]->IsNull()) {
if (shapes[0]->isNull()) {
THROWM(Base::TypeError, "AttachEngine3D::calculateAttachedPlacement: null shape!")
}
if (shapes[0]->ShapeType() != TopAbs_VERTEX) {
if (shapes[0]->shapeType() != TopAbs_VERTEX) {
THROWM(Base::TypeError,
"AttachEngine3D::calculateAttachedPlacement: first reference must be a "
"vertex, it's not")
}
SketchBasePoint = BRep_Tool::Pnt(TopoDS::Vertex(*(shapes[0])));
SketchBasePoint = BRep_Tool::Pnt(TopoDS::Vertex(shapes[0]->getShape()));
// read out axes directions
for (size_t i = 1; i < 3 && i < shapes.size(); ++i) {
if (shapes[i]->IsNull()) {
if (shapes[i]->isNull()) {
THROWM(Base::TypeError,
"AttachEngine3D::calculateAttachedPlacement: null shape!")
}
if (shapes[i]->ShapeType() == TopAbs_VERTEX) {
gp_Pnt p = BRep_Tool::Pnt(TopoDS::Vertex(*(shapes[i])));
if (shapes[i]->shapeType() == TopAbs_VERTEX) {
gp_Pnt p = BRep_Tool::Pnt(TopoDS::Vertex(shapes[i]->getShape()));
dirs[order[i - 1]] = gp_Vec(SketchBasePoint, p);
}
else if (shapes[i]->ShapeType() == TopAbs_EDGE) {
const TopoDS_Edge& e = TopoDS::Edge(*(shapes[i]));
else if (shapes[i]->shapeType() == TopAbs_EDGE) {
const TopoDS_Edge& e = TopoDS::Edge(shapes[i]->getShape());
BRepAdaptor_Curve crv(e);
double u1 = crv.FirstParameter();
double u2 = crv.LastParameter();
@@ -2083,8 +2082,8 @@ AttachEngineLine::_calculateAttachedPlacement(const std::vector<App::DocumentObj
Base::Placement plm;
if (!bReUsed) {
std::vector<const TopoDS_Shape*> shapes;
std::vector<TopoDS_Shape> copiedShapeStorage;
std::vector<const TopoShape*> shapes;
std::vector<TopoShape> copiedShapeStorage;
std::vector<eRefType> types;
readLinks(objs, subs, shapes, copiedShapeStorage, types);
@@ -2157,7 +2156,7 @@ AttachEngineLine::_calculateAttachedPlacement(const std::vector<App::DocumentObj
std::vector<gp_Pnt> points;
for (const auto & shape : shapes) {
const TopoDS_Shape &sh = *shape;
const TopoDS_Shape &sh = shape->getShape();
if (sh.IsNull()) {
throw Base::ValueError(
"Null shape in AttachEngineLine::calculateAttachedPlacement()!");
@@ -2197,13 +2196,13 @@ AttachEngineLine::_calculateAttachedPlacement(const std::vector<App::DocumentObj
} break;
case mm1Asymptote1:
case mm1Asymptote2: {
if (shapes[0]->IsNull()) {
if (shapes[0]->isNull()) {
throw Base::ValueError(
"Null shape in AttachEngineLine::calculateAttachedPlacement()!");
}
TopoDS_Edge e;
try {
e = TopoDS::Edge(*(shapes[0]));
e = TopoDS::Edge(shapes[0]->getShape());
}
catch (...) {
}
@@ -2228,13 +2227,13 @@ AttachEngineLine::_calculateAttachedPlacement(const std::vector<App::DocumentObj
} break;
case mm1Directrix1:
case mm1Directrix2: {
if (shapes[0]->IsNull()) {
if (shapes[0]->isNull()) {
throw Base::ValueError(
"Null shape in AttachEngineLine::calculateAttachedPlacement()!");
}
TopoDS_Edge e;
try {
e = TopoDS::Edge(*(shapes[0]));
e = TopoDS::Edge(shapes[0]->getShape());
}
catch (...) {
}
@@ -2283,13 +2282,13 @@ AttachEngineLine::_calculateAttachedPlacement(const std::vector<App::DocumentObj
"AttachEngineLine::calculateAttachedPlacement: Intersection mode requires "
"two shapes; only one is supplied");
}
if (shapes[0]->IsNull() || shapes[1]->IsNull()) {
if (shapes[0]->isNull() || shapes[1]->isNull()) {
throw Base::ValueError(
"Null shape in AttachEngineLine::calculateAttachedPlacement()!");
}
const TopoDS_Face& face1 = TopoDS::Face(*(shapes[0]));
const TopoDS_Face& face2 = TopoDS::Face(*(shapes[1]));
const TopoDS_Face& face1 = TopoDS::Face(shapes[0]->getShape());
const TopoDS_Face& face2 = TopoDS::Face(shapes[1]->getShape());
Handle(Geom_Surface) hSurf1 = BRep_Tool::Surface(face1);
Handle(Geom_Surface) hSurf2 = BRep_Tool::Surface(face2);
@@ -2324,15 +2323,15 @@ AttachEngineLine::_calculateAttachedPlacement(const std::vector<App::DocumentObj
"AttachEngineLine::calculateAttachedPlacement: Proximity mode requires two "
"shapes; only one is supplied");
}
if (shapes[0]->IsNull()) {
if (shapes[0]->isNull()) {
throw Base::ValueError(
"Null shape in AttachEngineLine::calculateAttachedPlacement()!");
}
if (shapes[1]->IsNull()) {
if (shapes[1]->isNull()) {
throw Base::ValueError(
"Null shape in AttachEngineLine::calculateAttachedPlacement()!");
}
BRepExtrema_DistShapeShape distancer(*(shapes[0]), *(shapes[1]));
BRepExtrema_DistShapeShape distancer(shapes[0]->getShape(), shapes[1]->getShape());
if (!distancer.IsDone()) {
throw Base::ValueError("AttachEngineLine::calculateAttachedPlacement: "
"proximity calculation failed.");
@@ -2450,8 +2449,8 @@ AttachEnginePoint::_calculateAttachedPlacement(const std::vector<App::DocumentOb
Base::Placement plm;
if (!bReUsed) {
std::vector<const TopoDS_Shape*> shapes;
std::vector<TopoDS_Shape> copiedShapeStorage;
std::vector<const TopoShape*> shapes;
std::vector<TopoShape> copiedShapeStorage;
std::vector<eRefType> types;
readLinks(objs, subs, shapes, copiedShapeStorage, types);
@@ -2470,7 +2469,7 @@ AttachEnginePoint::_calculateAttachedPlacement(const std::vector<App::DocumentOb
std::vector<gp_Pnt> points;
assert(!shapes.empty());
const TopoDS_Shape& sh = *shapes[0];
const TopoDS_Shape& sh = shapes[0]->getShape();
if (sh.IsNull()) {
throw Base::ValueError(
"Null shape in AttachEnginePoint::calculateAttachedPlacement()!");
@@ -2492,13 +2491,13 @@ AttachEnginePoint::_calculateAttachedPlacement(const std::vector<App::DocumentOb
} break;
case mm0Focus1:
case mm0Focus2: {
if (shapes[0]->IsNull()) {
if (shapes[0]->isNull()) {
throw Base::ValueError(
"Null shape in AttachEnginePoint::calculateAttachedPlacement()!");
}
TopoDS_Edge e;
try {
e = TopoDS::Edge(*(shapes[0]));
e = TopoDS::Edge(shapes[0]->getShape());
}
catch (...) {
}
@@ -2546,16 +2545,16 @@ AttachEnginePoint::_calculateAttachedPlacement(const std::vector<App::DocumentOb
"AttachEnginePoint::calculateAttachedPlacement: Proximity mode requires "
"two shapes; only one is supplied");
}
if (shapes[0]->IsNull()) {
if (shapes[0]->isNull()) {
throw Base::ValueError(
"Null shape in AttachEnginePoint::calculateAttachedPlacement()!");
}
if (shapes[1]->IsNull()) {
if (shapes[1]->isNull()) {
throw Base::ValueError(
"Null shape in AttachEnginePoint::calculateAttachedPlacement()!");
}
BasePoint = getProximityPoint(mmode, *(shapes[0]), *(shapes[1]));
BasePoint = getProximityPoint(mmode, shapes[0]->getShape(), shapes[1]->getShape());
} break;
case mm0CenterOfMass: {
GProp_GProps gpr = AttachEngine::getInertialPropsOfShape(shapes);

View File

@@ -363,7 +363,7 @@ public://helper functions that may be useful outside of the class
static eRefType getRefTypeByName(const std::string &typeName);
static GProp_GProps getInertialPropsOfShape(const std::vector<const TopoDS_Shape*> &shapes);
static GProp_GProps getInertialPropsOfShape(const std::vector<const Part::TopoShape*> &shapes);
std::vector<App::DocumentObject*> getRefObjects() const;
const std::vector<std::string> &getSubValues() const {return subnames;}
@@ -430,7 +430,9 @@ protected:
}
static void readLinks(const std::vector<App::DocumentObject*> &objs,
const std::vector<std::string> &subs,
std::vector<const TopoDS_Shape*>& shapes, std::vector<TopoDS_Shape> &storage,
std::vector<const Part::TopoShape*>& shapes,
std::vector<Part::TopoShape> &storage,
std::vector<eRefType> &types);
static void throwWrongMode(eMapMode mmode);

View File

@@ -79,8 +79,8 @@ TEST_F(AttacherTest, TestGetShapeType)
TEST_F(AttacherTest, TestGetInertialPropsOfShape)
{
auto& attacher = _boxes[1]->attacher();
std::vector<const TopoDS_Shape*> result;
auto faces = _boxes[1]->Shape.getShape().getSubShapes(TopAbs_FACE);
std::vector<const TopoShape*> result;
auto faces = _boxes[1]->Shape.getShape().getSubTopoShapes(TopAbs_FACE);
result.emplace_back(&faces[0]);
auto shapeType = attacher.getInertialPropsOfShape(result);
EXPECT_EQ(result.size(), 1);