diff --git a/src/Mod/PartDesign/App/Body.cpp b/src/Mod/PartDesign/App/Body.cpp index 0075fc4c67..3b043490e7 100644 --- a/src/Mod/PartDesign/App/Body.cpp +++ b/src/Mod/PartDesign/App/Body.cpp @@ -325,6 +325,17 @@ void Body::removeFeature(App::DocumentObject* feature) Model.setValues(model); } +bool Body::isFeature(App::DocumentObject* feature) +{ + for(App::DocumentObject* obj : Model.getValues()) { + + if(obj == feature) + return true; + } + return false; +} + + App::DocumentObjectExecReturn *Body::execute(void) { /* diff --git a/src/Mod/PartDesign/App/Body.h b/src/Mod/PartDesign/App/Body.h index d5218b3bf0..a4d8fde8d9 100644 --- a/src/Mod/PartDesign/App/Body.h +++ b/src/Mod/PartDesign/App/Body.h @@ -83,6 +83,9 @@ public: /// Remove the feature from the body void removeFeature(App::DocumentObject* feature); + + /// Checks if the given document object is a feaure of this body + bool isFeature(App::DocumentObject* feature); /// Return true if the given feature is member of a MultiTransform feature static const bool isMemberOfMultiTransform(const App::DocumentObject* f); diff --git a/src/Mod/PartDesign/App/FeatureBoolean.cpp b/src/Mod/PartDesign/App/FeatureBoolean.cpp index 998d49e647..fd0f2d5193 100644 --- a/src/Mod/PartDesign/App/FeatureBoolean.cpp +++ b/src/Mod/PartDesign/App/FeatureBoolean.cpp @@ -32,6 +32,7 @@ # include # include # include +#include #endif #include "Body.h" @@ -39,6 +40,8 @@ #include #include +#include +#include using namespace PartDesign; @@ -81,15 +84,43 @@ App::DocumentObjectExecReturn *Boolean::execute(void) Part::TopoShape baseTopShape = baseFeature->Shape.getShape(); if (baseTopShape._Shape.IsNull()) return new App::DocumentObjectExecReturn("Cannot do boolean operation with invalid base shape"); + + //get the body this boolean feature belongs to + PartDesign::Body* baseBody = NULL; + for(PartDesign::Body* b : this->getDocument()->getObjectsOfType()) { + if(b->isFeature(this)) { + baseBody = b; + break; + } + } + if(!baseBody) + return new App::DocumentObjectExecReturn("Cannot do boolean on feature which is not in a body"); - // Position this feature by the base feature - this->Placement.setValue(baseFeature->Placement.getValue()); - TopLoc_Location invObjLoc = this->getLocation().Inverted(); + //get the part every body should belong to + App::Part* part = NULL; + for(App::Part* p : this->getDocument()->getObjectsOfType()) { + if(p->hasObject(baseBody)) { + part = p; + break; + } + } + if(!part) + return new App::DocumentObjectExecReturn("Cannot do boolean on body which is not in a part"); - // create an untransformed copy of the base shape - Part::TopoShape baseShape(baseTopShape); - baseShape.setTransform(Base::Matrix4D()); - TopoDS_Shape result = baseShape._Shape; + + // TODO: Why is Feature::getLocation() protected? + Base::Placement place = baseBody->Placement.getValue(); + Base::Rotation rot(place.getRotation()); + Base::Vector3d axis; + double angle; + rot.getValue(axis, angle); + gp_Trsf trf; + trf.SetRotation(gp_Ax1(gp_Pnt(), gp_Dir(axis.x, axis.y, axis.z)), angle); + trf.SetTranslationPart(gp_Vec(place.getPosition().x,place.getPosition().y,place.getPosition().z)); + TopLoc_Location objLoc(trf); + + TopoDS_Shape result = baseTopShape._Shape; + result.Move(objLoc); // Get the operation type std::string type = Type.getValueAsString(); @@ -99,12 +130,12 @@ App::DocumentObjectExecReturn *Boolean::execute(void) // Extract the body shape. Its important to get the actual feature that provides the last solid in the body // so that the placement will be right PartDesign::Body* body = static_cast(*b); - Part::Feature* tipSolid = static_cast(body->getPrevSolidFeature()); - if (tipSolid == NULL) - continue; - TopoDS_Shape shape = tipSolid->Shape.getValue(); + if(!part->hasObject(body)) + return new App::DocumentObjectExecReturn("Cannot do boolean on bodies of different parts"); + + TopoDS_Shape shape = body->getTipShape()._Shape; - // Move the shape to the location of the base shape + // Move the shape to the location of the base shape in the other body Base::Placement pl = body->Placement.getValue(); // TODO: Why is Feature::getLocation() protected? Base::Rotation rot(pl.getRotation()); @@ -115,7 +146,7 @@ App::DocumentObjectExecReturn *Boolean::execute(void) trf.SetRotation(gp_Ax1(gp_Pnt(), gp_Dir(axis.x, axis.y, axis.z)), angle); trf.SetTranslationPart(gp_Vec(pl.getPosition().x,pl.getPosition().y,pl.getPosition().z)); TopLoc_Location bLoc(trf); - shape.Move(invObjLoc.Multiplied(bLoc)); + shape.Move(bLoc); TopoDS_Shape boolOp; @@ -150,6 +181,9 @@ App::DocumentObjectExecReturn *Boolean::execute(void) } result = boolOp; // Use result of this operation for fuse/cut of next body + //bring the result geometry into the correct coordinance of the body the boolean belongs to + BRepBuilderAPI_GTransform mkTrf(result, objLoc.Inverted().Transformation()); + result = mkTrf.Shape(); } this->Shape.setValue(result);