Salome HOME
Merge branch 'master' into cgt/devCEA
[modules/shaper.git] / src / GeomAlgoAPI / GeomAlgoAPI_ShapeTools.cpp
index 12e6c3c3bd190d62d18983b61ce0d6ace75bf355..bf7c58b550a2eaa6ff5bb9c19ea5c50f24055093 100644 (file)
@@ -1,13 +1,28 @@
-// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
-
-// File:        GeomAlgoAPI_ShapeTools.h
-// Created:     3 August 2015
-// Author:      Dmitry Bobylev
+// Copyright (C) 2014-2017  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<mailto:webmaster.salome@opencascade.com>
+//
 
 #include "GeomAlgoAPI_ShapeTools.h"
 
 #include "GeomAlgoAPI_SketchBuilder.h"
 
+#include <GeomAPI_Ax1.h>
 #include <GeomAPI_Edge.h>
 #include <GeomAPI_Dir.h>
 #include <GeomAPI_Face.h>
@@ -33,7 +48,9 @@
 #include <Geom2d_Curve.hxx>
 #include <BRepLib_CheckCurveOnSurface.hxx>
 #include <BRep_Tool.hxx>
+#include <Geom_Line.hxx>
 #include <Geom_Plane.hxx>
+#include <GeomAPI_ProjectPointOnCurve.hxx>
 #include <GeomLib_IsPlanarSurface.hxx>
 #include <GeomLib_Tool.hxx>
 #include <gp_Pln.hxx>
@@ -301,7 +318,7 @@ std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeTools::groupSharedTopology(
   }
 
   TopoDS_Shape anInShape = aResult->impl<TopoDS_Shape>();
-  NCollection_List<TopoDS_Shape> anUngroupedShapes;
+  NCollection_List<TopoDS_Shape> anUngroupedShapes, aStillUngroupedShapes;
   addSimpleShapeToList(anInShape, anUngroupedShapes);
 
   NCollection_Vector<NCollection_List<TopoDS_Shape>> aGroups;
