Sketcher: Extend distance constraint to arcs

This commit is contained in:
Florian Foinant-Willig
2023-09-03 22:29:27 +02:00
committed by abdullahtahiriyo
parent 94eaa7db78
commit d2a579bdc6
4 changed files with 86 additions and 39 deletions

View File

@@ -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;
}

View File

@@ -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<Constraint*> newVals(vals);
double oldDatum = newVals[ConstrId]->getValue();

View File

@@ -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<const Part::GeomArcOfCircle*>(geom2);
radius2 = arcSeg2->getRadius();
center2 = arcSeg2->getCenter();

View File

@@ -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<Part::GeomLineSegment>()) { // point to line distance
auto *lineSeg = static_cast<const Part::GeomLineSegment *>(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<Part::GeomCircle>() // circle to circle distance
|| geo->is<Part::GeomArcOfCircle>()) {
if (geo1->is<Part::GeomCircle>()
|| geo1->is<Part::GeomArcOfCircle>()) {
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<const Part::GeomLineSegment *>(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<const Part::GeomCircle*>(geo2);
ct = circleSeg2->getCenter();
rad = circleSeg2->getRadius();
}
else {
auto circleSeg2 = static_cast<const Part::GeomArcOfCircle*>(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<const Part::GeomLineSegment*>(geo1);
Base::Vector3d l2p1 = lineSeg->getStartPoint();
Base::Vector3d l2p2 = lineSeg->getEndPoint();
Base::Vector3d ct;
double rad;
if (isCircle(*geo2)){
auto circleSeg = static_cast<const Part::GeomCircle*>(geo2);
ct = circleSeg->getCenter();
rad = circleSeg->getRadius();
}
else {
auto circleSeg = static_cast<const Part::GeomArcOfCircle*>(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);