From 61b0755c89042e5876f921f88927857aafd65a2a Mon Sep 17 00:00:00 2001 From: wmayer Date: Mon, 8 Jul 2019 11:46:09 +0200 Subject: [PATCH 1/2] automatically redirect to tip object in case body display mode is set to Tip and a face was selected to create a new sketch --- src/Mod/PartDesign/Gui/Command.cpp | 43 +++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/src/Mod/PartDesign/Gui/Command.cpp b/src/Mod/PartDesign/Gui/Command.cpp index 5e12d95da4..674dc9bce0 100644 --- a/src/Mod/PartDesign/Gui/Command.cpp +++ b/src/Mod/PartDesign/Gui/Command.cpp @@ -66,6 +66,7 @@ #include "ReferenceSelection.h" #include "Utils.h" #include "WorkflowManager.h" +#include "ViewProviderBody.h" // TODO Remove this header after fixing code so it won;t be needed here (2015-10-20, Fat-Zer) #include "ui_DlgReference.h" @@ -461,15 +462,42 @@ void CmdPartDesignNewSketch::activated(int iMsg) App::DocumentObject* obj; if (FaceFilter.match()) { - obj = FaceFilter.Result[0][0].getObject(); + Gui::SelectionObject faceSelObject = FaceFilter.Result[0][0]; + const std::vector& subNames = faceSelObject.getSubNames(); + obj = faceSelObject.getObject(); - if(!obj->isDerivedFrom(Part::Feature::getClassTypeId())) + if (!obj->isDerivedFrom(Part::Feature::getClassTypeId())) return; + // In case the selected face belongs to the body then it means its + // Display Mode Body is set to Tip. But the body face is not allowed + // to be used as support because otherwise it would cause a cyclic + // dependency. So, instead we use the tip object as reference. + // https://forum.freecadweb.org/viewtopic.php?f=3&t=37448 + if (obj == pcActiveBody) { + App::DocumentObject* tip = pcActiveBody->Tip.getValue(); + if (tip && tip->isDerivedFrom(Part::Feature::getClassTypeId()) && subNames.size() == 1) { + Gui::SelectionChanges msg; + msg.pDocName = faceSelObject.getDocName(); + msg.pObjectName = tip->getNameInDocument(); + msg.pSubName = subNames[0].c_str(); + msg.pTypeName = tip->getTypeId().getName(); + + faceSelObject = Gui::SelectionObject(msg); + obj = tip; + + // automatically switch to 'Through' mode + PartDesignGui::ViewProviderBody* vpBody = dynamic_cast + (Gui::Application::Instance->getViewProvider(pcActiveBody)); + if (vpBody) { + vpBody->DisplayModeBody.setValue("Through"); + } + } + } + Part::Feature* feat = static_cast(obj); - const std::vector &sub = FaceFilter.Result[0][0].getSubNames(); - if (sub.size() > 1) { + if (subNames.size() > 1) { // No assert for wrong user input! QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Several sub-elements selected"), QObject::tr("You have to select a single face as support for a sketch!")); @@ -478,7 +506,7 @@ void CmdPartDesignNewSketch::activated(int iMsg) // get the selected sub shape (a Face) const Part::TopoShape &shape = feat->Shape.getValue(); - TopoDS_Shape sh = shape.getSubShape(sub[0].c_str()); + TopoDS_Shape sh = shape.getSubShape(subNames[0].c_str()); const TopoDS_Face& face = TopoDS::Face(sh); if (face.IsNull()) { // No assert for wrong user input! @@ -498,8 +526,9 @@ void CmdPartDesignNewSketch::activated(int iMsg) } } - supportString = FaceFilter.Result[0][0].getAsPropertyLinkSubString(); - } else { + supportString = faceSelObject.getAsPropertyLinkSubString(); + } + else { obj = static_cast(PlaneFilter.Result[0][0].getObject()); supportString = std::string("(App.activeDocument().") + obj->getNameInDocument() + ", '')"; } From 1b0d03e4ab9e9aea1adb9ea59afd57ccfc36d2d4 Mon Sep 17 00:00:00 2001 From: wmayer Date: Mon, 8 Jul 2019 14:37:00 +0200 Subject: [PATCH 2/2] Parametric refinement feature --- src/Mod/Part/App/AppPart.cpp | 1 + src/Mod/Part/App/PartFeatures.cpp | 25 ++++++++++++++++++ src/Mod/Part/App/PartFeatures.h | 19 ++++++++++++++ src/Mod/Part/Gui/AppPartGui.cpp | 1 + src/Mod/Part/Gui/CommandSimple.cpp | 34 ++++++++++++++++++------- src/Mod/Part/Gui/ViewProviderMirror.cpp | 13 ++++++++++ src/Mod/Part/Gui/ViewProviderMirror.h | 11 ++++++++ 7 files changed, 95 insertions(+), 9 deletions(-) diff --git a/src/Mod/Part/App/AppPart.cpp b/src/Mod/Part/App/AppPart.cpp index fa107b0c23..ed5bcb973e 100644 --- a/src/Mod/Part/App/AppPart.cpp +++ b/src/Mod/Part/App/AppPart.cpp @@ -474,6 +474,7 @@ PyMOD_INIT_FUNC(Part) Part::Offset ::init(); Part::Offset2D ::init(); Part::Thickness ::init(); + Part::Refine ::init(); // Geometry types Part::Geometry ::init(); diff --git a/src/Mod/Part/App/PartFeatures.cpp b/src/Mod/Part/App/PartFeatures.cpp index f711ec2ffb..33d4b40b83 100644 --- a/src/Mod/Part/App/PartFeatures.cpp +++ b/src/Mod/Part/App/PartFeatures.cpp @@ -673,3 +673,28 @@ App::DocumentObjectExecReturn *Thickness::execute(void) this->Shape.setValue(shape); return App::DocumentObject::StdReturn; } + +// ---------------------------------------------------------------------------- + +PROPERTY_SOURCE(Part::Refine, Part::Feature) + +Refine::Refine() +{ + ADD_PROPERTY_TYPE(Source,(0),"Refine",App::Prop_None,"Source shape"); +} + +App::DocumentObjectExecReturn *Refine::execute(void) +{ + Part::Feature* source = Source.getValue(); + if (!source) + return new App::DocumentObjectExecReturn("No part object linked."); + + try { + TopoShape myShape = source->Shape.getShape(); + this->Shape.setValue(myShape.removeSplitter()); + return App::DocumentObject::StdReturn; + } + catch (Standard_Failure& e) { + return new App::DocumentObjectExecReturn(e.GetMessageString()); + } +} diff --git a/src/Mod/Part/App/PartFeatures.h b/src/Mod/Part/App/PartFeatures.h index 0852a88c3d..18a2db9ac8 100644 --- a/src/Mod/Part/App/PartFeatures.h +++ b/src/Mod/Part/App/PartFeatures.h @@ -154,6 +154,25 @@ private: static const char* JoinEnums[]; }; +class Refine : public Part::Feature +{ + PROPERTY_HEADER(Part::Refine); + +public: + Refine(); + + App::PropertyLink Source; + + /** @name methods override feature */ + //@{ + /// recalculate the feature + App::DocumentObjectExecReturn *execute(void); + const char* getViewProviderName(void) const { + return "PartGui::ViewProviderRefine"; + } + //@} +}; + } //namespace Part diff --git a/src/Mod/Part/Gui/AppPartGui.cpp b/src/Mod/Part/Gui/AppPartGui.cpp index 67d51c5631..291c64f67e 100644 --- a/src/Mod/Part/Gui/AppPartGui.cpp +++ b/src/Mod/Part/Gui/AppPartGui.cpp @@ -171,6 +171,7 @@ PyMOD_INIT_FUNC(PartGui) PartGui::ViewProviderOffset ::init(); PartGui::ViewProviderOffset2D ::init(); PartGui::ViewProviderThickness ::init(); + PartGui::ViewProviderRefine ::init(); PartGui::ViewProviderCustom ::init(); PartGui::ViewProviderCustomPython ::init(); PartGui::ViewProviderBoolean ::init(); diff --git a/src/Mod/Part/Gui/CommandSimple.cpp b/src/Mod/Part/Gui/CommandSimple.cpp index a1dd37e61e..72b7d44485 100644 --- a/src/Mod/Part/Gui/CommandSimple.cpp +++ b/src/Mod/Part/Gui/CommandSimple.cpp @@ -235,21 +235,37 @@ CmdPartRefineShape::CmdPartRefineShape() void CmdPartRefineShape::activated(int iMsg) { Q_UNUSED(iMsg); + ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Part"); + bool parametric = hGrp->GetBool("ParametricRefine", true); + Gui::WaitCursor wc; Base::Type partid = Base::Type::fromName("Part::Feature"); std::vector objs = Gui::Selection().getObjectsOfType(partid); openCommand("Refine shape"); for (std::vector::iterator it = objs.begin(); it != objs.end(); ++it) { try { - doCommand(Doc,"App.ActiveDocument.addObject('Part::Feature','%s').Shape=" - "App.ActiveDocument.%s.Shape.removeSplitter()\n" - "App.ActiveDocument.ActiveObject.Label=" - "App.ActiveDocument.%s.Label\n" - "Gui.ActiveDocument.%s.hide()\n", - (*it)->getNameInDocument(), - (*it)->getNameInDocument(), - (*it)->getNameInDocument(), - (*it)->getNameInDocument()); + if (parametric) { + doCommand(Doc,"App.ActiveDocument.addObject('Part::Refine','%s').Source=" + "App.ActiveDocument.%s\n" + "App.ActiveDocument.ActiveObject.Label=" + "App.ActiveDocument.%s.Label\n" + "Gui.ActiveDocument.%s.hide()\n", + (*it)->getNameInDocument(), + (*it)->getNameInDocument(), + (*it)->getNameInDocument(), + (*it)->getNameInDocument()); + } + else { + doCommand(Doc,"App.ActiveDocument.addObject('Part::Feature','%s').Shape=" + "App.ActiveDocument.%s.Shape.removeSplitter()\n" + "App.ActiveDocument.ActiveObject.Label=" + "App.ActiveDocument.%s.Label\n" + "Gui.ActiveDocument.%s.hide()\n", + (*it)->getNameInDocument(), + (*it)->getNameInDocument(), + (*it)->getNameInDocument(), + (*it)->getNameInDocument()); + } copyVisual("ActiveObject", "ShapeColor", (*it)->getNameInDocument()); copyVisual("ActiveObject", "LineColor", (*it)->getNameInDocument()); copyVisual("ActiveObject", "PointColor", (*it)->getNameInDocument()); diff --git a/src/Mod/Part/Gui/ViewProviderMirror.cpp b/src/Mod/Part/Gui/ViewProviderMirror.cpp index 80e03983d4..51452220b7 100644 --- a/src/Mod/Part/Gui/ViewProviderMirror.cpp +++ b/src/Mod/Part/Gui/ViewProviderMirror.cpp @@ -667,3 +667,16 @@ bool ViewProviderThickness::onDelete(const std::vector &) return true; } + +// --------------------------------------- + +PROPERTY_SOURCE(PartGui::ViewProviderRefine, PartGui::ViewProviderPart) + +ViewProviderRefine::ViewProviderRefine() +{ + sPixmap = "Part_Refine_Shape"; +} + +ViewProviderRefine::~ViewProviderRefine() +{ +} diff --git a/src/Mod/Part/Gui/ViewProviderMirror.h b/src/Mod/Part/Gui/ViewProviderMirror.h index 793210439b..839ee4ba6d 100644 --- a/src/Mod/Part/Gui/ViewProviderMirror.h +++ b/src/Mod/Part/Gui/ViewProviderMirror.h @@ -193,6 +193,17 @@ protected: virtual void unsetEdit(int ModNum); }; +class ViewProviderRefine : public ViewProviderPart +{ + PROPERTY_HEADER(PartGui::ViewProviderRefine); + +public: + /// constructor + ViewProviderRefine(); + /// destructor + virtual ~ViewProviderRefine(); +}; + } // namespace PartGui