@@ -311,32 +328,40 @@ std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeTools::groupSharedTopology(
     anUngroupedShapes.RemoveFirst();
     for(NCollection_List<TopoDS_Shape>::Iterator aGroupIt(aGroupedShapes);
         aGroupIt.More(); aGroupIt.Next()) {
-      const TopoDS_Shape& aGroupShape = aGroupIt.Value();
-      for(NCollection_List<TopoDS_Shape>::Iterator anUngroupedIt(anUngroupedShapes);
-          anUngroupedIt.More(); anUngroupedIt.Next()) {
-        const TopoDS_Shape& anUngroupedShape = anUngroupedIt.Value();
-        bool isFound = false;
-        for(TopExp_Explorer aGroupShapeExp(aGroupShape, TopAbs_VERTEX);
-            aGroupShapeExp.More(); aGroupShapeExp.Next()) {
-          const TopoDS_Shape& aVertex1 = aGroupShapeExp.Current();
-          for(TopExp_Explorer anUngroupedShapeExp(anUngroupedShape, TopAbs_VERTEX);
-              anUngroupedShapeExp.More(); anUngroupedShapeExp.Next()) {
-            const TopoDS_Shape& aVertex2 = anUngroupedShapeExp.Current();
+      const TopoDS_Shape& aGroupedShape = aGroupIt.Value();
+      for(TopExp_Explorer aGroupShapeExp(aGroupedShape, TopAbs_VERTEX);
+          aGroupShapeExp.More();
+          aGroupShapeExp.Next()) {
+        // Find all shapes which have same vertex.
+        aStillUngroupedShapes.Clear();
+        const TopoDS_Shape& aVertex1 = aGroupShapeExp.Current();
+        for(NCollection_List<TopoDS_Shape>::Iterator anUngroupedIt(anUngroupedShapes);
+            anUngroupedIt.More();
+            anUngroupedIt.Next()) {
+          const TopoDS_Shape& anUngroupedShape = anUngroupedIt.Value();
+          bool isAdded = false;
+          for(TopExp_Explorer anUgroupedShapeExp(anUngroupedShape, TopAbs_VERTEX);
+              anUgroupedShapeExp.More();
+              anUgroupedShapeExp.Next()) {
+            const TopoDS_Shape& aVertex2 = anUgroupedShapeExp.Current();
             if(aVertex1.IsSame(aVertex2)) {
               aGroupedShapes.Append(anUngroupedShape);
-              anUngroupedShapes.Remove(anUngroupedIt);
-              isFound = true;
+              isAdded = true;
               break;
             }
           }
-          if(isFound) {
-            break;
+          if(!isAdded) {
+            aStillUngroupedShapes.Append(anUngroupedShape);
           }
         }
-        if(!anUngroupedIt.More()) {
+        anUngroupedShapes = aStillUngroupedShapes;
+        if(anUngroupedShapes.IsEmpty()) {
           break;
         }
       }
+      if(anUngroupedShapes.IsEmpty()) {
+        break;
+      }
     }
     aGroups.Append(aGroupedShapes);
   }
@@ -687,6 +712,56 @@ bool GeomAlgoAPI_ShapeTools::isParallel(const std::shared_ptr<GeomAPI_Edge> theE
 
 //==================================================================================================
 void GeomAlgoAPI_ShapeTools::splitShape(const std::shared_ptr<GeomAPI_Shape>& theBaseShape,
+                                      const GeomAlgoAPI_ShapeTools::PointToRefsMap& thePointsInfo,
+                                      std::set<std::shared_ptr<GeomAPI_Shape> >& theShapes)
+{
+  // to split shape at least one point should be presented in the points container
+  if (thePointsInfo.empty())
+    return;
+
+    // General Fuse to split edge by vertices
+  BOPAlgo_Builder aBOP;
+  TopoDS_Edge aBaseEdge = theBaseShape->impl<TopoDS_Edge>();
+  // Rebuild closed edge to place vertex to one of split points.
+  // This will prevent edge to be split on same vertex.
+  if (BRep_Tool::IsClosed(aBaseEdge))
+  {
+    Standard_Real aFirst, aLast;
+    Handle(Geom_Curve) aCurve = BRep_Tool::Curve(aBaseEdge, aFirst, aLast);
+
+    PointToRefsMap::const_iterator aPIt = thePointsInfo.begin();
+    std::shared_ptr<GeomAPI_Pnt> aPnt = aPIt->first;
+    gp_Pnt aPoint(aPnt->x(), aPnt->y(), aPnt->z());
+
+    TopAbs_Orientation anOrientation = aBaseEdge.Orientation();
+    aBaseEdge = BRepBuilderAPI_MakeEdge(aCurve, aPoint, aPoint).Edge();
+    aBaseEdge.Orientation(anOrientation);
+  }
+  aBOP.AddArgument(aBaseEdge);
+
+  PointToRefsMap::const_iterator aPIt = thePointsInfo.begin();
+  for (; aPIt != thePointsInfo.end(); ++aPIt) {
+    std::shared_ptr<GeomAPI_Pnt> aPnt = aPIt->first;
+    TopoDS_Vertex aV = BRepBuilderAPI_MakeVertex(gp_Pnt(aPnt->x(), aPnt->y(), aPnt->z()));
+    aBOP.AddArgument(aV);
+  }
+
+  aBOP.Perform();
+  if (aBOP.ErrorStatus())
+    return;
+
+  // Collect splits
+  const TopTools_ListOfShape& aSplits = aBOP.Modified(aBaseEdge);
+  TopTools_ListIteratorOfListOfShape anIt(aSplits);
+  for (; anIt.More(); anIt.Next()) {
+    std::shared_ptr<GeomAPI_Shape> anEdge(new GeomAPI_Shape);
+    anEdge->setImpl(new TopoDS_Shape(anIt.Value()));
+    theShapes.insert(anEdge);
+  }
+}
+
+//==================================================================================================
+void GeomAlgoAPI_ShapeTools::splitShape_p(const std::shared_ptr<GeomAPI_Shape>& theBaseShape,
                                           const std::list<std::shared_ptr<GeomAPI_Pnt> >& thePoints,
                                           std::set<std::shared_ptr<GeomAPI_Shape> >& theShapes)
 {
@@ -760,3 +835,20 @@ std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeTools::findShape(
 
   return aResultShape;
 }
+
+//==================================================================================================
+std::shared_ptr<GeomAPI_Dir> GeomAlgoAPI_ShapeTools::buildDirFromAxisAndShape(
+                                    const std::shared_ptr<GeomAPI_Shape> theBaseShape,
+                                    const std::shared_ptr<GeomAPI_Ax1> theAxis)
+{
+  gp_Pnt aCentreOfMassPoint =
+    GeomAlgoAPI_ShapeTools::centreOfMass(theBaseShape)->impl<gp_Pnt>();
+  Handle(Geom_Line) aLine = new Geom_Line(theAxis->impl<gp_Ax1>());
+  GeomAPI_ProjectPointOnCurve aPrjTool(aCentreOfMassPoint, aLine);
+  gp_Pnt aPoint = aPrjTool.NearestPoint();
+
+  std::shared_ptr<GeomAPI_Dir> aDir(new GeomAPI_Dir(aCentreOfMassPoint.X()-aPoint.X(),
+                                                    aCentreOfMassPoint.Y()-aPoint.Y(),
+                                                    aCentreOfMassPoint.Z()-aPoint.Z()));
+  return aDir;
+}
\ No newline at end of file