diff --git a/src/Mod/TechDraw/App/DrawHatch.cpp b/src/Mod/TechDraw/App/DrawHatch.cpp index af7390b210..16c058416a 100644 --- a/src/Mod/TechDraw/App/DrawHatch.cpp +++ b/src/Mod/TechDraw/App/DrawHatch.cpp @@ -43,6 +43,7 @@ #include #include "DrawViewPart.h" +#include "DrawUtil.h" #include "DrawHatch.h" #include // generated from DrawHatchPy.xml @@ -59,7 +60,7 @@ DrawHatch::DrawHatch(void) ADD_PROPERTY_TYPE(DirProjection ,(0,0,1.0) ,vgroup,App::Prop_None,"Projection direction when Hatch was defined"); //sb RO? ADD_PROPERTY_TYPE(Source,(0),vgroup,(App::PropertyType)(App::Prop_None),"The View + Face to be hatched"); - Source.setScope(App::LinkScope::Global); + Source.setScope(App::LinkScope::Global); ADD_PROPERTY_TYPE(HatchPattern ,(""),vgroup,App::Prop_None,"The hatch pattern file for this area"); DirProjection.setStatus(App::Property::ReadOnly,true); @@ -119,6 +120,78 @@ PyObject *DrawHatch::getPyObject(void) return Py::new_reference_to(PythonObject); } +bool DrawHatch::faceIsHatched(int i,std::vector hatchObjs) +{ + bool result = false; + bool found = false; + for (auto& h:hatchObjs) { + const std::vector &sourceNames = h->Source.getSubValues(); + for (auto& s : sourceNames) { + int fdx = TechDraw::DrawUtil::getIndexFromName(s); + if (fdx == i) { + result = true; + found = true; + break; + } + } + if (found) { + break; + } + } + return result; +} + +//does this hatch affect face i +bool DrawHatch::affectsFace(int i) +{ + bool result = false; + const std::vector &sourceNames = Source.getSubValues(); + for (auto& s : sourceNames) { + int fdx = TechDraw::DrawUtil::getIndexFromName(s); + if (fdx == i) { + result = true; + break; + } + } + return result; +} + +//remove a subElement(Face) from Source PropertyLinkSub +bool DrawHatch::removeSub(std::string toRemove) +{ +// Base::Console().Message("DH::removeSub(%s)\n",toRemove.c_str()); + bool removed = false; + const std::vector &sourceNames = Source.getSubValues(); + std::vector newList; + App::DocumentObject* sourceFeat = Source.getValue(); + for (auto& s: sourceNames) { + if (s == toRemove) { + removed = true; + } else { + newList.push_back(s); + } + } + if (removed) { + Source.setValue(sourceFeat, newList); + } + return removed; +} + +bool DrawHatch::removeSub(int i) +{ +// Base::Console().Message("DH::removeSub(%d)\n",i); + std::stringstream ss; + ss << "Face" << i; + return removeSub(ss.str()); +} + +bool DrawHatch::empty(void) +{ + const std::vector &sourceNames = Source.getSubValues(); + return sourceNames.empty(); +} + + // Python Drawing feature --------------------------------------------------------- namespace App { diff --git a/src/Mod/TechDraw/App/DrawHatch.h b/src/Mod/TechDraw/App/DrawHatch.h index d4419ee729..dfd2bba523 100644 --- a/src/Mod/TechDraw/App/DrawHatch.h +++ b/src/Mod/TechDraw/App/DrawHatch.h @@ -53,6 +53,12 @@ public: virtual PyObject *getPyObject(void); DrawViewPart* getSourceView(void) const; + bool affectsFace(int i); + bool removeSub(std::string toRemove); + bool removeSub(int i); + bool empty(void); + static bool faceIsHatched(int i,std::vector hatchObjs); + protected: void onChanged(const App::Property* prop); diff --git a/src/Mod/TechDraw/Gui/CommandDecorate.cpp b/src/Mod/TechDraw/Gui/CommandDecorate.cpp index a03b143866..22f3fe02e4 100644 --- a/src/Mod/TechDraw/Gui/CommandDecorate.cpp +++ b/src/Mod/TechDraw/Gui/CommandDecorate.cpp @@ -215,35 +215,84 @@ void CmdTechDrawNewHatch::activated(int iMsg) } std::vector selection = getSelection().getSelectionEx(); - auto objFeat( dynamic_cast(selection[0].getObject()) ); - if( objFeat == nullptr ) { + auto partFeat( dynamic_cast(selection[0].getObject()) ); + if( partFeat == nullptr ) { return; } const std::vector &subNames = selection[0].getSubNames(); - TechDraw::DrawPage* page = objFeat->findParentPage(); + TechDraw::DrawPage* page = partFeat->findParentPage(); std::string PageName = page->getNameInDocument(); + std::vector selFaces; + for (auto& s: subNames) { + int f = TechDraw::DrawUtil::getIndexFromName(s); + selFaces.push_back(f); + } + + bool removeOld = false; + std::vector hatchObjs = partFeat->getHatches(); + for (auto& s: subNames) { //all the faces selected in DVP + int face = TechDraw::DrawUtil::getIndexFromName(s); + if (TechDraw::DrawHatch::faceIsHatched(face, hatchObjs)) { + QMessageBox::StandardButton rc = + QMessageBox::question(Gui::getMainWindow(), QObject::tr("Replace Hatch?"), + QObject::tr("Some Faces in selection are already hatched. Replace?")); + if (rc == QMessageBox::StandardButton::NoButton) { + return; + } else { + removeOld = true; + break; + } + } + } + + openCommand("Create Hatch"); + if (removeOld) { + std::vector > toRemove; + for (auto& h: hatchObjs) { //all the hatch objects for selected DVP + std::vector hatchSubs = h->Source.getSubValues(); + for (auto& hs: hatchSubs) { //all the Faces in this hatch object + int hatchFace = TechDraw::DrawUtil::getIndexFromName(hs); + std::vector::iterator it = std::find(selFaces.begin(), selFaces.end(), hatchFace); + if (it != selFaces.end()) { + std::pair< int, TechDraw::DrawHatch*> removeItem; + removeItem.first = hatchFace; + removeItem.second = h; + toRemove.push_back(removeItem); + } + } + } + for (auto& r: toRemove) { + r.second->removeSub(r.first); + if (r.second->empty()) { + doCommand(Doc,"App.activeDocument().removeObject('%s')",r.second->getNameInDocument()); + } + } + } std::string FeatName = getUniqueObjectName("Hatch"); std::stringstream featLabel; - featLabel << FeatName << "F" << TechDraw::DrawUtil::getIndexFromName(subNames.at(0)); + featLabel << FeatName << "F" << + TechDraw::DrawUtil::getIndexFromName(subNames.at(0)); //use 1st face# for label - openCommand("Create Hatch"); doCommand(Doc,"App.activeDocument().addObject('TechDraw::DrawHatch','%s')",FeatName.c_str()); doCommand(Doc,"App.activeDocument().%s.Label = '%s'",FeatName.c_str(),featLabel.str().c_str()); auto hatch( static_cast(getDocument()->getObject(FeatName.c_str())) ); - hatch->Source.setValue(objFeat, subNames); + hatch->Source.setValue(partFeat, subNames); + //should this be: doCommand(Doc,"App..Feat..Source = [(App...%s,%s),(App..%s,%s),...]",objs[0]->getNameInDocument(),subs[0],...); //seems very unwieldy commitCommand(); - //Horrible hack to force Tree update ??still required?? - double x = objFeat->X.getValue(); - objFeat->X.setValue(x); + //Horrible hack to force Tree update ??still required?? + //WF: yes. ViewProvider will not claim children without this! + double x = partFeat->X.getValue(); + partFeat->X.setValue(x); getDocument()->recompute(); } + bool CmdTechDrawNewHatch::isActive(void) { bool havePage = DrawGuiUtil::needPage(this); diff --git a/src/Mod/TechDraw/Gui/QGIViewPart.cpp b/src/Mod/TechDraw/Gui/QGIViewPart.cpp index 50ae13322a..02c1067352 100644 --- a/src/Mod/TechDraw/Gui/QGIViewPart.cpp +++ b/src/Mod/TechDraw/Gui/QGIViewPart.cpp @@ -1058,15 +1058,23 @@ void QGIViewPart::toggleCosmeticLines(bool state) } } - +//get hatchObj for face i if it exists TechDraw::DrawHatch* QGIViewPart::faceIsHatched(int i,std::vector hatchObjs) const { TechDraw::DrawHatch* result = nullptr; + bool found = false; for (auto& h:hatchObjs) { const std::vector &sourceNames = h->Source.getSubValues(); - int fdx = TechDraw::DrawUtil::getIndexFromName(sourceNames.at(0)); - if (fdx == i) { - result = h; + for (auto& s: sourceNames) { +// int fdx = TechDraw::DrawUtil::getIndexFromName(sourceNames.at(0)); //this sb a loop through all subs + int fdx = TechDraw::DrawUtil::getIndexFromName(s); + if (fdx == i) { + result = h; + found = true; + break; + } + } + if (found) { break; } }