From ef2a723a32b24a95f74a902125a2aac2a6b99aa7 Mon Sep 17 00:00:00 2001 From: Paddle Date: Fri, 24 Nov 2023 11:45:10 +0100 Subject: [PATCH] Draw arc helpers for radius constraints. --- src/Gui/SoDatumLabel.cpp | 22 +++++++ .../Gui/EditModeConstraintCoinManager.cpp | 61 ++++++++++++++----- 2 files changed, 69 insertions(+), 14 deletions(-) diff --git a/src/Gui/SoDatumLabel.cpp b/src/Gui/SoDatumLabel.cpp index c8997233a0..2e2b44b3c4 100644 --- a/src/Gui/SoDatumLabel.cpp +++ b/src/Gui/SoDatumLabel.cpp @@ -996,6 +996,13 @@ void SoDatumLabel::GLRender(SoGLRenderAction * action) SbVec3f p2 = points[1]; SbVec3f dir = (p2-p1); + SbVec3f center = p1; + double radius = (p2 - p1).length(); + if (this->datumtype.getValue() == DIAMETER) { + center = (p1 + p2) / 2; + radius = radius / 2; + } + dir.normalize(); SbVec3f normal (-dir[1],dir[0],0); @@ -1055,7 +1062,22 @@ void SoDatumLabel::GLRender(SoGLRenderAction * action) glVertex2f(ar1_1[0], ar1_1[1]); glVertex2f(ar2_1[0], ar2_1[1]); glEnd(); + } + // Draw arc helper if needed + float startangle = this->param3.getValue(); + float range = this->param4.getValue(); + if (range != 0.0) { + int countSegments = std::max(6, abs(int(50.0 * range / (2 * M_PI)))); + double segment = range / (countSegments - 1); + + glBegin(GL_LINE_STRIP); + for (int i = 0; i < countSegments; i++) { + double theta = startangle + segment * i; + SbVec3f v1 = center + SbVec3f(radius * cos(theta), radius * sin(theta), 0); + glVertex2f(v1[0], v1[1]); + } + glEnd(); } } diff --git a/src/Mod/Sketcher/Gui/EditModeConstraintCoinManager.cpp b/src/Mod/Sketcher/Gui/EditModeConstraintCoinManager.cpp index 6286074e61..c8eb0a17d5 100644 --- a/src/Mod/Sketcher/Gui/EditModeConstraintCoinManager.cpp +++ b/src/Mod/Sketcher/Gui/EditModeConstraintCoinManager.cpp @@ -1332,27 +1332,42 @@ Restart: assert(Constr->First >= -extGeoCount && Constr->First < intGeoCount); Base::Vector3d pnt1(0., 0., 0.), pnt2(0., 0., 0.); + double helperStartAngle = 0.; + double helperRange = 0.; + if (Constr->First != GeoEnum::GeoUndef) { const Part::Geometry* geo = geolistfacade.getGeometryFromGeoId(Constr->First); if (geo->is()) { - const Part::GeomArcOfCircle* arc = - static_cast(geo); + auto* arc = static_cast(geo); double radius = arc->getRadius(); double angle = (double)Constr->LabelPosition; + double startAngle, endAngle; + arc->getRange(startAngle, endAngle, /*emulateCCW=*/true); if (angle == 10) { - double startangle, endangle; - arc->getRange(startangle, endangle, /*emulateCCW=*/true); - angle = (startangle + endangle) / 2; + angle = (startAngle + endAngle) / 2; + } + if (!(angle > startAngle && angle < endAngle)) { + if (angle < startAngle + && startAngle - angle < angle + 2 * M_PI - endAngle) { + helperStartAngle = angle; + helperRange = startAngle - angle; + } + else { + if (angle < endAngle) { + angle += 2 * M_PI; + } + helperStartAngle = endAngle; + helperRange = angle - endAngle; + } } Base::Vector3d center = arc->getCenter(); pnt1 = center - radius * Base::Vector3d(cos(angle), sin(angle), 0.); pnt2 = center + radius * Base::Vector3d(cos(angle), sin(angle), 0.); } else if (geo->is()) { - const Part::GeomCircle* circle = - static_cast(geo); + auto* circle = static_cast(geo); double radius = circle->getRadius(); double angle = (double)Constr->LabelPosition; if (angle == 10) { @@ -1383,6 +1398,8 @@ Restart: asciiText->datumtype = SoDatumLabel::DIAMETER; asciiText->param1 = Constr->LabelDistance; asciiText->param2 = Constr->LabelPosition; + asciiText->param3 = helperStartAngle; + asciiText->param4 = helperRange; asciiText->pnts.setNum(2); SbVec3f* verts = asciiText->pnts.startEditing(); @@ -1397,27 +1414,41 @@ Restart: assert(Constr->First >= -extGeoCount && Constr->First < intGeoCount); Base::Vector3d pnt1(0., 0., 0.), pnt2(0., 0., 0.); + double helperStartAngle = 0.; + double helperRange = 0.; if (Constr->First != GeoEnum::GeoUndef) { const Part::Geometry* geo = geolistfacade.getGeometryFromGeoId(Constr->First); if (geo->is()) { - const Part::GeomArcOfCircle* arc = - static_cast(geo); + auto* arc = static_cast(geo); double radius = arc->getRadius(); double angle = (double)Constr->LabelPosition; + double startAngle, endAngle; + arc->getRange(startAngle, endAngle, /*emulateCCW=*/true); if (angle == 10) { - double startangle, endangle; - arc->getRange(startangle, endangle, /*emulateCCW=*/true); - angle = (startangle + endangle) / 2; + angle = (startAngle + endAngle) / 2; + } + if (!(angle > startAngle && angle < endAngle)) { + if (angle < startAngle + && startAngle - angle < angle + 2 * M_PI - endAngle) { + helperStartAngle = angle; + helperRange = startAngle - angle; + } + else { + if (angle < endAngle) { + angle += 2 * M_PI; + } + helperStartAngle = endAngle; + helperRange = angle - endAngle; + } } pnt1 = arc->getCenter(); pnt2 = pnt1 + radius * Base::Vector3d(cos(angle), sin(angle), 0.); } else if (geo->is()) { - const Part::GeomCircle* circle = - static_cast(geo); + auto* circle = static_cast(geo); auto gf = GeometryFacade::getFacade(geo); double radius; @@ -1458,6 +1489,8 @@ Restart: asciiText->datumtype = SoDatumLabel::RADIUS; asciiText->param1 = Constr->LabelDistance; asciiText->param2 = Constr->LabelPosition; + asciiText->param3 = helperStartAngle; + asciiText->param4 = helperRange; asciiText->pnts.setNum(2); SbVec3f* verts = asciiText->pnts.startEditing();