Salome HOME
Task 2.12. New entities: ellipses and arcs of ellipses (issue #3003)
[modules/shaper.git] / src / GeomAlgoAPI / GeomAlgoAPI_WireBuilder.cpp
index b6b9dec26fcb4e8b66694c35d84a535956e94fe5..00c1e79d1e91119604b75a4f495e7127820e7f4c 100644 (file)
@@ -1,29 +1,51 @@
-// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
-
-// File:        GeomAlgoAPI_WireBuilder.cpp
-// Created:     14 April 2016
-// Author:      Dmitry Bobylev
+// Copyright (C) 2014-2019  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// 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
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
 
 #include "GeomAlgoAPI_WireBuilder.h"
 
+#include <GeomAPI_Edge.h>
+#include <GeomAPI_Pnt.h>
+#include <GeomAPI_Vertex.h>
+#include <GeomAPI_ShapeExplorer.h>
+
 #include <BRepBuilderAPI_MakeWire.hxx>
 #include <TopoDS.hxx>
 #include <TopoDS_Wire.hxx>
+#include <TopExp_Explorer.hxx>
 
 //=================================================================================================
-std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_WireBuilder::wire(const ListOfShape& theShapes)
+GeomShapePtr GeomAlgoAPI_WireBuilder::wire(const ListOfShape& theShapes)
 {
-  BRepBuilderAPI_MakeWire aWireBuilder;
+  TopTools_ListOfShape aListOfEdges;
 
-  for(ListOfShape::const_iterator anIt = theShapes.cbegin(); anIt != theShapes.cend(); ++anIt) {
+  ListOfShape::const_iterator anIt = theShapes.cbegin();
+  for(; anIt != theShapes.cend(); ++anIt) {
     const TopoDS_Shape& aShape = (*anIt)->impl<TopoDS_Shape>();
     switch(aShape.ShapeType()) {
       case TopAbs_EDGE: {
-        aWireBuilder.Add(TopoDS::Edge(aShape));
+        aListOfEdges.Append(aShape);
         break;
       }
       case TopAbs_WIRE: {
-        aWireBuilder.Add(TopoDS::Wire(aShape));
+        for(TopExp_Explorer anExp(aShape, TopAbs_EDGE); anExp.More(); anExp.Next()) {
+          aListOfEdges.Append(anExp.Current());
+        }
         break;
       }
       default: {
@@ -32,6 +54,8 @@ std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_WireBuilder::wire(const ListOfShape&
     }
   }
 
+  BRepBuilderAPI_MakeWire aWireBuilder;
+  aWireBuilder.Add(aListOfEdges);
   if(aWireBuilder.Error() != BRepBuilderAPI_WireDone) {
     return GeomShapePtr();
   }
@@ -40,3 +64,63 @@ std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_WireBuilder::wire(const ListOfShape&
   aResultShape->setImpl(new TopoDS_Shape(aWireBuilder.Wire()));
   return aResultShape;
 }
+
+//=================================================================================================
+bool GeomAlgoAPI_WireBuilder::isSelfIntersected(const GeomShapePtr& theWire)
+{
+  // Collect edges.
+  ListOfShape anEdges;
+
+  GeomAPI_ShapeExplorer anExp(theWire, GeomAPI_Shape::EDGE);
+  for (; anExp.more(); anExp.next()) {
+    GeomShapePtr anEdge = anExp.current();
+    anEdges.push_back(anEdge);
+  }
+
+  // Check intersections between edges pair-wise
+  int aNbEdges = (int)anEdges.size();
+  std::list<GeomShapePtr>::const_iterator anEdgesIt = anEdges.begin();
+  for (int i = 0; anEdgesIt != anEdges.end(); ++anEdgesIt, i++) {
+    GeomEdgePtr anEdge1(new GeomAPI_Edge(*anEdgesIt));
+
+    std::list<GeomShapePtr>::const_iterator anOtherEdgesIt = std::next(anEdgesIt);
+    for (int j = i + 1; anOtherEdgesIt != anEdges.end(); ++anOtherEdgesIt, j++) {
+      GeomEdgePtr anEdge2(new GeomAPI_Edge(*anOtherEdgesIt));
+      GeomShapePtr anInter = anEdge1->intersect(anEdge2);
+      if (!anInter.get()) {
+        continue;
+      }
+
+      bool isOk = false;
+
+      if (anInter->isVertex()) {
+        GeomVertexPtr aVertex(new GeomAPI_Vertex(anInter));
+        GeomPointPtr aPnt = aVertex->point();
+
+        GeomPointPtr aFirstPnt1 = anEdge1->orientation() == GeomAPI_Shape::FORWARD ?
+                                  anEdge1->firstPoint() : anEdge1->lastPoint();
+        GeomPointPtr aLastPnt1 = anEdge1->orientation() == GeomAPI_Shape::FORWARD ?
+                                 anEdge1->lastPoint() : anEdge1->firstPoint();
+        GeomPointPtr aFirstPnt2 = anEdge2->orientation() == GeomAPI_Shape::FORWARD ?
+                                  anEdge2->firstPoint() : anEdge2->lastPoint();
+        GeomPointPtr aLastPnt2 = anEdge2->orientation() == GeomAPI_Shape::FORWARD ?
+                                 anEdge2->lastPoint() : anEdge2->firstPoint();
+
+        GeomPointPtr aCommonEndPnt;
+        if (aFirstPnt1->isEqual(aLastPnt2)) {
+          aCommonEndPnt = aFirstPnt1;
+        } else if(aLastPnt1->isEqual(aFirstPnt2)) {
+          aCommonEndPnt = aLastPnt1;
+        }
+
+        isOk = aCommonEndPnt && aPnt->isEqual(aCommonEndPnt);
+      }
+
+      if (!isOk) {
+        return true;
+      }
+    }
+  }
+
+  return false;
+}
\ No newline at end of file