diff --git a/src/Mod/Sketcher/App/Sketch.cpp b/src/Mod/Sketcher/App/Sketch.cpp index fd29941145..a12383efe2 100644 --- a/src/Mod/Sketcher/App/Sketch.cpp +++ b/src/Mod/Sketcher/App/Sketch.cpp @@ -4315,168 +4315,10 @@ Base::Vector3d Sketch::calculateNormalAtPoint(int geoIdCurve, double px, double bool Sketch::updateGeometry() { int i = 0; - for (std::vector::const_iterator it = Geoms.begin(); it != Geoms.end(); ++it, i++) { + for (const GeoDef& it : Geoms) { try { - if (it->type == Point) { - GeomPoint* point = static_cast(it->geo); - auto pointf = GeometryFacade::getFacade(point); - - point->setPoint( - Vector3d(*Points[it->startPointId].x, *Points[it->startPointId].y, 0.0)); - } - else if (it->type == Line) { - GeomLineSegment* lineSeg = static_cast(it->geo); - lineSeg->setPoints(Vector3d(*Lines[it->index].p1.x, *Lines[it->index].p1.y, 0.0), - Vector3d(*Lines[it->index].p2.x, *Lines[it->index].p2.y, 0.0)); - } - else if (it->type == Arc) { - GCS::Arc& myArc = Arcs[it->index]; - // the following 4 lines are redundant since these equations are already included in - // the arc constraints *myArc.start.x = *myArc.center.x + *myArc.rad * - // cos(*myArc.startAngle); *myArc.start.y = *myArc.center.y + *myArc.rad * - // sin(*myArc.startAngle); *myArc.end.x = *myArc.center.x + *myArc.rad * - // cos(*myArc.endAngle); *myArc.end.y = *myArc.center.y + *myArc.rad * - // sin(*myArc.endAngle); - GeomArcOfCircle* aoc = static_cast(it->geo); - aoc->setCenter(Vector3d(*Points[it->midPointId].x, *Points[it->midPointId].y, 0.0)); - aoc->setRadius(*myArc.rad); - aoc->setRange(*myArc.startAngle, *myArc.endAngle, /*emulateCCW=*/true); - } - else if (it->type == ArcOfEllipse) { - GCS::ArcOfEllipse& myArc = ArcsOfEllipse[it->index]; - - GeomArcOfEllipse* aoe = static_cast(it->geo); - - Base::Vector3d center = - Vector3d(*Points[it->midPointId].x, *Points[it->midPointId].y, 0.0); - Base::Vector3d f1 = Vector3d(*myArc.focus1.x, *myArc.focus1.y, 0.0); - double radmin = *myArc.radmin; - - Base::Vector3d fd = f1 - center; - double radmaj = sqrt(fd * fd + radmin * radmin); - - aoe->setCenter(center); - // ensure that ellipse's major radius is always larger than minor radius... may - // still cause problems with degenerates. - if (radmaj >= aoe->getMinorRadius()) { - aoe->setMajorRadius(radmaj); - aoe->setMinorRadius(radmin); - } - else { - aoe->setMinorRadius(radmin); - aoe->setMajorRadius(radmaj); - } - aoe->setMajorAxisDir(fd); - aoe->setRange(*myArc.startAngle, *myArc.endAngle, /*emulateCCW=*/true); - } - else if (it->type == Circle) { - GeomCircle* circ = static_cast(it->geo); - circ->setCenter( - Vector3d(*Points[it->midPointId].x, *Points[it->midPointId].y, 0.0)); - circ->setRadius(*Circles[it->index].rad); - } - else if (it->type == Ellipse) { - - GeomEllipse* ellipse = static_cast(it->geo); - - Base::Vector3d center = - Vector3d(*Points[it->midPointId].x, *Points[it->midPointId].y, 0.0); - Base::Vector3d f1 = - Vector3d(*Ellipses[it->index].focus1.x, *Ellipses[it->index].focus1.y, 0.0); - double radmin = *Ellipses[it->index].radmin; - - Base::Vector3d fd = f1 - center; - double radmaj = sqrt(fd * fd + radmin * radmin); - - ellipse->setCenter(center); - // ensure that ellipse's major radius is always larger than minor radius... may - // still cause problems with degenerates. - if (radmaj >= ellipse->getMinorRadius()) { - ellipse->setMajorRadius(radmaj); - ellipse->setMinorRadius(radmin); - } - else { - ellipse->setMinorRadius(radmin); - ellipse->setMajorRadius(radmaj); - } - ellipse->setMajorAxisDir(fd); - } - else if (it->type == ArcOfHyperbola) { - GCS::ArcOfHyperbola& myArc = ArcsOfHyperbola[it->index]; - - GeomArcOfHyperbola* aoh = static_cast(it->geo); - - Base::Vector3d center = - Vector3d(*Points[it->midPointId].x, *Points[it->midPointId].y, 0.0); - Base::Vector3d f1 = Vector3d(*myArc.focus1.x, *myArc.focus1.y, 0.0); - double radmin = *myArc.radmin; - - Base::Vector3d fd = f1 - center; - double radmaj = sqrt(fd * fd - radmin * radmin); - - aoh->setCenter(center); - if (radmaj >= aoh->getMinorRadius()) { - aoh->setMajorRadius(radmaj); - aoh->setMinorRadius(radmin); - } - else { - aoh->setMinorRadius(radmin); - aoh->setMajorRadius(radmaj); - } - aoh->setMajorAxisDir(fd); - aoh->setRange(*myArc.startAngle, *myArc.endAngle, /*emulateCCW=*/true); - } - else if (it->type == ArcOfParabola) { - GCS::ArcOfParabola& myArc = ArcsOfParabola[it->index]; - - GeomArcOfParabola* aop = static_cast(it->geo); - - Base::Vector3d vertex = - Vector3d(*Points[it->midPointId].x, *Points[it->midPointId].y, 0.0); - Base::Vector3d f1 = Vector3d(*myArc.focus1.x, *myArc.focus1.y, 0.0); - - Base::Vector3d fd = f1 - vertex; - - aop->setXAxisDir(fd); - aop->setCenter(vertex); - aop->setFocal(fd.Length()); - aop->setRange(*myArc.startAngle, *myArc.endAngle, /*emulateCCW=*/true); - } - else if (it->type == BSpline) { - GCS::BSpline& mybsp = BSplines[it->index]; - - GeomBSplineCurve* bsp = static_cast(it->geo); - - std::vector poles; - std::vector weights; - - std::vector::const_iterator it1; - std::vector::const_iterator it2; - - for (it1 = mybsp.poles.begin(), it2 = mybsp.weights.begin(); - it1 != mybsp.poles.end() && it2 != mybsp.weights.end(); - ++it1, ++it2) { - poles.emplace_back(*(*it1).x, *(*it1).y, 0.0); - weights.push_back(*(*it2)); - } - - bsp->setPoles(poles, weights); - - std::vector knots; - std::vector mult; - - // This is the code that should be here when/if b-spline gets its full - // implementation in the solver. - /*std::vector::const_iterator it3; - std::vector::const_iterator it4; - - for( it3 = mybsp.knots.begin(), it4 = mybsp.mult.begin(); it3 != mybsp.knots.end() - && it4 != mybsp.mult.end(); ++it3, ++it4) { knots.push_back(*(*it3)); - mult.push_back((*it4)); - } - - bsp->setKnots(knots,mult);*/ - } + updateGeometry(it); + ++i; } catch (Base::Exception& e) { Base::Console().Error("Updating geometry: Error build geometry(%d): %s\n", i, e.what()); @@ -4486,6 +4328,214 @@ bool Sketch::updateGeometry() return true; } +void Sketch::tryUpdateGeometry() +{ + for (const GeoDef& it : Geoms) { + updateGeometry(it); + } +} + +void Sketch::updateGeometry(const GeoDef& it) +{ + if (it.type == Point) { + updatePoint(it); + } + else if (it.type == Line) { + updateLineSegment(it); + } + else if (it.type == Arc) { + updateArcOfCircle(it); + } + else if (it.type == ArcOfEllipse) { + updateArcOfEllipse(it); + } + else if (it.type == Circle) { + updateCircle(it); + } + else if (it.type == Ellipse) { + updateEllipse(it); + } + else if (it.type == ArcOfHyperbola) { + updateArcOfHyperbola(it); + } + else if (it.type == ArcOfParabola) { + updateArcOfParabola(it); + } + else if (it.type == BSpline) { + updateBSpline(it); + } +} + +void Sketch::updatePoint(const GeoDef& def) +{ + GeomPoint* point = static_cast(def.geo); + auto pointf = GeometryFacade::getFacade(point); + + point->setPoint(Vector3d(*Points[def.startPointId].x, *Points[def.startPointId].y, 0.0)); +} + +void Sketch::updateLineSegment(const GeoDef& def) +{ + GeomLineSegment* lineSeg = static_cast(def.geo); + lineSeg->setPoints(Vector3d(*Lines[def.index].p1.x, *Lines[def.index].p1.y, 0.0), + Vector3d(*Lines[def.index].p2.x, *Lines[def.index].p2.y, 0.0)); +} + +void Sketch::updateArcOfCircle(const GeoDef& def) +{ + GCS::Arc& myArc = Arcs[def.index]; + // the following 4 lines are redundant since these equations are already included in + // the arc constraints *myArc.start.x = *myArc.center.x + *myArc.rad * + // cos(*myArc.startAngle); *myArc.start.y = *myArc.center.y + *myArc.rad * + // sin(*myArc.startAngle); *myArc.end.x = *myArc.center.x + *myArc.rad * + // cos(*myArc.endAngle); *myArc.end.y = *myArc.center.y + *myArc.rad * + // sin(*myArc.endAngle); + GeomArcOfCircle* aoc = static_cast(def.geo); + aoc->setCenter(Vector3d(*Points[def.midPointId].x, *Points[def.midPointId].y, 0.0)); + aoc->setRadius(*myArc.rad); + aoc->setRange(*myArc.startAngle, *myArc.endAngle, /*emulateCCWXY=*/true); +} + +void Sketch::updateArcOfEllipse(const GeoDef& def) +{ + GCS::ArcOfEllipse& myArc = ArcsOfEllipse[def.index]; + + GeomArcOfEllipse* aoe = static_cast(def.geo); + + Base::Vector3d center = Vector3d(*Points[def.midPointId].x, *Points[def.midPointId].y, 0.0); + Base::Vector3d f1 = Vector3d(*myArc.focus1.x, *myArc.focus1.y, 0.0); + double radmin = *myArc.radmin; + + Base::Vector3d fd = f1 - center; + double radmaj = sqrt(fd * fd + radmin * radmin); + + aoe->setCenter(center); + // ensure that ellipse's major radius is always larger than minor radius... may + // still cause problems with degenerates. + if (radmaj >= aoe->getMinorRadius()) { + aoe->setMajorRadius(radmaj); + aoe->setMinorRadius(radmin); + } + else { + aoe->setMinorRadius(radmin); + aoe->setMajorRadius(radmaj); + } + aoe->setMajorAxisDir(fd); + aoe->setRange(*myArc.startAngle, *myArc.endAngle, /*emulateCCWXY=*/true); +} + +void Sketch::updateArcOfHyperbola(const GeoDef& def) +{ + GCS::ArcOfHyperbola& myArc = ArcsOfHyperbola[def.index]; + + GeomArcOfHyperbola* aoh = static_cast(def.geo); + + Base::Vector3d center = Vector3d(*Points[def.midPointId].x, *Points[def.midPointId].y, 0.0); + Base::Vector3d f1 = Vector3d(*myArc.focus1.x, *myArc.focus1.y, 0.0); + double radmin = *myArc.radmin; + + Base::Vector3d fd = f1 - center; + double radmaj = sqrt(fd * fd - radmin * radmin); + + aoh->setCenter(center); + if (radmaj >= aoh->getMinorRadius()) { + aoh->setMajorRadius(radmaj); + aoh->setMinorRadius(radmin); + } + else { + aoh->setMinorRadius(radmin); + aoh->setMajorRadius(radmaj); + } + aoh->setMajorAxisDir(fd); + aoh->setRange(*myArc.startAngle, *myArc.endAngle, /*emulateCCWXY=*/true); +} + +void Sketch::updateArcOfParabola(const GeoDef& def) +{ + GCS::ArcOfParabola& myArc = ArcsOfParabola[def.index]; + + GeomArcOfParabola* aop = static_cast(def.geo); + + Base::Vector3d vertex = Vector3d(*Points[def.midPointId].x, *Points[def.midPointId].y, 0.0); + Base::Vector3d f1 = Vector3d(*myArc.focus1.x, *myArc.focus1.y, 0.0); + + Base::Vector3d fd = f1 - vertex; + + aop->setXAxisDir(fd); + aop->setCenter(vertex); + aop->setFocal(fd.Length()); + aop->setRange(*myArc.startAngle, *myArc.endAngle, /*emulateCCWXY=*/true); +} + +void Sketch::updateCircle(const GeoDef& def) +{ + GeomCircle* circ = static_cast(def.geo); + circ->setCenter(Vector3d(*Points[def.midPointId].x, *Points[def.midPointId].y, 0.0)); + circ->setRadius(*Circles[def.index].rad); +} + +void Sketch::updateEllipse(const GeoDef& def) +{ + GeomEllipse* ellipse = static_cast(def.geo); + + Base::Vector3d center = Vector3d(*Points[def.midPointId].x, *Points[def.midPointId].y, 0.0); + Base::Vector3d f1 = Vector3d(*Ellipses[def.index].focus1.x, *Ellipses[def.index].focus1.y, 0.0); + double radmin = *Ellipses[def.index].radmin; + + Base::Vector3d fd = f1 - center; + double radmaj = sqrt(fd * fd + radmin * radmin); + + ellipse->setCenter(center); + // ensure that ellipse's major radius is always larger than minor radius... may + // still cause problems with degenerates. + if (radmaj >= ellipse->getMinorRadius()) { + ellipse->setMajorRadius(radmaj); + ellipse->setMinorRadius(radmin); + } + else { + ellipse->setMinorRadius(radmin); + ellipse->setMajorRadius(radmaj); + } + ellipse->setMajorAxisDir(fd); +} + +void Sketch::updateBSpline(const GeoDef& def) +{ + GCS::BSpline& mybsp = BSplines[def.index]; + + GeomBSplineCurve* bsp = static_cast(def.geo); + + std::vector poles; + std::vector weights; + + std::vector::const_iterator it1; + std::vector::const_iterator it2; + + for (it1 = mybsp.poles.begin(), it2 = mybsp.weights.begin(); + it1 != mybsp.poles.end() && it2 != mybsp.weights.end(); + ++it1, ++it2) { + poles.emplace_back(*(*it1).x, *(*it1).y, 0.0); + weights.push_back(*(*it2)); + } + + bsp->setPoles(poles, weights); + + std::vector knots; + std::vector mult; + + // This is the code that should be here when/if b-spline gets its full + // implementation in the solver. + /*std::vector::const_iterator it3; + std::vector::const_iterator it4; + + for( it3 = mybsp.knots.begin(), it4 = mybsp.mult.begin(); it3 != mybsp.knots.end() + && it4 != mybsp.mult.end(); ++it3, ++it4) { knots.push_back(*(*it3)); + mult.push_back((*it4)); + } + + bsp->setKnots(knots,mult);*/ +} + bool Sketch::updateNonDrivingConstraints() { for (std::vector::iterator it = Constrs.begin(); it != Constrs.end(); ++it) { diff --git a/src/Mod/Sketcher/App/Sketch.h b/src/Mod/Sketcher/App/Sketch.h index 9035c7ae23..0ffff0ed26 100644 --- a/src/Mod/Sketcher/App/Sketch.h +++ b/src/Mod/Sketcher/App/Sketch.h @@ -521,7 +521,7 @@ public: BSpline = 9 }; -protected: +private: float SolveTime; bool RecalculateInitialSolutionWhileMovingPoint; @@ -530,7 +530,7 @@ protected: // non-driving constraints) bool resolveAfterGeometryUpdated; -protected: +private: /// container element to store and work with the geometric elements of this sketch struct GeoDef { @@ -712,11 +712,22 @@ public: GCSsys.DL_tolfRedundant = val; } -protected: +private: GCS::DebugMode debugMode; private: bool updateGeometry(); + void tryUpdateGeometry(); + void updateGeometry(const GeoDef&); + void updatePoint(const GeoDef&); + void updateLineSegment(const GeoDef&); + void updateArcOfCircle(const GeoDef&); + void updateArcOfEllipse(const GeoDef&); + void updateArcOfHyperbola(const GeoDef&); + void updateArcOfParabola(const GeoDef&); + void updateCircle(const GeoDef&); + void updateEllipse(const GeoDef&); + void updateBSpline(const GeoDef&); bool updateNonDrivingConstraints(); void calculateDependentParametersElements();