From 655bf961beba0ffd83d22a5d669db7aec54a577e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Tr=C3=B6ger?= Date: Tue, 21 Jul 2015 18:09:05 +0200 Subject: [PATCH] add task for datum shape features --- src/Mod/PartDesign/App/ShapeBinder.cpp | 64 +++- src/Mod/PartDesign/App/ShapeBinder.h | 5 +- src/Mod/PartDesign/Gui/CMakeLists.txt | 5 + src/Mod/PartDesign/Gui/TaskShapeBinder.cpp | 360 ++++++++++++++++++ src/Mod/PartDesign/Gui/TaskShapeBinder.h | 106 ++++++ src/Mod/PartDesign/Gui/TaskShapeBinder.ui | 83 ++++ .../Gui/ViewProviderShapeBinder.cpp | 107 +++++- .../PartDesign/Gui/ViewProviderShapeBinder.h | 6 + 8 files changed, 714 insertions(+), 22 deletions(-) create mode 100644 src/Mod/PartDesign/Gui/TaskShapeBinder.cpp create mode 100644 src/Mod/PartDesign/Gui/TaskShapeBinder.h create mode 100644 src/Mod/PartDesign/Gui/TaskShapeBinder.ui diff --git a/src/Mod/PartDesign/App/ShapeBinder.cpp b/src/Mod/PartDesign/App/ShapeBinder.cpp index 03dd5a6d7..335e3cb38 100644 --- a/src/Mod/PartDesign/App/ShapeBinder.cpp +++ b/src/Mod/PartDesign/App/ShapeBinder.cpp @@ -57,44 +57,47 @@ void ShapeBinder::onChanged(const App::Property *prop) if(prop == &Support) { - auto objs = Support.getValues(); - auto subs = Support.getSubValues(); + Part::Feature* obj = nullptr; + std::vector subs; - Shape.setValue(buildShapeFromReferences(objs, subs)._Shape); + ShapeBinder::getFilterdReferences(&Support, obj, subs); + Shape.setValue(ShapeBinder::buildShapeFromReferences(obj, subs)._Shape); } } Part::Feature::onChanged(prop); } -TopoShape ShapeBinder::buildShapeFromReferences(std::vector< App::DocumentObject* > objs, std::vector< std::string > subs) { +void ShapeBinder::getFilterdReferences(App::PropertyLinkSubList* prop, Part::Feature*& obj, std::vector< std::string >& subobjects) { + obj = nullptr; + subobjects.clear(); + + auto objs = prop->getValues(); + auto subs = prop->getSubValues(); + if(objs.empty()) { - //kee the shape as it is, maybe we are just used as a copy - return TopoShape(); + return; } - //we only allow part feature, so get the first one we find - Part::Feature* obj = nullptr; + //we only allow one part feature, so get the first one we find int index = 0; while(!objs[index]->isDerivedFrom(Part::Feature::getClassTypeId()) && index < objs.size()) index++; //do we have any part feature? if(index >= objs.size()) - return TopoShape(); + return; obj = static_cast(objs[index]); //if we have no subshpape we use the whole shape if(subs[index].empty()) { - return obj->Shape.getShape(); + return; } - //if we use multiple subshapes we build a shape from them by fusing them together + //collect all subshapes for the object index = 0; - TopoShape base; - std::vector operators; for(std::string sub : subs) { //we only allow subshapes from a single Part::Feature @@ -104,15 +107,39 @@ TopoShape ShapeBinder::buildShapeFromReferences(std::vector< App::DocumentObject //in this mode the full shape is not allowed, as we already started the subshape //processing if(sub.empty()) - continue; + continue; + subobjects.push_back(sub); + } +} + + +TopoShape ShapeBinder::buildShapeFromReferences( Part::Feature* obj, std::vector< std::string > subs) { + + if(!obj) + return TopoDS_Shape(); + + if(subs.empty()) + return obj->Shape.getShape(); + + //if we use multiple subshapes we build a shape from them by fusing them together + TopoShape base; + std::vector operators; + for(std::string sub : subs) { + if(base.isNull()) base = obj->Shape.getShape().getSubShape(sub.c_str()); else operators.push_back(obj->Shape.getShape().getSubShape(sub.c_str())); } - base.multiFuse(operators); + try { + if(!operators.empty() && !base.isNull()) + return base.multiFuse(operators); + } + catch(...) { + return base; + } return base; } @@ -133,10 +160,11 @@ void ShapeBinder2D::onChanged(const App::Property* prop) { if(prop == &Support) { - auto objs = Support.getValues(); - auto subs = Support.getSubValues(); + Part::Feature* obj = nullptr; + std::vector subs; - Shape.setValue(ShapeBinder::buildShapeFromReferences(objs, subs)._Shape); + ShapeBinder::getFilterdReferences(&Support, obj, subs); + Shape.setValue(ShapeBinder::buildShapeFromReferences(obj, subs)._Shape); } } diff --git a/src/Mod/PartDesign/App/ShapeBinder.h b/src/Mod/PartDesign/App/ShapeBinder.h index 0edcb9963..ad9354a44 100644 --- a/src/Mod/PartDesign/App/ShapeBinder.h +++ b/src/Mod/PartDesign/App/ShapeBinder.h @@ -33,7 +33,7 @@ namespace PartDesign { /*Those two feature are not realy a classical datum. They are fully defined shapes and not - *infinit geometries likeplanes and lines. Also they are not calculated by references and hence + *infinit geometries like planes and lines. Also they are not calculated by references and hence *are not "attaced" to anything. Furthermore real shapes must be visualized. This makes it hard *to reuse the existing datum infrastructure and a special handling foor those two types is *created. @@ -50,7 +50,8 @@ public: App::PropertyLinkSubList Support; - static TopoShape buildShapeFromReferences(std::vector objects, std::vector subobjects); + static void getFilterdReferences(App::PropertyLinkSubList* prop, Part::Feature*& object, std::vector< std::string >& subobjects); + static TopoShape buildShapeFromReferences(Feature* obj, std::vector< std::string > subs); const char* getViewProviderName(void) const { return "PartDesignGui::ViewProviderShapeBinder"; diff --git a/src/Mod/PartDesign/Gui/CMakeLists.txt b/src/Mod/PartDesign/Gui/CMakeLists.txt index b161b7603..b9559cbe0 100644 --- a/src/Mod/PartDesign/Gui/CMakeLists.txt +++ b/src/Mod/PartDesign/Gui/CMakeLists.txt @@ -48,6 +48,7 @@ set(PartDesignGui_MOC_HDRS TaskScaledParameters.h TaskMultiTransformParameters.h TaskDatumParameters.h + TaskShapeBinder.h TaskBooleanParameters.h TaskPrimitiveParameters.h TaskPipeParameters.h @@ -76,6 +77,7 @@ set(PartDesignGui_UIC_SRCS TaskScaledParameters.ui TaskMultiTransformParameters.ui TaskDatumParameters.ui + TaskShapeBinder.ui TaskPrimitiveParameters.ui TaskPipeParameters.ui TaskPipeOrientation.ui @@ -207,6 +209,9 @@ SET(PartDesignGuiTaskDlgs_SRCS TaskDatumParameters.ui TaskDatumParameters.cpp TaskDatumParameters.h + TaskShapeBinder.ui + TaskShapeBinder.cpp + TaskShapeBinder.h TaskBooleanParameters.ui TaskBooleanParameters.cpp TaskBooleanParameters.h diff --git a/src/Mod/PartDesign/Gui/TaskShapeBinder.cpp b/src/Mod/PartDesign/Gui/TaskShapeBinder.cpp new file mode 100644 index 000000000..dd013451e --- /dev/null +++ b/src/Mod/PartDesign/Gui/TaskShapeBinder.cpp @@ -0,0 +1,360 @@ +/*************************************************************************** + * Copyright (c) 2015 Stefan Tröger * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#include "PreCompiled.h" + +#ifndef _PreComp_ +# include +# include +#endif + +#include +#include +#include +#include +#include + +#include +#include + +#include "ReferenceSelection.h" +#include "Workbench.h" + +#include "ui_TaskShapeBinder.h" +#include "TaskShapeBinder.h" + +using namespace PartDesignGui; +using namespace Gui; + +/* TRANSLATOR PartDesignGui::TaskShapeBinder */ + + +//************************************************************************** +//************************************************************************** +// Task Parameter +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +// TODO Review and cleanup the file (2015-09-11, Fat-Zer) + +TaskShapeBinder::TaskShapeBinder(ViewProviderShapeBinder *view,bool newObj, QWidget *parent) + : Gui::TaskView::TaskBox(Gui::BitmapFactory().pixmap("PartDesign_ShapeBinder"), + tr("Datum shape parameters"), true, parent) +{ + // we need a separate container widget to add all controls to + proxy = new QWidget(this); + ui = new Ui_TaskShapeBinder(); + ui->setupUi(proxy); + QMetaObject::connectSlotsByName(this); + + connect(ui->buttonRefAdd, SIGNAL(toggled(bool)), + this, SLOT(onButtonRefAdd(bool))); + connect(ui->buttonRefRemove, SIGNAL(toggled(bool)), + this, SLOT(onButtonRefRemove(bool))); + connect(ui->buttonBase, SIGNAL(toggled(bool)), + this, SLOT(onBaseButton(bool))); + + this->groupLayout()->addWidget(proxy); + + Gui::Document* doc = Gui::Application::Instance->activeDocument(); + vp = view; + + //add initial values + Part::Feature* obj = nullptr; + std::vector subs; + + if(vp->getObject()->isDerivedFrom(PartDesign::ShapeBinder::getClassTypeId())) + PartDesign::ShapeBinder::getFilterdReferences(&static_cast(vp->getObject())->Support, obj, subs); + else + PartDesign::ShapeBinder::getFilterdReferences(&static_cast(vp->getObject())->Support, obj, subs); + + if(obj) + ui->baseEdit->setText(QString::fromUtf8(obj->getNameInDocument())); + + for (auto sub : subs) + ui->listWidgetReferences->addItem(QString::fromStdString(sub)); + + //make sure th euser sees al important things: the base feature to select edges and the + //spine/auxillery spine he already selected + if(obj) { + auto* svp = doc->getViewProvider(obj); + if(svp) { + supportShow = svp->isShow(); + svp->setVisible(true); + } + } + + updateUI(); +} + +void TaskShapeBinder::updateUI() +{ + +} + +void TaskShapeBinder::onSelectionChanged(const Gui::SelectionChanges& msg) +{ + if (selectionMode == none) + return; + + if (msg.Type == Gui::SelectionChanges::AddSelection) { + if (referenceSelected(msg)) { + if (selectionMode == refAdd) { + QString sub = QString::fromStdString(msg.pSubName); + if(!sub.isEmpty()) + ui->listWidgetReferences->addItem(QString::fromStdString(msg.pSubName)); + + ui->baseEdit->setText(QString::fromStdString(msg.pObjectName)); + } + else if (selectionMode == refRemove) { + QString sub = QString::fromStdString(msg.pSubName); + if(!sub.isEmpty()) + removeFromListWidget(ui->listWidgetReferences, QString::fromUtf8(msg.pSubName)); + else { + ui->baseEdit->clear(); + } + } else if(selectionMode == refObjAdd) { + ui->listWidgetReferences->clear(); + ui->baseEdit->setText(QString::fromUtf8(msg.pObjectName)); + } + clearButtons(); + static_cast(vp)->highlightReferences(false, false); + vp->getObject()->getDocument()->recomputeFeature(vp->getObject()); + } + clearButtons(); + exitSelectionMode(); + } +} + +TaskShapeBinder::~TaskShapeBinder() +{/* + PartDesign::Pipe* pipe = static_cast(vp->getObject()); + Gui::Document* doc = Gui::Application::Instance->activeDocument(); + + //make sure th euser sees al important things: the base feature to select edges and the + //spine/auxillery spine he already selected + if(pipe->BaseFeature.getValue()) + doc->getViewProvider(pipe->BaseFeature.getValue())->hide(); + if(pipe->Spine.getValue()) { + auto* svp = doc->getViewProvider(pipe->Spine.getValue()); + svp->setVisible(supportShow); + supportShow = false; + } + static_cast(vp)->highlightReferences(false, false); + */ + delete ui; +} + +void TaskShapeBinder::changeEvent(QEvent *e) +{ +} + +void TaskShapeBinder::onButtonRefAdd(bool checked) { + + if (checked) { + //clearButtons(refAdd); + //hideObject(); + Gui::Selection().clearSelection(); + selectionMode = refAdd; + vp->highlightReferences(true, false); + } +} + +void TaskShapeBinder::onButtonRefRemove(bool checked) { + + if (checked) { + //clearButtons(refRemove); + //hideObject(); + Gui::Selection().clearSelection(); + selectionMode = refRemove; + vp->highlightReferences(true, false); + } +} + +void TaskShapeBinder::onBaseButton(bool checked) { + + if (checked) { + //clearButtons(refRemove); + //hideObject(); + Gui::Selection().clearSelection(); + selectionMode = refObjAdd; + //DressUpView->highlightReferences(true); + } +} + +void TaskShapeBinder::removeFromListWidget(QListWidget* widget, QString itemstr) { + + QList items = widget->findItems(itemstr, Qt::MatchExactly); + if (!items.empty()) { + for (QList::const_iterator i = items.begin(); i != items.end(); i++) { + QListWidgetItem* it = widget->takeItem(widget->row(*i)); + delete it; + } + } +} + +bool TaskShapeBinder::referenceSelected(const SelectionChanges& msg) const { + + if ((msg.Type == Gui::SelectionChanges::AddSelection) && ( + (selectionMode == refAdd) || (selectionMode == refRemove) + || (selectionMode == refObjAdd))) { + + if (strcmp(msg.pDocName, vp->getObject()->getDocument()->getName()) != 0) + return false; + + // not allowed to reference ourself + const char* fname = vp->getObject()->getNameInDocument(); + if (strcmp(msg.pObjectName, fname) == 0) + return false; + + //change the references + std::string subName(msg.pSubName); + + Part::Feature* obj = nullptr; + std::vector refs; + + if(vp->getObject()->isDerivedFrom(PartDesign::ShapeBinder::getClassTypeId())) + PartDesign::ShapeBinder::getFilterdReferences(&static_cast(vp->getObject())->Support, obj, refs); + else + PartDesign::ShapeBinder::getFilterdReferences(&static_cast(vp->getObject())->Support, obj, refs); + + //if we already have a object we need to ensure th new selected subref belongs to it + if(obj && strcmp(msg.pObjectName, obj->getNameInDocument()) != 0) + return false; + + std::vector::iterator f = std::find(refs.begin(), refs.end(), subName); + + if(selectionMode != refObjAdd) { + if (selectionMode == refAdd) { + if (f == refs.end()) + refs.push_back(subName); + else + return false; // duplicate selection + } else { + if (f != refs.end()) + refs.erase(f); + else + return false; + } + } + else { + refs.clear(); + } + + if(vp->getObject()->isDerivedFrom(PartDesign::ShapeBinder::getClassTypeId())) + static_cast(vp->getObject())->Support.setValue(obj, refs); + else + static_cast(vp->getObject())->Support.setValue( obj, refs); + + return true; + } + + return false; +} + +void TaskShapeBinder::clearButtons() { + + ui->buttonRefAdd->setChecked(false); + ui->buttonRefRemove->setChecked(false); + ui->buttonBase->setChecked(false); +} + +void TaskShapeBinder::exitSelectionMode() { + + selectionMode = none; + Gui::Selection().clearSelection(); +} + +//************************************************************************** +//************************************************************************** +// TaskDialog +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +TaskDlgShapeBinder::TaskDlgShapeBinder(ViewProviderShapeBinder *view, bool newObj) + : Gui::TaskView::TaskDialog() +{ + assert(view); + parameter = new TaskShapeBinder(view, newObj); + vp = view; + + Content.push_back(parameter); +} + +TaskDlgShapeBinder::~TaskDlgShapeBinder() +{ + +} + +//==== calls from the TaskView =============================================================== + + +bool TaskDlgShapeBinder::accept() +{ + std::string name = vp->getObject()->getNameInDocument(); + + try { + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.recompute()"); + if (!vp->getObject()->isValid()) + throw Base::Exception(vp->getObject()->getStatusString()); + Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()"); + Gui::Command::commitCommand(); + } + catch (const Base::Exception& e) { + QMessageBox::warning(parameter, tr("Input error"), QString::fromUtf8(e.what())); + return false; + } + + return true; +} + +//bool TaskDlgShapeBinder::reject() +//{ +// // get the support and Sketch +// PartDesign::Pipe* pcPipe = static_cast(PipeView->getObject()); +// Sketcher::SketchObject *pcSketch = 0; +// App::DocumentObject *pcSupport = 0; +// if (pcPipe->Sketch.getValue()) { +// pcSketch = static_cast(pcPipe->Sketch.getValue()); +// pcSupport = pcSketch->Support.getValue(); +// } +// +// // roll back the done things +// Gui::Command::abortCommand(); +// Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()"); +// +// // if abort command deleted the object the support is visible again +// if (!Gui::Application::Instance->getViewProvider(pcPipe)) { +// if (pcSketch && Gui::Application::Instance->getViewProvider(pcSketch)) +// Gui::Application::Instance->getViewProvider(pcSketch)->show(); +// if (pcSupport && Gui::Application::Instance->getViewProvider(pcSupport)) +// Gui::Application::Instance->getViewProvider(pcSupport)->show(); +// } +// +// //Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.recompute()"); +// //Gui::Command::commitCommand(); +// +// return true; +//} + + + +#include "moc_TaskShapeBinder.cpp" diff --git a/src/Mod/PartDesign/Gui/TaskShapeBinder.h b/src/Mod/PartDesign/Gui/TaskShapeBinder.h new file mode 100644 index 000000000..56856a857 --- /dev/null +++ b/src/Mod/PartDesign/Gui/TaskShapeBinder.h @@ -0,0 +1,106 @@ +/*************************************************************************** + * Copyright (c) 2015 Stefan Tröger * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#ifndef GUI_TASKVIEW_TaskDatumShapeBinder_H +#define GUI_TASKVIEW_TaskDatumShapeBinder_H + +#include +#include + +#include "ViewProviderShapeBinder.h" + +class Ui_TaskShapeBinder; +class QListWidget; + +namespace App { +class Property; +} + +namespace Gui { +class ViewProvider; +} + +namespace PartDesignGui { + + + +class TaskShapeBinder : public Gui::TaskView::TaskBox, Gui::SelectionObserver +{ + Q_OBJECT + +public: + TaskShapeBinder(ViewProviderShapeBinder *view,bool newObj=false,QWidget *parent = 0); + ~TaskShapeBinder(); + + +private Q_SLOTS: + void onButtonRefAdd(bool checked); + void onButtonRefRemove(bool checked); + void onBaseButton(bool checked); + +protected: + enum selectionModes { none, refAdd, refRemove, refObjAdd }; + void changeEvent(QEvent *e); + selectionModes selectionMode = none; + + void removeFromListWidget(QListWidget *w, QString name); + bool referenceSelected(const Gui::SelectionChanges& msg) const; + +private: + void onSelectionChanged(const Gui::SelectionChanges& msg); + void updateUI(); + void clearButtons(); + void exitSelectionMode(); + + bool supportShow = false; + +private: + QWidget* proxy; + Ui_TaskShapeBinder* ui; + ViewProviderShapeBinder* vp; +}; + + +/// simulation dialog for the TaskView +class TaskDlgShapeBinder : public Gui::TaskView::TaskDialog +{ + Q_OBJECT + +public: + TaskDlgShapeBinder(ViewProviderShapeBinder *view,bool newObj=false); + ~TaskDlgShapeBinder(); + +public: + /// is called by the framework if the dialog is accepted (Ok) + virtual bool accept(); + /// is called by the framework if the dialog is rejected (Cancel) + //virtual bool reject(); + +protected: + TaskShapeBinder *parameter; + ViewProviderShapeBinder* vp; +}; + +} //namespace PartDesignGui + +#endif // GUI_TASKVIEW_TASKAPPERANCE_H diff --git a/src/Mod/PartDesign/Gui/TaskShapeBinder.ui b/src/Mod/PartDesign/Gui/TaskShapeBinder.ui new file mode 100644 index 000000000..74f20ef53 --- /dev/null +++ b/src/Mod/PartDesign/Gui/TaskShapeBinder.ui @@ -0,0 +1,83 @@ + + + PartDesignGui::TaskShapeBinder + + + + 0 + 0 + 309 + 331 + + + + Form + + + + + + + + Object + + + true + + + + + + + + + + + + + + true + + + + 0 + 0 + + + + Add Geometry + + + true + + + false + + + + + + + + 0 + 0 + + + + Remove Geometry + + + true + + + + + + + + + + + + + diff --git a/src/Mod/PartDesign/Gui/ViewProviderShapeBinder.cpp b/src/Mod/PartDesign/Gui/ViewProviderShapeBinder.cpp index f10ba6db3..8aab7628b 100644 --- a/src/Mod/PartDesign/Gui/ViewProviderShapeBinder.cpp +++ b/src/Mod/PartDesign/Gui/ViewProviderShapeBinder.cpp @@ -24,12 +24,20 @@ #include "PreCompiled.h" #ifndef _PreComp_ +# include # include +# include +# include #endif +#include +#include +#include + #include #include "ViewProviderShapeBinder.h" +#include "TaskShapeBinder.h" using namespace PartDesignGui; @@ -64,9 +72,104 @@ ViewProviderShapeBinder::~ViewProviderShapeBinder() } bool ViewProviderShapeBinder::setEdit(int ModNum) { - return true;//PartGui::ViewProviderPartExt::setEdit(ModNum); + // TODO Share code with other view providers (2015-09-11, Fat-Zer) + + if (ModNum == ViewProvider::Default || ModNum == 1 ) { + + // When double-clicking on the item for this pad the + // object unsets and sets its edit mode without closing + // the task panel + Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog(); + TaskDlgShapeBinder *sbDlg = qobject_cast(dlg); + if (sbDlg) + sbDlg = 0; // another pad left open its task panel + if (dlg && !sbDlg) { + 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().reject(); + else + return false; + } + + // clear the selection (convenience) + Gui::Selection().clearSelection(); + + // start the edit dialog + if (sbDlg) + Gui::Control().showDialog(sbDlg); + else + Gui::Control().showDialog(new TaskDlgShapeBinder(this,ModNum == 1)); + + return true; + } + else { + return ViewProviderPart::setEdit(ModNum); + } } void ViewProviderShapeBinder::unsetEdit(int ModNum) { - return;//PartGui::ViewProviderPartExt::unsetEdit(ModNum); + + PartGui::ViewProviderPart::unsetEdit(ModNum); +} + +void ViewProviderShapeBinder::highlightReferences(const bool on, bool auxillery) { + + Part::Feature* obj; + std::vector subs; + + if(getObject()->isDerivedFrom(PartDesign::ShapeBinder::getClassTypeId())) + PartDesign::ShapeBinder::getFilterdReferences(&static_cast(getObject())->Support, obj, subs); + else if(getObject()->isDerivedFrom(PartDesign::ShapeBinder2D::getClassTypeId())) + PartDesign::ShapeBinder::getFilterdReferences(&static_cast(getObject())->Support, obj, subs); + else + return; + + PartGui::ViewProviderPart* svp = dynamic_cast( + Gui::Application::Instance->getViewProvider(obj)); + if (svp == NULL) return; + + if (on) { + if (!subs.empty() && originalLineColors.empty()) { + TopTools_IndexedMapOfShape eMap; + TopExp::MapShapes(obj->Shape.getValue(), TopAbs_EDGE, eMap); + originalLineColors = svp->LineColorArray.getValues(); + std::vector lcolors = originalLineColors; + lcolors.resize(eMap.Extent(), svp->LineColor.getValue()); + + TopExp::MapShapes(obj->Shape.getValue(), TopAbs_FACE, eMap); + originalFaceColors = svp->DiffuseColor.getValues(); + std::vector fcolors = originalFaceColors; + fcolors.resize(eMap.Extent(), svp->ShapeColor.getValue()); + + for (std::string e : subs) { + if(e.substr(4) == "Edge") { + + int idx = atoi(e.substr(4).c_str()) - 1; + if (idx < lcolors.size()) + lcolors[idx] = App::Color(1.0,0.0,1.0); // magenta + } + else if(e.substr(4) == "Face") { + + int idx = atoi(e.substr(4).c_str()) - 1; + if (idx < fcolors.size()) + fcolors[idx] = App::Color(1.0,0.0,1.0); // magenta + } + } + svp->LineColorArray.setValues(lcolors); + svp->DiffuseColor.setValues(fcolors); + } + } else { + if (!subs.empty() && !originalLineColors.empty()) { + svp->LineColorArray.setValues(originalLineColors); + originalLineColors.clear(); + + svp->DiffuseColor.setValues(originalFaceColors); + originalFaceColors.clear(); + } + } } diff --git a/src/Mod/PartDesign/Gui/ViewProviderShapeBinder.h b/src/Mod/PartDesign/Gui/ViewProviderShapeBinder.h index c9ef9c31c..850378baa 100644 --- a/src/Mod/PartDesign/Gui/ViewProviderShapeBinder.h +++ b/src/Mod/PartDesign/Gui/ViewProviderShapeBinder.h @@ -38,9 +38,15 @@ public: ViewProviderShapeBinder(); virtual ~ViewProviderShapeBinder(); + void highlightReferences(const bool on, bool auxillery); + protected: virtual bool setEdit(int ModNum); virtual void unsetEdit(int ModNum); + +private: + std::vector originalLineColors; + std::vector originalFaceColors; };