Salome HOME
updated copyright message
[modules/shaper.git] / src / GeomAPI / GeomAPI_Edge.cpp
index 127dbaabf62187b77b61c51d44014e5ef2b545c1..1126cfdcb029c8a2ce7fef41f3ef9a083592e95d 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2014-2017  CEA/DEN, EDF R&D
+// Copyright (C) 2014-2023  CEA, EDF
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 //
 // You should have received a copy of the GNU Lesser General Public
 // License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
-// See http://www.salome-platform.org/ or
-// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
 #include<GeomAPI_Edge.h>
@@ -26,6 +25,7 @@
 #include<GeomAPI_Lin.h>
 #include<GeomAPI_Ax2.h>
 #include<GeomAPI_Ellipse.h>
+#include<GeomAPI_Vertex.h>
 
 #include <BRepAdaptor_Curve.hxx>
 
 #include <BRep_Tool.hxx>
 #include <ElCLib.hxx>
 #include <GCPnts_UniformAbscissa.hxx>
+#include <Geom_BSplineCurve.hxx>
 #include <Geom_Curve.hxx>
 #include <Geom_Line.hxx>
 #include <Geom_Circle.hxx>
 #include <Geom_TrimmedCurve.hxx>
 #include <Geom_Ellipse.hxx>
 #include <Geom_Plane.hxx>
+#include <GeomAPI_ExtremaCurveCurve.hxx>
+#include <GeomAPI_ExtremaCurveSurface.hxx>
 #include <GeomAPI_IntCS.hxx>
 #include <GeomAdaptor_Curve.hxx>
 #include <gp_Ax1.hxx>
@@ -68,6 +71,48 @@ GeomAPI_Edge::GeomAPI_Edge(const std::shared_ptr<GeomAPI_Shape>& theShape)
   }
 }
 
+void GeomAPI_Edge::vertices(std::shared_ptr<GeomAPI_Vertex>& theStartVertex,
+                            std::shared_ptr<GeomAPI_Vertex>& theEndVertex) const
+{
+  const TopoDS_Edge& anEdge = impl<TopoDS_Edge>();
+  TopoDS_Vertex aStart, aEnd;
+  TopExp::Vertices(anEdge, aStart, aEnd);
+  theStartVertex.reset(new GeomAPI_Vertex);
+  theStartVertex->setImpl(new TopoDS_Vertex(aStart));
+  theEndVertex.reset(new GeomAPI_Vertex);
+  theEndVertex->setImpl(new TopoDS_Vertex(aEnd));
+}
+
+static Handle(Geom_Curve) baseCurve(const TopoDS_Edge& theEdge)
+{
+  double aFirst, aLast;
+  Handle(Geom_Curve) aCurve = BRep_Tool::Curve(theEdge, aFirst, aLast);
+  while (aCurve->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
+    Handle(Geom_TrimmedCurve) tc = Handle(Geom_TrimmedCurve)::DownCast(aCurve);
+    aCurve = tc->BasisCurve();
+  }
+  return aCurve;
+}
+
+bool GeomAPI_Edge::isSameGeometry(const std::shared_ptr<GeomAPI_Shape> theShape) const
+{
+  if (!theShape->isEdge())
+    return false;
+  if (isSame(theShape))
+    return true;
+
+  TopoDS_Edge anOwnEdge = TopoDS::Edge(impl<TopoDS_Shape>());
+  TopoDS_Edge anOtherEdge = TopoDS::Edge(theShape->impl<TopoDS_Shape>());
+
+  Handle(Geom_Curve) anOwnCurve = baseCurve(anOwnEdge);
+  Handle(Geom_Curve) anOtherCurve = baseCurve(anOtherEdge);
+  GeomAPI_ExtremaCurveCurve anExtrema(anOwnCurve, anOtherCurve);
+
+  bool isSame = anExtrema.Extrema().IsParallel() &&
+                anExtrema.TotalLowerDistance() < Precision::Confusion();
+  return isSame;
+}
+
 bool GeomAPI_Edge::isLine() const
 {
   const TopoDS_Shape& aShape = const_cast<GeomAPI_Edge*>(this)->impl<TopoDS_Shape>();
@@ -130,9 +175,21 @@ bool GeomAPI_Edge::isEllipse() const
   Handle(Geom_Curve) aCurve = BRep_Tool::Curve((const TopoDS_Edge&)aShape, aFirst, aLast);
   if (aCurve.IsNull()) // degenerative edge
     return false;
-  if (aCurve->IsKind(STANDARD_TYPE(Geom_Ellipse)))
-    return true;
-  return false;
+  while (aCurve->IsKind(STANDARD_TYPE(Geom_TrimmedCurve)))
+    aCurve = Handle(Geom_TrimmedCurve)::DownCast(aCurve)->BasisCurve();
+  return aCurve->IsKind(STANDARD_TYPE(Geom_Ellipse));
+}
+
+bool GeomAPI_Edge::isBSpline() const
+{
+  const TopoDS_Shape& aShape = const_cast<GeomAPI_Edge*>(this)->impl<TopoDS_Shape>();
+  double aFirst, aLast;
+  Handle(Geom_Curve) aCurve = BRep_Tool::Curve((const TopoDS_Edge&)aShape, aFirst, aLast);
+  if (aCurve.IsNull()) // degenerative edge
+    return false;
+  while (aCurve->IsKind(STANDARD_TYPE(Geom_TrimmedCurve)))
+    aCurve = Handle(Geom_TrimmedCurve)::DownCast(aCurve)->BasisCurve();
+  return aCurve->IsKind(STANDARD_TYPE(Geom_BSplineCurve));
 }
 
 std::shared_ptr<GeomAPI_Pnt> GeomAPI_Edge::firstPoint()
