Salome HOME
Fix for the issue #2753 : error when dump/load script
[modules/shaper.git] / src / GeomAPI / GeomAPI_Shell.cpp
index 5b7713a96a4e7f5bae799e120cc4d4fd5229cd51..ae5e12ae972a347398aa852ad71fefd8414fd931 100644 (file)
@@ -32,6 +32,8 @@
 #include "GeomAPI_XYZ.h"
 
 #include <BRep_Builder.hxx>
+#include <BRepGProp.hxx>
+#include <GProp_GProps.hxx>
 #include <Precision.hxx>
 #include <TopExp_Explorer.hxx>
 #include <TopoDS.hxx>
@@ -174,7 +176,7 @@ std::shared_ptr<GeomAPI_Cone> GeomAPI_Shell::getCone() const
 
   GeomPointPtr anApex;
   GeomDirPtr anAxis;
-  double aSemiAngle, aCosSemiAngle;
+  double aSemiAngle, aTanSemiAngle;
   double aHeight1, aHeight2;
 
   for (TopExp_Explorer anExp(impl<TopoDS_Shape>(), TopAbs_FACE); anExp.More(); anExp.Next()) {
@@ -191,9 +193,9 @@ std::shared_ptr<GeomAPI_Cone> GeomAPI_Shell::getCone() const
       anApex = aCurCone->apex();
       anAxis = aCurCone->axis();
       aSemiAngle = aCurCone->semiAngle();
-      aCosSemiAngle = Cos(aSemiAngle);
-      aHeight1 = aCurCone->radius1() * aCosSemiAngle;
-      aHeight2 = aCurCone->radius2() * aCosSemiAngle;
+      aTanSemiAngle = Tan(aSemiAngle);
+      aHeight1 = aCurCone->radius1() / aTanSemiAngle;
+      aHeight2 = aCurCone->radius2() / aTanSemiAngle;
       isFirstFace = false;
     }
     else {
@@ -209,15 +211,15 @@ std::shared_ptr<GeomAPI_Cone> GeomAPI_Shell::getCone() const
 
       double aSign = anAxis->dot(aCurCone->axis());
       double aCurSemiAngle = aCurCone->semiAngle();
-      double aCosCurSemiAngle = Cos(aSemiAngle);
+      double aTanCurSemiAngle = Tan(aSemiAngle);
 
-      double aH = aCurCone->radius1() * aCosCurSemiAngle * aSign;
+      double aH = aCurCone->radius1() / aTanCurSemiAngle * aSign;
       if (aH < aHeight1)
         aHeight1 = aH;
       else if (aH > aHeight2)
         aHeight2 = aH;
 
-      aH = aCurCone->radius2() * aCosCurSemiAngle * aSign;
+      aH = aCurCone->radius2() / aTanCurSemiAngle * aSign;
       if (aH < aHeight1)
         aHeight1 = aH;
       else if (aH > aHeight2)
@@ -229,8 +231,8 @@ std::shared_ptr<GeomAPI_Cone> GeomAPI_Shell::getCone() const
   if (isCone) {
     GeomPointPtr aLocation(new GeomAPI_Pnt(
       anApex->xyz()->added(anAxis->xyz()->multiplied(aHeight1))));
-    double aRadius1 = aHeight1 * Tan(aSemiAngle);
-    double aRadius2 = aHeight2 * Tan(aSemiAngle);
+    double aRadius1 = aHeight1 * aTanSemiAngle;
+    double aRadius2 = aHeight2 * aTanSemiAngle;
 
     aCone = GeomConePtr(new GeomAPI_Cone(aLocation, anAxis, aSemiAngle, aRadius1, aRadius2));
   }
@@ -296,11 +298,25 @@ std::shared_ptr<GeomAPI_Box> GeomAPI_Shell::getParallelepiped() const
     std::list<GeomPointPtr> aCorners;
     if (aWire->isRectangle(aCorners)) {
       // convert rectangle to plane with dimensions
-      GeomPointPtr anOrigin = aCorners.front();
-      aCorners.pop_front();
 
-      GeomPointPtr aFront = aCorners.front();
-      GeomPointPtr aBack = aCorners.back();
+      // find corner with the smallest coordinates
+      std::list<GeomPointPtr>::const_iterator aPrev = --aCorners.end();
+      std::list<GeomPointPtr>::const_iterator aCur = aPrev--;
+      std::list<GeomPointPtr>::const_iterator aNext = aCorners.begin();
+      GeomPointPtr anOrigin = *aCur;
+      GeomPointPtr aFront = *aNext;
+      GeomPointPtr aBack = *aPrev;
+      aPrev = aCur;
+      aCur = aNext++;
+      while (aNext != aCorners.end()) {
+        if ((*aCur)->isLess(anOrigin)) {
+          anOrigin = *aCur;
+          aFront = *aNext;
+          aBack = *aPrev;
+        }
+        aPrev = aCur;
+        aCur = aNext++;
+      }
 
       aPlanes[aNbPlanes].myWidth = aBack->distance(anOrigin);
       aPlanes[aNbPlanes].myDepth = aFront->distance(anOrigin);
@@ -365,3 +381,20 @@ std::shared_ptr<GeomAPI_Box> GeomAPI_Shell::getParallelepiped() const
                                   aPlanes[anIndex].myHeight));
   return aBox;
 }
+
+//=================================================================================================
+GeomPointPtr GeomAPI_Shell::middlePoint() const
+{
+  GeomPointPtr anInnerPoint;
+
+  const TopoDS_Shell& aShell = impl<TopoDS_Shell>();
+  if (aShell.IsNull())
+    return anInnerPoint;
+
+  GProp_GProps aProps;
+  BRepGProp::SurfaceProperties(aShell, aProps, 1.e-4);
+
+  gp_Pnt aPnt = aProps.CentreOfMass();
+  anInnerPoint = GeomPointPtr(new GeomAPI_Pnt(aPnt.X(), aPnt.Y(), aPnt.Z()));
+  return anInnerPoint;
+}