Toponaming: Update tests, implement missing subtractive operation tests,

fix helix and revolution
This commit is contained in:
bgbsww
2024-07-28 21:18:56 -04:00
committed by Chris Hennes
parent f03f4ace11
commit a348a1bc82
10 changed files with 283 additions and 41 deletions

View File

@@ -33,10 +33,12 @@
#include <App/DocumentObject.h>
#include <Base/Parameter.h>
#include <Mod/Part/App/modelRefine.h>
#include <Mod/Part/App/TopoShapeOpCode.h>
#include "FeatureBoolean.h"
#include "Body.h"
FC_LOG_LEVEL_INIT("PartDesign", true, true);
using namespace PartDesign;
@@ -106,7 +108,15 @@ App::DocumentObjectExecReturn *Boolean::execute()
if(!baseBody)
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Cannot do boolean on feature which is not in a body"));
TopoDS_Shape result = baseTopShape.getShape();
std::vector<TopoShape> shapes;
shapes.push_back(baseTopShape);
for(auto it=tools.begin(); it<tools.end(); ++it) {
auto shape = getTopoShape(*it);
if (shape.isNull())
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception","Tool shape is null"));
shapes.push_back(shape);
}
TopoShape result(baseTopShape);
Base::Placement bodyPlacement = baseBody->globalPlacement().inverse();
for (auto tool : tools)
@@ -121,12 +131,36 @@ App::DocumentObjectExecReturn *Boolean::execute()
TopoDS_Shape boolOp;
// Must not pass null shapes to the boolean operations
if (result.IsNull())
if (result.isNull())
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Base shape is null"));
if (shape.IsNull())
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Tool shape is null"));
#ifdef FC_USE_TNP_FIX
const char *op = nullptr;
if (type == "Fuse")
op = Part::OpCodes::Fuse;
else if(type == "Cut")
op = Part::OpCodes::Cut;
else if(type == "Common")
op = Part::OpCodes::Common;
// LinkStage3 defines these other types of Boolean operations. Removed for now pending
// decision to bring them in or not.
// else if(type == "Compound")
// op = Part::OpCodes::Compound;
// else if(type == "Section")
// op = Part::OpCodes::Section;
else
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Unsupported boolean operation"));
try {
result.makeElementBoolean(op, shapes);
} catch (Standard_Failure &e) {
FC_ERR("Boolean operation failed: " << e.GetMessageString());
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Boolean operation failed"));
}
#else
if (type == "Fuse") {
BRepAlgoAPI_Fuse mkFuse(result, shape);
if (!mkFuse.IsDone())
@@ -149,11 +183,12 @@ App::DocumentObjectExecReturn *Boolean::execute()
}
result = boolOp; // Use result of this operation for fuse/cut of next body
#endif
}
result = refineShapeIfActive(result);
if (!isSingleSolidRuleSatisfied(result)) {
if (!isSingleSolidRuleSatisfied(result.getShape())) {
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Result has multiple solids: that is not currently supported."));
}
@@ -178,13 +213,18 @@ void Boolean::handleChangedPropertyName(Base::XMLReader &reader, const char * Ty
}
}
TopoDS_Shape Boolean::refineShapeIfActive(const TopoDS_Shape& oldShape) const
// FIXME: This method ( and the Refine property it depends on ) is redundant with the exact same
// thing in FeatureAddSub, but cannot reasonably be moved up an inheritance level to Feature as
// there are inheritors like FeatureBox for which a refine Property does not make sense. A
// solution like moving Refine and refineShapeIfActive to a new FeatureRefine class that sits
// between Feature and FeatureBoolean / FeatureAddSub is a possibility, or maybe [ew!] hiding the
// property in Feature and only enabling it in the places it is relevant.
TopoShape Boolean::refineShapeIfActive(const TopoShape& oldShape) const
{
if (this->Refine.getValue()) {
try {
Part::BRepBuilderAPI_RefineModel mkRefine(oldShape);
TopoDS_Shape resShape = mkRefine.Shape();
return resShape;
return oldShape.makeElementRefine();
}
catch (Standard_Failure&) {
return oldShape;