Sketcher: Fix issue of reversed arcs input for polar pattern (#24351)

* Sketcher: Fix issue of reversed arcs input for polar pattern

* DrawSketchHandlerRotate: remove getRotatedPoint that is no longer needed

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Update Geometry.cpp

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
PaddleStroke
2025-10-20 17:45:18 +02:00
committed by GitHub
parent 5ba4feac59
commit 06c46bd352
4 changed files with 56 additions and 104 deletions

View File

@@ -2231,6 +2231,16 @@ bool GeomConic::isReversed() const
return conic->Axis().Direction().Z() < 0;
}
bool GeomConic::reverseIfReversed()
{
Handle(Geom_Conic) hConic = Handle(Geom_Conic)::DownCast(handle());
if (isReversed()) {
hConic->Reverse();
return true;
}
return false;
}
GeomBSplineCurve* GeomConic::toNurbs(double first, double last) const
{
Handle(Geom_Conic) conic = Handle(Geom_Conic)::DownCast(handle());
@@ -2501,6 +2511,18 @@ bool GeomArcOfConic::isReversed() const
return conic->Axis().Direction().Z() < 0;
}
bool GeomArcOfConic::reverseIfReversed()
{
Handle(Geom_TrimmedCurve) tCurve = Handle(Geom_TrimmedCurve)::DownCast(handle());
if (tCurve) {
if (isReversed()) {
tCurve->Reverse();
return true;
}
}
return false;
}
/*!
* \brief GeomArcOfConic::getAngleXU
* \return The angle between ellipse's major axis (in direction to focus1) and
@@ -7075,3 +7097,4 @@ std::unique_ptr<GeomCurve> makeFromCurveAdaptor(const Adaptor3d_Curve& adapt, bo
} // namespace Part

View File

@@ -129,6 +129,11 @@ public:
void transform(const Base::Matrix4D& mat) const;
void translate(const Base::Vector3d& vec) const;
virtual bool reverseIfReversed()
{
return false;
};
protected:
/// create a new tag for the geometry object
void createNewTag();
@@ -420,6 +425,7 @@ public:
double getAngleXU() const;
void setAngleXU(double angle);
bool isReversed() const;
bool reverseIfReversed() override;
Base::Vector3d getAxisDirection() const;
@@ -505,6 +511,7 @@ public:
inline void setRange(double u, double v) override { setRange(u,v,false);}
bool isReversed() const;
bool reverseIfReversed() override;
double getAngleXU() const;
void setAngleXU(double angle);

View File

@@ -305,11 +305,6 @@ private:
gCircle->setRadius(circle.Radius());
gCircle->setCenter(Base::Vector3d(cnt.X(), cnt.Y(), cnt.Z()));
if (edge.Orientation() == TopAbs_REVERSED) {
Handle(Geom_Circle) hCircle = Handle(Geom_Circle)::DownCast(gCircle->handle());
hCircle->Reverse();
}
GeometryFacade::setConstruction(gCircle, false);
return gCircle;
}
@@ -319,17 +314,12 @@ private:
double u1 = curve.FirstParameter();
double u2 = curve.LastParameter();
if (edge.Orientation() == TopAbs_REVERSED) {
hCircle->Reverse(); // Reverses the axis of the underlying circle
std::swap(u1, u2);
u1 = -u1;
u2 = -u2;
}
auto* gArc = new Part::GeomArcOfCircle();
Handle(Geom_TrimmedCurve) tCurve = new Geom_TrimmedCurve(hCircle, u1, u2);
gArc->setHandle(tCurve);
gArc->reverseIfReversed();
GeometryFacade::setConstruction(gArc, false);
return gArc;
}
@@ -345,11 +335,10 @@ private:
auto* gEllipse = new Part::GeomEllipse();
Handle(Geom_Ellipse) hEllipse = new Geom_Ellipse(ellipse);
if (edge.Orientation() == TopAbs_REVERSED) {
hEllipse->Reverse();
}
gEllipse->setHandle(hEllipse);
gEllipse->reverseIfReversed();
GeometryFacade::setConstruction(gEllipse, false);
return gEllipse;
}
@@ -359,17 +348,12 @@ private:
double u1 = curve.FirstParameter();
double u2 = curve.LastParameter();
if (edge.Orientation() == TopAbs_REVERSED) {
hEllipse->Reverse(); // Reverses the axis of the underlying ellipse
std::swap(u1, u2);
u1 = -u1;
u2 = -u2;
}
Handle(Geom_TrimmedCurve) tCurve = new Geom_TrimmedCurve(hEllipse, u1, u2);
auto* gArc = new Part::GeomArcOfEllipse();
gArc->setHandle(tCurve);
gArc->reverseIfReversed();
GeometryFacade::setConstruction(gArc, false);
return gArc;
}
@@ -386,7 +370,6 @@ private:
TopExp_Explorer expl(offsetShape, TopAbs_EDGE);
int geoIdToAdd = firstCurveCreated;
for (; expl.More(); expl.Next(), geoIdToAdd++) {
const TopoDS_Edge& edge = TopoDS::Edge(expl.Current());
BRepAdaptor_Curve curve(edge);
if (curve.GetType() == GeomAbs_Line) {
@@ -977,8 +960,19 @@ private:
for (auto& CC : vCC) {
BRepBuilderAPI_MakeWire mkWire;
for (auto& curve : CC) {
mkWire.Add(TopoDS::Edge(Obj->getGeometry(curve)->toShape()));
if (CC.size() > 1) {
// The element to become the new first element is the last one.
// The iterator to this element is one before the end.
std::rotate(CC.begin(), CC.end() - 1, CC.end());
}
for (auto& curveId : CC) {
const Part::Geometry* pGeo = Obj->getGeometry(curveId);
auto geoCopy = std::unique_ptr<Part::Geometry>(pGeo->copy());
Part::Geometry* geo = geoCopy.get();
geo->reverseIfReversed(); // make sure we don't have reversed conics
// Use the normalized copy to create the edge for the wire
mkWire.Add(TopoDS::Edge(geo->toShape()));
}
// Here we make sure that if possible the first wire is not a single line.

View File

@@ -297,68 +297,14 @@ private:
auto geoUniquePtr = std::unique_ptr<Part::Geometry>(pGeo->copy());
Part::Geometry* geo = geoUniquePtr.get();
if (!onlyeditoutline) {
geo->reverseIfReversed(); // make sure we don't have reversed conics
}
double angle = individualAngle * i;
if (isCircle(*geo)) {
auto* circle = static_cast<Part::GeomCircle*>(geo); // NOLINT
circle->setCenter(getRotatedPoint(circle->getCenter(), centerPoint, angle));
}
else if (isArcOfCircle(*geo)) {
auto* arcOfCircle = static_cast<Part::GeomArcOfCircle*>(geo); // NOLINT
arcOfCircle->setCenter(
getRotatedPoint(arcOfCircle->getCenter(), centerPoint, angle));
double arcStartAngle, arcEndAngle; // NOLINT
arcOfCircle->getRange(arcStartAngle, arcEndAngle, /*emulateCCWXY=*/true);
arcOfCircle->setRange(arcStartAngle + angle,
arcEndAngle + angle,
/*emulateCCWXY=*/true);
}
else if (isLineSegment(*geo)) {
auto* line = static_cast<Part::GeomLineSegment*>(geo); // NOLINT
line->setPoints(getRotatedPoint(line->getStartPoint(), centerPoint, angle),
getRotatedPoint(line->getEndPoint(), centerPoint, angle));
}
else if (isEllipse(*geo)) {
auto* ellipse = static_cast<Part::GeomEllipse*>(geo); // NOLINT
ellipse->setCenter(getRotatedPoint(ellipse->getCenter(), centerPoint, angle));
ellipse->setMajorAxisDir(
getRotatedPoint(ellipse->getMajorAxisDir(), Base::Vector2d(0., 0.), angle));
}
else if (isArcOfEllipse(*geo)) {
auto* arcOfEllipse = static_cast<Part::GeomArcOfEllipse*>(geo); // NOLINT
arcOfEllipse->setCenter(
getRotatedPoint(arcOfEllipse->getCenter(), centerPoint, angle));
arcOfEllipse->setMajorAxisDir(getRotatedPoint(arcOfEllipse->getMajorAxisDir(),
Base::Vector2d(0., 0.),
angle));
}
else if (isArcOfHyperbola(*geo)) {
auto* arcOfHyperbola = static_cast<Part::GeomArcOfHyperbola*>(geo); // NOLINT
arcOfHyperbola->setCenter(
getRotatedPoint(arcOfHyperbola->getCenter(), centerPoint, angle));
arcOfHyperbola->setMajorAxisDir(
getRotatedPoint(arcOfHyperbola->getMajorAxisDir(),
Base::Vector2d(0., 0.),
angle));
}
else if (isArcOfParabola(*geo)) {
auto* arcOfParabola = static_cast<Part::GeomArcOfParabola*>(geo); // NOLINT
arcOfParabola->setCenter(
getRotatedPoint(arcOfParabola->getCenter(), centerPoint, angle));
arcOfParabola->setAngleXU(arcOfParabola->getAngleXU() + angle);
}
else if (isBSplineCurve(*geo)) {
auto* bSpline = static_cast<Part::GeomBSplineCurve*>(geo); // NOLINT
std::vector<Base::Vector3d> poles = bSpline->getPoles();
for (size_t p = 0; p < poles.size(); p++) {
poles[p] = getRotatedPoint(std::move(poles[p]), centerPoint, angle);
}
bSpline->setPoles(poles);
}
else if (isPoint(*geo)) {
auto* point = static_cast<Part::GeomPoint*>(geo); // NOLINT
point->setPoint(getRotatedPoint(point->getPoint(), centerPoint, angle));
}
Base::Matrix4D matrix(toVector3d(centerPoint), Base::Vector3d(0, 0, 1), angle);
geo->transform(matrix);
ShapeGeometry.emplace_back(std::move(geoUniquePtr));
}
@@ -473,24 +419,6 @@ private:
}
}
}
Base::Vector3d
getRotatedPoint(Base::Vector3d&& pointToRotate, const Base::Vector2d& centerPoint, double angle)
{
Base::Vector2d pointToRotate2D = Base::Vector2d(pointToRotate.x, pointToRotate.y);
double initialAngle = (pointToRotate2D - centerPoint).Angle();
double lengthToCenter = (pointToRotate2D - centerPoint).Length();
pointToRotate2D = centerPoint
+ lengthToCenter * Base::Vector2d(cos(angle + initialAngle), sin(angle + initialAngle));
pointToRotate.x = pointToRotate2D.x;
pointToRotate.y = pointToRotate2D.y;
return pointToRotate;
}
};
template<>