1 // Copyright (C) 2014-2023 CEA, EDF
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include <PlaneGCSSolver_EdgeWrapper.h>
23 template <typename TYPE>
24 static bool isCurve(const GCSCurvePtr& theEntity)
26 return std::dynamic_pointer_cast<TYPE>(theEntity).get();
30 PlaneGCSSolver_EdgeWrapper::PlaneGCSSolver_EdgeWrapper(const GCSCurvePtr theEntity)
33 if (isCurve<GCS::Line>(myEntity))
35 else if (isCurve<GCS::Arc>(myEntity))
37 else if (isCurve<GCS::Circle>(myEntity))
38 myType = ENTITY_CIRCLE;
39 else if (isCurve<GCS::ArcOfEllipse>(myEntity))
40 myType = ENTITY_ELLIPTIC_ARC;
41 else if (isCurve<GCS::Ellipse>(myEntity))
42 myType = ENTITY_ELLIPSE;
43 else if (isCurve<GCS::BSpline>(myEntity))
44 myType = ENTITY_BSPLINE;
47 static double squareDistance(const GCS::Point& theP1, const GCS::Point& theP2)
49 double dx = *theP1.x - *theP2.x;
50 double dy = *theP1.y - *theP2.y;
54 bool PlaneGCSSolver_EdgeWrapper::isDegenerated() const
56 static const double THE_SQ_TOL = tolerance * 1e-2;
57 static const double THE_ANGLE_TOL = 1.e-5;
58 static const double THE_MAX_RADIUS = 1e8;
59 static const double THE_SQ_MAX_RADIUS = THE_MAX_RADIUS * THE_MAX_RADIUS;
61 if (myType == ENTITY_LINE) {
62 std::shared_ptr<GCS::Line> aLine = std::dynamic_pointer_cast<GCS::Line>(myEntity);
63 return squareDistance(aLine->p1, aLine->p2) < THE_SQ_TOL;
65 else if (myType == ENTITY_CIRCLE) {
66 std::shared_ptr<GCS::Circle> aCircle = std::dynamic_pointer_cast<GCS::Circle>(myEntity);
67 return *aCircle->rad < tolerance || *aCircle->rad > THE_MAX_RADIUS;
69 else if (myType == ENTITY_ARC) {
70 std::shared_ptr<GCS::Arc> anArc = std::dynamic_pointer_cast<GCS::Arc>(myEntity);
71 double anAngleDiff = fabs(*anArc->startAngle - *anArc->endAngle);
72 double aSqRadius = squareDistance(anArc->center, anArc->start);
73 return aSqRadius < THE_SQ_TOL || aSqRadius > THE_SQ_MAX_RADIUS || // <- arc radius
74 anAngleDiff < THE_ANGLE_TOL || fabs(anAngleDiff - 2*PI) < THE_ANGLE_TOL; // <- arc angle
76 else if (myType == ENTITY_ELLIPSE) {
77 std::shared_ptr<GCS::Ellipse> anEllipse = std::dynamic_pointer_cast<GCS::Ellipse>(myEntity);
78 return *anEllipse->radmin < tolerance || anEllipse->getRadMaj() > THE_MAX_RADIUS;
80 else if (myType == ENTITY_ELLIPTIC_ARC) {
81 std::shared_ptr<GCS::ArcOfEllipse> anArc =
82 std::dynamic_pointer_cast<GCS::ArcOfEllipse>(myEntity);
83 double anAngleDiff = fabs(*anArc->startAngle - *anArc->endAngle);
84 return *anArc->radmin < THE_SQ_TOL || anArc->getRadMaj() > THE_SQ_MAX_RADIUS || // <- arc radius
85 anAngleDiff < THE_ANGLE_TOL || fabs(anAngleDiff - 2*PI) < THE_ANGLE_TOL; // <- arc angle