Salome HOME
Adding test for bos #41748 [CEA] Issue in interpolation edition
[modules/shaper.git] / src / GeomAPI / GeomAPI_Shape.cpp
index 7168ccdb5ac04c8bfc87a3aec94ac45d3a7b6a2b..3fb717b753f7e05d5b41f579de458b58c91e367f 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2014-2021  CEA/DEN, EDF R&D
+// Copyright (C) 2014-2024  CEA, EDF
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
@@ -19,6 +19,8 @@
 
 #include "GeomAPI_Shape.h"
 
+#include <Basics_OCCTVersion.hxx>
+
 #include <GeomAPI_Pnt.h>
 #include <GeomAPI_Vertex.h>
 #include <GeomAPI_Edge.h>
@@ -60,8 +62,6 @@
 #include <sstream>
 #include <algorithm> // for std::transform
 
-#include <BRepTools.hxx>
-
 #define MY_SHAPE implPtr<TopoDS_Shape>()
 
 GeomAPI_Shape::GeomAPI_Shape()
@@ -326,23 +326,50 @@ bool GeomAPI_Shape::isPlanar() const
     BRepBuilderAPI_FindPlane aFindPlane(aShape);
     bool isFound = aFindPlane.Found() == Standard_True;
 
-    if(!isFound && aShapeType == TopAbs_EDGE) {
-      Standard_Real aFirst, aLast;
-      Handle(Geom_Curve) aCurve = BRep_Tool::Curve(TopoDS::Edge(aShape), aFirst, aLast);
-      Handle(Standard_Type) aType = aCurve->DynamicType();
+    if(!isFound) {
 
-      if(aType == STANDARD_TYPE(Geom_TrimmedCurve)) {
-        Handle(Geom_TrimmedCurve) aTrimCurve = Handle(Geom_TrimmedCurve)::DownCast(aCurve);
-        aType = aTrimCurve->BasisCurve()->DynamicType();
-      }
+      auto checkEdge = [](const TopoDS_Shape& theShape){
+        if(theShape.ShapeType()!= TopAbs_EDGE) 
+          return false;
 
-      if(aType == STANDARD_TYPE(Geom_Line)
-          || aType == STANDARD_TYPE(Geom_Conic)
-          || aType == STANDARD_TYPE(Geom_Circle)
-          || aType == STANDARD_TYPE(Geom_Ellipse)
-          || aType == STANDARD_TYPE(Geom_Hyperbola)
-          || aType == STANDARD_TYPE(Geom_Parabola)) {
-        isFound = true;
+        Standard_Real aFirst, aLast;
+        Handle(Geom_Curve) aCurve = BRep_Tool::Curve(TopoDS::Edge(theShape), aFirst, aLast);
+        Handle(Standard_Type) aType = aCurve->DynamicType();
+        if(aType == STANDARD_TYPE(Geom_TrimmedCurve)) {
+          Handle(Geom_TrimmedCurve) aTrimCurve = Handle(Geom_TrimmedCurve)::DownCast(aCurve);
+          aType = aTrimCurve->BasisCurve()->DynamicType();
+        }
+
+        if(aType == STANDARD_TYPE(Geom_Line)
+            || aType == STANDARD_TYPE(Geom_Conic)
+            || aType == STANDARD_TYPE(Geom_Circle)
+            || aType == STANDARD_TYPE(Geom_Ellipse)
+            || aType == STANDARD_TYPE(Geom_Hyperbola)
+            || aType == STANDARD_TYPE(Geom_Parabola)) {
+          return true;
+        }
+        return false;
+      };
+
+      if(aShapeType == TopAbs_WIRE){
+        //check if wire consist of only one edge
+        int aNbEdges = 0;
+        TopExp_Explorer anExp(aShape, TopAbs_EDGE);
+        for (TopExp_Explorer anExp(aShape, TopAbs_EDGE); anExp.More(); anExp.Next()) {
+          aNbEdges++;
+          if(aNbEdges == 1){
+            const TopoDS_Edge& anEdge = TopoDS::Edge(anExp.Current());
+            isFound = checkEdge(anEdge);
+          }
+          else{
+            //if more than one edge, check is not valid
+            isFound = false;
+            break;
+          }
+        }
+      }
+      else if(aShapeType == TopAbs_EDGE){
+        isFound = checkEdge(aShape);
       }
     }
 
@@ -419,21 +446,25 @@ std::shared_ptr<GeomAPI_Solid> GeomAPI_Shape::solid() const
 }
 
 std::list<std::shared_ptr<GeomAPI_Shape> >
-GeomAPI_Shape::subShapes(ShapeType theSubShapeType) const
+GeomAPI_Shape::subShapes(const ShapeType theSubShapeType, const bool theOnlyUnique) const
 {
   ListOfShape aSubs;
   const TopoDS_Shape& aShape = impl<TopoDS_Shape>();
   if (aShape.IsNull())
     return aSubs;
 
+  TopTools_MapOfShape alreadyThere;
+
   // process multi-level compounds
   if (shapeType() == COMPOUND && theSubShapeType == COMPOUND) {
     for (TopoDS_Iterator anIt(aShape); anIt.More(); anIt.Next()) {
       const TopoDS_Shape& aCurrent = anIt.Value();
       if (aCurrent.ShapeType() == TopAbs_COMPOUND) {
-        GeomShapePtr aSub(new GeomAPI_Shape);
-        aSub->setImpl(new TopoDS_Shape(aCurrent));
-        aSubs.push_back(aSub);
+        if (!theOnlyUnique || alreadyThere.Add(aCurrent)) {
+          GeomShapePtr aSub(new GeomAPI_Shape);
+          aSub->setImpl(new TopoDS_Shape(aCurrent));
+          aSubs.push_back(aSub);
+        }
       }
     }
     // add self
@@ -444,9 +475,11 @@ GeomAPI_Shape::subShapes(ShapeType theSubShapeType) const
   else {
     for (TopExp_Explorer anExp(aShape, (TopAbs_ShapeEnum)theSubShapeType);
          anExp.More(); anExp.Next()) {
-      GeomShapePtr aSub(new GeomAPI_Shape);
-      aSub->setImpl(new TopoDS_Shape(anExp.Current()));
-      aSubs.push_back(aSub);
+      if (!theOnlyUnique || alreadyThere.Add(anExp.Current())) {
+        GeomShapePtr aSub(new GeomAPI_Shape);
+        aSub->setImpl(new TopoDS_Shape(anExp.Current()));
+        aSubs.push_back(aSub);
+      }
     }
   }
   return aSubs;
@@ -777,8 +810,13 @@ bool GeomAPI_Shape::Comparator::operator()(const std::shared_ptr<GeomAPI_Shape>&
   const TopoDS_Shape& aShape2 = theShape2->impl<TopoDS_Shape>();
   bool isLess = aShape1.TShape() < aShape2.TShape();
   if (aShape1.TShape() == aShape2.TShape()) {
+#if OCC_VERSION_LARGE < 0x07080000
     Standard_Integer aHash1 = aShape1.Location().HashCode(IntegerLast());
     Standard_Integer aHash2 = aShape2.Location().HashCode(IntegerLast());
+#else
+    Standard_Integer aHash1 = aShape1.Location().HashCode();
+    Standard_Integer aHash2 = aShape2.Location().HashCode();
+#endif
     isLess = aHash1 < aHash2;
   }
   return isLess;
@@ -792,8 +830,13 @@ bool GeomAPI_Shape::ComparatorWithOri::operator()(
   const TopoDS_Shape& aShape2 = theShape2->impl<TopoDS_Shape>();
   bool isLess = aShape1.TShape() < aShape2.TShape();
   if (aShape1.TShape() == aShape2.TShape()) {
+#if OCC_VERSION_LARGE < 0x07080000
     Standard_Integer aHash1 = aShape1.Location().HashCode(IntegerLast());
     Standard_Integer aHash2 = aShape2.Location().HashCode(IntegerLast());
+#else
+    Standard_Integer aHash1 = aShape1.Location().HashCode();
+    Standard_Integer aHash2 = aShape2.Location().HashCode();
+#endif
     isLess = (aHash1 < aHash2) ||
              (aHash1 == aHash2 && aShape1.Orientation() < aShape2.Orientation());
   }
@@ -803,7 +846,11 @@ bool GeomAPI_Shape::ComparatorWithOri::operator()(
 int GeomAPI_Shape::Hash::operator()(const std::shared_ptr<GeomAPI_Shape>& theShape) const
 {
   const TopoDS_Shape& aShape = theShape->impl<TopoDS_Shape>();
+#if OCC_VERSION_LARGE < 0x07080000
   return aShape.HashCode(IntegerLast());
+#else
+  return std::hash<TopoDS_Shape>{}(aShape);
+#endif
 }
 
 bool GeomAPI_Shape::Equal::operator()(const std::shared_ptr<GeomAPI_Shape>& theShape1,
@@ -812,8 +859,13 @@ bool GeomAPI_Shape::Equal::operator()(const std::shared_ptr<GeomAPI_Shape>& theS
   const TopoDS_Shape& aShape1 = theShape1->impl<TopoDS_Shape>();
   const TopoDS_Shape& aShape2 = theShape2->impl<TopoDS_Shape>();
 
+#if OCC_VERSION_LARGE < 0x07080000
   Standard_Integer aHash1 = aShape1.Location().HashCode(IntegerLast());
   Standard_Integer aHash2 = aShape2.Location().HashCode(IntegerLast());
+#else
+  Standard_Integer aHash1 = aShape1.Location().HashCode();
+  Standard_Integer aHash2 = aShape2.Location().HashCode();
+#endif
 
   return aShape1.TShape() == aShape2.TShape() && aHash1 == aHash2;
 }