diff --git a/src/Mod/Sketcher/App/Sketch.cpp b/src/Mod/Sketcher/App/Sketch.cpp index a42bbdbcb4..b328cb3595 100644 --- a/src/Mod/Sketcher/App/Sketch.cpp +++ b/src/Mod/Sketcher/App/Sketch.cpp @@ -3178,7 +3178,7 @@ int Sketch::addDistanceConstraint(int geoId, double* value, bool driving) return ConstraintsCounter; } -// point to line or circle distance constraint +// point to line or circular distance constraint int Sketch::addDistanceConstraint(int geoId1, PointPos pos1, int geoId2, @@ -3201,15 +3201,20 @@ int Sketch::addDistanceConstraint(int geoId1, GCSsys.addConstraintP2LDistance(p1, l2, value, tag, driving); return ConstraintsCounter; } - else if (Geoms[geoId2].type == Circle) { - GCS::Circle& c2 = Circles[Geoms[geoId2].index]; - - int tag = ++ConstraintsCounter; - GCSsys.addConstraintP2CDistance(p1, c2, value, tag, driving); - return ConstraintsCounter; - } else { - return -1; + GCS::Circle* c2; + if (Geoms[geoId2].type == Circle) { + c2 = &Circles[Geoms[geoId2].index]; + } + else if (Geoms[geoId2].type == Arc) { + c2 = &Arcs[Geoms[geoId2].index]; + } + else { + return -1; + } + int tag = ++ConstraintsCounter; + GCSsys.addConstraintP2CDistance(p1, *c2, value, tag, driving); + return ConstraintsCounter; } } @@ -3239,7 +3244,7 @@ int Sketch::addDistanceConstraint(int geoId1, return -1; } -// circle-(circle or line) distance constraint +// circular-(circular or line) distance constraint int Sketch::addDistanceConstraint(int geoId1, int geoId2, double* value, bool driving) { geoId1 = checkGeoId(geoId1); @@ -3259,23 +3264,19 @@ int Sketch::addDistanceConstraint(int geoId1, int geoId2, double* value, bool dr return ConstraintsCounter; } else { - if ((Geoms[geoId1].type == Circle) && (Geoms[geoId2].type == Circle)) { + if (Geoms[geoId1].type == Circle) { c1 = &Circles[Geoms[geoId1].index]; + } + else if (Geoms[geoId1].type == Arc) { + c1 = &Arcs[Geoms[geoId1].index]; + } + if (Geoms[geoId2].type == Circle) { c2 = &Circles[Geoms[geoId2].index]; } - else if ((Geoms[geoId1].type == Arc) && (Geoms[geoId2].type == Circle)) { - c1 = &Arcs[Geoms[geoId1].index]; - c2 = &Circles[Geoms[geoId2].index]; - } - else if ((Geoms[geoId1].type == Circle) && (Geoms[geoId2].type == Arc)) { - c1 = &Circles[Geoms[geoId1].index]; + else if (Geoms[geoId2].type == Arc) { c2 = &Arcs[Geoms[geoId2].index]; } - else if ((Geoms[geoId1].type == Arc) && (Geoms[geoId2].type == Arc)) { - c1 = &Arcs[Geoms[geoId1].index]; - c2 = &Arcs[Geoms[geoId2].index]; - } - else { + if (c1 == nullptr || c2 == nullptr) { return -1; } diff --git a/src/Mod/Sketcher/App/SketchObject.cpp b/src/Mod/Sketcher/App/SketchObject.cpp index a3c35d1c82..fe6906223e 100644 --- a/src/Mod/Sketcher/App/SketchObject.cpp +++ b/src/Mod/Sketcher/App/SketchObject.cpp @@ -445,9 +445,12 @@ int SketchObject::setDatum(int ConstrId, double Datum) if (!vals[ConstrId]->isDimensional() && type != Tangent && type != Perpendicular) return -1; - if ((type == Distance || type == Radius || type == Diameter || type == Weight) && Datum <= 0) + if ((type == Radius || type == Diameter || type == Weight) && Datum <= 0) return (Datum == 0) ? -5 : -4; + if (type == Distance && Datum == 0) + return -5; + // copy the list std::vector newVals(vals); double oldDatum = newVals[ConstrId]->getValue(); diff --git a/src/Mod/Sketcher/Gui/CommandConstraints.cpp b/src/Mod/Sketcher/Gui/CommandConstraints.cpp index f792900fd1..eace6bc300 100644 --- a/src/Mod/Sketcher/Gui/CommandConstraints.cpp +++ b/src/Mod/Sketcher/Gui/CommandConstraints.cpp @@ -4370,7 +4370,7 @@ void CmdSketcherConstrainDistance::activated(int iMsg) radius1 = arcSeg1->getRadius(); center1 = arcSeg1->getCenter(); } - if (isArcOfCircle(*geom2))) { + if (isArcOfCircle(*geom2)) { auto arcSeg2 = static_cast(geom2); radius2 = arcSeg2->getRadius(); center2 = arcSeg2->getCenter(); diff --git a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp index e4f6715ee3..bc754d3a75 100644 --- a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp +++ b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp @@ -1698,24 +1698,67 @@ void ViewProviderSketch::moveConstraint(int constNum, const Base::Vector2d& toPo } else if (Constr->Second != GeoEnum::GeoUndef) { p1 = getSolvedSketch().getPoint(Constr->First, Constr->FirstPos); - const Part::Geometry *geo = GeoList::getGeometryFromGeoId (geomlist, Constr->Second); const Part::Geometry *geo1 = GeoList::getGeometryFromGeoId (geomlist, Constr->First); - if (geo->is()) { // point to line distance - auto *lineSeg = static_cast(geo); - Base::Vector3d l2p1 = lineSeg->getStartPoint(); - Base::Vector3d l2p2 = lineSeg->getEndPoint(); - // calculate the projection of p1 onto line2 - p2.ProjectToLine(p1-l2p1, l2p2-l2p1); - p2 += p1; - } else if (geo->is() // circle to circle distance - || geo->is()) { - if (geo1->is() - || geo1->is()) { - GetCirclesMinimalDistance(geo1, geo, p1, p2); + const Part::Geometry *geo2 = GeoList::getGeometryFromGeoId (geomlist, Constr->Second); + if (isLineSegment(*geo2)) { + if (isCircle(*geo1) || isArcOfCircle(*geo1)){ + std::swap(geo1, geo2); // see below + } + else { + // point to line distance + auto lineSeg = static_cast(geo2); + Base::Vector3d l2p1 = lineSeg->getStartPoint(); + Base::Vector3d l2p2 = lineSeg->getEndPoint(); + // calculate the projection of p1 onto line2 + p2.ProjectToLine(p1-l2p1, l2p2-l2p1); + p2 += p1; + } + } + if (isCircle(*geo2) || isArcOfCircle(*geo2)) { + if (Constr->FirstPos != Sketcher::PointPos::none){ // circular to point distance + Base::Vector3d ct; + double rad = 0.0; + if (isCircle(*geo2)){ + auto circleSeg2 = static_cast(geo2); + ct = circleSeg2->getCenter(); + rad = circleSeg2->getRadius(); + } + else { + auto circleSeg2 = static_cast(geo2); + ct = circleSeg2->getCenter(); + rad = circleSeg2->getRadius(); + } + Base::Vector3d v = p1 - ct; + v = v.Normalize(); + p2 = ct + rad * v; + } + else if (isCircle(*geo1) || isArcOfCircle(*geo1)) { // circular to circular distance + GetCirclesMinimalDistance(geo1, geo2, p1, p2); + } + else if (isLineSegment(*geo1)){ // circular to line distance + auto lineSeg = static_cast(geo1); + Base::Vector3d l2p1 = lineSeg->getStartPoint(); + Base::Vector3d l2p2 = lineSeg->getEndPoint(); + + Base::Vector3d ct; + double rad; + if (isCircle(*geo2)){ + auto circleSeg = static_cast(geo2); + ct = circleSeg->getCenter(); + rad = circleSeg->getRadius(); + } + else { + auto circleSeg = static_cast(geo2); + ct = circleSeg->getCenter(); + rad = circleSeg->getRadius(); + } + p1.ProjectToLine(ct - l2p1, l2p2 - l2p1);// project on the line translated to origin + Base::Vector3d v = p1; + p1 += ct; + v.Normalize(); + p2 = ct + v * rad; } } - else - return; } else if (Constr->FirstPos != Sketcher::PointPos::none) { p2 = getSolvedSketch().getPoint(Constr->First, Constr->FirstPos);