Salome HOME
updated copyright message
[modules/shaper.git] / src / GeomAPI / GeomAPI_Shell.cpp
index 5b7713a96a4e7f5bae799e120cc4d4fd5229cd51..0b07404d0a8b42144d972c14cef08288b618cb9b 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2018-20xx  CEA/DEN, EDF R&D
+// Copyright (C) 2018-2023  CEA, EDF
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 //
 // 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
+// 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>
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
 #include "GeomAPI_Shell.h"
@@ -32,6 +31,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>
@@ -96,8 +97,8 @@ std::shared_ptr<GeomAPI_Cylinder> GeomAPI_Shell::getCylinder() const
 
   GeomPointPtr aLocation;
   GeomDirPtr anAxis;
-  double aRadius;
-  double aHeight;
+  double aRadius = 0.0;
+  double aHeight = 0.0;
 
   for (TopExp_Explorer anExp(impl<TopoDS_Shape>(), TopAbs_FACE); anExp.More(); anExp.Next()) {
     GeomFacePtr aFace(new GeomAPI_Face);
@@ -174,8 +175,8 @@ std::shared_ptr<GeomAPI_Cone> GeomAPI_Shell::getCone() const
 
   GeomPointPtr anApex;
   GeomDirPtr anAxis;
-  double aSemiAngle, aCosSemiAngle;
-  double aHeight1, aHeight2;
+  double aSemiAngle = 0.0, aTanSemiAngle = 0.0;
+  double aHeight1 = 0.0, aHeight2 = 0.0;
 
   for (TopExp_Explorer anExp(impl<TopoDS_Shape>(), TopAbs_FACE); anExp.More(); anExp.Next()) {
     GeomFacePtr aFace(new GeomAPI_Face);
@@ -191,9 +192,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 +210,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(aCurSemiAngle);
 
-      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 +230,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 +297,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 +380,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;
+}