Salome HOME
Issue #2657: Impossible to create sketch line with start point in the origin
[modules/shaper.git] / src / GeomAlgoAPI / GeomAlgoAPI_ShapeTools.cpp
index ac3bee2557ca5faee1c330a6731ebeef1bbbe7b7..a47c77c7f28d1fa298a72a1613b71a5eabdd06ff 100644 (file)
@@ -55,6 +55,7 @@
 #include <Geom_Line.hxx>
 #include <Geom_Plane.hxx>
 #include <GeomAPI_ProjectPointOnCurve.hxx>
+#include <GeomAPI_ShapeIterator.h>
 #include <GeomLib_IsPlanarSurface.hxx>
 #include <GeomLib_Tool.hxx>
 #include <GeomAPI_IntCS.hxx>
@@ -426,7 +427,7 @@ std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeTools::groupSharedTopology(
   }
 
   // Iterate over the map and group shapes.
-  NCollection_Vector<TopTools_ListOfShape> aGroups; // groups of shapes connected by vertices
+  NCollection_Vector<TopTools_MapOfShape> aGroups; // groups of shapes connected by vertices
   while (!allVertices.IsEmpty()) {
     // Get first group of shapes in map, and then unbind it.
     const TopoDS_Shape& aKey = allVertices.First();
@@ -467,12 +468,12 @@ std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeTools::groupSharedTopology(
       }
     }
     // Sort shapes from the most complicated to the simplest ones
-    TopTools_ListOfShape aSortedGroup;
+    TopTools_MapOfShape aSortedGroup;
     for (int aST = TopAbs_COMPOUND; aST <= TopAbs_SHAPE; ++aST) {
       TopTools_ListOfShape::Iterator anIt(aConnectedShapes);
       while (anIt.More()) {
         if (anIt.Value().ShapeType() == aST) {
-          aSortedGroup.Append(anIt.Value());
+          aSortedGroup.Add(anIt.Value());
           aConnectedShapes.Remove(anIt);
         }
         else {
@@ -487,14 +488,21 @@ std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeTools::groupSharedTopology(
   BRep_Builder aBuilder;
   aBuilder.MakeCompound(aCompound);
   ListOfShape aCompSolids, aFreeSolids;
-  for(NCollection_Vector<NCollection_List<TopoDS_Shape>>::Iterator
-      anIt(aGroups); anIt.More(); anIt.Next()) {
-    NCollection_List<TopoDS_Shape> aGroup = anIt.Value();
+  for (NCollection_Vector<TopTools_MapOfShape>::Iterator anIt(aGroups); anIt.More(); anIt.Next()) {
+    const TopTools_MapOfShape& aGroup = anIt.ChangeValue();
     GeomShapePtr aGeomShape(new GeomAPI_Shape());
     if(aGroup.Size() == 1) {
-      aGeomShape->setImpl(new TopoDS_Shape(aGroup.First()));
+      TopTools_MapOfShape::Iterator aOneShapeIter(aGroup);
+      aGeomShape->setImpl(new TopoDS_Shape(aOneShapeIter.Value()));
     } else {
-      aGeomShape->setImpl(new TopoDS_Shape(makeCompound(aGroup)));
+      // make sub-shapes in the group have order same as in original shape
+      TopTools_ListOfShape anOrderedGoup;
+      NCollection_List<TopoDS_Shape>::Iterator anUngrouped(anUngroupedShapes);
+      for (; anUngrouped.More(); anUngrouped.Next()) {
+        if (aGroup.Contains(anUngrouped.Value()))
+          anOrderedGoup.Append(anUngrouped.Value());
+      }
+      aGeomShape->setImpl(new TopoDS_Shape(makeCompound(anOrderedGoup)));
       aGeomShape = GeomAlgoAPI_ShapeTools::combineShapes(aGeomShape,
                                                          GeomAPI_Shape::COMPSOLID,
                                                          aCompSolids,
@@ -1057,3 +1065,25 @@ std::shared_ptr<GeomAPI_Edge> GeomAlgoAPI_ShapeTools::wireToEdge(
   }
   return anEdge;
 }
+
+ListOfShape GeomAlgoAPI_ShapeTools::getLowLevelSubShapes(const GeomShapePtr& theShape)
+{
+  ListOfShape aSubShapes;
+
+  if (!theShape->isCompound() && !theShape->isCompSolid() &&
+      !theShape->isShell() && !theShape->isWire()) {
+    return aSubShapes;
+  }
+
+  for (GeomAPI_ShapeIterator anIt(theShape); anIt.more(); anIt.next()) {
+    GeomShapePtr aSubShape = anIt.current();
+    if (aSubShape->isVertex() || aSubShape->isEdge() ||
+        aSubShape->isFace() || aSubShape->isSolid()) {
+      aSubShapes.push_back(aSubShape);
+    } else {
+      aSubShapes.splice(aSubShapes.end(), getLowLevelSubShapes(aSubShape));
+    }
+  }
+
+  return aSubShapes;
+}
\ No newline at end of file