PartDesign: Refactor single-solid rule enforcement

This refactors a single solid rule checking code from using the solid
count directly to using well abstracted `isSingleSolidRuleSatisfied`
method. This makes code easier to read and is the basis for next step
which is allowing users to disable this checks.
This commit is contained in:
Kacper Donat
2024-05-11 13:35:18 +02:00
committed by Adrián Insaurralde Avalos
parent f937d4579a
commit 935bdf9a0f
15 changed files with 43 additions and 44 deletions

View File

@@ -151,6 +151,12 @@ int Feature::countSolids(const TopoDS_Shape& shape, TopAbs_ShapeEnum type)
return result; return result;
} }
bool Feature::isSingleSolidRuleSatisfied(const TopoDS_Shape& shape, TopAbs_ShapeEnum type)
{
int solidCount = countSolids(shape, type);
return solidCount <= 1;
}
const gp_Pnt Feature::getPointFromFace(const TopoDS_Face& f) const gp_Pnt Feature::getPointFromFace(const TopoDS_Face& f)

View File

@@ -100,6 +100,11 @@ protected:
TopoShape getSolid(const TopoShape&); TopoShape getSolid(const TopoShape&);
static int countSolids(const TopoDS_Shape&, TopAbs_ShapeEnum type = TopAbs_SOLID); static int countSolids(const TopoDS_Shape&, TopAbs_ShapeEnum type = TopAbs_SOLID);
/**
* Checks if the single-solid body rule is fulfilled.
*/
static bool isSingleSolidRuleSatisfied(const TopoDS_Shape&, TopAbs_ShapeEnum type = TopAbs_SOLID);
/// Grab any point from the given face /// Grab any point from the given face
static const gp_Pnt getPointFromFace(const TopoDS_Face& f); static const gp_Pnt getPointFromFace(const TopoDS_Face& f);
/// Make a shape from a base plane (convenience method) /// Make a shape from a base plane (convenience method)

View File

@@ -153,8 +153,7 @@ App::DocumentObjectExecReturn *Boolean::execute()
result = refineShapeIfActive(result); result = refineShapeIfActive(result);
int solidCount = countSolids(result); if (!isSingleSolidRuleSatisfied(result)) {
if (solidCount > 1) {
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Result has multiple solids: that is not currently supported.")); return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Result has multiple solids: that is not currently supported."));
} }

View File

@@ -270,10 +270,11 @@ App::DocumentObjectExecReturn *Chamfer::execute()
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Resulting shape is invalid")); return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Resulting shape is invalid"));
} }
} }
int solidCount = countSolids(shape);
if (solidCount > 1) { if (!isSingleSolidRuleSatisfied(shape)) {
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Result has multiple solids: that is not currently supported.")); return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Result has multiple solids: that is not currently supported."));
} }
shape = refineShapeIfActive(shape); shape = refineShapeIfActive(shape);
this->Shape.setValue(getSolid(shape)); this->Shape.setValue(getSolid(shape));
return App::DocumentObject::StdReturn; return App::DocumentObject::StdReturn;

View File

@@ -318,8 +318,7 @@ App::DocumentObjectExecReturn *Draft::execute()
if (shape.IsNull()) if (shape.IsNull())
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Resulting shape is null")); return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Resulting shape is null"));
int solidCount = countSolids(shape); if (!isSingleSolidRuleSatisfied(shape)) {
if (solidCount > 1) {
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Result has multiple solids: that is not currently supported.")); return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Result has multiple solids: that is not currently supported."));
} }

View File

@@ -193,8 +193,7 @@ App::DocumentObjectExecReturn *Fillet::execute()
} }
} }
int solidCount = countSolids(shape); if (!isSingleSolidRuleSatisfied(shape)) {
if (solidCount > 1) {
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Result has multiple solids: that is not currently supported.")); return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Result has multiple solids: that is not currently supported."));
} }

View File

@@ -188,8 +188,7 @@ App::DocumentObjectExecReturn *Groove::execute()
TopoDS_Shape subshape = refineShapeIfActive(mkCut.Shape()); TopoDS_Shape subshape = refineShapeIfActive(mkCut.Shape());
this->AddSubShape.setValue(subshape); this->AddSubShape.setValue(subshape);
int resultCount = countSolids(result); if (!isSingleSolidRuleSatisfied(result)) {
if (resultCount > 1) {
return new App::DocumentObjectExecReturn("Groove: Result has multiple solids. This is not supported at this time."); return new App::DocumentObjectExecReturn("Groove: Result has multiple solids. This is not supported at this time.");
} }
@@ -221,8 +220,7 @@ App::DocumentObjectExecReturn *Groove::execute()
solRes = refineShapeIfActive(solRes); solRes = refineShapeIfActive(solRes);
this->Shape.setValue(getSolid(solRes)); this->Shape.setValue(getSolid(solRes));
int solidCount = countSolids(solRes); if (!isSingleSolidRuleSatisfied(solRes)) {
if (solidCount > 1) {
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Result has multiple solids: that is not currently supported.")); return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Result has multiple solids: that is not currently supported."));
} }
} }

