From 55639df57325290e5a9d98ef48d6e17898fe0fc1 Mon Sep 17 00:00:00 2001 From: Abdullah Tahiri Date: Sat, 11 Nov 2023 18:03:16 +0100 Subject: [PATCH] Sketcher: Box Selection - refactor ================================== Full refactor of this function without change of functionality (hopefully). --- src/Mod/Sketcher/Gui/ViewProviderSketch.cpp | 619 ++++---------------- src/Mod/Sketcher/Gui/ViewProviderSketch.h | 3 + 2 files changed, 133 insertions(+), 489 deletions(-) diff --git a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp index 026f7f6132..18871d939f 100644 --- a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp +++ b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp @@ -95,6 +95,20 @@ T getSketcherGeneralParameter(const std::string& string, T defaultvalue) } } +template +T getPreferencesViewParameter(const std::string& string, T defaultvalue) +{ + ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath( + "User parameter:BaseApp/Preferences/View"); + + if constexpr (std::is_same_v) { + return static_cast(hGrp->GetUnsigned(string.c_str(), defaultvalue)); + } + else if constexpr (std::is_same_v) { + return static_cast(hGrp->GetInt(string.c_str(), defaultvalue)); + } +} + ViewProviderSketch::ParameterObserver::ParameterObserver(ViewProviderSketch& client) : Client(client) {} @@ -343,6 +357,13 @@ void ViewProviderSketch::ParameterObserver::initParameters() Client.setGridDivLineColor(color); }, nullptr}}, + {"SegmentsPerGeometry", + {[this, packedDefaultGridColor](const std::string& string, + [[maybe_unused]] App::Property* property) { + auto v = getPreferencesViewParameter(string, 50); + Client.viewProviderParameters.stdCountSegments = v; + }, + nullptr}}, }; for (auto& val : parameterMap) { @@ -2304,10 +2325,15 @@ void ViewProviderSketch::doBoxSelection(const SbVec2s& startPos, const SbVec2s& assert(int(geomlist.size()) == extGeoCount + intGeoCount); assert(int(geomlist.size()) >= 2); - Base::Vector3d pnt0, pnt1, pnt2, pnt; - int VertexId = - -1;// the loop below should be in sync with the main loop in ViewProviderSketch::draw - // so that the vertex indices are calculated correctly + auto inBBCoords = [&Plm, &proj](const Base::Vector3d & point) { + Base::Vector3d pnt; + Plm.multVec(point, pnt); + return proj(pnt); + }; + + int VertexId = -1; // the loop below should be in sync with the main loop in + // ViewProviderSketch::draw so that the vertex indices are calculated + // correctly int GeoId = 0; bool touchMode = false; @@ -2316,6 +2342,58 @@ void ViewProviderSketch::doBoxSelection(const SbVec2s& startPos, const SbVec2s& if (corners[0].getValue()[0] > corners[1].getValue()[0]) touchMode = true; + auto selectVertex = [this](int vertexid) { + std::stringstream ss; + ss << "Vertex" << vertexid; + addSelection2(ss.str()); + }; + + auto selectEdge = [this](int edgeid) { + std::stringstream ss; + ss << "Edge" << edgeid; + addSelection2(ss.str()); + }; + + auto selectVertexIfInsideBox = [&polygon, &VertexId, &selectVertex](const Base::Vector3d & point) { + if (polygon.Contains(Base::Vector2d(point.x, point.y))) { + selectVertex( VertexId + 1); + return true; // inside + } + + return false; // outside + }; + + auto selectEdgeIfInsideBox = [&touchMode, &polygon, &GeoId, &inBBCoords, &selectEdge, + numSegments = viewProviderParameters.stdCountSegments](auto geo){ + + if constexpr (std::is_same::value) { + numSegments *= geo->countKnots(); // one less segments than knots + } + + double segment = (geo->getLastParameter() - geo->getFirstParameter()) / numSegments; + + bool bpolyInside = true; + + for (int i = 0; i < numSegments; i++) { + Base::Vector3d pnt = geo->value(geo->getFirstParameter() + i * segment); + pnt = inBBCoords(pnt); + if (!polygon.Contains(Base::Vector2d(pnt.x, pnt.y))) { + bpolyInside = false; + if (!touchMode) { + break; + } + } + else if (touchMode) { + bpolyInside = true; + break; + } + } + + if (bpolyInside) { + selectEdge(GeoId+1); + } + }; + for (std::vector::const_iterator it = geomlist.begin(); it != geomlist.end() - 2; ++it, ++GeoId) { @@ -2326,43 +2404,28 @@ void ViewProviderSketch::doBoxSelection(const SbVec2s& startPos, const SbVec2s& if ((*it)->is()) { // ----- Check if single point lies inside box selection -----/ const Part::GeomPoint* point = static_cast(*it); - Plm.multVec(point->getPoint(), pnt0); - pnt0 = proj(pnt0); - VertexId += 1; + Base::Vector3d pnt0 = inBBCoords(point->getPoint()); + VertexId++; - if (polygon.Contains(Base::Vector2d(pnt0.x, pnt0.y))) { - std::stringstream ss; - ss << "Vertex" << VertexId + 1; - addSelection2(ss.str()); - } + selectVertexIfInsideBox(pnt0); } else if ((*it)->is()) { // ----- Check if line segment lies inside box selection -----/ const Part::GeomLineSegment* lineSeg = static_cast(*it); - Plm.multVec(lineSeg->getStartPoint(), pnt1); - Plm.multVec(lineSeg->getEndPoint(), pnt2); - pnt1 = proj(pnt1); - pnt2 = proj(pnt2); - VertexId += 2; + Base::Vector3d pnt1 = inBBCoords(lineSeg->getStartPoint()); + Base::Vector3d pnt2 = inBBCoords(lineSeg->getEndPoint()); - bool pnt1Inside = polygon.Contains(Base::Vector2d(pnt1.x, pnt1.y)); - bool pnt2Inside = polygon.Contains(Base::Vector2d(pnt2.x, pnt2.y)); - if (pnt1Inside) { - std::stringstream ss; - ss << "Vertex" << VertexId; - addSelection2(ss.str()); - } + VertexId++; + bool pnt1Inside = selectVertexIfInsideBox(pnt1); + + VertexId++; + bool pnt2Inside = selectVertexIfInsideBox(pnt2); + polygon.Contains(Base::Vector2d(pnt1.x, pnt1.y)); + polygon.Contains(Base::Vector2d(pnt2.x, pnt2.y)); - if (pnt2Inside) { - std::stringstream ss; - ss << "Vertex" << VertexId + 1; - addSelection2(ss.str()); - } if ((pnt1Inside && pnt2Inside) && !touchMode) { - std::stringstream ss; - ss << "Edge" << GeoId + 1; - addSelection2(ss.str()); + selectEdge(GeoId+1); } // check if line intersects with polygon else if (touchMode) { @@ -2372,488 +2435,66 @@ void ViewProviderSketch::doBoxSelection(const SbVec2s& startPos, const SbVec2s& std::list resultList; polygon.Intersect(lineAsPolygon, resultList); if (!resultList.empty()) { - std::stringstream ss; - ss << "Edge" << GeoId + 1; - addSelection2(ss.str()); + selectEdge(GeoId+1); } } } - else if ((*it)->is()) { + else if ((*it)->isDerivedFrom()) { // ----- Check if circle lies inside box selection -----/ - /// TODO: Make it impossible to miss the circle if it's big and the selection pretty + /// TODO: Make it impossible to miss the conic if it's big and the selection pretty /// thin. - const Part::GeomCircle* circle = static_cast(*it); - pnt0 = circle->getCenter(); - VertexId += 1; + const Part::GeomConic* circle = static_cast(*it); + Base::Vector3d pnt0 = inBBCoords(circle->getCenter()); + VertexId++; - Plm.multVec(pnt0, pnt0); - pnt0 = proj(pnt0); + bool pnt0Inside = selectVertexIfInsideBox(pnt0); - if (polygon.Contains(Base::Vector2d(pnt0.x, pnt0.y)) || touchMode) { - if (polygon.Contains(Base::Vector2d(pnt0.x, pnt0.y))) { - std::stringstream ss; - ss << "Vertex" << VertexId + 1; - addSelection2(ss.str()); - } - int countSegments = 12; - if (touchMode) - countSegments = 36; - - float segment = float(2 * M_PI) / countSegments; - - // circumscribed polygon radius - float radius = float(circle->getRadius()) / cos(segment / 2); - - bool bpolyInside = true; - pnt0 = circle->getCenter(); - float angle = 0.f; - for (int i = 0; i < countSegments; ++i, angle += segment) { - pnt = Base::Vector3d( - pnt0.x + radius * cos(angle), pnt0.y + radius * sin(angle), 0.f); - Plm.multVec(pnt, pnt); - pnt = proj(pnt); - if (!polygon.Contains(Base::Vector2d(pnt.x, pnt.y))) { - bpolyInside = false; - if (!touchMode) - break; - } - else if (touchMode) { - bpolyInside = true; - break; - } - } - - if (bpolyInside) { - std::stringstream ss; - ss << "Edge" << GeoId + 1; - addSelection2(ss.str()); - } + if (pnt0Inside || touchMode) { + selectEdgeIfInsideBox(circle); } } - else if ((*it)->is()) { - // ----- Check if ellipse lies inside box selection -----/ - const Part::GeomEllipse* ellipse = static_cast(*it); - pnt0 = ellipse->getCenter(); - VertexId += 1; - - Plm.multVec(pnt0, pnt0); - pnt0 = proj(pnt0); - - if (polygon.Contains(Base::Vector2d(pnt0.x, pnt0.y)) || touchMode) { - if (polygon.Contains(Base::Vector2d(pnt0.x, pnt0.y))) { - std::stringstream ss; - ss << "Vertex" << VertexId + 1; - addSelection2(ss.str()); - } - - int countSegments = 12; - if (touchMode) - countSegments = 24; - double segment = (2 * M_PI) / countSegments; - - // circumscribed polygon radius - double a = (ellipse->getMajorRadius()) / cos(segment / 2); - double b = (ellipse->getMinorRadius()) / cos(segment / 2); - Base::Vector3d majdir = ellipse->getMajorAxisDir(); - Base::Vector3d mindir = Base::Vector3d(-majdir.y, majdir.x, 0.0); - - bool bpolyInside = true; - pnt0 = ellipse->getCenter(); - double angle = 0.; - for (int i = 0; i < countSegments; ++i, angle += segment) { - pnt = pnt0 + (cos(angle) * a) * majdir + sin(angle) * b * mindir; - Plm.multVec(pnt, pnt); - pnt = proj(pnt); - if (!polygon.Contains(Base::Vector2d(pnt.x, pnt.y))) { - bpolyInside = false; - if (!touchMode) - break; - } - else if (touchMode) { - bpolyInside = true; - break; - } - } - - if (bpolyInside) { - std::stringstream ss; - ss << "Edge" << GeoId + 1; - addSelection2(ss.str()); - } - } - } - else if ((*it)->is()) { + else if ((*it)->isDerivedFrom()) { // Check if arc lies inside box selection - const Part::GeomArcOfCircle* aoc = static_cast(*it); + const Part::GeomArcOfConic* aoc = static_cast(*it); - pnt0 = aoc->getStartPoint(/*emulateCCW=*/true); - pnt1 = aoc->getEndPoint(/*emulateCCW=*/true); - pnt2 = aoc->getCenter(); - VertexId += 3; + Base::Vector3d pnt0 = inBBCoords(aoc->getStartPoint(/*emulateCCW=*/true)); + VertexId++; + bool pnt0Inside = selectVertexIfInsideBox(pnt0); - Plm.multVec(pnt0, pnt0); - Plm.multVec(pnt1, pnt1); - Plm.multVec(pnt2, pnt2); - pnt0 = proj(pnt0); - pnt1 = proj(pnt1); - pnt2 = proj(pnt2); + Base::Vector3d pnt1 = inBBCoords(aoc->getEndPoint(/*emulateCCW=*/true)); + VertexId++; + bool pnt1Inside = selectVertexIfInsideBox(pnt1); - bool pnt0Inside = polygon.Contains(Base::Vector2d(pnt0.x, pnt0.y)); - bool pnt1Inside = polygon.Contains(Base::Vector2d(pnt1.x, pnt1.y)); - bool bpolyInside = true; + Base::Vector3d pnt2 = inBBCoords(aoc->getCenter()); + VertexId++; + selectVertexIfInsideBox(pnt2); if ((pnt0Inside && pnt1Inside) || touchMode) { - double startangle, endangle; - aoc->getRange(startangle, endangle, /*emulateCCW=*/true); - - if (startangle > endangle)// if arc is reversed - std::swap(startangle, endangle); - - double range = endangle - startangle; - int countSegments = std::max(2, int(12.0 * range / (2 * M_PI))); - if (touchMode) - countSegments = countSegments * 2.5; - float segment = float(range) / countSegments; - - // circumscribed polygon radius - float radius = float(aoc->getRadius()) / cos(segment / 2); - - pnt0 = aoc->getCenter(); - float angle = float(startangle) + segment / 2; - for (int i = 0; i < countSegments; ++i, angle += segment) { - pnt = Base::Vector3d( - pnt0.x + radius * cos(angle), pnt0.y + radius * sin(angle), 0.f); - Plm.multVec(pnt, pnt); - pnt = proj(pnt); - if (!polygon.Contains(Base::Vector2d(pnt.x, pnt.y))) { - bpolyInside = false; - if (!touchMode) - break; - } - else if (touchMode) { - bpolyInside = true; - break; - } - } - - if (bpolyInside) { - std::stringstream ss; - ss << "Edge" << GeoId + 1; - addSelection2(ss.str()); - } - } - - if (pnt0Inside) { - std::stringstream ss; - ss << "Vertex" << VertexId - 1; - addSelection2(ss.str()); - } - - if (pnt1Inside) { - std::stringstream ss; - ss << "Vertex" << VertexId; - addSelection2(ss.str()); - } - - if (polygon.Contains(Base::Vector2d(pnt2.x, pnt2.y))) { - std::stringstream ss; - ss << "Vertex" << VertexId + 1; - addSelection2(ss.str()); - } - } - else if ((*it)->is()) { - // Check if arc lies inside box selection - const Part::GeomArcOfEllipse* aoe = static_cast(*it); - - pnt0 = aoe->getStartPoint(/*emulateCCW=*/true); - pnt1 = aoe->getEndPoint(/*emulateCCW=*/true); - pnt2 = aoe->getCenter(); - - VertexId += 3; - - Plm.multVec(pnt0, pnt0); - Plm.multVec(pnt1, pnt1); - Plm.multVec(pnt2, pnt2); - pnt0 = proj(pnt0); - pnt1 = proj(pnt1); - pnt2 = proj(pnt2); - - bool pnt0Inside = polygon.Contains(Base::Vector2d(pnt0.x, pnt0.y)); - bool pnt1Inside = polygon.Contains(Base::Vector2d(pnt1.x, pnt1.y)); - bool bpolyInside = true; - - if ((pnt0Inside && pnt1Inside) || touchMode) { - double startangle, endangle; - aoe->getRange(startangle, endangle, /*emulateCCW=*/true); - - if (startangle > endangle)// if arc is reversed - std::swap(startangle, endangle); - - double range = endangle - startangle; - int countSegments = std::max(2, int(12.0 * range / (2 * M_PI))); - if (touchMode) - countSegments = countSegments * 2.5; - double segment = (range) / countSegments; - - // circumscribed polygon radius - double a = (aoe->getMajorRadius()) / cos(segment / 2); - double b = (aoe->getMinorRadius()) / cos(segment / 2); - Base::Vector3d majdir = aoe->getMajorAxisDir(); - Base::Vector3d mindir = Base::Vector3d(-majdir.y, majdir.x, 0.0); - - pnt0 = aoe->getCenter(); - double angle = (startangle) + segment / 2; - for (int i = 0; i < countSegments; ++i, angle += segment) { - pnt = pnt0 + cos(angle) * a * majdir + sin(angle) * b * mindir; - - Plm.multVec(pnt, pnt); - pnt = proj(pnt); - if (!polygon.Contains(Base::Vector2d(pnt.x, pnt.y))) { - bpolyInside = false; - if (!touchMode) - break; - } - else if (touchMode) { - bpolyInside = true; - break; - } - } - - if (bpolyInside) { - std::stringstream ss; - ss << "Edge" << GeoId + 1; - addSelection2(ss.str()); - } - } - if (pnt0Inside) { - std::stringstream ss; - ss << "Vertex" << VertexId - 1; - addSelection2(ss.str()); - } - - if (pnt1Inside) { - std::stringstream ss; - ss << "Vertex" << VertexId; - addSelection2(ss.str()); - } - - if (polygon.Contains(Base::Vector2d(pnt2.x, pnt2.y))) { - std::stringstream ss; - ss << "Vertex" << VertexId + 1; - addSelection2(ss.str()); - } - } - else if ((*it)->is()) { - // Check if arc lies inside box selection - const Part::GeomArcOfHyperbola* aoh = static_cast(*it); - pnt0 = aoh->getStartPoint(); - pnt1 = aoh->getEndPoint(); - pnt2 = aoh->getCenter(); - - VertexId += 3; - - Plm.multVec(pnt0, pnt0); - Plm.multVec(pnt1, pnt1); - Plm.multVec(pnt2, pnt2); - pnt0 = proj(pnt0); - pnt1 = proj(pnt1); - pnt2 = proj(pnt2); - - bool pnt0Inside = polygon.Contains(Base::Vector2d(pnt0.x, pnt0.y)); - bool pnt1Inside = polygon.Contains(Base::Vector2d(pnt1.x, pnt1.y)); - bool bpolyInside = true; - - if ((pnt0Inside && pnt1Inside) || touchMode) { - double startangle, endangle; - - aoh->getRange(startangle, endangle, /*emulateCCW=*/true); - - if (startangle > endangle)// if arc is reversed - std::swap(startangle, endangle); - - double range = endangle - startangle; - int countSegments = std::max(2, int(12.0 * range / (2 * M_PI))); - if (touchMode) - countSegments = countSegments * 2.5; - - float segment = float(range) / countSegments; - - // circumscribed polygon radius - float a = float(aoh->getMajorRadius()) / cos(segment / 2); - float b = float(aoh->getMinorRadius()) / cos(segment / 2); - float phi = float(aoh->getAngleXU()); - - pnt0 = aoh->getCenter(); - float angle = float(startangle) + segment / 2; - for (int i = 0; i < countSegments; ++i, angle += segment) { - pnt = Base::Vector3d( - pnt0.x + a * cosh(angle) * cos(phi) - b * sinh(angle) * sin(phi), - pnt0.y + a * cosh(angle) * sin(phi) + b * sinh(angle) * cos(phi), - 0.f); - - Plm.multVec(pnt, pnt); - pnt = proj(pnt); - if (!polygon.Contains(Base::Vector2d(pnt.x, pnt.y))) { - bpolyInside = false; - if (!touchMode) - break; - } - else if (touchMode) { - bpolyInside = true; - break; - } - } - - if (bpolyInside) { - std::stringstream ss; - ss << "Edge" << GeoId + 1; - addSelection2(ss.str()); - } - } - if (pnt0Inside) { - std::stringstream ss; - ss << "Vertex" << VertexId - 1; - addSelection2(ss.str()); - } - - if (pnt1Inside) { - std::stringstream ss; - ss << "Vertex" << VertexId; - addSelection2(ss.str()); - } - - if (polygon.Contains(Base::Vector2d(pnt2.x, pnt2.y))) { - std::stringstream ss; - ss << "Vertex" << VertexId + 1; - addSelection2(ss.str()); - } - } - else if ((*it)->is()) { - // Check if arc lies inside box selection - const Part::GeomArcOfParabola* aop = static_cast(*it); - - pnt0 = aop->getStartPoint(); - pnt1 = aop->getEndPoint(); - pnt2 = aop->getCenter(); - - VertexId += 3; - - Plm.multVec(pnt0, pnt0); - Plm.multVec(pnt1, pnt1); - Plm.multVec(pnt2, pnt2); - pnt0 = proj(pnt0); - pnt1 = proj(pnt1); - pnt2 = proj(pnt2); - - bool pnt0Inside = polygon.Contains(Base::Vector2d(pnt0.x, pnt0.y)); - bool pnt1Inside = polygon.Contains(Base::Vector2d(pnt1.x, pnt1.y)); - bool bpolyInside = true; - - if ((pnt0Inside && pnt1Inside) || touchMode) { - double startangle, endangle; - - aop->getRange(startangle, endangle, /*emulateCCW=*/true); - - if (startangle > endangle)// if arc is reversed - std::swap(startangle, endangle); - - double range = endangle - startangle; - int countSegments = std::max(2, int(12.0 * range / (2 * M_PI))); - if (touchMode) - countSegments = countSegments * 2.5; - - float segment = float(range) / countSegments; - // In local coordinate system, value() of parabola is: - // P(U) = O + U*U/(4.*F)*XDir + U*YDir - // circumscribed polygon radius - float focal = float(aop->getFocal()) / cos(segment / 2); - float phi = float(aop->getAngleXU()); - - pnt0 = aop->getCenter(); - float angle = float(startangle) + segment / 2; - for (int i = 0; i < countSegments; ++i, angle += segment) { - pnt = Base::Vector3d( - pnt0.x + angle * angle / 4 / focal * cos(phi) - angle * sin(phi), - pnt0.y + angle * angle / 4 / focal * sin(phi) + angle * cos(phi), - 0.f); - - Plm.multVec(pnt, pnt); - pnt = proj(pnt); - if (!polygon.Contains(Base::Vector2d(pnt.x, pnt.y))) { - bpolyInside = false; - if (!touchMode) - break; - } - else if (touchMode) { - bpolyInside = true; - break; - } - } - - if (bpolyInside) { - std::stringstream ss; - ss << "Edge" << GeoId + 1; - addSelection2(ss.str()); - } - } - - if (pnt0Inside) { - std::stringstream ss; - ss << "Vertex" << VertexId - 1; - addSelection2(ss.str()); - } - - if (pnt1Inside) { - std::stringstream ss; - ss << "Vertex" << VertexId; - addSelection2(ss.str()); - } - - if (polygon.Contains(Base::Vector2d(pnt2.x, pnt2.y))) { - std::stringstream ss; - ss << "Vertex" << VertexId + 1; - addSelection2(ss.str()); + selectEdgeIfInsideBox(aoc); } } else if ((*it)->is()) { const Part::GeomBSplineCurve* spline = static_cast(*it); - // std::vector poles = spline->getPoles(); - VertexId += 2; - Plm.multVec(spline->getStartPoint(), pnt1); - Plm.multVec(spline->getEndPoint(), pnt2); - pnt1 = proj(pnt1); - pnt2 = proj(pnt2); + Base::Vector3d pnt1 = inBBCoords(spline->getStartPoint()); + VertexId++; + bool pnt1Inside = selectVertexIfInsideBox(pnt1); - bool pnt1Inside = polygon.Contains(Base::Vector2d(pnt1.x, pnt1.y)); - bool pnt2Inside = polygon.Contains(Base::Vector2d(pnt2.x, pnt2.y)); - if (pnt1Inside || (touchMode && pnt2Inside)) { - std::stringstream ss; - ss << "Vertex" << VertexId; - addSelection2(ss.str()); - } - - if (pnt2Inside || (touchMode && pnt1Inside)) { - std::stringstream ss; - ss << "Vertex" << VertexId + 1; - addSelection2(ss.str()); - } - - // This is a rather approximated approach. No it does not guarantee that the whole curve - // is boxed, specially for periodic curves, but it works reasonably well. Including all - // poles, which could be done, generally forces the user to select much more than the - // curve (all the poles) and it would not select the curve in cases where it is indeed - // comprised in the box. The implementation of the touch mode is also far from a - // desirable "touch" as it only recognizes touched points not the curve itself - if ((pnt1Inside && pnt2Inside) || (touchMode && (pnt1Inside || pnt2Inside))) { - std::stringstream ss; - ss << "Edge" << GeoId + 1; - addSelection2(ss.str()); + Base::Vector3d pnt2 = inBBCoords(spline->getEndPoint()); + VertexId++; + bool pnt2Inside = selectVertexIfInsideBox(pnt2); + + if ((pnt1Inside && pnt2Inside) || touchMode) { + selectEdgeIfInsideBox(spline); } } + else { + Base::Console().DeveloperError("ViewProviderSketch::doBoxSelection", + "Geometry type is unsupported. Selection may be unsynchronised and fail."); + } } - pnt0 = proj(Plm.getPosition()); + Base::Vector3d pnt0 = proj(Plm.getPosition()); if (polygon.Contains(Base::Vector2d(pnt0.x, pnt0.y))) { std::stringstream ss; ss << "RootPoint"; diff --git a/src/Mod/Sketcher/Gui/ViewProviderSketch.h b/src/Mod/Sketcher/Gui/ViewProviderSketch.h index ed44ef6ddb..792a81d356 100644 --- a/src/Mod/Sketcher/Gui/ViewProviderSketch.h +++ b/src/Mod/Sketcher/Gui/ViewProviderSketch.h @@ -461,6 +461,9 @@ private: false; // indicates whether the present virtual space view is the // Real Space or the Virtual Space (virtual space 1 or 2) bool buttonPress = false; + + int stdCountSegments = + 50; // preferences controlled default geometry sampling for selection }; /** @brief Private struct grouping ViewProvider and RenderManager node, to be used as SoNode