@@ -177,6 +234,8 @@ std::shared_ptr<GeomAPI_Ellipse> GeomAPI_Edge::ellipse() const
   double aFirst, aLast;
   Handle(Geom_Curve) aCurve = BRep_Tool::Curve((const TopoDS_Edge&)aShape, aFirst, aLast);
   if (!aCurve.IsNull()) {
+    while (aCurve->IsKind(STANDARD_TYPE(Geom_TrimmedCurve)))
+      aCurve = Handle(Geom_TrimmedCurve)::DownCast(aCurve)->BasisCurve();
     Handle(Geom_Ellipse) aElips = Handle(Geom_Ellipse)::DownCast(aCurve);
     if (!aElips.IsNull()) {
       gp_Elips aGpElips = aElips->Elips();
@@ -250,13 +309,26 @@ bool GeomAPI_Edge::isEqual(const std::shared_ptr<GeomAPI_Shape> theEdge) const
   return true;
 }
 
-// LCOV_EXCL_START
+void GeomAPI_Edge::setRange(const double& theFirst, const double& theLast)
+{
+  TopoDS_Edge anEdge = impl<TopoDS_Edge>();
+  double aFirst, aLast;
+  Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast);
+  double aTolerance = BRep_Tool::Tolerance(anEdge);
+  if (aCurve->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve)) {
+    aCurve = Handle(Geom_TrimmedCurve)::DownCast(aCurve)->BasisCurve();
+    BRep_Builder().UpdateEdge(anEdge, aCurve, aTolerance);
+  }
+  BRep_Builder().Range(anEdge, theFirst, theLast);
+}
+
 void GeomAPI_Edge::getRange(double& theFirst, double& theLast) const
 {
   const TopoDS_Shape& aShape = const_cast<GeomAPI_Edge*>(this)->impl<TopoDS_Shape>();
   Handle(Geom_Curve) aCurve = BRep_Tool::Curve((const TopoDS_Edge&)aShape, theFirst, theLast);
 }
 
+// LCOV_EXCL_START
 bool GeomAPI_Edge::isInPlane(std::shared_ptr<GeomAPI_Pln> thePlane) const
 {
   double aFirst, aLast;
@@ -307,8 +379,9 @@ void GeomAPI_Edge::intersectWithPlane(const std::shared_ptr<GeomAPI_Pln> thePlan
     double A, B, C, D;
     thePlane->coefficients(A, B, C, D);
     gp_Pln aPln(A, B, C, D);
-
     Handle(Geom_Plane) aPlane = new Geom_Plane(aPln);
+
+    // intersect the plane with the curve
     GeomAPI_IntCS aIntersect;
     aIntersect.Perform(aCurve, aPlane);
     if (aIntersect.IsDone() && (aIntersect.NbPoints() > 0)) {
@@ -327,6 +400,20 @@ void GeomAPI_Edge::intersectWithPlane(const std::shared_ptr<GeomAPI_Pln> thePlan
         theResult.push_back(aPntPtr);
       }
     }
+    else {
+      // find minimal distance between the plane and the curve
+      GeomAPI_ExtremaCurveSurface anExtrema(aCurve, aPlane);
+      double aTolerance = BRep_Tool::Tolerance(TopoDS::Edge(aShape));
+      if (anExtrema.NbExtrema() > 0 &&
+          !anExtrema.Extrema().IsParallel() &&
+          anExtrema.LowerDistance() < aTolerance) {
+        // distance is lower than tolerance => tangent case
+        gp_Pnt aPntC, aPntS;
+        anExtrema.NearestPoints(aPntC, aPntS);
+        std::shared_ptr<GeomAPI_Pnt> aPntPtr(new GeomAPI_Pnt(aPntS.X(), aPntS.Y(), aPntS.Z()));
+        theResult.push_back(aPntPtr);
+      }
+    }
   }
 }
 
@@ -376,6 +463,22 @@ void GeomAPI_Edge::setLastPointTolerance(const double theTolerance)
   BRep_Builder().UpdateVertex(aVLast, theTolerance);
 }
 
+double GeomAPI_Edge::firstPointTolerance() const
+{
+  TopoDS_Edge anEdge = impl<TopoDS_Edge>();
+  TopoDS_Vertex aVFirst, aVLast;
+  TopExp::Vertices(anEdge, aVFirst, aVLast);
+  return BRep_Tool::Tolerance(aVFirst);
+}
+
+double GeomAPI_Edge::lastPointTolerance() const
+{
+  TopoDS_Edge anEdge = impl<TopoDS_Edge>();
+  TopoDS_Vertex aVFirst, aVLast;
+  TopExp::Vertices(anEdge, aVFirst, aVLast);
+  return BRep_Tool::Tolerance(aVLast);
+}
+
 GeomPointPtr GeomAPI_Edge::middlePoint() const
 {
   GeomPointPtr aMiddlePoint;