View File

@@ -251,10 +251,10 @@ App::DocumentObjectExecReturn* Helix::execute()
if (getAddSubType() == FeatureAddSub::Subtractive) if (getAddSubType() == FeatureAddSub::Subtractive)
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Error: There is nothing to subtract")); return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Error: There is nothing to subtract"));
int solidCount = countSolids(result); if (!isSingleSolidRuleSatisfied(result)) {
if (solidCount > 1) {
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Error: Result has multiple solids")); return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Error: Result has multiple solids"));
} }
Shape.setValue(getSolid(result)); Shape.setValue(getSolid(result));
return App::DocumentObject::StdReturn; return App::DocumentObject::StdReturn;
} }
@@ -271,8 +271,8 @@ App::DocumentObjectExecReturn* Helix::execute()
if (boolOp.IsNull()) if (boolOp.IsNull())
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Error: Result is not a solid")); return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Error: Result is not a solid"));
int solidCount = countSolids(boolOp);
if (solidCount > 1) { if (!isSingleSolidRuleSatisfied(boolOp)) {
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Error: Result has multiple solids")); return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Error: Result has multiple solids"));
} }
@@ -301,8 +301,7 @@ App::DocumentObjectExecReturn* Helix::execute()
if (boolOp.IsNull()) if (boolOp.IsNull())
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Error: Result is not a solid")); return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Error: Result is not a solid"));
int solidCount = countSolids(boolOp); if (!isSingleSolidRuleSatisfied(boolOp)) {
if (solidCount > 1) {
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Error: Result has multiple solids")); return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Error: Result has multiple solids"));
} }

View File

@@ -1900,10 +1900,7 @@ App::DocumentObjectExecReturn* Hole::execute()
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Resulting shape is not a solid")); return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Resulting shape is not a solid"));
base = refineShapeIfActive(base); base = refineShapeIfActive(base);
if (!isSingleSolidRuleSatisfied(base.getShape())) {
int solidCount = countSolids(base.getShape());
if (solidCount > 1) {
return new App::DocumentObjectExecReturn( return new App::DocumentObjectExecReturn(
QT_TRANSLATE_NOOP("Exception", "Result has multiple solids: that is not currently supported.")); QT_TRANSLATE_NOOP("Exception", "Result has multiple solids: that is not currently supported."));
} }

View File

@@ -288,13 +288,15 @@ App::DocumentObjectExecReturn *Loft::execute()
BRepAlgoAPI_Fuse mkFuse(base, result); BRepAlgoAPI_Fuse mkFuse(base, result);
if (!mkFuse.IsDone()) if (!mkFuse.IsDone())
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Loft: Adding the loft failed")); return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Loft: Adding the loft failed"));
// we have to get the solids (fuse sometimes creates compounds) // we have to get the solids (fuse sometimes creates compounds)
TopoDS_Shape boolOp = this->getSolid(mkFuse.Shape()); TopoDS_Shape boolOp = this->getSolid(mkFuse.Shape());
// lets check if the result is a solid // lets check if the result is a solid
if (boolOp.IsNull()) if (boolOp.IsNull())
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Resulting shape is not a solid")); return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Resulting shape is not a solid"));
int solidCount = countSolids(boolOp);
if (solidCount > 1) { if (!isSingleSolidRuleSatisfied(boolOp)) {
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Result has multiple solids: that is not currently supported.")); return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Result has multiple solids: that is not currently supported."));
} }
@@ -306,13 +308,15 @@ App::DocumentObjectExecReturn *Loft::execute()
BRepAlgoAPI_Cut mkCut(base, result); BRepAlgoAPI_Cut mkCut(base, result);
if (!mkCut.IsDone()) if (!mkCut.IsDone())
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Loft: Subtracting the loft failed")); return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Loft: Subtracting the loft failed"));
// we have to get the solids (fuse sometimes creates compounds) // we have to get the solids (fuse sometimes creates compounds)
TopoDS_Shape boolOp = this->getSolid(mkCut.Shape()); TopoDS_Shape boolOp = this->getSolid(mkCut.Shape());
// lets check if the result is a solid // lets check if the result is a solid
if (boolOp.IsNull()) if (boolOp.IsNull())
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Resulting shape is not a solid")); return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Resulting shape is not a solid"));
int solidCount = countSolids(boolOp);
if (solidCount > 1) { if (!isSingleSolidRuleSatisfied(boolOp)) {
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Result has multiple solids: that is not currently supported.")); return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Result has multiple solids: that is not currently supported."));
} }

View File

