From b97a2ef6dcd4f0a93c243cdebea4acbfb26c8115 Mon Sep 17 00:00:00 2001 From: Paddle Date: Tue, 12 Sep 2023 10:40:30 +0200 Subject: [PATCH 1/2] Adds a small convenience function to get arc of circle angle. --- src/Mod/Part/App/Geometry.cpp | 15 ++++++++++++++- src/Mod/Part/App/Geometry.h | 2 ++ src/Mod/Sketcher/Gui/CommandConstraints.cpp | 6 ++---- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/Mod/Part/App/Geometry.cpp b/src/Mod/Part/App/Geometry.cpp index a461fe6eca..fa2ed4043e 100644 --- a/src/Mod/Part/App/Geometry.cpp +++ b/src/Mod/Part/App/Geometry.cpp @@ -2428,11 +2428,24 @@ void GeomArcOfCircle::setRadius(double Radius) } } +/*! + * \brief GeomArcOfCircle::getAngle + * \param emulateCCWXY: if true, the arc will pretend to be a CCW arc in XY plane. + * For this to work, the arc must lie in XY plane (i.e. Axis is either +Z or -Z). + */ +double GeomArcOfCircle::getAngle(bool emulateCCWXY) const +{ + double startangle, endangle; + getRange(startangle, endangle, emulateCCWXY); + double angle = endangle - startangle; + return angle; +} + /*! * \brief GeomArcOfCircle::getRange * \param u [out] start angle of the arc, in radians. * \param v [out] end angle of the arc, in radians. - * \param emulateCCWXY: if true, the arc will pretent to be a CCW arc in XY plane. + * \param emulateCCWXY: if true, the arc will pretend to be a CCW arc in XY plane. * For this to work, the arc must lie in XY plane (i.e. Axis is either +Z or -Z). * Additionally, arc's rotation as a whole will be included in the returned u,v * (ArcOfCircle specific). diff --git a/src/Mod/Part/App/Geometry.h b/src/Mod/Part/App/Geometry.h index 6ca3eb8e33..aa92f85c2e 100644 --- a/src/Mod/Part/App/Geometry.h +++ b/src/Mod/Part/App/Geometry.h @@ -502,6 +502,8 @@ public: double getRadius() const; void setRadius(double Radius); + double getAngle(bool emulateCCWXY) const; + void getRange(double& u, double& v, bool emulateCCWXY) const override; void setRange(double u, double v, bool emulateCCWXY) override; diff --git a/src/Mod/Sketcher/Gui/CommandConstraints.cpp b/src/Mod/Sketcher/Gui/CommandConstraints.cpp index b9ef7c96d4..89f8e68f8f 100644 --- a/src/Mod/Sketcher/Gui/CommandConstraints.cpp +++ b/src/Mod/Sketcher/Gui/CommandConstraints.cpp @@ -8772,7 +8772,7 @@ void CmdSketcherConstrainAngle::activated(int iMsg) return; } } - else if (isEdge(GeoId1, PosId1)) {// line angle + else if (isEdge(GeoId1, PosId1)) {// line angle or arc angle if (GeoId1 < 0 && GeoId1 >= Sketcher::GeoEnum::VAxis) { Gui::TranslatedUserWarning( Obj, @@ -8812,9 +8812,7 @@ void CmdSketcherConstrainAngle::activated(int iMsg) } else if (isArcOfCircle(*geom)) { auto arc = static_cast(geom); - double startangle, endangle; - arc->getRange(startangle, endangle, /*EmulateCCWXY=*/true); - double angle = endangle - startangle; + double angle = arc->getAngle(/*EmulateCCWXY=*/true); openCommand(QT_TRANSLATE_NOOP("Command", "Add angle constraint")); Gui::cmdAppObjectArgs(selection[0].getObject(), From f080b39829683984a1918b6281646c168d8c1246 Mon Sep 17 00:00:00 2001 From: Paddle Date: Sat, 16 Sep 2023 08:12:35 +0200 Subject: [PATCH 2/2] Sketcher_Dimension : adds arc-angle mode for arcs. --- src/Mod/Sketcher/Gui/CommandConstraints.cpp | 46 +++++++++++++++++---- 1 file changed, 39 insertions(+), 7 deletions(-) diff --git a/src/Mod/Sketcher/Gui/CommandConstraints.cpp b/src/Mod/Sketcher/Gui/CommandConstraints.cpp index 89f8e68f8f..347a689f33 100644 --- a/src/Mod/Sketcher/Gui/CommandConstraints.cpp +++ b/src/Mod/Sketcher/Gui/CommandConstraints.cpp @@ -1794,10 +1794,19 @@ protected: void makeCts_1Circle(bool& selAllowed, Base::Vector2d onSketchPos) { - //Radius/diameter. Mode changes in createRadiusDiameterConstrain. - restartCommand(QT_TRANSLATE_NOOP("Command", "Add Radius constraint")); - createRadiusDiameterConstrain(selCircleArc[0].GeoId, onSketchPos); - selAllowed = true; + const Part::Geometry* geom = Obj->getGeometry(selCircleArc[0].GeoId); + if (availableConstraint == AvailableConstraint::FIRST + || availableConstraint == AvailableConstraint::SECOND) { + //Radius/diameter. Mode changes in createRadiusDiameterConstrain. + restartCommand(QT_TRANSLATE_NOOP("Command", "Add Radius constraint")); + createRadiusDiameterConstrain(selCircleArc[0].GeoId, onSketchPos); + selAllowed = true; + } + if (availableConstraint == AvailableConstraint::THIRD) { + restartCommand(QT_TRANSLATE_NOOP("Command", "Add arc angle constraint")); + createArcAngleConstrain(selCircleArc[0].GeoId, onSketchPos); + availableConstraint = AvailableConstraint::RESET; + } } void makeCts_2Circle(bool& selAllowed, Base::Vector2d onSketchPos) @@ -2037,9 +2046,10 @@ protected: radius = circle->getRadius(); } - if (isBsplinePole(geom)) + if (isBsplinePole(geom)) { Gui::cmdAppObjectArgs(Obj, "addConstraint(Sketcher.Constraint('Weight',%d,%f)) ", GeoId, radius); + } else { ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher/dimensioning"); bool dimensioningDiameter = hGrp->GetBool("DimensioningDiameter", true); @@ -2048,8 +2058,10 @@ protected: bool firstCstr = true; if (availableConstraint != AvailableConstraint::FIRST) { firstCstr = false; - //This way if key is pressed again it goes back to FIRST - availableConstraint = AvailableConstraint::RESET; + if (!isArcOfCircle(*geom)) { + //This way if key is pressed again it goes back to FIRST + availableConstraint = AvailableConstraint::RESET; + } } if ((firstCstr && dimensioningRadius && !dimensioningDiameter) || @@ -2213,6 +2225,26 @@ protected: } } + void createArcAngleConstrain(int GeoId, Base::Vector2d onSketchPos) { + const Part::Geometry* geom = Obj->getGeometry(GeoId); + if (isArcOfCircle(*geom)) { + + const auto* arc = static_cast(geom); + double angle = arc->getAngle(/*EmulateCCWXY=*/true); + + Gui::cmdAppObjectArgs(Obj, "addConstraint(Sketcher.Constraint('Angle',%d,%f))", + GeoId, angle); + + const std::vector& ConStr = Obj->Constraints.getValues(); + if (isPointOrSegmentFixed(Obj, GeoId) || constraintCreationMode == Reference) { + // it is a constraint on a external line, make it non-driving + Gui::cmdAppObjectArgs(Obj, "setDriving(%i,%s)", ConStr.size() - 1, "False"); + } + numberOfConstraintsCreated++; + moveConstraint(ConStr.size() - 1, onSketchPos); + } + } + void createVerticalConstrain(int GeoId1, Sketcher::PointPos PosId1, int GeoId2, Sketcher::PointPos PosId2) { if (selLine.size() == 1) { Gui::cmdAppObjectArgs(sketchgui->getObject(), "addConstraint(Sketcher.Constraint('Vertical',%d)) ", GeoId1);