From 026242231ea3f6ca236129e2f880bf5d87ded177 Mon Sep 17 00:00:00 2001 From: jrheinlaender Date: Fri, 24 May 2013 08:23:04 +0430 Subject: [PATCH] Changed tree ordering of booleans and bodies --- src/Mod/PartDesign/App/Feature.cpp | 18 ++++++++- src/Mod/PartDesign/App/Feature.h | 4 ++ src/Mod/PartDesign/App/FeatureBoolean.cpp | 37 ++++++++++--------- src/Mod/PartDesign/Gui/Command.cpp | 37 ++++++++++++------- src/Mod/PartDesign/Gui/ReferenceSelection.cpp | 11 ++++++ src/Mod/PartDesign/Gui/ReferenceSelection.h | 4 +- .../PartDesign/Gui/TaskBooleanParameters.cpp | 36 ++++++++++++------ .../Gui/TaskRevolutionParameters.cpp | 2 +- 8 files changed, 104 insertions(+), 45 deletions(-) diff --git a/src/Mod/PartDesign/App/Feature.cpp b/src/Mod/PartDesign/App/Feature.cpp index 1e091b4ab..da4990b11 100644 --- a/src/Mod/PartDesign/App/Feature.cpp +++ b/src/Mod/PartDesign/App/Feature.cpp @@ -90,7 +90,7 @@ const gp_Pnt Feature::getPointFromFace(const TopoDS_Face& f) throw Base::Exception("getPointFromFace(): Not implemented yet for this case"); } -const TopoDS_Shape& Feature::getBaseShape() const { +const Part::Feature* Feature::getBaseObject() const { App::DocumentObject* BaseLink = BaseFeature.getValue(); if (BaseLink == NULL) throw Base::Exception("Base property not set"); Part::Feature* BaseObject = NULL; @@ -100,6 +100,12 @@ const TopoDS_Shape& Feature::getBaseShape() const { if (BaseObject == NULL) throw Base::Exception("No base feature linked"); + return BaseObject; +} + +const TopoDS_Shape& Feature::getBaseShape() const { + const Part::Feature* BaseObject = getBaseObject(); + const TopoDS_Shape& result = BaseObject->Shape.getValue(); if (result.IsNull()) throw Base::Exception("Base feature's shape is invalid"); @@ -110,6 +116,16 @@ const TopoDS_Shape& Feature::getBaseShape() const { return result; } +const Part::TopoShape Feature::getBaseTopoShape() const { + const Part::Feature* BaseObject = getBaseObject(); + + const Part::TopoShape& result = BaseObject->Shape.getShape(); + if (result._Shape.IsNull()) + throw Base::Exception("Base feature's TopoShape is invalid"); + + return result; +} + bool Feature::isDatum(const App::DocumentObject* feature) { return feature->getTypeId().isDerivedFrom(App::Plane::getClassTypeId()) || diff --git a/src/Mod/PartDesign/App/Feature.h b/src/Mod/PartDesign/App/Feature.h index adba54e43..c9f0d170e 100644 --- a/src/Mod/PartDesign/App/Feature.h +++ b/src/Mod/PartDesign/App/Feature.h @@ -57,8 +57,12 @@ public: static bool isDatum(const App::DocumentObject* feature); protected: + /// Returns the BaseFeature property's object (if any) + const Part::Feature* getBaseObject() const; /// Returns the BaseFeature property's shape (if any) const TopoDS_Shape& getBaseShape() const; + /// Returns the BaseFeature property's TopoShape (if any) + const Part::TopoShape getBaseTopoShape() const; /** * Get a solid of the given shape. If no solid is found an exception is raised. diff --git a/src/Mod/PartDesign/App/FeatureBoolean.cpp b/src/Mod/PartDesign/App/FeatureBoolean.cpp index 73a5a633b..978ef0bea 100644 --- a/src/Mod/PartDesign/App/FeatureBoolean.cpp +++ b/src/Mod/PartDesign/App/FeatureBoolean.cpp @@ -60,33 +60,36 @@ short Boolean::mustExecute() const App::DocumentObjectExecReturn *Boolean::execute(void) { + // Get the base shape to operate on + Part::TopoShape baseTopShape; + try { + baseTopShape = getBaseTopoShape(); + } catch (const Base::Exception&) { + return new App::DocumentObjectExecReturn("Cannot do boolean operation with invalid base shape"); + } + std::vector bodies = Bodies.getValues(); if (bodies.empty()) return App::DocumentObject::StdReturn; - // Get the first body - if (bodies.front() == NULL) - return new App::DocumentObjectExecReturn("No body for boolean"); - PartDesign::Body* body = static_cast(bodies.front()); - const Part::TopoShape& bodyTopShape = body->Shape.getShape(); - if (bodyTopShape._Shape.IsNull()) - return new App::DocumentObjectExecReturn("Cannot do boolean operation on invalid body shape"); - - // create an untransformed copy of the body shape - Part::TopoShape bodyShape(bodyTopShape); - bodyShape.setTransform(Base::Matrix4D()); - TopoDS_Shape result = bodyShape._Shape; + // create an untransformed copy of the base shape + Part::TopoShape baseShape(baseTopShape); + baseShape.setTransform(Base::Matrix4D()); + TopoDS_Shape result = baseShape._Shape; // Position this feature by the first body - this->Placement.setValue(body->Placement.getValue()); + const Part::Feature* baseFeature; + try { + baseFeature = getBaseObject(); + } catch (const Base::Exception&) { + return new App::DocumentObjectExecReturn("Cannot do boolean operation with invalid BaseFeature"); + } + this->Placement.setValue(baseFeature->Placement.getValue()); // Get the operation type std::string type = Type.getValueAsString(); - std::vector::const_iterator b = bodies.begin(); - b++; - - for (; b != bodies.end(); b++) + for (std::vector::const_iterator b = bodies.begin(); b != bodies.end(); b++) { // Extract the body shape PartDesign::Body* body = static_cast(*b); diff --git a/src/Mod/PartDesign/Gui/Command.cpp b/src/Mod/PartDesign/Gui/Command.cpp index d2971b833..87d2609e0 100644 --- a/src/Mod/PartDesign/Gui/Command.cpp +++ b/src/Mod/PartDesign/Gui/Command.cpp @@ -79,6 +79,7 @@ using namespace std; +#include "ReferenceSelection.h" //=========================================================================== // PartDesign_Body @@ -737,7 +738,7 @@ bool CmdPartDesignNewSketch::isActive(void) // Common utility functions for all features creating solids //=========================================================================== -void finishFeature(const Gui::Command* cmd, const std::string& FeatName) +void finishFeature(const Gui::Command* cmd, const std::string& FeatName, const bool hidePrevSolid = true) { PartDesign::Body *pcActiveBody = PartDesignGui::getBody(); @@ -746,7 +747,7 @@ void finishFeature(const Gui::Command* cmd, const std::string& FeatName) if (cmd->isActiveObjectValid() && (pcActiveBody != NULL)) { App::DocumentObject* prevSolidFeature = pcActiveBody->getPrevSolidFeature(NULL, false); - if (prevSolidFeature != NULL) + if (hidePrevSolid && (prevSolidFeature != NULL)) cmd->doCommand(cmd->Gui,"Gui.activeDocument().hide(\"%s\")", prevSolidFeature->getNameInDocument()); } cmd->updateActive(); @@ -1626,33 +1627,41 @@ CmdPartDesignBoolean::CmdPartDesignBoolean() void CmdPartDesignBoolean::activated(int iMsg) { Gui::SelectionFilter BodyFilter("SELECT PartDesign::Body COUNT 1.."); - std::string bodyString("["); + PartDesign::Body* body; + std::string bodyString(""); if (BodyFilter.match()) { + body = static_cast(BodyFilter.Result[0][0].getObject()); std::vector bodies; - for (std::vector >::iterator i = BodyFilter.Result.begin(); - i != BodyFilter.Result.end(); i++) { + std::vector >::iterator i = BodyFilter.Result.begin(); + i++; + for (; i != BodyFilter.Result.end(); i++) { for (std::vector::iterator j = i->begin(); j != i->end(); j++) { bodies.push_back(j->getObject()); } } - - for (std::vector::const_iterator b = bodies.begin(); b != bodies.end(); b++) - bodyString += std::string("App.activeDocument().") + (*b)->getNameInDocument() + ","; - bodyString += "]"; + bodyString = PartDesignGui::getPythonStr(bodies); } else { - bodyString = ""; + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No body selected"), + QObject::tr("Please select a body for the boolean operation")); + return; + } + + openCommand("Create Boolean"); + + // Make sure we are working on the selected body + if (body != PartDesignGui::ActivePartObject) { + Gui::Selection().clearSelection(); + Gui::Selection().addSelection(body->getDocument()->getName(), body->Tip.getValue()->getNameInDocument()); + Gui::Command::doCommand(Gui::Command::Gui,"FreeCADGui.runCommand('PartDesign_MoveTip')"); } std::string FeatName = getUniqueObjectName("Boolean"); - openCommand("Create Boolean"); doCommand(Doc,"App.activeDocument().addObject('PartDesign::Boolean','%s')",FeatName.c_str()); if (!bodyString.empty()) doCommand(Doc,"App.activeDocument().%s.Bodies = %s",FeatName.c_str(),bodyString.c_str()); - //doCommand(Gui,"App.activeDocument().recompute()"); - //doCommand(Gui,"Gui.activeDocument().activeView().setCamera('%s')",cam.c_str()); - doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); + finishFeature(this, FeatName, false); } bool CmdPartDesignBoolean::isActive(void) diff --git a/src/Mod/PartDesign/Gui/ReferenceSelection.cpp b/src/Mod/PartDesign/Gui/ReferenceSelection.cpp index 8ae2c4ae2..2a8df942b 100644 --- a/src/Mod/PartDesign/Gui/ReferenceSelection.cpp +++ b/src/Mod/PartDesign/Gui/ReferenceSelection.cpp @@ -155,4 +155,15 @@ const std::string getPythonStr(const App::DocumentObject* obj, const std::vector return std::string("(App.ActiveDocument.") + obj->getNameInDocument() + ", [\"" + sub.front() + "\"])"; } +const std::string getPythonStr(const std::vector objs) +{ + std::string result("["); + + for (std::vector::const_iterator o = objs.begin(); o != objs.end(); o++) + result += std::string("App.activeDocument().") + (*o)->getNameInDocument() + ","; + result += "]"; + + return result; +} + } diff --git a/src/Mod/PartDesign/Gui/ReferenceSelection.h b/src/Mod/PartDesign/Gui/ReferenceSelection.h index 8046be6c9..46699c9de 100644 --- a/src/Mod/PartDesign/Gui/ReferenceSelection.h +++ b/src/Mod/PartDesign/Gui/ReferenceSelection.h @@ -53,8 +53,10 @@ void getReferencedSelection(const App::DocumentObject* thisObj, const Gui::Selec App::DocumentObject*& selObj, std::vector& selSub); /// Return reference as string for UI elements (format : const QString getRefStr(const App::DocumentObject* obj, const std::vector& sub); -/// Return reference as string for python (format (, [""]) ) +/// Return reference as string for python in the format (, ["",]) const std::string getPythonStr(const App::DocumentObject* obj, const std::vector& sub); +/// Return reference as string for python in the format [obj1, obj2, ...,] +const std::string getPythonStr(const std::vector objs); } //namespace PartDesignGui diff --git a/src/Mod/PartDesign/Gui/TaskBooleanParameters.cpp b/src/Mod/PartDesign/Gui/TaskBooleanParameters.cpp index ee14dbf53..f5986f053 100644 --- a/src/Mod/PartDesign/Gui/TaskBooleanParameters.cpp +++ b/src/Mod/PartDesign/Gui/TaskBooleanParameters.cpp @@ -122,15 +122,15 @@ void TaskBooleanParameters::onSelectionChanged(const Gui::SelectionChanges& msg) ui->buttonBodyAdd->setChecked(false); exitSelectionMode(); - // Hide the bodies if there are more than two - if (bodies.size() == 2) { - // Hide both bodies + // Hide the bodies + if (bodies.size() == 1) { + // Hide base body and added body Gui::ViewProviderDocumentObject* vp = dynamic_cast( - Gui::Application::Instance->getViewProvider(bodies.front())); + Gui::Application::Instance->getViewProvider(pcBoolean->BaseFeature.getValue())); if (vp != NULL) vp->hide(); vp = dynamic_cast( - Gui::Application::Instance->getViewProvider(bodies.back())); + Gui::Application::Instance->getViewProvider(bodies.front())); if (vp != NULL) vp->hide(); BooleanView->show(); @@ -163,9 +163,9 @@ void TaskBooleanParameters::onSelectionChanged(const Gui::SelectionChanges& msg) Gui::Application::Instance->getViewProvider(*b)); if (vp != NULL) vp->show(); - if (bodies.size() == 1) { + if (bodies.size() == 0) { Gui::ViewProviderDocumentObject* vp = dynamic_cast( - Gui::Application::Instance->getViewProvider(bodies.front())); + Gui::Application::Instance->getViewProvider(pcBoolean->BaseFeature.getValue())); if (vp != NULL) vp->show(); BooleanView->hide(); @@ -180,7 +180,10 @@ void TaskBooleanParameters::onButtonBodyAdd(bool checked) if (checked) { Gui::Document* doc = Gui::Application::Instance->activeDocument(); if (doc != NULL) - doc->setHide(BooleanView->getObject()->getNameInDocument()); + BooleanView->hide(); + PartDesign::Boolean* pcBoolean = static_cast(BooleanView->getObject()); + if (pcBoolean->Bodies.getValues().empty()) + doc->setHide(pcBoolean->BaseFeature.getValue()->getNameInDocument()); selectionMode = bodyAdd; Gui::Selection().clearSelection(); } else { @@ -193,7 +196,7 @@ void TaskBooleanParameters::onButtonBodyRemove(bool checked) if (checked) { Gui::Document* doc = Gui::Application::Instance->activeDocument(); if (doc != NULL) - doc->setHide(BooleanView->getObject()->getNameInDocument()); + BooleanView->show(); selectionMode = bodyRemove; Gui::Selection().clearSelection(); } else { @@ -247,9 +250,9 @@ void TaskBooleanParameters::onBodyDeleted(void) Gui::Application::Instance->getViewProvider(body)); if (vp != NULL) vp->show(); - if (bodies.size() == 1) { + if (bodies.empty()) { Gui::ViewProviderDocumentObject* vp = dynamic_cast( - Gui::Application::Instance->getViewProvider(bodies.front())); + Gui::Application::Instance->getViewProvider(pcBoolean->BaseFeature.getValue())); if (vp != NULL) vp->show(); BooleanView->hide(); @@ -343,10 +346,21 @@ bool TaskDlgBooleanParameters::accept() bool TaskDlgBooleanParameters::reject() { + // Show the bodies again + PartDesign::Boolean* obj = static_cast(BooleanView->getObject()); + Gui::Document* doc = Gui::Application::Instance->activeDocument(); + if (doc != NULL) { + doc->setShow(obj->BaseFeature.getValue()->getNameInDocument()); + std::vector bodies = obj->Bodies.getValues(); + for (std::vector::const_iterator b = bodies.begin(); b != bodies.end(); b++) + doc->setShow((*b)->getNameInDocument()); + } + // roll back the done things Gui::Command::abortCommand(); Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()"); + return true; } diff --git a/src/Mod/PartDesign/Gui/TaskRevolutionParameters.cpp b/src/Mod/PartDesign/Gui/TaskRevolutionParameters.cpp index 740311c50..339592b9e 100644 --- a/src/Mod/PartDesign/Gui/TaskRevolutionParameters.cpp +++ b/src/Mod/PartDesign/Gui/TaskRevolutionParameters.cpp @@ -94,7 +94,7 @@ TaskRevolutionParameters::TaskRevolutionParameters(ViewProviderRevolution *Revol ui->checkBoxReversed->setChecked(reversed); ui->revolveAngle->bind(pcRevolution->Angle); - ui->doubleSpinBox->blockSignals(false); + ui->revolveAngle->blockSignals(false); ui->axis->blockSignals(false); ui->checkBoxMidplane->blockSignals(false); ui->checkBoxReversed->blockSignals(false);