From c5e2aba15ef542affc8606825fbe6e5ff58398d1 Mon Sep 17 00:00:00 2001 From: donovaly Date: Mon, 27 Jul 2020 00:16:12 +0200 Subject: [PATCH] [PD] allow multiselection on creation of pattern - Since realthunder's contributions some months ago, the 4 pattern features (mirror, linear, polar, mulitransform) can handle several features at once. This PR allows to select multiple features when creating a pattern. (This speeds up the workflow because at the moment one has to create the pattern with one feature and subsequently add more.) - fix dialog issue that Add and Remove button could be active the same time - use the keyboardTracking feature to avoid unnecessary recomputes (e.g. currently 3 recomputes when inserting "12.5" to the length field of linear pattern) - fix wrong statement in .ui files (automatically spotted and fixed by Qt's Designer) --- src/Mod/PartDesign/Gui/Command.cpp | 118 +++--- .../Gui/TaskLinearPatternParameters.ui | 338 +++++++++-------- .../PartDesign/Gui/TaskMirroredParameters.ui | 225 ++++++----- .../Gui/TaskMultiTransformParameters.ui | 183 +++++---- .../Gui/TaskPolarPatternParameters.ui | 350 ++++++++++-------- 5 files changed, 674 insertions(+), 540 deletions(-) diff --git a/src/Mod/PartDesign/Gui/Command.cpp b/src/Mod/PartDesign/Gui/Command.cpp index d6f34c516f..79d7b8969f 100644 --- a/src/Mod/PartDesign/Gui/Command.cpp +++ b/src/Mod/PartDesign/Gui/Command.cpp @@ -123,7 +123,7 @@ void UnifiedDatumCommand(Gui::Command &cmd, Base::Type type, std::string name) support.removeValue(pcActiveBody); auto Feat = pcActiveBody->getDocument()->getObject(FeatName.c_str()); - if(!Feat) return; + if (!Feat) return; //test if current selection fits a mode. if (support.getSize() > 0) { @@ -313,7 +313,7 @@ void CmdPartDesignShapeBinder::activated(int iMsg) support.removeValue(pcActiveBody); auto Feat = pcActiveBody->getObject(FeatName.c_str()); - if(!Feat) return; + if (!Feat) return; //test if current selection fits a mode. if (support.getSize() > 0) { @@ -355,30 +355,30 @@ void CmdPartDesignSubShapeBinder::activated(int iMsg) App::DocumentObject *parent = 0; std::string parentSub; std::map > values; - for(auto &sel : Gui::Selection().getCompleteSelection(0)) { - if(!sel.pObject) continue; + for (auto &sel : Gui::Selection().getCompleteSelection(0)) { + if (!sel.pObject) continue; auto &subs = values[sel.pObject]; - if(sel.SubName && sel.SubName[0]) + if (sel.SubName && sel.SubName[0]) subs.emplace_back(sel.SubName); } std::string FeatName; PartDesign::Body *pcActiveBody = PartDesignGui::getBody(false,true,true,&parent,&parentSub); FeatName = getUniqueObjectName("Binder",pcActiveBody); - if(parent) { + if (parent) { decltype(values) links; - for(auto &v : values) { + for (auto &v : values) { App::DocumentObject *obj = v.first; - if(obj != parent) { + if (obj != parent) { auto &subs = links[obj]; subs.insert(subs.end(),v.second.begin(),v.second.end()); continue; } - for(auto &sub : v.second) { + for (auto &sub : v.second) { auto link = obj; auto linkSub = parentSub; parent->resolveRelativeLink(linkSub,link,sub); - if(link && link != pcActiveBody) + if (link && link != pcActiveBody) links[link].push_back(sub); } } @@ -388,7 +388,7 @@ void CmdPartDesignSubShapeBinder::activated(int iMsg) PartDesign::SubShapeBinder *binder = 0; try { openCommand("Create SubShapeBinder"); - if(pcActiveBody) { + if (pcActiveBody) { FCMD_OBJ_CMD(pcActiveBody,"newObject('PartDesign::SubShapeBinder','" << FeatName << "')"); binder = dynamic_cast(pcActiveBody->getObject(FeatName.c_str())); } else { @@ -397,11 +397,11 @@ void CmdPartDesignSubShapeBinder::activated(int iMsg) binder = dynamic_cast( App::GetApplication().getActiveDocument()->getObject(FeatName.c_str())); } - if(!binder) return; + if (!binder) return; binder->setLinks(std::move(values)); updateActive(); commitCommand(); - }catch(Base::Exception &e) { + } catch (Base::Exception &e) { e.ReportException(); QMessageBox::critical(Gui::getMainWindow(), QObject::tr("Sub-Shape Binder"), QString::fromUtf8(e.what())); @@ -637,7 +637,7 @@ void CmdPartDesignNewSketch::activated(int iMsg) else if (!dlg.radioXRef->isChecked()) { openCommand("Make copy"); std::string sub; - if(FaceFilter.match()) + if (FaceFilter.match()) sub = FaceFilter.Result[0][0].getSubNames()[0]; auto copy = PartDesignGui::TaskFeaturePick::makeCopy(obj, sub, dlg.radioIndependent->isChecked()); @@ -646,7 +646,7 @@ void CmdPartDesignNewSketch::activated(int iMsg) else if (pcActivePart) pcActivePart->addObject(copy); - if(PlaneFilter.match()) + if (PlaneFilter.match()) supportString = getObjectCmd(copy,"(",",'')"); else //it is ensured that only a single face is selected, hence it must always be Face1 of the shapebinder @@ -817,7 +817,7 @@ void CmdPartDesignNewSketch::activated(int iMsg) } } - if(dlg) + if (dlg) Gui::Control().closeDialog(); Gui::Selection().clearSelection(); @@ -858,10 +858,10 @@ void finishFeature(const Gui::Command* cmd, App::DocumentObject *Feat, cmd->updateActive(); auto base = dynamic_cast(Feat); - if(base) + if (base) base = dynamic_cast(base->getBaseObject(true)); App::DocumentObject *obj = base; - if(!obj) + if (!obj) obj = pcActiveBody; // Do this before calling setEdit to avoid to override the 'Shape preview' mode (#0003621) @@ -911,9 +911,9 @@ unsigned validateSketches(std::vector& sketches, } else if (!pcActiveBody->hasObject(*s)) { // Check whether this plane belongs to a body of the same part PartDesign::Body* b = PartDesign::Body::findBodyOf(*s); - if(!b) + if (!b) status.push_back(PartDesignGui::TaskFeaturePick::notInBody); - else if(pcActivePart && pcActivePart->hasObject(b, true)) + else if (pcActivePart && pcActivePart->hasObject(b, true)) status.push_back(PartDesignGui::TaskFeaturePick::otherBody); else status.push_back(PartDesignGui::TaskFeaturePick::otherPart); @@ -1001,7 +1001,7 @@ void prepareProfileBased(PartDesign::Body *pcActiveBody, Gui::Command* cmd, cons } else { std::ostringstream ss; - for(auto &s : subs) + for (auto &s : subs) ss << "'" << s << "',"; FCMD_OBJ_CMD(Feat,"Profile = (" << objCmd << ", [" << ss.str() << "])"); } @@ -1039,7 +1039,7 @@ void prepareProfileBased(PartDesign::Body *pcActiveBody, Gui::Command* cmd, cons auto accepter = [=](const std::vector& features) -> bool { - if(features.empty()) + if (features.empty()) return false; return true; @@ -1114,7 +1114,7 @@ void prepareProfileBased(PartDesign::Body *pcActiveBody, Gui::Command* cmd, cons return; } - if(dlg) + if (dlg) Gui::Control().closeDialog(); Gui::Selection().clearSelection(); @@ -1138,7 +1138,7 @@ void prepareProfileBased(PartDesign::Body *pcActiveBody, Gui::Command* cmd, cons void finishProfileBased(const Gui::Command* cmd, const Part::Feature* sketch, App::DocumentObject *Feat) { - if(sketch && sketch->isDerivedFrom(Part::Part2DObject::getClassTypeId())) + if (sketch && sketch->isDerivedFrom(Part::Part2DObject::getClassTypeId())) FCMD_OBJ_HIDE(sketch); finishFeature(cmd, Feat); } @@ -1273,7 +1273,7 @@ void CmdPartDesignHole::activated(int iMsg) Gui::Command* cmd = this; auto worker = [cmd](Part::Feature* sketch, App::DocumentObject *Feat) { - if(!Feat) return; + if (!Feat) return; finishProfileBased(cmd, sketch, Feat); cmd->adjustCameraPosition(); @@ -1679,7 +1679,7 @@ void finishDressupFeature(const Gui::Command* cmd, const std::string& which, std::ostringstream str; str << '(' << Gui::Command::getObjectCmd(base) << ",["; - for(std::vector::const_iterator it = SubNames.begin();it!=SubNames.end();++it){ + for (std::vector::const_iterator it = SubNames.begin();it!=SubNames.end();++it){ str << "'" << *it << "',"; } str << "])"; @@ -1687,7 +1687,7 @@ void finishDressupFeature(const Gui::Command* cmd, const std::string& which, std::string FeatName = cmd->getUniqueObjectName(which.c_str(),base); auto body = PartDesignGui::getBodyFor(base,false); - if(!body) return; + if (!body) return; cmd->openCommand((std::string("Make ") + which).c_str()); FCMD_OBJ_CMD(body,"newObject('PartDesign::"<getDocument()->getObject(FeatName.c_str()); @@ -1800,7 +1800,7 @@ void CmdPartDesignDraft::activated(int iMsg) { std::string aSubName = static_cast(SubNames.at(i)); - if(aSubName.size() > 4 && aSubName.substr(0,4) == "Face") { + if (aSubName.size() > 4 && aSubName.substr(0,4) == "Face") { // Check for valid face types TopoDS_Face face = TopoDS::Face(TopShape.getSubShape(aSubName.c_str())); BRepAdaptor_Surface sf(face); @@ -1856,7 +1856,7 @@ void CmdPartDesignThickness::activated(int iMsg) { std::string aSubName = static_cast(SubNames.at(i)); - if(aSubName.size() > 4 && aSubName.substr(0,4) != "Face") { + if (aSubName.size() > 4 && aSubName.substr(0,4) != "Face") { // empty name or any other sub-element SubNames.erase(SubNames.begin()+i); } @@ -1876,13 +1876,13 @@ bool CmdPartDesignThickness::isActive(void) //=========================================================================== void prepareTransformed(PartDesign::Body *pcActiveBody, Gui::Command* cmd, const std::string& which, - boost::function)> func) + boost::function)> func) { - std::string FeatName = cmd->getUniqueObjectName(which.c_str(),pcActiveBody); + std::string FeatName = cmd->getUniqueObjectName(which.c_str(), pcActiveBody); - auto accepter = [=](std::vector features) -> bool{ + auto accepter = [=](std::vector features) -> bool { - if(features.empty()) + if (features.empty()) return false; return true; @@ -1890,8 +1890,8 @@ void prepareTransformed(PartDesign::Body *pcActiveBody, Gui::Command* cmd, const auto worker = [=](std::vector features) { std::stringstream str; - str << cmd->getObjectCmd(FeatName.c_str(),pcActiveBody->getDocument()) << ".Originals = ["; - for (std::vector::iterator it = features.begin(); it != features.end(); ++it){ + str << cmd->getObjectCmd(FeatName.c_str(), pcActiveBody->getDocument()) << ".Originals = ["; + for (std::vector::iterator it = features.begin(); it != features.end(); ++it) { str << cmd->getObjectCmd(*it) << ","; } str << "]"; @@ -1899,7 +1899,7 @@ void prepareTransformed(PartDesign::Body *pcActiveBody, Gui::Command* cmd, const std::string msg("Make "); msg += which; Gui::Command::openCommand(msg.c_str()); - FCMD_OBJ_CMD(pcActiveBody,"newObject('PartDesign::"< 1) { - QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Multiple Features Selected"), - QObject::tr("Please select only one feature first.")); - return; - } - else { - PartDesign::Body *activeBody = PartDesignGui::getBody(true); - if (activeBody != PartDesignGui::getBodyFor(features[0], false)) { + + PartDesign::Body* activeBody = PartDesignGui::getBody(true); + for (std::size_t i = 0; i < features.size(); i++) { + if (activeBody != PartDesignGui::getBodyFor(features[i], false)) { QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Selection is not in Active Body"), QObject::tr("Please select only one feature in an active body.")); return; } - worker(features); } + worker(features); } void finishTransformed(Gui::Command* cmd, App::DocumentObject *Feat) @@ -2012,16 +2008,16 @@ void CmdPartDesignMirrored::activated(int iMsg) return; bool direction = false; - if(features.front()->isDerivedFrom(PartDesign::ProfileBased::getClassTypeId())) { + if (features.front()->isDerivedFrom(PartDesign::ProfileBased::getClassTypeId())) { Part::Part2DObject *sketch = (static_cast(features.front()))->getVerifiedSketch(/* silent =*/ true); if (sketch) { FCMD_OBJ_CMD(Feat,"MirrorPlane = ("<(Part::BodyBase::findBodyOf(features.front())); - if(body) { + if (body) { FCMD_OBJ_CMD(Feat,"MirrorPlane = ("<getOrigin()->getXY())<<", [''])"); } } @@ -2074,16 +2070,16 @@ void CmdPartDesignLinearPattern::activated(int iMsg) return; bool direction = false; - if(features.front()->isDerivedFrom(PartDesign::ProfileBased::getClassTypeId())) { + if (features.front()->isDerivedFrom(PartDesign::ProfileBased::getClassTypeId())) { Part::Part2DObject *sketch = (static_cast(features.front()))->getVerifiedSketch(/* silent =*/ true); if (sketch) { FCMD_OBJ_CMD(Feat,"Direction = ("<(Part::BodyBase::findBodyOf(features.front())); - if(body) { + if (body) { FCMD_OBJ_CMD(Feat,"Direction = ("<getOrigin()->getX())<<",[''])"); } } @@ -2138,16 +2134,16 @@ void CmdPartDesignPolarPattern::activated(int iMsg) return; bool direction = false; - if(features.front()->isDerivedFrom(PartDesign::ProfileBased::getClassTypeId())) { + if (features.front()->isDerivedFrom(PartDesign::ProfileBased::getClassTypeId())) { Part::Part2DObject *sketch = (static_cast(features.front()))->getVerifiedSketch(/* silent =*/ true); if (sketch) { FCMD_OBJ_CMD(Feat,"Axis = ("<(Part::BodyBase::findBodyOf(features.front())); - if(body) { + if (body) { FCMD_OBJ_CMD(Feat,"Axis = ("<getOrigin()->getZ())<<",[''])"); } } @@ -2286,7 +2282,7 @@ void CmdPartDesignMultiTransform::activated(int iMsg) // #0003509 #if 0 // Remove the Transformed feature from the Body - if(pcActiveBody) + if (pcActiveBody) FCMD_OBJ_CMD(pcActiveBody,"removeObject("< >::iterator i = BodyFilter.Result.begin(); for (; i != BodyFilter.Result.end(); i++) { for (std::vector::iterator j = i->begin(); j != i->end(); j++) { - if(j->getObject() != pcActiveBody) + if (j->getObject() != pcActiveBody) bodies.push_back(j->getObject()); } } diff --git a/src/Mod/PartDesign/Gui/TaskLinearPatternParameters.ui b/src/Mod/PartDesign/Gui/TaskLinearPatternParameters.ui index 88bb271731..aa81d8af5a 100644 --- a/src/Mod/PartDesign/Gui/TaskLinearPatternParameters.ui +++ b/src/Mod/PartDesign/Gui/TaskLinearPatternParameters.ui @@ -1,151 +1,187 @@ - - - PartDesignGui::TaskLinearPatternParameters - - - - 0 - 0 - 270 - 366 - - - - Form - - - - - - - - Add feature - - - true - - - - - - - Remove feature - - - true - - - - - - - - - - - - - - Direction - - - - - - - - - - - - Reverse direction - - - - - - - - - Length - - - - - - - mm - - - 100.000000000000000 - - - - - - - - - - - Occurrences - - - - - - - - - - - - - - OK - - - - - - - - - Update view - - - true - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - Gui::QuantitySpinBox - QWidget -
Gui/QuantitySpinBox.h
-
- - Gui::UIntSpinBox - QWidget -
Gui/SpinBox.h
- 1 -
-
- - -
+ + + PartDesignGui::TaskLinearPatternParameters + + + + 0 + 0 + 270 + 366 + + + + Form + + + + + + + + Add feature + + + true + + + + + + + Remove feature + + + true + + + + + + + + + + + + + + Direction + + + + + + + + + + + + Reverse direction + + + + + + + + + Length + + + + + + + false + + + mm + + + 100.000000000000000 + + + + + + + + + + + Occurrences + + + + + + + + + + + + + + OK + + + + + + + + + Update view + + + true + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + Gui::QuantitySpinBox + QWidget +
Gui/QuantitySpinBox.h
+
+ + Gui::UIntSpinBox + QSpinBox +
Gui/SpinBox.h
+ 1 +
+
+ + + + buttonAddFeature + clicked(bool) + buttonRemoveFeature + setDisabled(bool) + + + 70 + 21 + + + 198 + 21 + + + + + buttonRemoveFeature + clicked(bool) + buttonAddFeature + setDisabled(bool) + + + 198 + 21 + + + 70 + 21 + + + + +
diff --git a/src/Mod/PartDesign/Gui/TaskMirroredParameters.ui b/src/Mod/PartDesign/Gui/TaskMirroredParameters.ui index c03461ab3d..8c75b6f888 100644 --- a/src/Mod/PartDesign/Gui/TaskMirroredParameters.ui +++ b/src/Mod/PartDesign/Gui/TaskMirroredParameters.ui @@ -1,96 +1,129 @@ - - - PartDesignGui::TaskMirroredParameters - - - - 0 - 0 - 253 - 260 - - - - Form - - - - - - - - Add feature - - - true - - - - - - - Remove feature - - - true - - - - - - - - - - - - - - Plane - - - - - - - - - - - - - - OK - - - - - - - - - Update view - - - true - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - + + + PartDesignGui::TaskMirroredParameters + + + + 0 + 0 + 253 + 260 + + + + Form + + + + + + + + Add feature + + + true + + + + + + + Remove feature + + + true + + + + + + + + + + + + + + Plane + + + + + + + + + + + + + + OK + + + + + + + + + Update view + + + true + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + buttonAddFeature + clicked(bool) + buttonRemoveFeature + setDisabled(bool) + + + 66 + 21 + + + 186 + 21 + + + + + buttonRemoveFeature + clicked(bool) + buttonAddFeature + setDisabled(bool) + + + 186 + 21 + + + 66 + 21 + + + + + diff --git a/src/Mod/PartDesign/Gui/TaskMultiTransformParameters.ui b/src/Mod/PartDesign/Gui/TaskMultiTransformParameters.ui index 0269861739..d93323b3b9 100644 --- a/src/Mod/PartDesign/Gui/TaskMultiTransformParameters.ui +++ b/src/Mod/PartDesign/Gui/TaskMultiTransformParameters.ui @@ -1,75 +1,108 @@ - - - PartDesignGui::TaskMultiTransformParameters - - - - 0 - 0 - 256 - 266 - - - - Form - - - - - - - - Add feature - - - true - - - - - - - Remove feature - - - true - - - - - - - - - - - - Transformations - - - - - - - - 16777215 - 80 - - - - - - - - Update view - - - true - - - - - - - - + + + PartDesignGui::TaskMultiTransformParameters + + + + 0 + 0 + 256 + 266 + + + + Form + + + + + + + + Add feature + + + true + + + + + + + Remove feature + + + true + + + + + + + + + + + + Transformations + + + + + + + + 16777215 + 80 + + + + + + + + Update view + + + true + + + + + + + + + buttonAddFeature + clicked(bool) + buttonRemoveFeature + setDisabled(bool) + + + 67 + 21 + + + 188 + 21 + + + + + buttonRemoveFeature + clicked(bool) + buttonAddFeature + setDisabled(bool) + + + 188 + 21 + + + 67 + 21 + + + + + diff --git a/src/Mod/PartDesign/Gui/TaskPolarPatternParameters.ui b/src/Mod/PartDesign/Gui/TaskPolarPatternParameters.ui index c9be696ead..11a83434ed 100644 --- a/src/Mod/PartDesign/Gui/TaskPolarPatternParameters.ui +++ b/src/Mod/PartDesign/Gui/TaskPolarPatternParameters.ui @@ -1,157 +1,193 @@ - - - PartDesignGui::TaskPolarPatternParameters - - - - 0 - 0 - 253 - 366 - - - - Form - - - - - - - - Add feature - - - true - - - - - - - Remove feature - - - true - - - - - - - - - - - - - - Axis - - - - - - - - - - - - Reverse direction - - - - - - - - - Angle - - - - - - - deg - - - 0.000000000000000 - - - 360.000000000000000 - - - 360.000000000000000 - - - - - - - - - - - Occurrences - - - - - - - - - - - - - - OK - - - - - - - - - Update view - - - true - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - Gui::QuantitySpinBox - QWidget -
Gui/QuantitySpinBox.h
-
- - Gui::UIntSpinBox - QWidget -
Gui/SpinBox.h
- 1 -
-
- - -
+ + + PartDesignGui::TaskPolarPatternParameters + + + + 0 + 0 + 253 + 366 + + + + Form + + + + + + + + Add feature + + + true + + + + + + + Remove feature + + + true + + + + + + + + + + + + + + Axis + + + + + + + + + + + + Reverse direction + + + + + + + + + Angle + + + + + + + false + + + deg + + + 0.000000000000000 + + + 360.000000000000000 + + + 360.000000000000000 + + + + + + + + + + + Occurrences + + + + + + + + + + + + + + OK + + + + + + + + + Update view + + + true + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + Gui::QuantitySpinBox + QWidget +
Gui/QuantitySpinBox.h
+
+ + Gui::UIntSpinBox + QSpinBox +
Gui/SpinBox.h
+ 1 +
+
+ + + + buttonAddFeature + clicked(bool) + buttonRemoveFeature + setDisabled(bool) + + + 66 + 21 + + + 186 + 21 + + + + + buttonRemoveFeature + clicked(bool) + buttonAddFeature + setDisabled(bool) + + + 186 + 21 + + + 66 + 21 + + + + +