Salome HOME
Finalization of the sketch drawer "Create dimensions" flag implemented
[modules/shaper.git] / src / GeomAlgoAPI / GeomAlgoAPI_WireBuilder.cpp
index a251c76a0455cc080b2c7157f5933c40acae6c17..f342ccdef0386d1c104975ad780397709dc16ead 100644 (file)
 
 #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)
 {
   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: {
@@ -59,3 +65,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