From fc1e8b8d17aa34fbe943985d98f1ef712614ef8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Tr=C3=B6ger?= Date: Wed, 20 May 2015 21:51:19 +0200 Subject: [PATCH] allow to add faces to fillet and chamfer --- src/Mod/PartDesign/App/FeatureChamfer.cpp | 19 +- src/Mod/PartDesign/App/FeatureDressUp.cpp | 72 ++ src/Mod/PartDesign/App/FeatureDressUp.h | 3 + src/Mod/PartDesign/App/FeatureFillet.cpp | 24 +- src/Mod/PartDesign/App/FeatureFillet.cpp.orig | 30 +- src/Mod/PartDesign/Gui/Command.cpp | 71 -- src/Mod/PartDesign/Gui/Command.cpp.orig | 821 +++++++++--------- .../PartDesign/Gui/TaskChamferParameters.cpp | 2 +- .../PartDesign/Gui/TaskDraftParameters.cpp | 2 +- .../PartDesign/Gui/TaskDressUpParameters.cpp | 13 +- .../PartDesign/Gui/TaskDressUpParameters.h | 3 +- .../PartDesign/Gui/TaskFilletParameters.cpp | 2 +- .../PartDesign/Gui/ViewProviderDressUp.cpp | 6 +- 13 files changed, 551 insertions(+), 517 deletions(-) diff --git a/src/Mod/PartDesign/App/FeatureChamfer.cpp b/src/Mod/PartDesign/App/FeatureChamfer.cpp index 2c0685abf..23e5d751e 100644 --- a/src/Mod/PartDesign/App/FeatureChamfer.cpp +++ b/src/Mod/PartDesign/App/FeatureChamfer.cpp @@ -32,6 +32,7 @@ # include # include # include +#include #endif #include @@ -74,8 +75,10 @@ App::DocumentObjectExecReturn *Chamfer::execute(void) return new App::DocumentObjectExecReturn(e.what()); } - const std::vector& SubVals = Base.getSubValuesStartsWith("Edge"); - if (SubVals.size() == 0) + std::vector SubNames = std::vector(Base.getSubValues()); + getContiniusEdges(TopShape, SubNames); + + if (SubNames.size() == 0) return new App::DocumentObjectExecReturn("No edges specified"); double size = Size.getValue(); @@ -92,7 +95,7 @@ App::DocumentObjectExecReturn *Chamfer::execute(void) TopExp::MapShapesAndAncestors(baseShape._Shape, TopAbs_EDGE, TopAbs_FACE, mapEdgeFace); TopExp::MapShapes(baseShape._Shape, TopAbs_EDGE, mapOfEdges); - for (std::vector::const_iterator it=SubVals.begin(); it != SubVals.end(); ++it) { + for (std::vector::const_iterator it=SubNames.begin(); it != SubNames.end(); ++it) { TopoDS_Edge edge = TopoDS::Edge(baseShape.getSubShape(it->c_str())); const TopoDS_Face& face = TopoDS::Face(mapEdgeFace.FindFromKey(edge).First()); mkChamfer.Add(size, edge, face); @@ -106,11 +109,11 @@ App::DocumentObjectExecReturn *Chamfer::execute(void) if (shape.IsNull()) return new App::DocumentObjectExecReturn("Resulting shape is null"); - TopTools_ListOfShape aLarg; - aLarg.Append(baseShape._Shape); - if (!BRepAlgo::IsValid(aLarg, shape, Standard_False, Standard_False)) { - return new App::DocumentObjectExecReturn("Resulting shape is invalid"); - } + TopTools_ListOfShape aLarg; + aLarg.Append(baseShape._Shape); + if (!BRepAlgo::IsValid(aLarg, shape, Standard_False, Standard_False)) { + return new App::DocumentObjectExecReturn("Resulting shape is invalid"); + } this->Shape.setValue(shape); return App::DocumentObject::StdReturn; diff --git a/src/Mod/PartDesign/App/FeatureDressUp.cpp b/src/Mod/PartDesign/App/FeatureDressUp.cpp index 95fc0467f..4b99ad102 100644 --- a/src/Mod/PartDesign/App/FeatureDressUp.cpp +++ b/src/Mod/PartDesign/App/FeatureDressUp.cpp @@ -28,6 +28,12 @@ #include "FeatureDressUp.h" #include +#include +#include +#include +#include +#include +#include using namespace PartDesign; @@ -74,6 +80,72 @@ Part::TopoShape DressUp::getBaseShape() return shape; } +void DressUp::getContiniusEdges(Part::TopoShape TopShape, std::vector< std::string >& SubNames) { + + TopTools_IndexedMapOfShape mapOfEdges; + TopTools_IndexedDataMapOfShapeListOfShape mapEdgeFace; + TopExp::MapShapesAndAncestors(TopShape._Shape, TopAbs_EDGE, TopAbs_FACE, mapEdgeFace); + TopExp::MapShapes(TopShape._Shape, TopAbs_EDGE, mapOfEdges); + + unsigned int i = 0; + while(i < SubNames.size()) + { + std::string aSubName = static_cast(SubNames.at(i)); + + if (aSubName.size() > 4 && aSubName.substr(0,4) == "Edge") { + TopoDS_Edge edge = TopoDS::Edge(TopShape.getSubShape(aSubName.c_str())); + const TopTools_ListOfShape& los = mapEdgeFace.FindFromKey(edge); + + if(los.Extent() != 2) + { + SubNames.erase(SubNames.begin()+i); + continue; + } + + const TopoDS_Shape& face1 = los.First(); + const TopoDS_Shape& face2 = los.Last(); + GeomAbs_Shape cont = BRep_Tool::Continuity(TopoDS::Edge(edge), + TopoDS::Face(face1), + TopoDS::Face(face2)); + if (cont != GeomAbs_C0) { + SubNames.erase(SubNames.begin()+i); + continue; + } + + i++; + } + else if(aSubName.size() > 4 && aSubName.substr(0,4) == "Face") { + TopoDS_Face face = TopoDS::Face(TopShape.getSubShape(aSubName.c_str())); + + TopTools_IndexedMapOfShape mapOfFaces; + TopExp::MapShapes(face, TopAbs_EDGE, mapOfFaces); + + for(int j = 1; j <= mapOfFaces.Extent(); ++j) { + TopoDS_Edge edge = TopoDS::Edge(mapOfFaces.FindKey(j)); + + int id = mapOfEdges.FindIndex(edge); + + std::stringstream buf; + buf << "Edge"; + buf << id; + + if(std::find(SubNames.begin(),SubNames.end(),buf.str()) == SubNames.end()) + { + SubNames.push_back(buf.str()); + } + + } + + SubNames.erase(SubNames.begin()+i); + } + // empty name or any other sub-element + else { + SubNames.erase(SubNames.begin()+i); + } + } +} + + void DressUp::onChanged(const App::Property* prop) { if (prop == &BaseFeature) { diff --git a/src/Mod/PartDesign/App/FeatureDressUp.h b/src/Mod/PartDesign/App/FeatureDressUp.h index af143e8fc..e61b2980a 100644 --- a/src/Mod/PartDesign/App/FeatureDressUp.h +++ b/src/Mod/PartDesign/App/FeatureDressUp.h @@ -43,6 +43,9 @@ public: /// updates the Placement property from the Placement of the BaseFeature void positionByBaseFeature(void); Part::TopoShape getBaseShape(); + /// extracts all edges from the subshapes (inkluding face edges) and furthermore adds + /// all C0 continius edges to the vector + void getContiniusEdges(Part::TopoShape, std::vector< std::string >&); protected: void onChanged(const App::Property* prop); diff --git a/src/Mod/PartDesign/App/FeatureFillet.cpp b/src/Mod/PartDesign/App/FeatureFillet.cpp index 0c82686df..e1f37bbb2 100644 --- a/src/Mod/PartDesign/App/FeatureFillet.cpp +++ b/src/Mod/PartDesign/App/FeatureFillet.cpp @@ -29,6 +29,9 @@ # include # include # include +#include +#include +#include #endif #include @@ -68,11 +71,12 @@ App::DocumentObjectExecReturn *Fillet::execute(void) } catch (Base::Exception& e) { return new App::DocumentObjectExecReturn(e.what()); } + std::vector SubNames = std::vector(Base.getSubValues()); + getContiniusEdges(TopShape, SubNames); - const std::vector& SubVals = Base.getSubValuesStartsWith("Edge"); - if (SubVals.size() == 0) - return new App::DocumentObjectExecReturn("No edges specified"); - + if (SubNames.size() == 0) + return new App::DocumentObjectExecReturn("Fillet not possible on selected shapes"); + double radius = Radius.getValue(); this->positionByBaseFeature(); @@ -83,7 +87,7 @@ App::DocumentObjectExecReturn *Fillet::execute(void) try { BRepFilletAPI_MakeFillet mkFillet(baseShape._Shape); - for (std::vector::const_iterator it=SubVals.begin(); it != SubVals.end(); ++it) { + for (std::vector::const_iterator it=SubNames.begin(); it != SubNames.end(); ++it) { TopoDS_Edge edge = TopoDS::Edge(baseShape.getSubShape(it->c_str())); mkFillet.Add(radius, edge); } @@ -96,11 +100,11 @@ App::DocumentObjectExecReturn *Fillet::execute(void) if (shape.IsNull()) return new App::DocumentObjectExecReturn("Resulting shape is null"); - TopTools_ListOfShape aLarg; - aLarg.Append(baseShape._Shape); - if (!BRepAlgo::IsValid(aLarg, shape, Standard_False, Standard_False)) { - return new App::DocumentObjectExecReturn("Resulting shape is invalid"); - } + TopTools_ListOfShape aLarg; + aLarg.Append(baseShape._Shape); + if (!BRepAlgo::IsValid(aLarg, shape, Standard_False, Standard_False)) { + return new App::DocumentObjectExecReturn("Resulting shape is invalid"); + } this->Shape.setValue(shape); return App::DocumentObject::StdReturn; diff --git a/src/Mod/PartDesign/App/FeatureFillet.cpp.orig b/src/Mod/PartDesign/App/FeatureFillet.cpp.orig index 7e4324a6f..e92edeedb 100644 --- a/src/Mod/PartDesign/App/FeatureFillet.cpp.orig +++ b/src/Mod/PartDesign/App/FeatureFillet.cpp.orig @@ -23,18 +23,23 @@ #include "PreCompiled.h" #ifndef _PreComp_ +# include # include # include # include # include +<<<<<<< 2c7cc8276bd6dd4ccc4aa28daa809a688bd493c5 +# include +======= +#include +#include +#include +>>>>>>> allow to add faces to fillet and chamfer #endif -<<<<<<< 50287516b47694e57429cc98f6d5596a06a635d6 #include -#include -======= #include ->>>>>>> Some code unification for DressUp features +#include #include #include "FeatureFillet.h" @@ -69,11 +74,12 @@ App::DocumentObjectExecReturn *Fillet::execute(void) } catch (Base::Exception& e) { return new App::DocumentObjectExecReturn(e.what()); } + std::vector SubNames = std::vector(Base.getSubValues()); + getContiniusEdges(TopShape, SubNames); - const std::vector& SubVals = Base.getSubValuesStartsWith("Edge"); - if (SubVals.size() == 0) - return new App::DocumentObjectExecReturn("No edges specified"); - + if (SubNames.size() == 0) + return new App::DocumentObjectExecReturn("Fillet not possible on selected shapes"); + double radius = Radius.getValue(); this->positionByBaseFeature(); @@ -84,7 +90,7 @@ App::DocumentObjectExecReturn *Fillet::execute(void) try { BRepFilletAPI_MakeFillet mkFillet(baseShape._Shape); - for (std::vector::const_iterator it=SubVals.begin(); it != SubVals.end(); ++it) { + for (std::vector::const_iterator it=SubNames.begin(); it != SubNames.end(); ++it) { TopoDS_Edge edge = TopoDS::Edge(baseShape.getSubShape(it->c_str())); mkFillet.Add(radius, edge); } @@ -97,6 +103,12 @@ App::DocumentObjectExecReturn *Fillet::execute(void) if (shape.IsNull()) return new App::DocumentObjectExecReturn("Resulting shape is null"); + TopTools_ListOfShape aLarg; + aLarg.Append(baseShape._Shape); + if (!BRepAlgo::IsValid(aLarg, shape, Standard_False, Standard_False)) { + return new App::DocumentObjectExecReturn("Resulting shape is invalid"); + } + this->Shape.setValue(shape); return App::DocumentObject::StdReturn; } diff --git a/src/Mod/PartDesign/Gui/Command.cpp b/src/Mod/PartDesign/Gui/Command.cpp index 885d96a0a..67705ddde 100644 --- a/src/Mod/PartDesign/Gui/Command.cpp +++ b/src/Mod/PartDesign/Gui/Command.cpp @@ -1269,78 +1269,7 @@ void makeChamferOrFillet(Gui::Command* cmd, const std::string& which) return; } - const Part::TopoShape& TopShape = base->Shape.getShape(); - if (TopShape._Shape.IsNull()){ - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("Shape of selected part is empty.")); - return; - } - - TopTools_IndexedMapOfShape mapOfEdges; - TopTools_IndexedDataMapOfShapeListOfShape mapEdgeFace; - TopExp::MapShapesAndAncestors(TopShape._Shape, TopAbs_EDGE, TopAbs_FACE, mapEdgeFace); - TopExp::MapShapes(TopShape._Shape, TopAbs_EDGE, mapOfEdges); - std::vector SubNames = std::vector(selection[0].getSubNames()); - - unsigned int i = 0; - - while(i < SubNames.size()) - { - std::string aSubName = static_cast(SubNames.at(i)); - - if (aSubName.size() > 4 && aSubName.substr(0,4) == "Edge") { - TopoDS_Edge edge = TopoDS::Edge(TopShape.getSubShape(aSubName.c_str())); - const TopTools_ListOfShape& los = mapEdgeFace.FindFromKey(edge); - - if(los.Extent() != 2) - { - SubNames.erase(SubNames.begin()+i); - continue; - } - - const TopoDS_Shape& face1 = los.First(); - const TopoDS_Shape& face2 = los.Last(); - GeomAbs_Shape cont = BRep_Tool::Continuity(TopoDS::Edge(edge), - TopoDS::Face(face1), - TopoDS::Face(face2)); - if (cont != GeomAbs_C0) { - SubNames.erase(SubNames.begin()+i); - continue; - } - - i++; - } - else if(aSubName.size() > 4 && aSubName.substr(0,4) == "Face") { - TopoDS_Face face = TopoDS::Face(TopShape.getSubShape(aSubName.c_str())); - - TopTools_IndexedMapOfShape mapOfFaces; - TopExp::MapShapes(face, TopAbs_EDGE, mapOfFaces); - - for(int j = 1; j <= mapOfFaces.Extent(); ++j) { - TopoDS_Edge edge = TopoDS::Edge(mapOfFaces.FindKey(j)); - - int id = mapOfEdges.FindIndex(edge); - - std::stringstream buf; - buf << "Edge"; - buf << id; - - if(std::find(SubNames.begin(),SubNames.end(),buf.str()) == SubNames.end()) - { - SubNames.push_back(buf.str()); - } - - } - - SubNames.erase(SubNames.begin()+i); - } - // empty name or any other sub-element - else { - SubNames.erase(SubNames.begin()+i); - } - } - if (SubNames.size() == 0) { QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), QString::fromStdString(which) + QObject::tr(" not possible on selected faces/edges.")); diff --git a/src/Mod/PartDesign/Gui/Command.cpp.orig b/src/Mod/PartDesign/Gui/Command.cpp.orig index 0b3d31bff..a71c325d3 100644 --- a/src/Mod/PartDesign/Gui/Command.cpp.orig +++ b/src/Mod/PartDesign/Gui/Command.cpp.orig @@ -48,6 +48,7 @@ #include #include +#include #include #include #include @@ -66,8 +67,6 @@ #include #include #include -#include -#include #include #include #include @@ -75,12 +74,11 @@ #include #include #include - -#include "FeaturePickDialog.h" #include "Workbench.h" using namespace std; +#include "TaskFeaturePick.h" #include "ReferenceSelection.h" //=========================================================================== @@ -97,7 +95,7 @@ CmdPartDesignBody::CmdPartDesignBody() sToolTipText = QT_TR_NOOP("Create a new body feature"); sWhatsThis = sToolTipText; sStatusTip = sToolTipText; - sPixmap = "PartDesign_Body"; + sPixmap = "PartDesign_Body_Create_New"; } void CmdPartDesignBody::activated(int iMsg) @@ -105,48 +103,31 @@ void CmdPartDesignBody::activated(int iMsg) openCommand("Add a body feature"); std::string FeatName = getUniqueObjectName("Body"); - // add the standard planes at the root of the feature tree - // first check if they already exist - // FIXME: If the user renames them, they won't be found... - bool found = false; - std::vector planes = getDocument()->getObjectsOfType(App::Plane::getClassTypeId()); - for (std::vector::const_iterator p = planes.begin(); p != planes.end(); p++) { - for (unsigned i = 0; i < 3; i++) { - if (strcmp(PartDesignGui::BaseplaneNames[i], (*p)->getNameInDocument()) == 0) { - found = true; - break; - } - } - if (found) break; + // first check if Part is already created: + App::Part *actPart = getDocument()->Tip.getValue(); + std::string PartName; + + if(!actPart){ + // if not, creating a part and set it up by calling the appropiated function in Workbench + //if we create a new part we automaticly get a new body, there is no need to create a second one + PartName = getUniqueObjectName("Part"); + doCommand(Doc,"App.activeDocument().Tip = App.activeDocument().addObject('App::Part','%s')",PartName.c_str()); + doCommand(Doc,"App.activeDocument().ActiveObject.Label = '%s'", QObject::tr(PartName.c_str()).toStdString().c_str()); + PartDesignGui::Workbench::setUpPart(dynamic_cast(getDocument()->getObject(PartName.c_str()))); + } else { + PartName = actPart->getNameInDocument(); + // add the Body feature itself, and make it active + doCommand(Doc,"App.activeDocument().addObject('PartDesign::Body','%s')",FeatName.c_str()); + //doCommand(Doc,"App.activeDocument().%s.Model = []",FeatName.c_str()); + //doCommand(Doc,"App.activeDocument().%s.Tip = None",FeatName.c_str()); + addModule(Gui,"PartDesignGui"); // import the Gui module only once a session + doCommand(Gui::Command::Gui, "Gui.activeView().setActiveObject('%s', App.activeDocument().%s)", PDBODYKEY, FeatName.c_str()); + // Make the "Create sketch" prompt appear in the task panel + doCommand(Gui,"Gui.Selection.clearSelection()"); + doCommand(Gui,"Gui.Selection.addSelection(App.ActiveDocument.%s)", FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.addObject(App.ActiveDocument.%s)",PartName.c_str(),FeatName.c_str()); } - if (!found) { - // Add the planes ... - doCommand(Doc,"App.activeDocument().addObject('App::Plane','%s')", PartDesignGui::BaseplaneNames[0]); - doCommand(Doc,"App.activeDocument().ActiveObject.Label = '%s'", QObject::tr("XY-Plane").toStdString().c_str()); - doCommand(Doc,"App.activeDocument().addObject('App::Plane','%s')", PartDesignGui::BaseplaneNames[1]); - doCommand(Doc,"App.activeDocument().ActiveObject.Placement = App.Placement(App.Vector(),App.Rotation(App.Vector(1,0,0),-90))"); - doCommand(Doc,"App.activeDocument().ActiveObject.Label = '%s'", QObject::tr("XZ-Plane").toStdString().c_str()); - doCommand(Doc,"App.activeDocument().addObject('App::Plane','%s')", PartDesignGui::BaseplaneNames[2]); - doCommand(Doc,"App.activeDocument().ActiveObject.Placement = App.Placement(App.Vector(),App.Rotation(App.Vector(0,1,0),90))"); - doCommand(Doc,"App.activeDocument().ActiveObject.Label = '%s'", QObject::tr("YZ-Plane").toStdString().c_str()); - // ... and put them in the 'Origin' group - doCommand(Doc,"App.activeDocument().addObject('App::DocumentObjectGroup','%s')", QObject::tr("Origin").toStdString().c_str()); - for (unsigned i = 0; i < 3; i++) - doCommand(Doc,"App.activeDocument().Origin.addObject(App.activeDocument().getObject('%s'))", PartDesignGui::BaseplaneNames[i]); - // TODO: Fold the group (is that possible through the Python interface?) - } - - // add the Body feature itself, and make it active - doCommand(Doc,"App.activeDocument().addObject('PartDesign::Body','%s')",FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.Model = []",FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.Tip = None",FeatName.c_str()); - doCommand(Doc,"import PartDesignGui"); - doCommand(Gui,"PartDesignGui.setActivePart(App.ActiveDocument.%s)", FeatName.c_str()); - // Make the "Create sketch" prompt appear in the task panel - doCommand(Gui,"Gui.Selection.clearSelection()"); - doCommand(Gui,"Gui.Selection.addSelection(App.ActiveDocument.%s)", FeatName.c_str()); - updateActive(); } @@ -174,7 +155,7 @@ CmdPartDesignMoveTip::CmdPartDesignMoveTip() void CmdPartDesignMoveTip::activated(int iMsg) { - PartDesign::Body *pcActiveBody = PartDesignGui::getBody(); + PartDesign::Body *pcActiveBody = PartDesignGui::getBody(/*messageIfNot = */true); if(!pcActiveBody) return; std::vector features = getSelection().getObjectsOfType(Part::Feature::getClassTypeId()); @@ -192,8 +173,8 @@ void CmdPartDesignMoveTip::activated(int iMsg) // Switch to other body pcActiveBody = static_cast(Part::BodyBase::findBodyOf(selFeature)); if (pcActiveBody != NULL) - Gui::Command::doCommand(Gui::Command::Gui,"PartDesignGui.setActivePart(App.activeDocument().%s)", - pcActiveBody->getNameInDocument()); + Gui::Command::doCommand(Gui::Command::Gui, "Gui.activeView().setActiveObject('%s',App.activeDocument().%s)", + PDBODYKEY, pcActiveBody->getNameInDocument()); else return; } @@ -250,7 +231,7 @@ CmdPartDesignDuplicateSelection::CmdPartDesignDuplicateSelection() void CmdPartDesignDuplicateSelection::activated(int iMsg) { - PartDesign::Body *pcActiveBody = PartDesignGui::getBody(); + PartDesign::Body *pcActiveBody = PartDesignGui::getBody(/*messageIfNot = */true); if(!pcActiveBody) return; std::vector features = getSelection().getObjectsOfType(Part::Feature::getClassTypeId()); @@ -262,19 +243,19 @@ void CmdPartDesignDuplicateSelection::activated(int iMsg) // Switch to other body pcActiveBody = static_cast(Part::BodyBase::findBodyOf(selFeature)); if (pcActiveBody != NULL) - Gui::Command::doCommand(Gui::Command::Gui,"PartDesignGui.setActivePart(App.activeDocument().%s)", - pcActiveBody->getNameInDocument()); + Gui::Command::doCommand(Gui::Command::Gui, "Gui.activeView().setActiveObject('%s', App.activeDocument().%s)", + PDBODYKEY, pcActiveBody->getNameInDocument()); else return; } - std::vector beforeFeatures = PartDesignGui::ActiveAppDoc->getObjects(); + std::vector beforeFeatures = getDocument()->getObjects(); openCommand("Duplicate a PartDesign object"); doCommand(Doc,"FreeCADGui.runCommand('Std_DuplicateSelection')"); // Find the features that were added - std::vector afterFeatures = PartDesignGui::ActiveAppDoc->getObjects(); + std::vector afterFeatures = getDocument()->getObjects(); std::vector newFeatures; std::set_difference(afterFeatures.begin(), afterFeatures.end(), beforeFeatures.begin(), beforeFeatures.end(), std::back_inserter(newFeatures)); @@ -322,7 +303,7 @@ CmdPartDesignMoveFeature::CmdPartDesignMoveFeature() void CmdPartDesignMoveFeature::activated(int iMsg) { - PartDesign::Body *pcActiveBody = PartDesignGui::getBody(); + PartDesign::Body *pcActiveBody = PartDesignGui::getBody(/*messageIfNot = */true); if(!pcActiveBody) return; std::vector features = getSelection().getObjectsOfType(Part::Feature::getClassTypeId()); @@ -402,7 +383,7 @@ CmdPartDesignMoveFeatureInTree::CmdPartDesignMoveFeatureInTree() void CmdPartDesignMoveFeatureInTree::activated(int iMsg) { - PartDesign::Body *pcActiveBody = PartDesignGui::getBody(); + PartDesign::Body *pcActiveBody = PartDesignGui::getBody(/*messageIfNot = */true); if(!pcActiveBody) return; std::vector features = getSelection().getObjectsOfType(Part::Feature::getClassTypeId()); @@ -466,11 +447,19 @@ bool CmdPartDesignMoveFeatureInTree::isActive(void) // PartDesign_Datum //=========================================================================== +/** + * @brief getReferenceString Prepares selection to be fed through Python to a datum feature. + * @param cmd + * @return string representing the selection, in format + * "[(App.activeDocument().Pad,'Vertex8'),(App.activeDocument().Pad,'Vertex9')]". + * Zero-length string if there is no selection, or the selection is + * inappropriate. + */ const QString getReferenceString(Gui::Command* cmd) { QString referenceString; - PartDesign::Body *pcActiveBody = PartDesignGui::getBody(); + PartDesign::Body *pcActiveBody = PartDesignGui::getBody(/*messageIfNot = */false); if(!pcActiveBody) return QString::fromAscii(""); Gui::SelectionFilter GeometryFilter("SELECT Part::Feature SUBELEMENT Face COUNT 1"); @@ -528,79 +517,10 @@ const QString getReferenceString(Gui::Command* cmd) QString::fromAscii(",'')]"); } } - else { - // Get a valid datum feature from the user - std::vector status; - std::vector refs = cmd->getDocument()->getObjectsOfType(App::Plane::getClassTypeId()); - std::vector refstmp = cmd->getDocument()->getObjectsOfType(PartDesign::Plane::getClassTypeId()); - refs.insert(refs.end(), refstmp.begin(), refstmp.end()); - refstmp = cmd->getDocument()->getObjectsOfType(PartDesign::Line::getClassTypeId()); - refs.insert(refs.end(), refstmp.begin(), refstmp.end()); - refstmp = cmd->getDocument()->getObjectsOfType(PartDesign::Point::getClassTypeId()); - refs.insert(refs.end(), refstmp.begin(), refstmp.end()); - - unsigned validRefs = 0; - std::vector chosenRefs; - - for (std::vector::iterator r = refs.begin(); r != refs.end(); r++) { - // Check whether this reference is a base plane - bool base = false; - for (unsigned i = 0; i < 3; i++) { - if (strcmp(PartDesignGui::BaseplaneNames[i], (*r)->getNameInDocument()) == 0) { - status.push_back(PartDesignGui::FeaturePickDialog::basePlane); - if (chosenRefs.empty()) - chosenRefs.push_back(*r); - validRefs++; - base = true; - break; - } - } - if (base) continue; - - // Check whether this reference belongs to the active body - PartDesign::Body* body = PartDesignGui::getBody(); - if (!body->hasFeature(*r)) { - status.push_back(PartDesignGui::FeaturePickDialog::otherBody); - continue; - } else if (body->isAfterTip(*r)) { - status.push_back(PartDesignGui::FeaturePickDialog::afterTip); - continue; - } - - // All checks passed - found a valid reference - if (chosenRefs.empty()) - chosenRefs.push_back(*r); - validRefs++; - status.push_back(PartDesignGui::FeaturePickDialog::validFeature); - } - - if (validRefs == 0) { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid references in this document"), - QObject::tr("Please select a datum feature, or a face, edge or vertex")); - return QString::fromAscii(""); - } - - // If there is more than one possibility, show dialog and let user pick references - if (validRefs > 1) { - PartDesignGui::FeaturePickDialog Dlg(refs, status); - if ((Dlg.exec() != QDialog::Accepted) || (chosenRefs = Dlg.getFeatures()).empty()) - return QString::fromAscii(""); // Cancelled or nothing selected - if (chosenRefs.size() > 3) - Base::Console().Warning("You have chosen more than three references for a datum feature. The extra references are being ignored"); - } - - // TODO: Allow user to choose front or back of the plane - - referenceString = QString::fromAscii("["); - for (int i = 0; i < chosenRefs.size(); i++) { - referenceString += QString::fromAscii(i == 0 ? "" : ",") + - QString::fromAscii("(App.activeDocument().") + QString::fromUtf8(chosenRefs[i]->getNameInDocument()) + - QString::fromAscii(",'front')"); - } - - referenceString += QString::fromAscii("]"); - return referenceString; - } + + //datum features task can start without reference, as every needed one can be set from + //withing the task. + return QString::fromAscii(""); } /* Datum feature commands =======================================================*/ @@ -624,7 +544,9 @@ void CmdPartDesignPlane::activated(int iMsg) // create Datum plane std::string FeatName = getUniqueObjectName("DatumPlane"); QString refStr = getReferenceString(this); - PartDesign::Body *pcActiveBody = PartDesignGui::getBody(); + PartDesign::Body *pcActiveBody = PartDesignGui::getBody(/*messageIfNot = */true); + if (pcActiveBody == 0) + return; openCommand("Create a datum plane"); doCommand(Doc,"App.activeDocument().addObject('PartDesign::Plane','%s')",FeatName.c_str()); @@ -666,7 +588,9 @@ void CmdPartDesignLine::activated(int iMsg) // create Datum line std::string FeatName = getUniqueObjectName("DatumLine"); QString refStr = getReferenceString(this); - PartDesign::Body *pcActiveBody = PartDesignGui::getBody(); + PartDesign::Body *pcActiveBody = PartDesignGui::getBody(/*messageIfNot = */true); + if (pcActiveBody == 0) + return; openCommand("Create a datum line"); doCommand(Doc,"App.activeDocument().addObject('PartDesign::Line','%s')",FeatName.c_str()); @@ -706,7 +630,9 @@ void CmdPartDesignPoint::activated(int iMsg) // create Datum point std::string FeatName = getUniqueObjectName("DatumPoint"); QString refStr = getReferenceString(this); - PartDesign::Body *pcActiveBody = PartDesignGui::getBody(); + PartDesign::Body *pcActiveBody = PartDesignGui::getBody(/*messageIfNot = */true); + if (pcActiveBody == 0) + return; openCommand("Create a datum point"); doCommand(Doc,"App.activeDocument().addObject('PartDesign::Point','%s')",FeatName.c_str()); @@ -749,7 +675,7 @@ CmdPartDesignNewSketch::CmdPartDesignNewSketch() void CmdPartDesignNewSketch::activated(int iMsg) { - PartDesign::Body *pcActiveBody = PartDesignGui::getBody(); + PartDesign::Body *pcActiveBody = PartDesignGui::getBody(/*messageIfNot = */true); // No PartDesign feature without Body past FreeCAD 0.13 if(!pcActiveBody) return; @@ -808,9 +734,18 @@ void CmdPartDesignNewSketch::activated(int iMsg) } if (!pcActiveBody->hasFeature(feat)) { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Selection from other body"), - QObject::tr("You have to select a face or plane from the active body!")); - return; + bool isBasePlane = false; + for (unsigned i = 0; i < 3; i++) { + if (strcmp(App::Part::BaseplaneTypes[i], feat->getNameInDocument()) == 0) { + isBasePlane = true; + break; + } + } + if (!isBasePlane) { + QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Selection from other body"), + QObject::tr("You have to select a face or plane from the active body!")); + return; + } } else if (pcActiveBody->isAfterTip(feat)) { QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Selection from inactive feature"), QObject::tr("You have to select a face or plane before the current insert point, or move the insert point")); @@ -831,7 +766,7 @@ void CmdPartDesignNewSketch::activated(int iMsg) } else { // Get a valid plane from the user - std::vector status; + std::vector status; std::vector planes = getDocument()->getObjectsOfType(App::Plane::getClassTypeId()); std::vector planestmp = getDocument()->getObjectsOfType(PartDesign::Plane::getClassTypeId()); planes.insert(planes.end(), planestmp.begin(), planestmp.end()); @@ -843,8 +778,8 @@ void CmdPartDesignNewSketch::activated(int iMsg) // Check whether this plane is a base plane bool base = false; for (unsigned i = 0; i < 3; i++) { - if (strcmp(PartDesignGui::BaseplaneNames[i], (*p)->getNameInDocument()) == 0) { - status.push_back(PartDesignGui::FeaturePickDialog::basePlane); + if (strcmp(App::Part::BaseplaneTypes[i], (*p)->getNameInDocument()) == 0) { + status.push_back(PartDesignGui::TaskFeaturePick::basePlane); if (firstValidPlane == planes.end()) firstValidPlane = p; validPlanes++; @@ -856,19 +791,20 @@ void CmdPartDesignNewSketch::activated(int iMsg) // Check whether this plane belongs to the active body if (!pcActiveBody->hasFeature(*p)) { - status.push_back(PartDesignGui::FeaturePickDialog::otherBody); + status.push_back(PartDesignGui::TaskFeaturePick::otherBody); continue; } else { - if (pcActiveBody->isAfterTip(*p)) - status.push_back(PartDesignGui::FeaturePickDialog::afterTip); - continue; + if (pcActiveBody->isAfterTip(*p)){ + status.push_back(PartDesignGui::TaskFeaturePick::afterTip); + continue; + } } // All checks passed - found a valid plane if (firstValidPlane == planes.end()) firstValidPlane = p; validPlanes++; - status.push_back(PartDesignGui::FeaturePickDialog::validFeature); + status.push_back(PartDesignGui::TaskFeaturePick::validFeature); } if (validPlanes == 0) { @@ -877,29 +813,58 @@ void CmdPartDesignNewSketch::activated(int iMsg) return; } + auto accepter = [=](const std::vector& features) -> bool { + + if(features.empty()) + return false; + + return true; + }; + + auto worker = [=](const std::vector& features) { + App::Plane* plane = static_cast(features.front()); + std::string FeatName = getUniqueObjectName("Sketch"); + std::string supportString = std::string("(App.activeDocument().") + plane->getNameInDocument() + + ", ['" + (false ? "back" : "front") + "'])"; + + Gui::Command::openCommand("Create a new Sketch"); + Gui::Command::doCommand(Doc,"App.activeDocument().addObject('Sketcher::SketchObject','%s')",FeatName.c_str()); + Gui::Command::doCommand(Doc,"App.activeDocument().%s.Support = %s",FeatName.c_str(),supportString.c_str()); + Gui::Command::updateActive(); // Make sure the Support's Placement property is updated + Gui::Command::doCommand(Doc,"App.activeDocument().%s.addFeature(App.activeDocument().%s)", + pcActiveBody->getNameInDocument(), FeatName.c_str()); + //doCommand(Gui,"Gui.activeDocument().activeView().setCamera('%s')",cam.c_str()); + Gui::Command::doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); + }; + // If there is more than one possibility, show dialog and let user pick plane bool reversed = false; if (validPlanes > 1) { - PartDesignGui::FeaturePickDialog Dlg(planes, status); - if ((Dlg.exec() != QDialog::Accepted) || (planes = Dlg.getFeatures()).empty()) - return; // Cancelled or nothing selected - firstValidPlane = planes.begin(); - reversed = Dlg.getReverse(); + + Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog(); + PartDesignGui::TaskDlgFeaturePick *pickDlg = qobject_cast(dlg); + if (dlg && !pickDlg) { + QMessageBox msgBox; + msgBox.setText(QObject::tr("A dialog is already open in the task panel")); + msgBox.setInformativeText(QObject::tr("Do you want to close this dialog?")); + msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + msgBox.setDefaultButton(QMessageBox::Yes); + int ret = msgBox.exec(); + if (ret == QMessageBox::Yes) + Gui::Control().closeDialog(); + else + return; + } + + if(dlg) + Gui::Control().closeDialog(); + + Gui::Selection().clearSelection(); + Gui::Control().showDialog(new PartDesignGui::TaskDlgFeaturePick(planes, status, accepter, worker)); + } + else { + worker(planes); } - - App::Plane* plane = static_cast(*firstValidPlane); - std::string FeatName = getUniqueObjectName("Sketch"); - std::string supportString = std::string("(App.activeDocument().") + plane->getNameInDocument() + - ", ['" + (reversed ? "back" : "front") + "'])"; - - openCommand("Create a new Sketch"); - doCommand(Doc,"App.activeDocument().addObject('Sketcher::SketchObject','%s')",FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.Support = %s",FeatName.c_str(),supportString.c_str()); - updateActive(); // Make sure the Support's Placement property is updated - doCommand(Doc,"App.activeDocument().%s.addFeature(App.activeDocument().%s)", - pcActiveBody->getNameInDocument(), FeatName.c_str()); - //doCommand(Gui,"Gui.activeDocument().activeView().setCamera('%s')",cam.c_str()); - doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); } } @@ -917,7 +882,9 @@ bool CmdPartDesignNewSketch::isActive(void) void finishFeature(const Gui::Command* cmd, const std::string& FeatName, const bool hidePrevSolid = true) { - PartDesign::Body *pcActiveBody = PartDesignGui::getBody(); + PartDesign::Body *pcActiveBody = PartDesignGui::getBody(/*messageIfNot = */false); + if (pcActiveBody == 0) + throw Base::Exception("No active body!"); cmd->doCommand(cmd->Doc,"App.activeDocument().%s.addFeature(App.activeDocument().%s)", pcActiveBody->getNameInDocument(), FeatName.c_str()); @@ -948,7 +915,7 @@ void finishFeature(const Gui::Command* cmd, const std::string& FeatName, const b // Take a list of Part2DObjects and erase those which are not eligible for creating a // SketchBased feature. const unsigned validateSketches(std::vector& sketches, - std::vector& status, + std::vector& status, std::vector::iterator& firstValidSketch) { // TODO: If the user previously opted to allow multiple use of sketches or use of sketches from other bodies, @@ -970,14 +937,14 @@ void finishFeature(const Gui::Command* cmd, const std::string& FeatName, const b ++o; } if (inList.size() > 0) { - status.push_back(PartDesignGui::FeaturePickDialog::isUsed); + status.push_back(PartDesignGui::TaskFeaturePick::isUsed); continue; } // Check whether this sketch belongs to the active body - PartDesign::Body* body = PartDesignGui::getBody(); + PartDesign::Body* body = PartDesignGui::getBody(/*messageIfNot = */false); if (!body->hasFeature(*s)) { - status.push_back(PartDesignGui::FeaturePickDialog::otherBody); + status.push_back(PartDesignGui::TaskFeaturePick::otherBody); continue; } @@ -985,7 +952,7 @@ void finishFeature(const Gui::Command* cmd, const std::string& FeatName, const b Part::Part2DObject* sketch = static_cast(*s); const TopoDS_Shape& shape = sketch->Shape.getValue(); if (shape.IsNull()) { - status.push_back(PartDesignGui::FeaturePickDialog::invalidShape); + status.push_back(PartDesignGui::TaskFeaturePick::invalidShape); continue; } @@ -996,7 +963,7 @@ void finishFeature(const Gui::Command* cmd, const std::string& FeatName, const b ctWires++; } if (ctWires == 0) { - status.push_back(PartDesignGui::FeaturePickDialog::noWire); + status.push_back(PartDesignGui::TaskFeaturePick::noWire); continue; } @@ -1004,21 +971,21 @@ void finishFeature(const Gui::Command* cmd, const std::string& FeatName, const b if (firstValidSketch == sketches.end()) firstValidSketch = s; validSketches++; - status.push_back(PartDesignGui::FeaturePickDialog::validFeature); + status.push_back(PartDesignGui::TaskFeaturePick::validFeature); } return validSketches; } -void prepareSketchBased(Gui::Command* cmd, const std::string& which, Part::Part2DObject*& sketch, std::string& FeatName) +void prepareSketchBased(Gui::Command* cmd, const std::string& which, + boost::function func) { - PartDesign::Body *pcActiveBody = PartDesignGui::getBody(); + PartDesign::Body *pcActiveBody = PartDesignGui::getBody(/*messageIfNot = */true); if (!pcActiveBody) return; // Get a valid sketch from the user // First check selections - FeatName = ""; // Empty string means prepareSketchBased() was not successful - std::vector status; + std::vector status; std::vector::iterator firstValidSketch; std::vector sketches = cmd->getSelection().getObjectsOfType(Part::Part2DObject::getClassTypeId()); // Next let the user choose from a list of all eligible objects @@ -1033,23 +1000,61 @@ void prepareSketchBased(Gui::Command* cmd, const std::string& which, Part::Part2 return; } } + + auto accepter = [=](const std::vector& features) -> bool { + + if(features.empty()) + return false; + + return true; + }; + + auto worker = [which, cmd, func](std::vector features) { + + auto firstValidSketch = features.begin(); + Part::Part2DObject* sketch = static_cast(*firstValidSketch); + + std::string FeatName = cmd->getUniqueObjectName(which.c_str()); + + Gui::Command::openCommand((std::string("Make ") + which).c_str()); + Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().addObject(\"PartDesign::%s\",\"%s\")", + which.c_str(), FeatName.c_str()); + Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.Sketch = App.activeDocument().%s", + FeatName.c_str(), sketch->getNameInDocument()); + //Gui::Command::doCommand(cmd->Doc,"App.activeDocument().%s.addFeature(App.activeDocument().%s)", + // pcActiveBody->getNameInDocument(), FeatName.c_str()); + + func(sketch, FeatName); + }; + // If there is more than one selection/possibility, show dialog and let user pick sketch if (validSketches > 1) { - PartDesignGui::FeaturePickDialog Dlg(sketches, status); - if ((Dlg.exec() != QDialog::Accepted) || (sketches = Dlg.getFeatures()).empty()) - return; // Cancelled or nothing selected - firstValidSketch = sketches.begin(); + + Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog(); + PartDesignGui::TaskDlgFeaturePick *pickDlg = qobject_cast(dlg); + if (dlg && !pickDlg) { + QMessageBox msgBox; + msgBox.setText(QObject::tr("A dialog is already open in the task panel")); + msgBox.setInformativeText(QObject::tr("Do you want to close this dialog?")); + msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + msgBox.setDefaultButton(QMessageBox::Yes); + int ret = msgBox.exec(); + if (ret == QMessageBox::Yes) + Gui::Control().closeDialog(); + else + return; + } + + if(dlg) + Gui::Control().closeDialog(); + + Gui::Selection().clearSelection(); + Gui::Control().showDialog(new PartDesignGui::TaskDlgFeaturePick(sketches, status, accepter, worker)); } - - sketch = static_cast(*firstValidSketch); - - FeatName = cmd->getUniqueObjectName(which.c_str()); - - cmd->openCommand((std::string("Make ") + which).c_str()); - cmd->doCommand(cmd->Doc,"App.activeDocument().addObject(\"PartDesign::%s\",\"%s\")", - which.c_str(), FeatName.c_str()); - cmd->doCommand(cmd->Doc,"App.activeDocument().%s.Sketch = App.activeDocument().%s", - FeatName.c_str(), sketch->getNameInDocument()); + else { + worker(sketches); + } + } void finishSketchBased(const Gui::Command* cmd, const Part::Part2DObject* sketch, const std::string& FeatName) @@ -1078,17 +1083,28 @@ CmdPartDesignPad::CmdPartDesignPad() } void CmdPartDesignPad::activated(int iMsg) -{ - Part::Part2DObject* sketch; - std::string FeatName; - prepareSketchBased(this, "Pad", sketch, FeatName); - if (FeatName.empty()) return; +{ + Gui::Command* cmd = this; + auto worker = [cmd](Part::Part2DObject* sketch, std::string FeatName) { + + if (FeatName.empty()) return; + + // specific parameters for Pad + Gui::Command::doCommand(Doc,"App.activeDocument().%s.Length = 10.0",FeatName.c_str()); + App::DocumentObjectGroup* grp = sketch->getGroup(); + if (grp) { + Gui::Command::doCommand(Doc,"App.activeDocument().%s.addObject(App.activeDocument().%s)" + ,grp->getNameInDocument(),FeatName.c_str()); + Gui::Command::doCommand(Doc,"App.activeDocument().%s.removeObject(App.activeDocument().%s)" + ,grp->getNameInDocument(),sketch->getNameInDocument()); + } + Gui::Command::updateActive(); - // specific parameters for Pad - doCommand(Doc,"App.activeDocument().%s.Length = 10.0",FeatName.c_str()); - - finishSketchBased(this, sketch, FeatName); - adjustCameraPosition(); + finishSketchBased(cmd, sketch, FeatName); + //adjustCameraPosition(); + }; + + prepareSketchBased(this, "Pad", worker); } bool CmdPartDesignPad::isActive(void) @@ -1115,15 +1131,17 @@ CmdPartDesignPocket::CmdPartDesignPocket() void CmdPartDesignPocket::activated(int iMsg) { - Part::Part2DObject* sketch; - std::string FeatName; - prepareSketchBased(this, "Pocket", sketch, FeatName); - if (FeatName.empty()) return; - - doCommand(Doc,"App.activeDocument().%s.Length = 5.0",FeatName.c_str()); - - finishSketchBased(this, sketch, FeatName); - adjustCameraPosition(); + Gui::Command* cmd = this; + auto worker = [cmd](Part::Part2DObject* sketch, std::string FeatName) { + + if (FeatName.empty()) return; + + Gui::Command::doCommand(Doc,"App.activeDocument().%s.Length = 5.0",FeatName.c_str()); + finishSketchBased(cmd, sketch, FeatName); + //adjustCameraPosition(); + }; + + prepareSketchBased(this, "Pocket", worker); } bool CmdPartDesignPocket::isActive(void) @@ -1150,20 +1168,23 @@ CmdPartDesignRevolution::CmdPartDesignRevolution() void CmdPartDesignRevolution::activated(int iMsg) { - Part::Part2DObject* sketch; - std::string FeatName; - prepareSketchBased(this, "Revolution", sketch, FeatName); - if (FeatName.empty()) return; + Gui::Command* cmd = this; + auto worker = [cmd](Part::Part2DObject* sketch, std::string FeatName) { + + if (FeatName.empty()) return; - doCommand(Doc,"App.activeDocument().%s.ReferenceAxis = (App.activeDocument().%s,['V_Axis'])", - FeatName.c_str(), sketch->getNameInDocument()); - doCommand(Doc,"App.activeDocument().%s.Angle = 360.0",FeatName.c_str()); - PartDesign::Revolution* pcRevolution = static_cast(getDocument()->getObject(FeatName.c_str())); - if (pcRevolution && pcRevolution->suggestReversed()) - doCommand(Doc,"App.activeDocument().%s.Reversed = 1",FeatName.c_str()); - - finishSketchBased(this, sketch, FeatName); - adjustCameraPosition(); + Gui::Command::doCommand(Doc,"App.activeDocument().%s.ReferenceAxis = (App.activeDocument().%s,['V_Axis'])", + FeatName.c_str(), sketch->getNameInDocument()); + Gui::Command::doCommand(Doc,"App.activeDocument().%s.Angle = 360.0",FeatName.c_str()); + PartDesign::Revolution* pcRevolution = static_cast(cmd->getDocument()->getObject(FeatName.c_str())); + if (pcRevolution && pcRevolution->suggestReversed()) + Gui::Command::doCommand(Doc,"App.activeDocument().%s.Reversed = 1",FeatName.c_str()); + + finishSketchBased(cmd, sketch, FeatName); + //adjustCameraPosition(); + }; + + prepareSketchBased(this, "Revolution", worker); } bool CmdPartDesignRevolution::isActive(void) @@ -1189,21 +1210,24 @@ CmdPartDesignGroove::CmdPartDesignGroove() } void CmdPartDesignGroove::activated(int iMsg) -{ - Part::Part2DObject* sketch; - std::string FeatName; - prepareSketchBased(this, "Groove", sketch, FeatName); - if (FeatName.empty()) return; +{ + Gui::Command* cmd = this; + auto worker = [cmd](Part::Part2DObject* sketch, std::string FeatName) { + + if (FeatName.empty()) return; - doCommand(Doc,"App.activeDocument().%s.ReferenceAxis = (App.activeDocument().%s,['V_Axis'])", + Gui::Command::doCommand(Doc,"App.activeDocument().%s.ReferenceAxis = (App.activeDocument().%s,['V_Axis'])", FeatName.c_str(), sketch->getNameInDocument()); - doCommand(Doc,"App.activeDocument().%s.Angle = 360.0",FeatName.c_str()); - PartDesign::Groove* pcGroove = static_cast(getDocument()->getObject(FeatName.c_str())); - if (pcGroove && pcGroove->suggestReversed()) - doCommand(Doc,"App.activeDocument().%s.Reversed = 1",FeatName.c_str()); + Gui::Command::doCommand(Doc,"App.activeDocument().%s.Angle = 360.0",FeatName.c_str()); + PartDesign::Groove* pcGroove = static_cast(cmd->getDocument()->getObject(FeatName.c_str())); + if (pcGroove && pcGroove->suggestReversed()) + Gui::Command::doCommand(Doc,"App.activeDocument().%s.Reversed = 1",FeatName.c_str()); - finishSketchBased(this, sketch, FeatName); - adjustCameraPosition(); + finishSketchBased(cmd, sketch, FeatName); + //adjustCameraPosition(); + }; + + prepareSketchBased(this, "Groove", worker); } bool CmdPartDesignGroove::isActive(void) @@ -1217,7 +1241,7 @@ bool CmdPartDesignGroove::isActive(void) void makeChamferOrFillet(Gui::Command* cmd, const std::string& which) { - PartDesign::Body *pcActiveBody = PartDesignGui::getBody(); + PartDesign::Body *pcActiveBody = PartDesignGui::getBody(/*messageIfNot = */false); if (!pcActiveBody) return; @@ -1228,6 +1252,8 @@ void makeChamferOrFillet(Gui::Command* cmd, const std::string& which) QObject::tr("Select an edge, face or body. Only one body is allowed.")); return; } + + Gui::Selection().clearSelection(); if (!selection[0].isObjectTypeOf(Part::Feature::getClassTypeId())){ QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong object type"), @@ -1243,6 +1269,7 @@ void makeChamferOrFillet(Gui::Command* cmd, const std::string& which) return; } +<<<<<<< 2c7cc8276bd6dd4ccc4aa28daa809a688bd493c5 const Part::TopoShape& TopShape = base->Shape.getShape(); if (TopShape._Shape.IsNull()){ QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), @@ -1255,66 +1282,9 @@ void makeChamferOrFillet(Gui::Command* cmd, const std::string& which) TopExp::MapShapesAndAncestors(TopShape._Shape, TopAbs_EDGE, TopAbs_FACE, mapEdgeFace); TopExp::MapShapes(TopShape._Shape, TopAbs_EDGE, mapOfEdges); +======= +>>>>>>> allow to add faces to fillet and chamfer std::vector SubNames = std::vector(selection[0].getSubNames()); - - unsigned int i = 0; - - while(i < SubNames.size()) - { - std::string aSubName = static_cast(SubNames.at(i)); - - if (aSubName.size() > 4 && aSubName.substr(0,4) == "Edge") { - TopoDS_Edge edge = TopoDS::Edge(TopShape.getSubShape(aSubName.c_str())); - const TopTools_ListOfShape& los = mapEdgeFace.FindFromKey(edge); - - if(los.Extent() != 2) - { - SubNames.erase(SubNames.begin()+i); - continue; - } - - const TopoDS_Shape& face1 = los.First(); - const TopoDS_Shape& face2 = los.Last(); - GeomAbs_Shape cont = BRep_Tool::Continuity(TopoDS::Edge(edge), - TopoDS::Face(face1), - TopoDS::Face(face2)); - if (cont != GeomAbs_C0) { - SubNames.erase(SubNames.begin()+i); - continue; - } - - i++; - } - else if(aSubName.size() > 4 && aSubName.substr(0,4) == "Face") { - TopoDS_Face face = TopoDS::Face(TopShape.getSubShape(aSubName.c_str())); - - TopTools_IndexedMapOfShape mapOfFaces; - TopExp::MapShapes(face, TopAbs_EDGE, mapOfFaces); - - for(int j = 1; j <= mapOfFaces.Extent(); ++j) { - TopoDS_Edge edge = TopoDS::Edge(mapOfFaces.FindKey(j)); - - int id = mapOfEdges.FindIndex(edge); - - std::stringstream buf; - buf << "Edge"; - buf << id; - - if(std::find(SubNames.begin(),SubNames.end(),buf.str()) == SubNames.end()) - { - SubNames.push_back(buf.str()); - } - - } - - SubNames.erase(SubNames.begin()+i); - } - // empty name or any other sub-element - else { - SubNames.erase(SubNames.begin()+i); - } - } - if (SubNames.size() == 0) { QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), QString::fromStdString(which) + QObject::tr(" not possible on selected faces/edges.")); @@ -1419,7 +1389,7 @@ CmdPartDesignDraft::CmdPartDesignDraft() void CmdPartDesignDraft::activated(int iMsg) { - PartDesign::Body *pcActiveBody = PartDesignGui::getBody(); + PartDesign::Body *pcActiveBody = PartDesignGui::getBody(/*messageIfNot = */true); if (!pcActiveBody) return; std::vector selection = getSelection().getSelectionEx(); @@ -1517,61 +1487,82 @@ bool CmdPartDesignDraft::isActive(void) // Common functions for all Transformed features //=========================================================================== -void prepareTransformed(Gui::Command* cmd, const std::string& which, - std::vector& features, std::string& FeatName, - std::vector& selList, std::string& selNames) +void prepareTransformed(Gui::Command* cmd, const std::string& which, + boost::function)> func) { + std::string FeatName = cmd->getUniqueObjectName(which.c_str()); + + auto accepter = [=](std::vector features) -> bool{ + + if(features.empty()) + return false; + + return true; + }; + + auto worker = [=](std::vector features) { + std::stringstream str; + str << "App.activeDocument()." << FeatName << ".Originals = ["; + for (std::vector::iterator it = features.begin(); it != features.end(); ++it){ + str << "App.activeDocument()." << (*it)->getNameInDocument() << ","; + } + str << "]"; + + Gui::Command::openCommand((std::string("Make ") + which + " feature").c_str()); + Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().addObject(\"PartDesign::%s\",\"%s\")",which.c_str(), FeatName.c_str()); + // FIXME: There seems to be kind of a race condition here, leading to sporadic errors like + // Exception (Thu Sep 6 11:52:01 2012): 'App.Document' object has no attribute 'Mirrored' + Gui::Command::updateActive(); // Helps to ensure that the object already exists when the next command comes up + Gui::Command::doCommand(Gui::Command::Doc, str.str().c_str()); + + func(FeatName, features); + }; + // Get a valid original from the user // First check selections - features = cmd->getSelection().getObjectsOfType(PartDesign::Additive::getClassTypeId()); - std::vector subtractive = cmd->getSelection().getObjectsOfType(PartDesign::Subtractive::getClassTypeId()); - features.insert(features.end(), subtractive.begin(), subtractive.end()); + std::vector features = cmd->getSelection().getObjectsOfType(PartDesign::FeatureAddSub::getClassTypeId()); // Next create a list of all eligible objects if (features.size() == 0) { - features = cmd->getDocument()->getObjectsOfType(PartDesign::Additive::getClassTypeId()); - subtractive = cmd->getDocument()->getObjectsOfType(PartDesign::Subtractive::getClassTypeId()); - features.insert(features.end(), subtractive.begin(), subtractive.end()); + features = cmd->getDocument()->getObjectsOfType(PartDesign::FeatureAddSub::getClassTypeId()); // If there is more than one selected or eligible object, show dialog and let user pick one if (features.size() > 1) { - std::vector status; + std::vector status; for (unsigned i = 0; i < features.size(); i++) - status.push_back(PartDesignGui::FeaturePickDialog::validFeature); - PartDesignGui::FeaturePickDialog Dlg(features, status); - if ((Dlg.exec() != QDialog::Accepted) || (features = Dlg.getFeatures()).empty()) { - features.clear(); - return; // Cancelled or nothing selected + status.push_back(PartDesignGui::TaskFeaturePick::validFeature); + + Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog(); + PartDesignGui::TaskDlgFeaturePick *pickDlg = qobject_cast(dlg); + if (dlg && !pickDlg) { + QMessageBox msgBox; + msgBox.setText(QObject::tr("A dialog is already open in the task panel")); + msgBox.setInformativeText(QObject::tr("Do you want to close this dialog?")); + msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + msgBox.setDefaultButton(QMessageBox::Yes); + int ret = msgBox.exec(); + if (ret == QMessageBox::Yes) + Gui::Control().closeDialog(); + else + return; } + + if(dlg) + Gui::Control().closeDialog(); + + Gui::Selection().clearSelection(); + Gui::Control().showDialog(new PartDesignGui::TaskDlgFeaturePick(features, status, accepter, worker)); } else { QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No valid features in this document"), QObject::tr("Please create a subtractive or additive feature first.")); return; } } - - FeatName = cmd->getUniqueObjectName(which.c_str()); - - std::stringstream str; - str << "App.activeDocument()." << FeatName << ".Originals = ["; - for (std::vector::iterator it = features.begin(); it != features.end(); ++it){ - str << "App.activeDocument()." << (*it)->getNameInDocument() << ","; - selList.push_back((*it)->getNameInDocument()); + else { + worker(features); } - str << "]"; - selNames = str.str(); - - cmd->openCommand((std::string("Make ") + which + " feature").c_str()); - cmd->doCommand(cmd->Doc,"App.activeDocument().addObject(\"PartDesign::%s\",\"%s\")",which.c_str(), FeatName.c_str()); - // FIXME: There seems to be kind of a race condition here, leading to sporadic errors like - // Exception (Thu Sep 6 11:52:01 2012): 'App.Document' object has no attribute 'Mirrored' - cmd->updateActive(); // Helps to ensure that the object already exists when the next command comes up - cmd->doCommand(cmd->Doc,selNames.c_str()); } -void finishTransformed(Gui::Command* cmd, std::string& FeatName, std::vector& selList) +void finishTransformed(Gui::Command* cmd, std::string& FeatName) { - //for (std::vector::iterator it = selList.begin(); it != selList.end(); ++it) - // cmd->doCommand(cmd->Gui,"Gui.activeDocument().%s.Visibility=False",it->c_str()); - finishFeature(cmd, FeatName); } @@ -1594,19 +1585,27 @@ CmdPartDesignMirrored::CmdPartDesignMirrored() void CmdPartDesignMirrored::activated(int iMsg) { - std::string FeatName, selNames; - std::vector features; - std::vector selList; - prepareTransformed(this, "Mirrored", features, FeatName, selList, selNames); - if (features.empty()) + Gui::Command* cmd = this; + auto worker = [cmd](std::string FeatName, std::vector features) { + + if (features.empty()) return; + + if(features.front()->isDerivedFrom(PartDesign::SketchBased::getClassTypeId())) { + Part::Part2DObject *sketch = (static_cast(features.front()))->getVerifiedSketch(); + if (sketch) + Gui::Command::doCommand(Doc,"App.activeDocument().%s.MirrorPlane = (App.activeDocument().%s, [\"V_Axis\"])", + FeatName.c_str(), sketch->getNameInDocument()); + } + else { + doCommand(Doc,"App.activeDocument().%s.MirrorPlane = (App.activeDocument().%s, [\"\"])", FeatName.c_str(), + App::Part::BaseplaneTypes[0]); + } - Part::Part2DObject *sketch = (static_cast(features.front()))->getVerifiedSketch(); - if (sketch) - doCommand(Doc,"App.activeDocument().%s.MirrorPlane = (App.activeDocument().%s, [\"V_Axis\"])", - FeatName.c_str(), sketch->getNameInDocument()); - - finishTransformed(this, FeatName, selList); + finishTransformed(cmd, FeatName); + }; + + prepareTransformed(this, "Mirrored", worker); } bool CmdPartDesignMirrored::isActive(void) @@ -1633,21 +1632,28 @@ CmdPartDesignLinearPattern::CmdPartDesignLinearPattern() void CmdPartDesignLinearPattern::activated(int iMsg) { - std::string FeatName, selNames; - std::vector features; - std::vector selList; - prepareTransformed(this, "LinearPattern", features, FeatName, selList, selNames); - if (features.empty()) - return; + Gui::Command* cmd = this; + auto worker = [cmd](std::string FeatName, std::vector features) { + + if (features.empty()) + return; - Part::Part2DObject *sketch = (static_cast(features.front()))->getVerifiedSketch(); - if (sketch) - doCommand(Doc,"App.activeDocument().%s.Direction = (App.activeDocument().%s, [\"H_Axis\"])", - FeatName.c_str(), sketch->getNameInDocument()); - doCommand(Doc,"App.activeDocument().%s.Length = 100", FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.Occurrences = 2", FeatName.c_str()); + if(features.front()->isDerivedFrom(PartDesign::SketchBased::getClassTypeId())) { + Part::Part2DObject *sketch = (static_cast(features.front()))->getVerifiedSketch(); + if (sketch) + doCommand(Doc,"App.activeDocument().%s.Direction = (App.activeDocument().%s, [\"H_Axis\"])", + FeatName.c_str(), sketch->getNameInDocument()); + } + else { + doCommand(Doc,"App.activeDocument().%s.Direction = (App.activeDocument().%s, [\"\"])", FeatName.c_str(), + App::Part::BaselineTypes[0]); + } + doCommand(Doc,"App.activeDocument().%s.Length = 100", FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.Occurrences = 2", FeatName.c_str()); - finishTransformed(this, FeatName, selList); + finishTransformed(cmd, FeatName); + }; + prepareTransformed(this, "LinearPattern", worker); } bool CmdPartDesignLinearPattern::isActive(void) @@ -1673,22 +1679,31 @@ CmdPartDesignPolarPattern::CmdPartDesignPolarPattern() } void CmdPartDesignPolarPattern::activated(int iMsg) -{ - std::string FeatName, selNames; - std::vector features; - std::vector selList; - prepareTransformed(this, "PolarPattern", features, FeatName, selList, selNames); - if (features.empty()) - return; +{ + Gui::Command* cmd = this; + auto worker = [cmd](std::string FeatName, std::vector features) { + + if (features.empty()) + return; + + if(features.front()->isDerivedFrom(PartDesign::SketchBased::getClassTypeId())) { + Part::Part2DObject *sketch = (static_cast(features.front()))->getVerifiedSketch(); + if (sketch) + doCommand(Doc,"App.activeDocument().%s.Axis = (App.activeDocument().%s, [\"N_Axis\"])", + FeatName.c_str(), sketch->getNameInDocument()); + } + else { + doCommand(Doc,"App.activeDocument().%s.Axis = (App.activeDocument().%s, [\"\"])", FeatName.c_str(), + App::Part::BaselineTypes[0]); + } + + doCommand(Doc,"App.activeDocument().%s.Angle = 360", FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.Occurrences = 2", FeatName.c_str()); - Part::Part2DObject *sketch = (static_cast(features.front()))->getVerifiedSketch(); - if (sketch) - doCommand(Doc,"App.activeDocument().%s.Axis = (App.activeDocument().%s, [\"N_Axis\"])", - FeatName.c_str(), sketch->getNameInDocument()); - doCommand(Doc,"App.activeDocument().%s.Angle = 360", FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.Occurrences = 2", FeatName.c_str()); - - finishTransformed(this, FeatName, selList); + finishTransformed(cmd, FeatName); + }; + + prepareTransformed(this, "PolarPattern", worker); } bool CmdPartDesignPolarPattern::isActive(void) @@ -1714,18 +1729,20 @@ CmdPartDesignScaled::CmdPartDesignScaled() } void CmdPartDesignScaled::activated(int iMsg) -{ - std::string FeatName, selNames; - std::vector features; - std::vector selList; - prepareTransformed(this, "Scaled", features, FeatName, selList, selNames); - if (features.empty()) +{ + Gui::Command* cmd = this; + auto worker = [cmd](std::string FeatName, std::vector features) { + + if (features.empty()) return; + + doCommand(Doc,"App.activeDocument().%s.Factor = 2", FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.Occurrences = 2", FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.Factor = 2", FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.Occurrences = 2", FeatName.c_str()); - - finishTransformed(this, FeatName, selList); + finishTransformed(cmd, FeatName); + }; + + prepareTransformed(this, "Scaled", worker); } bool CmdPartDesignScaled::isActive(void) @@ -1743,11 +1760,7 @@ CmdPartDesignMultiTransform::CmdPartDesignMultiTransform() { sAppModule = "PartDesign"; sGroup = QT_TR_NOOP("PartDesign"); -<<<<<<< 7296e4f7ad6f07270ba640d4816ec51e5a23b2c9 - sMenuText = QT_TR_NOOP("MultiTransform"); -======= sMenuText = QT_TR_NOOP("Create MultiTransform"); ->>>>>>> Allow transforming a Pattern feature into a MultiTransform feature sToolTipText = QT_TR_NOOP("Create a multitransform feature"); sWhatsThis = "PartDesign_MultiTransform"; sStatusTip = sToolTipText; @@ -1756,7 +1769,7 @@ CmdPartDesignMultiTransform::CmdPartDesignMultiTransform() void CmdPartDesignMultiTransform::activated(int iMsg) { - PartDesign::Body *pcActiveBody = PartDesignGui::getBody(); + PartDesign::Body *pcActiveBody = PartDesignGui::getBody(/*messageIfNot = */true); if (!pcActiveBody) return; std::vector features; @@ -1807,27 +1820,24 @@ void CmdPartDesignMultiTransform::activated(int iMsg) Gui::Selection().clearSelection(); } // otherwise the insert point remains at the new MultiTransform, which is fine } else { - std::string FeatName, selNames; - std::vector selList; - prepareTransformed(this, "MultiTransform", features, FeatName, selList, selNames); - if (features.empty()) - return; + + Gui::Command* cmd = this; + auto worker = [cmd, pcActiveBody](std::string FeatName, std::vector features) { + + if (features.empty()) + return; - PartDesign::Body *pcActiveBody = PartDesignGui::getBody(); - if (!pcActiveBody) - return; - updateActive(); - doCommand(Doc,selNames.c_str()); - - // Make sure the user isn't presented with an empty screen because no transformations are defined yet... - App::DocumentObject* prevSolid = pcActiveBody->getPrevSolidFeature(NULL, true); - if (prevSolid != NULL) { - Part::Feature* feat = static_cast(prevSolid); - doCommand(Doc,"App.activeDocument().%s.Shape = App.activeDocument().%s.Shape", - FeatName.c_str(), feat->getNameInDocument()); - } - - finishFeature(this, FeatName); + // Make sure the user isn't presented with an empty screen because no transformations are defined yet... + App::DocumentObject* prevSolid = pcActiveBody->getPrevSolidFeature(NULL, true); + if (prevSolid != NULL) { + Part::Feature* feat = static_cast(prevSolid); + doCommand(Doc,"App.activeDocument().%s.Shape = App.activeDocument().%s.Shape", + FeatName.c_str(), feat->getNameInDocument()); + } + finishFeature(cmd, FeatName); + }; + + prepareTransformed(this, "MultiTransform", worker); } } @@ -1881,8 +1891,9 @@ void CmdPartDesignBoolean::activated(int iMsg) openCommand("Create Boolean"); + PartDesign::Body* activeBody = Gui::Application::Instance->activeView()->getActiveObject(PDBODYKEY); // Make sure we are working on the selected body - if (body != PartDesignGui::ActivePartObject) { + if (body != activeBody) { Gui::Selection().clearSelection(); Gui::Selection().addSelection(body->getDocument()->getName(), body->Tip.getValue()->getNameInDocument()); Gui::Command::doCommand(Gui::Command::Gui,"FreeCADGui.runCommand('PartDesign_MoveTip')"); diff --git a/src/Mod/PartDesign/Gui/TaskChamferParameters.cpp b/src/Mod/PartDesign/Gui/TaskChamferParameters.cpp index 9e9d9351f..e9c06b54b 100644 --- a/src/Mod/PartDesign/Gui/TaskChamferParameters.cpp +++ b/src/Mod/PartDesign/Gui/TaskChamferParameters.cpp @@ -51,7 +51,7 @@ using namespace Gui; /* TRANSLATOR PartDesignGui::TaskChamferParameters */ TaskChamferParameters::TaskChamferParameters(ViewProviderDressUp *DressUpView,QWidget *parent) - : TaskDressUpParameters(DressUpView, parent) + : TaskDressUpParameters(DressUpView, true, true, parent) { // we need a separate container widget to add all controls to proxy = new QWidget(this); diff --git a/src/Mod/PartDesign/Gui/TaskDraftParameters.cpp b/src/Mod/PartDesign/Gui/TaskDraftParameters.cpp index 65702bea7..7b9b7c4f5 100644 --- a/src/Mod/PartDesign/Gui/TaskDraftParameters.cpp +++ b/src/Mod/PartDesign/Gui/TaskDraftParameters.cpp @@ -51,7 +51,7 @@ using namespace Gui; /* TRANSLATOR PartDesignGui::TaskDraftParameters */ TaskDraftParameters::TaskDraftParameters(ViewProviderDressUp *DressUpView,QWidget *parent) - : TaskDressUpParameters(DressUpView, parent) + : TaskDressUpParameters(DressUpView, false, true, parent) { // we need a separate container widget to add all controls to proxy = new QWidget(this); diff --git a/src/Mod/PartDesign/Gui/TaskDressUpParameters.cpp b/src/Mod/PartDesign/Gui/TaskDressUpParameters.cpp index 1ce79c32f..b41e8bb9a 100644 --- a/src/Mod/PartDesign/Gui/TaskDressUpParameters.cpp +++ b/src/Mod/PartDesign/Gui/TaskDressUpParameters.cpp @@ -50,8 +50,9 @@ using namespace Gui; /* TRANSLATOR PartDesignGui::TaskDressUpParameters */ -TaskDressUpParameters::TaskDressUpParameters(ViewProviderDressUp *DressUpView,QWidget *parent) - : TaskBox(Gui::BitmapFactory().pixmap((std::string("PartDesign_") + DressUpView->featureName).c_str()), +TaskDressUpParameters::TaskDressUpParameters(ViewProviderDressUp *DressUpView, bool selectEdges, bool selectFaces, QWidget *parent) + : allowFaces(selectFaces), allowEdges(selectEdges), + TaskBox(Gui::BitmapFactory().pixmap((std::string("PartDesign_") + DressUpView->featureName).c_str()), QString::fromAscii((DressUpView->featureName + " parameters").c_str()), true, parent), @@ -113,9 +114,7 @@ void TaskDressUpParameters::onButtonRefAdd(bool checked) hideObject(); selectionMode = refAdd; Gui::Selection().clearSelection(); - bool edge = (DressUpView->featureName != "Draft"); - bool face = (DressUpView->featureName == "Draft"); - Gui::Selection().addSelectionGate(new ReferenceSelection(this->getBase(), edge, face, false)); + Gui::Selection().addSelectionGate(new ReferenceSelection(this->getBase(), allowEdges, allowFaces, false)); DressUpView->highlightReferences(true); } } @@ -127,9 +126,7 @@ void TaskDressUpParameters::onButtonRefRemove(const bool checked) hideObject(); selectionMode = refRemove; Gui::Selection().clearSelection(); - bool edge = (DressUpView->featureName != "Draft"); - bool face = (DressUpView->featureName == "Draft"); - Gui::Selection().addSelectionGate(new ReferenceSelection(this->getBase(), edge, face, false)); + Gui::Selection().addSelectionGate(new ReferenceSelection(this->getBase(), allowEdges, allowFaces, false)); DressUpView->highlightReferences(true); } } diff --git a/src/Mod/PartDesign/Gui/TaskDressUpParameters.h b/src/Mod/PartDesign/Gui/TaskDressUpParameters.h index ccdaefefe..b46b2a631 100644 --- a/src/Mod/PartDesign/Gui/TaskDressUpParameters.h +++ b/src/Mod/PartDesign/Gui/TaskDressUpParameters.h @@ -39,7 +39,7 @@ class TaskDressUpParameters : public Gui::TaskView::TaskBox, public Gui::Selecti Q_OBJECT public: - TaskDressUpParameters(ViewProviderDressUp *DressUpView, QWidget *parent=0); + TaskDressUpParameters(ViewProviderDressUp *DressUpView, bool selectEdges, bool selectFaces, QWidget* parent = 0); virtual ~TaskDressUpParameters(); const std::vector getReferences(void) const; @@ -73,6 +73,7 @@ protected: QWidget* proxy; ViewProviderDressUp *DressUpView; + bool allowFaces, allowEdges; selectionModes selectionMode; }; diff --git a/src/Mod/PartDesign/Gui/TaskFilletParameters.cpp b/src/Mod/PartDesign/Gui/TaskFilletParameters.cpp index 089534a6f..761c917fe 100644 --- a/src/Mod/PartDesign/Gui/TaskFilletParameters.cpp +++ b/src/Mod/PartDesign/Gui/TaskFilletParameters.cpp @@ -51,7 +51,7 @@ using namespace Gui; /* TRANSLATOR PartDesignGui::TaskFilletParameters */ TaskFilletParameters::TaskFilletParameters(ViewProviderDressUp *DressUpView,QWidget *parent) - : TaskDressUpParameters(DressUpView, parent) + : TaskDressUpParameters(DressUpView, true, true, parent) { // we need a separate container widget to add all controls to proxy = new QWidget(this); diff --git a/src/Mod/PartDesign/Gui/ViewProviderDressUp.cpp b/src/Mod/PartDesign/Gui/ViewProviderDressUp.cpp index 35e01fa65..5437d03d1 100644 --- a/src/Mod/PartDesign/Gui/ViewProviderDressUp.cpp +++ b/src/Mod/PartDesign/Gui/ViewProviderDressUp.cpp @@ -115,7 +115,8 @@ void ViewProviderDressUp::highlightReferences(const bool on) colors[idx] = App::Color(1.0,0.0,1.0); // magenta } vp->DiffuseColor.setValues(colors); - } else if (!edges.empty() && originalLineColors.empty()) { + } + if (!edges.empty() && originalLineColors.empty()) { TopTools_IndexedMapOfShape eMap; TopExp::MapShapes(base->Shape.getValue(), TopAbs_EDGE, eMap); originalLineColors = vp->LineColorArray.getValues(); @@ -133,7 +134,8 @@ void ViewProviderDressUp::highlightReferences(const bool on) if (!faces.empty() && !originalFaceColors.empty()) { vp->DiffuseColor.setValues(originalFaceColors); originalFaceColors.clear(); - } else if (!edges.empty() && !originalLineColors.empty()) { + } + if (!edges.empty() && !originalLineColors.empty()) { vp->LineColorArray.setValues(originalLineColors); originalLineColors.clear(); }