diff --git a/src/Mod/Sketcher/Gui/CommandConstraints.cpp b/src/Mod/Sketcher/Gui/CommandConstraints.cpp index b04b9912ad..35f326c31a 100644 --- a/src/Mod/Sketcher/Gui/CommandConstraints.cpp +++ b/src/Mod/Sketcher/Gui/CommandConstraints.cpp @@ -1792,10 +1792,10 @@ protected: void makeCts_1Point1Circle(bool& selAllowed, Base::Vector2d onSketchPos) { - //Distance. For now only circles not arcs! + //Distance const Part::Geometry* geom = Obj->getGeometry(selCircleArc[0].GeoId); - if (availableConstraint == AvailableConstraint::FIRST && isCircle(*geom)) { + if (availableConstraint == AvailableConstraint::FIRST) { restartCommand(QT_TRANSLATE_NOOP("Command", "Add length constraint")); createDistanceConstrain(selPoints[0].GeoId, selPoints[0].PosId, selCircleArc[0].GeoId, selCircleArc[0].PosId, onSketchPos); selAllowed = true; @@ -1885,10 +1885,10 @@ protected: void makeCts_1Line1Circle(bool& selAllowed, Base::Vector2d onSketchPos) { - //Distance. For now only circles not arcs! + //Distance const Part::Geometry* geom = Obj->getGeometry(selCircleArc[0].GeoId); - if (availableConstraint == AvailableConstraint::FIRST && isCircle(*geom)) { + if (availableConstraint == AvailableConstraint::FIRST) { restartCommand(QT_TRANSLATE_NOOP("Command", "Add length constraint")); createDistanceConstrain(selCircleArc[0].GeoId, selCircleArc[0].PosId, selLine[0].GeoId, selLine[0].PosId, onSketchPos); //Line second parameter selAllowed = true; @@ -1966,17 +1966,9 @@ protected: void makeCts_2Circle(bool& selAllowed, Base::Vector2d onSketchPos) { //Distance, radial distance, equality - //Distance: For now only circles not arcs! - const Part::Geometry* geom = Obj->getGeometry(selCircleArc[0].GeoId); - const Part::Geometry* geom2 = Obj->getGeometry(selCircleArc[1].GeoId); if (availableConstraint == AvailableConstraint::FIRST) { - if (isCircle(*geom) && isCircle(*geom2)) { - restartCommand(QT_TRANSLATE_NOOP("Command", "Add length constraint")); - createDistanceConstrain(selCircleArc[0].GeoId, selCircleArc[0].PosId, selCircleArc[1].GeoId, selCircleArc[1].PosId, onSketchPos); - } - else { - availableConstraint = AvailableConstraint::THIRD; - } + restartCommand(QT_TRANSLATE_NOOP("Command", "Add length constraint")); + createDistanceConstrain(selCircleArc[0].GeoId, selCircleArc[0].PosId, selCircleArc[1].GeoId, selCircleArc[1].PosId, onSketchPos); selAllowed = true; } if (availableConstraint == AvailableConstraint::SECOND) { @@ -2054,8 +2046,8 @@ protected: } bool arebothpointsorsegmentsfixed = isPointOrSegmentFixed(Obj, GeoId1) && isPointOrSegmentFixed(Obj, GeoId2); - - if (PosId1 != Sketcher::PointPos::none && PosId2 == Sketcher::PointPos::none) { // Point-line case and point-circle + // Point-line case and point-circle/arc + if (PosId1 != Sketcher::PointPos::none && PosId2 == Sketcher::PointPos::none) { Base::Vector3d pnt = Obj->getPoint(GeoId1, PosId1); double ActDist = 0.; const Part::Geometry* geom = Obj->getGeometry(GeoId2); @@ -2073,40 +2065,63 @@ protected: Base::Vector3d di = ct - pnt; ActDist = std::abs(di.Length() - circle->getRadius()); } + else if (isArcOfCircle(*geom)) { + auto arc = static_cast(geom); + Base::Vector3d ct = arc->getCenter(); + Base::Vector3d di = ct - pnt; + ActDist = std::abs(di.Length() - arc->getRadius()); + } Gui::cmdAppObjectArgs(Obj, "addConstraint(Sketcher.Constraint('Distance',%d,%d,%d,%f)) ", GeoId1, static_cast(PosId1), GeoId2, ActDist); } - else if (PosId1 == Sketcher::PointPos::none && PosId2 == Sketcher::PointPos::none) { // Circle - line, circle - circle cases + // Circle/arc - line, circle/arc - circle/arc cases + else if (PosId1 == Sketcher::PointPos::none + && PosId2 == Sketcher::PointPos::none) { const Part::Geometry* geo1 = Obj->getGeometry(GeoId1); const Part::Geometry* geo2 = Obj->getGeometry(GeoId2); - - if (isCircle(*geo1) && isLineSegment(*geo2)) { // Circle - line case - auto circleSeg = static_cast(geo1); - double radius = circleSeg->getRadius(); - Base::Vector3d center = circleSeg->getCenter(); - + double radius1, radius2; + Base::Vector3d center1, center2; + if (isCircle(*geo1)) { + auto conic = static_cast(geo1); + radius1 = conic->getRadius(); + center1 = conic->getCenter(); + } + else if (isArcOfCircle(*geo1)) { + auto conic = static_cast(geo1); + radius1 = conic->getRadius(); + center1 = conic->getCenter(); + } + if (isCircle(*geo2)) { + auto conic = static_cast(geo2); + radius2 = conic->getRadius(); + center2 = conic->getCenter(); + } + else if (isArcOfCircle(*geo2)){ + auto conic = static_cast(geo2); + radius2 = conic->getRadius(); + center2 = conic->getCenter(); + } + // Circle/arc - line case + if ((isCircle(*geo1) || isArcOfCircle(*geo1)) && isLineSegment(*geo2)) { auto lineSeg = static_cast(geo2); Base::Vector3d pnt1 = lineSeg->getStartPoint(); Base::Vector3d pnt2 = lineSeg->getEndPoint(); Base::Vector3d d = pnt2 - pnt1; double ActDist = - std::abs(-center.x * d.y + center.y * d.x + pnt1.x * pnt2.y - pnt2.x * pnt1.y) - / d.Length() - - radius; + std::abs(-center1.x * d.y + center1.y * d.x + pnt1.x * pnt2.y - pnt2.x * pnt1.y) + / d.Length() + - radius1; - Gui::cmdAppObjectArgs(Obj, "addConstraint(Sketcher.Constraint('Distance',%d,%d,%f))", - GeoId1, GeoId2, ActDist); + Gui::cmdAppObjectArgs(Obj, + "addConstraint(Sketcher.Constraint('Distance',%d,%d,%f))", + GeoId1, + GeoId2, + ActDist); } - else if (isCircle(*geo1) && isCircle(*geo2)) { // Circle - circle case - auto circleSeg1 = static_cast(geo1); - double radius1 = circleSeg1->getRadius(); - Base::Vector3d center1 = circleSeg1->getCenter(); - - auto circleSeg2 = static_cast(geo2); - double radius2 = circleSeg2->getRadius(); - Base::Vector3d center2 = circleSeg2->getCenter(); - + // Circle/arc - circle/arc case + else if ((isCircle(*geo1) || isArcOfCircle(*geo1)) + && (isCircle(*geo2) || isArcOfCircle(*geo2))) { double ActDist = 0.; Base::Vector3d intercenter = center1 - center2; @@ -2123,21 +2138,28 @@ protected: ActDist = bigradius - smallradius - intercenterdistance; } - Gui::cmdAppObjectArgs(Obj, "addConstraint(Sketcher.Constraint('Distance',%d,%d,%f))", - GeoId1, GeoId2, ActDist); + Gui::cmdAppObjectArgs(Obj, + "addConstraint(Sketcher.Constraint('Distance',%d,%d,%f))", + GeoId1, + GeoId2, + ActDist); } } - else { //both points + else { // both points Base::Vector3d pnt1 = Obj->getPoint(GeoId1, PosId1); Base::Vector3d pnt2 = Obj->getPoint(GeoId2, PosId2); - Gui::cmdAppObjectArgs(Obj, "addConstraint(Sketcher.Constraint('Distance',%d,%d,%d,%d,%f)) ", - GeoId1, static_cast(PosId1), GeoId2, static_cast(PosId2), (pnt2 - pnt1).Length()); + Gui::cmdAppObjectArgs(Obj, + "addConstraint(Sketcher.Constraint('Distance',%d,%d,%d,%d,%f)) ", + GeoId1, + static_cast(PosId1), + GeoId2, + static_cast(PosId2), + (pnt2 - pnt1).Length()); } const std::vector& ConStr = Obj->Constraints.getValues(); - if (arebothpointsorsegmentsfixed - || GeoId1 <= Sketcher::GeoEnum::RefExt + if (arebothpointsorsegmentsfixed || GeoId1 <= Sketcher::GeoEnum::RefExt || constraintCreationMode == Reference) { // it is a constraint on a external line, make it non-driving Gui::cmdAppObjectArgs(Obj, "setDriving(%i,%s)", ConStr.size() - 1, "False");