Salome HOME
Merge branch 'csgroup_IS2'
[modules/shaper.git] / src / GeomAlgoAPI / GeomAlgoAPI_ShapeTools.cpp
index a6cbafc0223cd1ee005d89bfc21b620fbbb12b1d..c4cdde252a42e8a4b9dd457415058c75cc1359de 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2014-2020  CEA/DEN, EDF R&D
+// Copyright (C) 2014-2021  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
 #include <BRepAlgo_FaceRestrictor.hxx>
 #include <BRepAdaptor_Curve.hxx>
 #include <BRepBndLib.hxx>
+#include <BRepBuilderAPI_Copy.hxx>
 #include <BRepBuilderAPI_FindPlane.hxx>
 #include <BRepBuilderAPI_MakeEdge.hxx>
 #include <BRepBuilderAPI_MakeFace.hxx>
 #include <BRepBuilderAPI_MakeVertex.hxx>
+#include <BRepBuilderAPI_MakeWire.hxx>
 #include <BRepCheck_Analyzer.hxx>
 #include <BRepExtrema_DistShapeShape.hxx>
 #include <BRepExtrema_ExtCF.hxx>
@@ -122,6 +124,22 @@ static GProp_GProps props(const TopoDS_Shape& theShape)
   return aGProps;
 }
 
+//==================================================================================================
+double GeomAlgoAPI_ShapeTools::length(const std::shared_ptr<GeomAPI_Shape> theShape)
+{
+  GProp_GProps aGProps;
+  if(!theShape.get()) {
+    return 0.0;
+  }
+  const TopoDS_Shape& aShape = theShape->impl<TopoDS_Shape>();
+  if(aShape.IsNull()) {
+    return 0.0;
+  }
+
+  BRepGProp::LinearProperties(aShape, aGProps, Standard_True);
+  return  aGProps.Mass();
+}
+
 //==================================================================================================
 double GeomAlgoAPI_ShapeTools::volume(const std::shared_ptr<GeomAPI_Shape> theShape)
 {
@@ -133,20 +151,13 @@ double GeomAlgoAPI_ShapeTools::volume(const std::shared_ptr<GeomAPI_Shape> theSh
     return 0.0;
   }
   const Standard_Real anEps = 1.e-6;
-  TopExp_Explorer anExp(aShape, TopAbs_SOLID);
-  if (anExp.More()) { // return volume if there is at least one solid
-    double aVolume = 0.0;
-    for (; anExp.More(); anExp.Next()) {
-      GProp_GProps aGProps;
-      BRepGProp::VolumeProperties(anExp.Current(), aGProps, anEps);
-      aVolume += aGProps.Mass();
-    }
-    return aVolume;
+  double aVolume = 0.0;
+  for (TopExp_Explorer anExp(aShape, TopAbs_SOLID); anExp.More(); anExp.Next()) {
+    GProp_GProps aGProps;
+    BRepGProp::VolumeProperties(anExp.Current(), aGProps, anEps);
+    aVolume += aGProps.Mass();
   }
-  // return surfaces area
-  GProp_GProps aGProps;
-  BRepGProp::SurfaceProperties(aShape, aGProps, anEps);
-  return aGProps.Mass();
+  return aVolume;
 }
 
 //==================================================================================================
@@ -1157,6 +1168,21 @@ std::shared_ptr<GeomAPI_Edge> GeomAlgoAPI_ShapeTools::wireToEdge(
     TopoDS_Edge aNewEdge = aWExp.Current();
     aWExp.Next();
     if (aWExp.More()) {
+      // Workaround for the closed wire to avoid jumping of its start point:
+      // split this wire for two parts, convert them to edges, then compose together
+      if (BRep_Tool::IsClosed(aWire)) {
+        aWire = TopoDS::Wire(BRepBuilderAPI_Copy(aWire).Shape());
+        aWExp.Init(aWire);
+        aNewEdge = aWExp.Current();
+
+        BRep_Builder().Remove(aWire, aNewEdge);
+        GeomWirePtr aSplitWire(new GeomAPI_Wire);
+        aSplitWire->setImpl(new TopoDS_Wire(aWire));
+        GeomEdgePtr aMergedEdge = wireToEdge(aSplitWire);
+
+        aWire = BRepBuilderAPI_MakeWire(aNewEdge, aMergedEdge->impl<TopoDS_Edge>());
+      }
+
       // Workaround: when concatenate a wire consisting of two edges based on the same B-spline
       // curve (non-periodic, but having equal start and end points), first of which is placed
       // at the end on the curve and second is placed at the start, this workaround copies