Merge pull request #25580 from kadet1090/fix-boolean-position

PartDesign: Fix boolean positioning
This commit is contained in:
Chris Hennes
2025-11-26 14:22:59 -06:00
committed by GitHub
5 changed files with 30 additions and 52 deletions

View File

@@ -3267,6 +3267,30 @@ void TopoShape::transformGeometry(const Base::Matrix4D& rclMat)
}
}
void TopoShape::bakeInTransform()
{
if (getShape().IsNull()) {
return;
}
if (shapeType() != TopAbs_COMPOUND) {
transformGeometry(getTransform());
setTransform(Base::Matrix4D {});
return;
}
TopoShape result;
std::vector<TopoShape> shapes;
for (auto& subshape : getSubTopoShapes()) {
subshape.bakeInTransform();
shapes.push_back(subshape);
}
result.makeCompound(shapes);
*this = result;
}
TopoDS_Shape TopoShape::transformGShape(const Base::Matrix4D& rclTrf, bool copy) const
{
if (this->_Shape.IsNull()) {

View File

@@ -668,6 +668,7 @@ public:
/** @name Manipulation*/
//@{
void transformGeometry(const Base::Matrix4D& rclMat) override;
void bakeInTransform();
TopoDS_Shape transformGShape(const Base::Matrix4D&, bool copy = false) const;
bool transformShape(const Base::Matrix4D&, bool copy, bool checkScale = false);
TopoDS_Shape mirror(const gp_Ax2&) const;

View File

@@ -40,10 +40,9 @@ using namespace PartDesign;
namespace PartDesign
{
extern bool getPDRefineModelParameter();
PROPERTY_SOURCE_WITH_EXTENSIONS(PartDesign::Boolean, PartDesign::Feature)
PROPERTY_SOURCE_WITH_EXTENSIONS(PartDesign::Boolean, PartDesign::FeatureRefine)
const char* Boolean::TypeEnums[] = {"Fuse", "Cut", "Common", nullptr};
@@ -52,15 +51,6 @@ Boolean::Boolean()
ADD_PROPERTY(Type, ((long)0));
Type.setEnums(TypeEnums);
ADD_PROPERTY_TYPE(
UsePlacement,
(0),
"Part Design",
(App::PropertyType)(App::Prop_None),
"Apply the placement of the second ( tool ) object"
);
this->UsePlacement.setValue(false);
App::GeoFeatureGroupExtension::initExtension(this);
}
@@ -115,15 +105,6 @@ App::DocumentObjectExecReturn* Boolean::execute()
);
}
// get the body this boolean feature belongs to
Part::BodyBase* baseBody = Part::BodyBase::findBodyOf(this);
if (!baseBody) {
return new App::DocumentObjectExecReturn(
QT_TRANSLATE_NOOP("Exception", "Cannot do boolean on feature which is not in a body")
);
}
std::vector<TopoShape> shapes;
shapes.push_back(baseTopShape);
for (auto it = tools.begin(); it < tools.end(); ++it) {
@@ -137,36 +118,9 @@ App::DocumentObjectExecReturn* Boolean::execute()
}
TopoShape result(baseTopShape);
Base::Placement bodyPlacement = baseBody->globalPlacement().inverse();
for (auto tool : tools) {
if (!tool->isDerivedFrom<Part::Feature>()) {
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP(
"Exception",
"Cannot do boolean with anything but Part::Feature and its derivatives"
));
}
Part::TopoShape toolShape = static_cast<Part::Feature*>(tool)->Shape.getShape();
if (UsePlacement.getValue()) {
toolShape.setPlacement(bodyPlacement * toolShape.getPlacement());
}
TopoDS_Shape shape = toolShape.getShape();
TopoDS_Shape boolOp;
// Must not pass null shapes to the boolean operations
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")
);
}
if (!tools.empty()) {
const char* op = nullptr;
if (type == "Fuse") {
op = Part::OpCodes::Fuse;
}
@@ -199,6 +153,8 @@ App::DocumentObjectExecReturn* Boolean::execute()
}
}
result.bakeInTransform();
result = refineShapeIfActive(result);
if (!isSingleSolidRuleSatisfied(result.getShape())) {

View File

@@ -46,8 +46,6 @@ public:
/// The type of the boolean operation
App::PropertyEnumeration Type;
App::PropertyBool UsePlacement;
/** @name methods override feature */
//@{
/// Recalculate the feature

View File

@@ -2598,7 +2598,6 @@ void CmdPartDesignBoolean::activated(int iMsg)
std::string FeatName = getUniqueObjectName("Boolean", pcActiveBody);
FCMD_OBJ_CMD(pcActiveBody, "newObject('PartDesign::Boolean','" << FeatName << "')");
auto Feat = pcActiveBody->getDocument()->getObject(FeatName.c_str());
static_cast<PartDesign::Boolean*>(Feat)->UsePlacement.setValue(true);
// If we don't add an object to the boolean group then don't update the body
// as otherwise this will fail and it will be marked as invalid