Salome HOME
Issue #2657: Impossible to create sketch line with start point in the origin
[modules/shaper.git] / src / GeomAlgoAPI / GeomAlgoAPI_ShapeTools.cpp
index a8df94d7dbd49d0fcbae3da17db9a159078a9fb2..a47c77c7f28d1fa298a72a1613b71a5eabdd06ff 100644 (file)
 #include <Geom2d_Curve.hxx>
 #include <BRepLib_CheckCurveOnSurface.hxx>
 #include <BRep_Tool.hxx>
+#include  <Geom_CylindricalSurface.hxx>
 #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>
 #include <BRepBuilderAPI_MakeVertex.hxx>
 #include <TopoDS_Edge.hxx>
 
+//==================================================================================================
+static GProp_GProps props(const TopoDS_Shape& theShape)
+{
+  GProp_GProps aGProps;
+
+  if (theShape.ShapeType() == TopAbs_EDGE || theShape.ShapeType() == TopAbs_WIRE)
+  {
+    BRepGProp::LinearProperties(theShape, aGProps);
+  }
+  else if (theShape.ShapeType() == TopAbs_FACE || theShape.ShapeType() == TopAbs_SHELL)
+  {
+    const Standard_Real anEps = 1.e-6;
+    BRepGProp::SurfaceProperties(theShape, aGProps, anEps);
+  }
+  else if (theShape.ShapeType() == TopAbs_SOLID || theShape.ShapeType() == TopAbs_COMPSOLID)
+  {
+    BRepGProp::VolumeProperties(theShape, aGProps);
+  }
+  else if (theShape.ShapeType() == TopAbs_COMPOUND)
+  {
+    for (TopoDS_Iterator anIt(theShape); anIt.More(); anIt.Next())
+    {
+      aGProps.Add(props(anIt.Value()));
+    }
+  }
+
+  return aGProps;
+}
+
 //==================================================================================================
 double GeomAlgoAPI_ShapeTools::volume(const std::shared_ptr<GeomAPI_Shape> theShape)
 {
@@ -131,17 +162,40 @@ std::shared_ptr<GeomAPI_Pnt>
   gp_Pnt aCentre;
   if(aShape.ShapeType() == TopAbs_VERTEX) {
     aCentre = BRep_Tool::Pnt(TopoDS::Vertex(aShape));
-  } else if(aShape.ShapeType() == TopAbs_EDGE || aShape.ShapeType() == TopAbs_WIRE) {
-    BRepGProp::LinearProperties(aShape, aGProps);
-    aCentre = aGProps.CentreOfMass();
   } else {
-    const Standard_Real anEps = 1.e-6;
-    BRepGProp::SurfaceProperties(aShape, aGProps, anEps);
+    aGProps = props(aShape);
     aCentre = aGProps.CentreOfMass();
   }
+
   return std::shared_ptr<GeomAPI_Pnt>(new GeomAPI_Pnt(aCentre.X(), aCentre.Y(), aCentre.Z()));
 }
 
+//==================================================================================================
+double GeomAlgoAPI_ShapeTools::radius(const std::shared_ptr<GeomAPI_Face>& theCylinder)
+{
+  double aRadius = -1.0;
+  if (theCylinder->isCylindrical()) {
+    const TopoDS_Shape& aShape = theCylinder->impl<TopoDS_Shape>();
+    Handle(Geom_Surface) aSurf = BRep_Tool::Surface(TopoDS::Face(aShape));
+    Handle(Geom_CylindricalSurface) aCyl = Handle(Geom_CylindricalSurface)::DownCast(aSurf);
+    if (!aCyl.IsNull())
+      aRadius = aCyl->Radius();
+  }
+  return aRadius;
+}
+
+//==================================================================================================
+double GeomAlgoAPI_ShapeTools::minimalDistance(const GeomShapePtr& theShape1,
+                                               const GeomShapePtr& theShape2)
+{
+  const TopoDS_Shape& aShape1 = theShape1->impl<TopoDS_Shape>();
+  const TopoDS_Shape& aShape2 = theShape2->impl<TopoDS_Shape>();
+
+  BRepExtrema_DistShapeShape aDist(aShape1, aShape2);
+  aDist.Perform();
+  return aDist.IsDone() ? aDist.Value() : Precision::Infinite();
+}
+
 //==================================================================================================
 std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_ShapeTools::combineShapes(
   const std::shared_ptr<GeomAPI_Shape> theCompound,
@@ -373,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();
@@ -414,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 {
@@ -434,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,
@@ -1004,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