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:
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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<>
|
||||
|
||||
Reference in New Issue
Block a user