diff --git a/src/Mod/Part/Gui/BoxSelection.cpp b/src/Mod/Part/Gui/BoxSelection.cpp index 1265a07770..c6d103e49f 100644 --- a/src/Mod/Part/Gui/BoxSelection.cpp +++ b/src/Mod/Part/Gui/BoxSelection.cpp @@ -84,6 +84,8 @@ public: }; BoxSelection::BoxSelection() + : autodelete(false) + , shapeEnum(TopAbs_SHAPE) { } @@ -93,6 +95,16 @@ BoxSelection::~BoxSelection() } +void BoxSelection::setAutoDelete(bool on) +{ + autodelete = on; +} + +bool BoxSelection::isAutoDelete() const +{ + return autodelete; +} + void BoxSelection::selectionCallback(void * ud, SoEventCallback * cb) { Gui::View3DInventorViewer* view = reinterpret_cast(cb->getUserData()); @@ -129,40 +141,61 @@ void BoxSelection::selectionCallback(void * ud, SoEventCallback * cb) if (!vp->isVisible()) continue; const TopoDS_Shape& shape = it->Shape.getValue(); - self->addFacesToSelection(doc->getName(), it->getNameInDocument(), proj, polygon, shape); + self->addShapeToSelection(doc->getName(), it->getNameInDocument(), proj, polygon, shape, self->shapeEnum); } view->redraw(); } Gui::Selection().rmvSelectionGate(); - delete self; + + if (self->isAutoDelete()) { + delete self; + } } -void BoxSelection::addFacesToSelection(const char* doc, const char* obj, +const char* BoxSelection::nameFromShapeType(TopAbs_ShapeEnum type) const +{ + switch (type) { + case TopAbs_FACE: + return "Face"; + case TopAbs_EDGE: + return "Edge"; + case TopAbs_VERTEX: + return "Vertex"; + default: + return nullptr; + } +} + +void BoxSelection::addShapeToSelection(const char* doc, const char* obj, const Gui::ViewVolumeProjection& proj, const Base::Polygon2d& polygon, - const TopoDS_Shape& shape) + const TopoDS_Shape& shape, + TopAbs_ShapeEnum subtype) { try { - TopTools_IndexedMapOfShape M; + const char* subname = nameFromShapeType(subtype); + if (!subname) + return; - TopExp_Explorer xp_face(shape,TopAbs_FACE); - while (xp_face.More()) { - M.Add(xp_face.Current()); - xp_face.Next(); + TopTools_IndexedMapOfShape M; + TopExp_Explorer xp(shape, subtype); + while (xp.More()) { + M.Add(xp.Current()); + xp.Next(); } for (Standard_Integer k = 1; k <= M.Extent(); k++) { - const TopoDS_Shape& face = M(k); + const TopoDS_Shape& subshape = M(k); - TopExp_Explorer xp_vertex(face,TopAbs_VERTEX); + TopExp_Explorer xp_vertex(subshape, TopAbs_VERTEX); while (xp_vertex.More()) { gp_Pnt p = BRep_Tool::Pnt(TopoDS::Vertex(xp_vertex.Current())); Base::Vector3d pt2d; pt2d = proj(Base::Vector3d(p.X(), p.Y(), p.Z())); if (polygon.Contains(Base::Vector2d(pt2d.x, pt2d.y))) { std::stringstream str; - str << "Face" << k; + str << subname << k; Gui::Selection().addSelection(doc, obj, str.str().c_str()); break; } @@ -174,7 +207,7 @@ void BoxSelection::addFacesToSelection(const char* doc, const char* obj, } } -void BoxSelection::start() +void BoxSelection::start(TopAbs_ShapeEnum shape) { Gui::View3DInventor* view = qobject_cast(Gui::getMainWindow()->activeWindow()); if (view) { @@ -186,8 +219,7 @@ void BoxSelection::start() // called immediately SoNode* root = viewer->getSceneGraph(); static_cast(root)->selectionRole.setValue(false); - - Gui::Selection().addSelectionGate(new FaceSelectionGate); + shapeEnum = shape; } } } diff --git a/src/Mod/Part/Gui/BoxSelection.h b/src/Mod/Part/Gui/BoxSelection.h index 07d0d1b94f..a53dd52913 100644 --- a/src/Mod/Part/Gui/BoxSelection.h +++ b/src/Mod/Part/Gui/BoxSelection.h @@ -24,6 +24,8 @@ #ifndef PARTGUI_BOXSELECTION_H #define PARTGUI_BOXSELECTION_H +#include + class SoEventCallback; class TopoDS_Shape; @@ -44,15 +46,23 @@ public: BoxSelection(); ~BoxSelection(); - void start(); + void setAutoDelete(bool); + bool isAutoDelete() const; + void start(TopAbs_ShapeEnum shape); private: class FaceSelectionGate; - void addFacesToSelection(const char* doc, const char* obj, + void addShapeToSelection(const char* doc, const char* obj, const Gui::ViewVolumeProjection& proj, const Base::Polygon2d& polygon, - const TopoDS_Shape& shape); + const TopoDS_Shape& shape, + TopAbs_ShapeEnum subtype); + const char* nameFromShapeType(TopAbs_ShapeEnum) const; static void selectionCallback(void * ud, SoEventCallback * cb); + +private: + bool autodelete; + TopAbs_ShapeEnum shapeEnum; }; } //namespace PartGui diff --git a/src/Mod/Part/Gui/Command.cpp b/src/Mod/Part/Gui/Command.cpp index f8a705af9d..2a07634c98 100644 --- a/src/Mod/Part/Gui/Command.cpp +++ b/src/Mod/Part/Gui/Command.cpp @@ -2484,7 +2484,8 @@ void CmdBoxSelection::activated(int iMsg) { Q_UNUSED(iMsg); PartGui::BoxSelection* sel = new PartGui::BoxSelection(); - sel->start(); + sel->setAutoDelete(true); + sel->start(TopAbs_FACE); } bool CmdBoxSelection::isActive(void) diff --git a/src/Mod/Part/Gui/TaskShapeBuilder.cpp b/src/Mod/Part/Gui/TaskShapeBuilder.cpp index b85ceb504b..d0585b6968 100644 --- a/src/Mod/Part/Gui/TaskShapeBuilder.cpp +++ b/src/Mod/Part/Gui/TaskShapeBuilder.cpp @@ -36,6 +36,7 @@ #include "ViewProviderExt.h" #include "ui_TaskShapeBuilder.h" #include "TaskShapeBuilder.h" +#include "BoxSelection.h" #include #include @@ -96,6 +97,7 @@ public: Ui_TaskShapeBuilder ui; QButtonGroup bg; ShapeSelection* gate; + BoxSelection selection; Private() { Gui::Command::runCommand(Gui::Command::App, "from FreeCAD import Base"); @@ -202,6 +204,23 @@ void ShapeBuilderWidget::on_createButton_clicked() } } +void ShapeBuilderWidget::on_selectButton_clicked() +{ + int id = d->bg.checkedId(); + if (id == 0 || id == 2) { + d->selection.start(TopAbs_VERTEX); + } + else if (id == 1 || id == 3) { + d->selection.start(TopAbs_EDGE); + } + else if (id == 4) { + d->selection.start(TopAbs_FACE); + } + else { + QMessageBox::warning(this, tr("Unsupported"), tr("Box selection for shells is not supported")); + } +} + void ShapeBuilderWidget::createEdgeFromVertex() { Gui::SelectionFilter vertexFilter ("SELECT Part::Feature SUBELEMENT Vertex COUNT 2"); diff --git a/src/Mod/Part/Gui/TaskShapeBuilder.h b/src/Mod/Part/Gui/TaskShapeBuilder.h index 718e86d271..2129553f41 100644 --- a/src/Mod/Part/Gui/TaskShapeBuilder.h +++ b/src/Mod/Part/Gui/TaskShapeBuilder.h @@ -44,6 +44,7 @@ public: private Q_SLOTS: void on_createButton_clicked(); + void on_selectButton_clicked(); void switchMode(int); private: diff --git a/src/Mod/Part/Gui/TaskShapeBuilder.ui b/src/Mod/Part/Gui/TaskShapeBuilder.ui index f47c0b70d6..d756d2b8c4 100644 --- a/src/Mod/Part/Gui/TaskShapeBuilder.ui +++ b/src/Mod/Part/Gui/TaskShapeBuilder.ui @@ -95,6 +95,13 @@ + + + + Box selection... + + +