@@ -235,8 +235,7 @@ App::DocumentObjectExecReturn *Pad::execute()
if (solRes.IsNull()) if (solRes.IsNull())
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Resulting shape is not a solid")); return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Resulting shape is not a solid"));
int solidCount = countSolids(result); if (!isSingleSolidRuleSatisfied(result)) {
if (solidCount > 1) {
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Result has multiple solids: that is not currently supported.")); return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Result has multiple solids: that is not currently supported."));
} }
@@ -244,8 +243,7 @@ App::DocumentObjectExecReturn *Pad::execute()
this->Shape.setValue(getSolid(solRes)); this->Shape.setValue(getSolid(solRes));
} }
else { else {
int solidCount = countSolids(prism); if (!isSingleSolidRuleSatisfied(prism)) {
if (solidCount > 1) {
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Result has multiple solids: that is not currently supported.")); return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Result has multiple solids: that is not currently supported."));
} }

View File

@@ -398,8 +398,7 @@ App::DocumentObjectExecReturn *Pipe::execute()
if (boolOp.IsNull()) if (boolOp.IsNull())
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Resulting shape is not a solid")); return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Resulting shape is not a solid"));
int solidCount = countSolids(boolOp); if (!isSingleSolidRuleSatisfied(boolOp)) {
if (solidCount > 1) {
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception",
"Result has multiple solids: that is not currently supported.")); "Result has multiple solids: that is not currently supported."));
} }
@@ -418,8 +417,7 @@ App::DocumentObjectExecReturn *Pipe::execute()
if (boolOp.IsNull()) if (boolOp.IsNull())
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Resulting shape is not a solid")); return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Resulting shape is not a solid"));
int solidCount = countSolids(boolOp); if (!isSingleSolidRuleSatisfied(boolOp)) {
if (solidCount > 1) {
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception",
"Result has multiple solids: that is not currently supported.")); "Result has multiple solids: that is not currently supported."));
} }

View File

@@ -194,8 +194,7 @@ App::DocumentObjectExecReturn *Pocket::execute()
TopoDS_Shape result = refineShapeIfActive(mkCut.Shape()); TopoDS_Shape result = refineShapeIfActive(mkCut.Shape());
this->AddSubShape.setValue(result); this->AddSubShape.setValue(result);
int prismCount = countSolids(prism); if (!isSingleSolidRuleSatisfied(result)) {
if (prismCount > 1) {
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Result has multiple solids: that is not currently supported.")); return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Result has multiple solids: that is not currently supported."));
} }
@@ -229,8 +228,7 @@ App::DocumentObjectExecReturn *Pocket::execute()
if (solRes.IsNull()) if (solRes.IsNull())
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Resulting shape is not a solid")); return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Resulting shape is not a solid"));
int solidCount = countSolids(result); if (!isSingleSolidRuleSatisfied(result)) {
if (solidCount > 1) {
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Result has multiple solids: that is not currently supported.")); return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Result has multiple solids: that is not currently supported."));
} }

View File

@@ -145,12 +145,12 @@ App::DocumentObjectExecReturn* FeaturePrimitive::execute(const TopoDS_Shape& pri
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Adding the primitive failed")); return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Adding the primitive failed"));
// we have to get the solids (fuse sometimes creates compounds) // we have to get the solids (fuse sometimes creates compounds)
boolOp = this->getSolid(mkFuse.Shape()); boolOp = this->getSolid(mkFuse.Shape());
// lets check if the result is a solid // lets check if the result is a solid
if (boolOp.IsNull()) if (boolOp.IsNull())
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Resulting shape is not a solid")); return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Resulting shape is not a solid"));
int solidCount = countSolids(boolOp); if (!isSingleSolidRuleSatisfied(boolOp)) {
if (solidCount > 1) {
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Result has multiple solids: that is not currently supported.")); return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Result has multiple solids: that is not currently supported."));
} }
} }
@@ -165,8 +165,7 @@ App::DocumentObjectExecReturn* FeaturePrimitive::execute(const TopoDS_Shape& pri
if (boolOp.IsNull()) if (boolOp.IsNull())
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Resulting shape is not a solid")); return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Resulting shape is not a solid"));
int solidCount = countSolids(boolOp); if (!isSingleSolidRuleSatisfied(boolOp)) {
if (solidCount > 1) {
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Result has multiple solids: that is not currently supported.")); return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Result has multiple solids: that is not currently supported."));
} }
} }

View File

@@ -327,8 +327,7 @@ App::DocumentObjectExecReturn *Transformed::execute()
support = refineShapeIfActive(support); support = refineShapeIfActive(support);
int solidCount = countSolids(support); if (!isSingleSolidRuleSatisfied(support)) {
if (solidCount > 1) {
Base::Console().Warning("Transformed: Result has multiple solids. Only keeping the first.\n"); Base::Console().Warning("Transformed: Result has multiple solids. Only keeping the first.\n");
} }