diff --git a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp index ca815cdee5..dd3b963bc0 100644 --- a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp +++ b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp @@ -937,8 +937,9 @@ bool ViewProviderSketch::mouseButtonPressed(int Button, bool pressed, const SbVe -16000, -16000);// certainly far away from any clickable place, to avoid // re-trigger of double-click if next click happens fast. - - Mode = STATUS_NONE; + if (Mode != STATUS_SELECT_Wire) { + Mode = STATUS_NONE; + } } else { DoubleClick::prvClickTime = SbTime::getTimeOfDay(); @@ -1031,6 +1032,11 @@ bool ViewProviderSketch::mouseButtonPressed(int Button, bool pressed, const SbVe } Mode = STATUS_NONE; return true; + case STATUS_SELECT_Wire: { + toggleWireSelelection(preselection.PreselectCurve); + Mode = STATUS_NONE; + return true; + } case STATUS_SELECT_Constraint: if (pp) { auto sels = preselection.PreselectConstraintSet; @@ -1251,7 +1257,9 @@ void ViewProviderSketch::editDoubleClicked() Base::Console().Log("double click point:%d\n", preselection.PreselectPoint); } else if (preselection.isPreselectCurveValid()) { - Base::Console().Log("double click edge:%d\n", preselection.PreselectCurve); + // We cannot do toggleWireSelelection directly here because the released event with + //STATUS_NONE return false which clears the selection. + Mode = STATUS_SELECT_Wire; } else if (preselection.isCrossPreselected()) { Base::Console().Log("double click cross:%d\n", @@ -1278,6 +1286,70 @@ void ViewProviderSketch::editDoubleClicked() } } +void ViewProviderSketch::toggleWireSelelection(int clickedGeoId) +{ + Sketcher::SketchObject* obj = getSketchObject(); + + const Part::Geometry* geo1 = obj->getGeometry(clickedGeoId); + if (isPoint(*geo1) || isCircle(*geo1) || isEllipse(*geo1) || isPeriodicBSplineCurve(*geo1)) { + return; + } + + const char* type1 = (clickedGeoId >= 0) ? "Edge" : "ExternalEdge"; + std::stringstream ss1; + ss1 << type1 << clickedGeoId + 1; + bool selecting = isSelected(ss1.str()); + + std::vector connectedEdges = { clickedGeoId }; + bool partHasBeenAdded = true; + while (partHasBeenAdded) { + partHasBeenAdded = false; + for (int geoId = 0; geoId <= obj->getHighestCurveIndex(); geoId++) { + if (geoId == clickedGeoId || std::find(connectedEdges.begin(), connectedEdges.end(), geoId) != connectedEdges.end()) { + continue; + } + + const Part::Geometry* geo = obj->getGeometry(geoId); + if (isPoint(*geo) || isCircle(*geo) || isEllipse(*geo) || isPeriodicBSplineCurve(*geo1)) { + continue; + } + + Base::Vector3d p11 = obj->getPoint(geoId, PointPos::start); + Base::Vector3d p12 = obj->getPoint(geoId, PointPos::end); + bool connected = false; + for (auto conGeoId : connectedEdges) { + Base::Vector3d p21 = obj->getPoint(conGeoId, PointPos::start); + Base::Vector3d p22 = obj->getPoint(conGeoId, PointPos::end); + if ((p11 - p21).Length() < Precision::Confusion() + || (p11 - p22).Length() < Precision::Confusion() + || (p12 - p21).Length() < Precision::Confusion() + || (p12 - p22).Length() < Precision::Confusion()) { + connected = true; + } + } + + if (connected) { + connectedEdges.push_back(geoId); + partHasBeenAdded = true; + break; + } + } + } + + for (auto geoId : connectedEdges) { + std::stringstream ss; + const char* type = (geoId >= 0) ? "Edge" : "ExternalEdge"; + ss << type << geoId + 1; + if (!selecting && isSelected(ss.str())) { + rmvSelection(ss.str()); + } + else if (selecting && !isSelected(ss.str())) { + addSelection2(ss.str()); + } + } + +} + bool ViewProviderSketch::mouseMove(const SbVec2s& cursorPos, Gui::View3DInventorViewer* viewer) { // maximum radius for mouse moves when selecting a geometry before switching to drag mode diff --git a/src/Mod/Sketcher/Gui/ViewProviderSketch.h b/src/Mod/Sketcher/Gui/ViewProviderSketch.h index 71f770aec7..e8e16c5c08 100644 --- a/src/Mod/Sketcher/Gui/ViewProviderSketch.h +++ b/src/Mod/Sketcher/Gui/ViewProviderSketch.h @@ -549,6 +549,7 @@ public: STATUS_SELECT_Edge, /**< enum value an edge was selected. */ STATUS_SELECT_Constraint, /**< enum value a constraint was selected. */ STATUS_SELECT_Cross, /**< enum value the base coordinate system was selected. */ + STATUS_SELECT_Wire, /**< enum value and edge was double clicked. */ STATUS_SKETCH_DragPoint, /**< enum value while dragging a point. */ STATUS_SKETCH_DragCurve, /**< enum value while dragging a curve. */ STATUS_SKETCH_DragConstraint, /**< enum value while dragging a compatible constraint. */ @@ -720,6 +721,8 @@ protected: void deactivateHandler(); /// get called if a subelement is double clicked while editing void editDoubleClicked(); + /// get called when an edge is double clicked to select/unselect the whole wire + void toggleWireSelelection(int geoId); //@} /** @name Solver Information */