Salome HOME
0021866: [CEA 670] Returning exact coordinates of the bounding box
authorskv <skv@opencascade.com>
Thu, 23 May 2013 12:53:40 +0000 (12:53 +0000)
committerskv <skv@opencascade.com>
Thu, 23 May 2013 12:53:40 +0000 (12:53 +0000)
14 files changed:
doc/salome/gui/GEOM/input/bounding_box.doc
idl/GEOM_Gen.idl
src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx
src/GEOMImpl/GEOMImpl_IMeasureOperations.hxx
src/GEOMImpl/GEOMImpl_MeasureDriver.cxx
src/GEOMImpl/GEOMImpl_Types.hxx
src/GEOMUtils/GEOMUtils.cxx
src/GEOMUtils/GEOMUtils.hxx
src/GEOM_I/GEOM_IMeasureOperations_i.cc
src/GEOM_I/GEOM_IMeasureOperations_i.hh
src/GEOM_SWIG/geomBuilder.py
src/MeasureGUI/MeasureGUI_BndBoxDlg.cxx
src/TransformationGUI/TransformationGUI_MultiRotationDlg.cxx
src/TransformationGUI/TransformationGUI_MultiTranslationDlg.cxx

index 99bd0538f8f2dd72359980b55b2addacf1b40a93..365c3600eb54985bcc594a536aeeb12aa2f8747a 100644 (file)
@@ -14,9 +14,10 @@ faces (by iterating through all faces of a shape).
 This functionallity is implemented in such a way to have 
 a satisfactory performance.
 
-\n <b>TUI Commands:</b> <em>[Xmin,Xmax, Ymin,Ymax, Zmin,Zmax] = geompy.BoundingBox(Shape)</em>,
-<em>BBox = geompy.MakeBoundingBox(Shape)</em>, where \em Shape
-is the shape for which the bounding box is computed.
+\n <b>TUI Commands:</b> <em>[Xmin,Xmax, Ymin,Ymax, Zmin,Zmax] = geompy.BoundingBox(Shape, precise)</em>,
+<em>BBox = geompy.MakeBoundingBox(Shape, precise)</em>, where \em Shape
+is the shape for which the bounding box is computed. \em precise TRUE
+ for precise computation; FALSE for fast one. Default value is False.
 
 See also a \ref tui_bounding_box_page "TUI example".
 
index 1395c58597c575f48bf934c24ec463c44b115ced..f8642857cca1c9aa37ea48eb734f52bcf55a189a 100644 (file)
@@ -3640,12 +3640,14 @@ module GEOM
     /*!
      *  \brief Get parameters of bounding box of the given shape
      *  \param theShape Shape to obtain bounding box of.
+     *  \param precise TRUE for precise computation; FALSE for fast one.
      *  \param Xmin,Xmax Output. Limits of shape along OX axis.
      *  \param Ymin,Ymax Output. Limits of shape along OY axis.
      *  \param Zmin,Zmax Output. Limits of shape along OZ axis.
      *  \return Returns parameters of bounding box through the last six arguments.
      */
     void GetBoundingBox (in GEOM_Object theShape,
+                         in boolean precise,
                          out double Xmin, out double Xmax,
                          out double Ymin, out double Ymax,
                          out double Zmin, out double Zmax);
@@ -3653,9 +3655,11 @@ module GEOM
     /*!
      *  \brief Get bounding box of the given shape
      *  \param theShape Shape to obtain bounding box of.
+     *  \param precise TRUE for precise computation; FALSE for fast one.
      *  \return New GEOM_Object, containing the created bounding box.
      */
-    GEOM_Object MakeBoundingBox (in GEOM_Object theShape);
+    GEOM_Object MakeBoundingBox (in GEOM_Object theShape,
+                                 in boolean precise);
 
     /*!
      *  \brief Get min and max tolerances of sub-shapes of theShape
index 55dff9bff1eea738bae7db918233cc5362e120cd..b03746e6ea61c4cc28e18ed8f424babcadab388d 100644 (file)
 
 #include <ShapeAnalysis.hxx>
 #include <ShapeAnalysis_Surface.hxx>
-#include <ShapeFix_Shape.hxx>
 
 #include <GeomAPI_IntSS.hxx>
 #include <GeomAPI_ProjectPointOnCurve.hxx>
 
 #include <GeomAbs_SurfaceType.hxx>
 
-#include <Geom_BezierSurface.hxx>
-#include <Geom_BSplineSurface.hxx>
-#include <Geom_Circle.hxx>
-#include <Geom_ConicalSurface.hxx>
-#include <Geom_CylindricalSurface.hxx>
 #include <Geom_Line.hxx>
-#include <Geom_OffsetSurface.hxx>
-#include <Geom_Plane.hxx>
-#include <Geom_RectangularTrimmedSurface.hxx>
-#include <Geom_SphericalSurface.hxx>
 #include <Geom_Surface.hxx>
-#include <Geom_SurfaceOfLinearExtrusion.hxx>
-#include <Geom_SurfaceOfRevolution.hxx>
-#include <Geom_ToroidalSurface.hxx>
 
 #include <GeomLProp_CLProps.hxx>
 #include <GeomLProp_SLProps.hxx>
@@ -1120,6 +1107,7 @@ void GEOMImpl_IMeasureOperations::GetInertia
 //=============================================================================
 void GEOMImpl_IMeasureOperations::GetBoundingBox
                                      (Handle(GEOM_Object) theShape,
+                                      const Standard_Boolean precise,
                                       Standard_Real& Xmin, Standard_Real& Xmax,
                                       Standard_Real& Ymin, Standard_Real& Ymax,
                                       Standard_Real& Zmin, Standard_Real& Zmax)
@@ -1156,6 +1144,14 @@ void GEOMImpl_IMeasureOperations::GetBoundingBox
     BRepTools::Clean(aShape);
 
     BRepBndLib::Add(aShape, B);
+
+    if (precise) {
+      if (!GEOMUtils::PreciseBoundingBox(aShape, B)) {
+        SetErrorCode("GetBoundingBox Error: Bounding box cannot be precised");
+        return;
+      }
+    }
+
     B.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
   }
   catch (Standard_Failure) {
@@ -1173,7 +1169,8 @@ void GEOMImpl_IMeasureOperations::GetBoundingBox
  */
 //=============================================================================
 Handle(GEOM_Object) GEOMImpl_IMeasureOperations::GetBoundingBox
-                                                (Handle(GEOM_Object) theShape)
+                                                (Handle(GEOM_Object) theShape,
+                                                 const Standard_Boolean precise)
 {
   SetErrorCode(KO);
 
@@ -1183,8 +1180,9 @@ Handle(GEOM_Object) GEOMImpl_IMeasureOperations::GetBoundingBox
   Handle(GEOM_Object) aBnd = GetEngine()->AddObject(GetDocID(), GEOM_BOX);
 
   //Add a new BoundingBox function
+  const int aType = (precise ? BND_BOX_MEASURE_PRECISE : BND_BOX_MEASURE);
   Handle(GEOM_Function) aFunction =
-    aBnd->AddFunction(GEOMImpl_MeasureDriver::GetID(), BND_BOX_MEASURE);
+    aBnd->AddFunction(GEOMImpl_MeasureDriver::GetID(), aType);
   if (aFunction.IsNull()) return NULL;
 
   //Check if the function is set correctly
@@ -1214,7 +1212,15 @@ Handle(GEOM_Object) GEOMImpl_IMeasureOperations::GetBoundingBox
   }
 
   //Make a Python command
-  GEOM::TPythonDump(aFunction) << aBnd << " = geompy.MakeBoundingBox(" << theShape << ")";
+  GEOM::TPythonDump aPd(aFunction);
+  
+  aPd << aBnd << " = geompy.MakeBoundingBox(" << theShape;
+
+  if (precise) {
+    aPd << ", True";
+  }
+
+  aPd << ")";
 
   SetErrorCode(OK);
   return aBnd;
@@ -1584,308 +1590,6 @@ std::vector<bool> GEOMImpl_IMeasureOperations::AreCoordsInside(Handle(GEOM_Objec
   return res;
 }
 
-//=======================================================================
-//function : CheckSingularCase
-//purpose  : auxilary for GetMinDistance()
-//           workaround for bugs 19899, 19908 and 19910 from Mantis
-//=======================================================================
-static double CheckSingularCase(const TopoDS_Shape& aSh1,
-                                const TopoDS_Shape& aSh2,
-                                gp_Pnt& Ptmp1, gp_Pnt& Ptmp2)
-{
-  bool IsChange1 = false;
-  double AddDist1 = 0.0;
-  TopExp_Explorer anExp;
-  TopoDS_Shape tmpSh1, tmpSh2;
-  int nbf = 0;
-  for ( anExp.Init( aSh1, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
-    nbf++;
-    tmpSh1 = anExp.Current();
-  }
-  if(nbf==1) {
-    TopoDS_Shape sh = aSh1;
-    while(sh.ShapeType()==TopAbs_COMPOUND) {
-      TopoDS_Iterator it(sh);
-      sh = it.Value();
-    }
-    Handle(Geom_Surface) S = BRep_Tool::Surface(TopoDS::Face(tmpSh1));
-    if( S->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
-        S->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ) {
-      if( sh.ShapeType()==TopAbs_SHELL || sh.ShapeType()==TopAbs_FACE ) {
-        // non solid case
-        double U1,U2,V1,V2;
-        // changes for 0020677: EDF 1219 GEOM: MinDistance gives 0 instead of 20.88
-        //S->Bounds(U1,U2,V1,V2); changed by
-        ShapeAnalysis::GetFaceUVBounds(TopoDS::Face(tmpSh1),U1,U2,V1,V2);
-        // end of changes for 020677 (dmv)
-        Handle(Geom_RectangularTrimmedSurface) TrS1 =
-          new Geom_RectangularTrimmedSurface(S,U1,(U1+U2)/2.,V1,V2);
-        Handle(Geom_RectangularTrimmedSurface) TrS2 =
-          new Geom_RectangularTrimmedSurface(S,(U1+U2)/2.,U2,V1,V2);
-        BRep_Builder B;
-        TopoDS_Face F1,F2;
-        TopoDS_Compound Comp;
-        B.MakeCompound(Comp);
-        B.MakeFace(F1,TrS1,1.e-7);
-        B.Add(Comp,F1);
-        B.MakeFace(F2,TrS2,1.e-7);
-        B.Add(Comp,F2);
-        Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape;
-        sfs->Init(Comp);
-        sfs->SetPrecision(1.e-6);
-        sfs->SetMaxTolerance(1.0);
-        sfs->Perform();
-        tmpSh1 = sfs->Shape();
-        IsChange1 = true;
-      }
-      else {
-        if( S->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ) {
-          Handle(Geom_SphericalSurface) SS = Handle(Geom_SphericalSurface)::DownCast(S);
-          gp_Pnt PC = SS->Location();
-          BRep_Builder B;
-          TopoDS_Vertex V;
-          B.MakeVertex(V,PC,1.e-7);
-          tmpSh1 = V;
-          AddDist1 = SS->Radius();
-          IsChange1 = true;
-        }
-        else {
-          Handle(Geom_ToroidalSurface) TS = Handle(Geom_ToroidalSurface)::DownCast(S);
-          gp_Ax3 ax3 = TS->Position();
-          Handle(Geom_Circle) C = new Geom_Circle(ax3.Ax2(),TS->MajorRadius());
-          BRep_Builder B;
-          TopoDS_Edge E;
-          B.MakeEdge(E,C,1.e-7);
-          tmpSh1 = E;
-          AddDist1 = TS->MinorRadius();
-          IsChange1 = true;
-        }
-      }
-    }
-    else
-      tmpSh1 = aSh1;
-  }
-  else
-    tmpSh1 = aSh1;
-  bool IsChange2 = false;
-  double AddDist2 = 0.0;
-  nbf = 0;
-  for ( anExp.Init( aSh2, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
-    nbf++;
-    tmpSh2 = anExp.Current();
-  }
-  if(nbf==1) {
-    TopoDS_Shape sh = aSh2;
-    while(sh.ShapeType()==TopAbs_COMPOUND) {
-      TopoDS_Iterator it(sh);
-      sh = it.Value();
-    }
-    Handle(Geom_Surface) S = BRep_Tool::Surface(TopoDS::Face(tmpSh2));
-    if( S->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
-        S->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ) {
-      if( sh.ShapeType()==TopAbs_SHELL || sh.ShapeType()==TopAbs_FACE ) {
-        // non solid case
-        double U1,U2,V1,V2;
-        //S->Bounds(U1,U2,V1,V2);
-        ShapeAnalysis::GetFaceUVBounds(TopoDS::Face(tmpSh2),U1,U2,V1,V2);
-        Handle(Geom_RectangularTrimmedSurface) TrS1 =
-          new Geom_RectangularTrimmedSurface(S,U1,(U1+U2)/2.,V1,V2);
-        Handle(Geom_RectangularTrimmedSurface) TrS2 =
-          new Geom_RectangularTrimmedSurface(S,(U1+U2)/2.,U2,V1,V2);
-        BRep_Builder B;
-        TopoDS_Face F1,F2;
-        TopoDS_Compound Comp;
-        B.MakeCompound(Comp);
-        B.MakeFace(F1,TrS1,1.e-7);
-        B.Add(Comp,F1);
-        B.MakeFace(F2,TrS2,1.e-7);
-        B.Add(Comp,F2);
-        Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape;
-        sfs->Init(Comp);
-        sfs->SetPrecision(1.e-6);
-        sfs->SetMaxTolerance(1.0);
-        sfs->Perform();
-        tmpSh2 = sfs->Shape();
-        IsChange2 = true;
-      }
-      else {
-        if( S->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ) {
-          Handle(Geom_SphericalSurface) SS = Handle(Geom_SphericalSurface)::DownCast(S);
-          gp_Pnt PC = SS->Location();
-          BRep_Builder B;
-          TopoDS_Vertex V;
-          B.MakeVertex(V,PC,1.e-7);
-          tmpSh2 = V;
-          AddDist2 = SS->Radius();
-          IsChange2 = true;
-        }
-        else if( S->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ) {
-          Handle(Geom_ToroidalSurface) TS = Handle(Geom_ToroidalSurface)::DownCast(S);
-          gp_Ax3 ax3 = TS->Position();
-          Handle(Geom_Circle) C = new Geom_Circle(ax3.Ax2(),TS->MajorRadius());
-          BRep_Builder B;
-          TopoDS_Edge E;
-          B.MakeEdge(E,C,1.e-7);
-          tmpSh2 = E;
-          AddDist2 = TS->MinorRadius();
-          IsChange2 = true;
-        }
-      }
-    }
-    else
-      tmpSh2 = aSh2;
-  }
-  else
-    tmpSh2 = aSh2;
-
-  if( !IsChange1 && !IsChange2 )
-    return -2.0;
-
-  BRepExtrema_DistShapeShape dst(tmpSh1,tmpSh2);
-  if (dst.IsDone()) {
-    double MinDist = 1.e9;
-    gp_Pnt PMin1, PMin2, P1, P2;
-    for (int i = 1; i <= dst.NbSolution(); i++) {
-      P1 = dst.PointOnShape1(i);
-      P2 = dst.PointOnShape2(i);
-      Standard_Real Dist = P1.Distance(P2);
-      if (MinDist > Dist) {
-        MinDist = Dist;
-        PMin1 = P1;
-        PMin2 = P2;
-      }
-    }
-    if(MinDist<1.e-7) {
-      Ptmp1 = PMin1;
-      Ptmp2 = PMin2;
-    }
-    else {
-      gp_Dir aDir(gp_Vec(PMin1,PMin2));
-      if( MinDist > (AddDist1+AddDist2) ) {
-        Ptmp1 = gp_Pnt( PMin1.X() + aDir.X()*AddDist1,
-                        PMin1.Y() + aDir.Y()*AddDist1,
-                        PMin1.Z() + aDir.Z()*AddDist1 );
-        Ptmp2 = gp_Pnt( PMin2.X() - aDir.X()*AddDist2,
-                        PMin2.Y() - aDir.Y()*AddDist2,
-                        PMin2.Z() - aDir.Z()*AddDist2 );
-        return (MinDist - AddDist1 - AddDist2);
-      }
-      else {
-        if( AddDist1 > 0 ) {
-          Ptmp1 = gp_Pnt( PMin1.X() + aDir.X()*AddDist1,
-                          PMin1.Y() + aDir.Y()*AddDist1,
-                          PMin1.Z() + aDir.Z()*AddDist1 );
-          Ptmp2 = Ptmp1;
-        }
-        else {
-          Ptmp2 = gp_Pnt( PMin2.X() - aDir.X()*AddDist2,
-                          PMin2.Y() - aDir.Y()*AddDist2,
-                          PMin2.Z() - aDir.Z()*AddDist2 );
-          Ptmp1 = Ptmp2;
-        }
-      }
-    }
-    double res = MinDist - AddDist1 - AddDist2;
-    if(res<0.) res = 0.0;
-    return res;
-  }
-  return -2.0;
-}
-/* old variant
-static bool CheckSingularCase(const TopoDS_Shape& aSh1,
-                              const TopoDS_Shape& aSh2,
-                              gp_Pnt& Ptmp)
-{
-  TopExp_Explorer anExp;
-  TopoDS_Shape tmpSh1, tmpSh2;
-  int nbf = 0;
-  for ( anExp.Init( aSh1, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
-    nbf++;
-    tmpSh1 = anExp.Current();
-  }
-  if(nbf==1) {
-    Handle(Geom_Surface) S1 = BRep_Tool::Surface(TopoDS::Face(tmpSh1));
-    if( S1->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
-        S1->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ) {
-      nbf = 0;
-      for ( anExp.Init( aSh2, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
-        nbf++;
-        tmpSh2 = anExp.Current();
-        Handle(Geom_Surface) S2 = BRep_Tool::Surface(TopoDS::Face(tmpSh2));
-        GeomAPI_IntSS ISS(S1,S2,1.e-7);
-        if(ISS.IsDone()) {
-          for(int i=1; i<=ISS.NbLines(); i++) {
-            Handle(Geom_Curve) C3d = ISS.Line(i);
-            BRep_Builder B;
-            TopoDS_Edge E;
-            B.MakeEdge(E,C3d,1.e-7);
-            BRepExtrema_DistShapeShape dst(tmpSh2,E);
-            if (dst.IsDone()) {
-              gp_Pnt PMin1, PMin2, P1, P2;
-              double MinDist = 1.e9;
-              for (int i = 1; i <= dst.NbSolution(); i++) {
-                P1 = dst.PointOnShape1(i);
-                P2 = dst.PointOnShape2(i);
-                Standard_Real Dist = P1.Distance(P2);
-                if (MinDist > Dist) {
-                  MinDist = Dist;
-                  Ptmp = P1;
-                }
-              }
-              if(MinDist<1.e-7)
-                return true;
-            }
-          }
-        }
-      }
-    }
-  }
-  nbf = 0;
-  for ( anExp.Init( aSh2, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
-    nbf++;
-    tmpSh1 = anExp.Current();
-  }
-  if(nbf==1) {
-    Handle(Geom_Surface) S1 = BRep_Tool::Surface(TopoDS::Face(tmpSh1));
-    if( S1->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
-        S1->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ) {
-      nbf = 0;
-      for ( anExp.Init( aSh1, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
-        nbf++;
-        tmpSh2 = anExp.Current();
-        Handle(Geom_Surface) S2 = BRep_Tool::Surface(TopoDS::Face(tmpSh2));
-        GeomAPI_IntSS ISS(S1,S2,1.e-7);
-        if(ISS.IsDone()) {
-          for(int i=1; i<=ISS.NbLines(); i++) {
-            Handle(Geom_Curve) C3d = ISS.Line(i);
-            BRep_Builder B;
-            TopoDS_Edge E;
-            B.MakeEdge(E,C3d,1.e-7);
-            BRepExtrema_DistShapeShape dst(tmpSh2,E);
-            if (dst.IsDone()) {
-              gp_Pnt P1,P2;
-              double MinDist = 1.e9;
-              for (int i = 1; i <= dst.NbSolution(); i++) {
-                P1 = dst.PointOnShape1(i);
-                P2 = dst.PointOnShape2(i);
-                Standard_Real Dist = P1.Distance(P2);
-                if (MinDist > Dist) {
-                  MinDist = Dist;
-                  Ptmp = P1;
-                }
-              }
-              if(MinDist<1.e-7)
-                return true;
-            }
-          }
-        }
-      }
-    }
-  }
-  return false;
-}
-*/
-
 //=============================================================================
 /*!
  *  GetMinDistance
@@ -1918,63 +1622,15 @@ Standard_Real GEOMImpl_IMeasureOperations::GetMinDistance
     OCC_CATCH_SIGNALS;
 #endif
 
-    // Issue 0020231: A min distance bug with torus and vertex.
-    // Make GetMinDistance() return zero if a sole VERTEX is inside any of SOLIDs
-
-    // which of shapes consists of only one vertex?
-    TopExp_Explorer exp1(aShape1,TopAbs_VERTEX), exp2(aShape2,TopAbs_VERTEX);
-    TopoDS_Shape V1 = exp1.More() ? exp1.Current() : TopoDS_Shape();
-    TopoDS_Shape V2 = exp2.More() ? exp2.Current() : TopoDS_Shape();
-    exp1.Next(); exp2.Next();
-    if ( exp1.More() ) V1.Nullify();
-    if ( exp2.More() ) V2.Nullify();
-    // vertex and container of solids
-    TopoDS_Shape V = V1.IsNull() ? V2 : V1;
-    TopoDS_Shape S = V1.IsNull() ? aShape1 : aShape2;
-    if ( !V.IsNull() ) {
-      // classify vertex against solids
-      gp_Pnt p = BRep_Tool::Pnt( TopoDS::Vertex( V ) );
-      for ( exp1.Init( S, TopAbs_SOLID ); exp1.More(); exp1.Next() ) {
-        BRepClass3d_SolidClassifier classifier( exp1.Current(), p, 1e-6);
-        if ( classifier.State() == TopAbs_IN ) {
-          p.Coord(X1, Y1, Z1);
-          p.Coord(X2, Y2, Z2);
-          SetErrorCode(OK);
-          return 0.0;
-        }
-      }
-    }
-    // End Issue 0020231
+    gp_Pnt aPnt1, aPnt2;
 
-    // skl 30.06.2008
-    // additional workaround for bugs 19899, 19908 and 19910 from Mantis
-    gp_Pnt Ptmp1, Ptmp2;
-    double dist = CheckSingularCase(aShape1, aShape2, Ptmp1, Ptmp2);
-    if (dist > -1.0) {
-      Ptmp1.Coord(X1, Y1, Z1);
-      Ptmp2.Coord(X2, Y2, Z2);
-      SetErrorCode(OK);
-      return dist;
-    }
+    MinDist = GEOMUtils::GetMinDistance(aShape1, aShape2, aPnt1, aPnt2);
 
-    BRepExtrema_DistShapeShape dst (aShape1, aShape2);
-    if (dst.IsDone()) {
-      gp_Pnt PMin1, PMin2, P1, P2;
-
-      for (int i = 1; i <= dst.NbSolution(); i++) {
-        P1 = dst.PointOnShape1(i);
-        P2 = dst.PointOnShape2(i);
-
-        Standard_Real Dist = P1.Distance(P2);
-        if (MinDist > Dist) {
-          MinDist = Dist;
-          PMin1 = P1;
-          PMin2 = P2;
-        }
-      }
-
-      PMin1.Coord(X1, Y1, Z1);
-      PMin2.Coord(X2, Y2, Z2);
+    if (MinDist >= 0.0) {
+      aPnt1.Coord(X1, Y1, Z1);
+      aPnt2.Coord(X2, Y2, Z2);
+    } else {
+      return MinDist;
     }
   }
   catch (Standard_Failure) {
@@ -2021,7 +1677,7 @@ Standard_Integer GEOMImpl_IMeasureOperations::ClosestPoints (Handle(GEOM_Object)
     // skl 30.06.2008
     // additional workaround for bugs 19899, 19908 and 19910 from Mantis
     gp_Pnt P1, P2;
-    double dist = CheckSingularCase(aShape1, aShape2, P1, P2);
+    double dist = GEOMUtils::GetMinDistanceSingular(aShape1, aShape2, P1, P2);
     if (dist > -1.0) {
       nbSolutions = 1;
 
index dd85841ee7161b18a6526d701e471c845b5653f9..bd66e79c5355a62db0add5b0ff18dd2e91d3628e 100644 (file)
@@ -114,11 +114,13 @@ class GEOMImpl_IMeasureOperations : public GEOM_IOperations {
                                    Standard_Real& Ix , Standard_Real& Iy , Standard_Real& Iz);
 
   Standard_EXPORT void GetBoundingBox (Handle(GEOM_Object) theShape,
+                                       const Standard_Boolean precise,
                                        Standard_Real& Xmin, Standard_Real& Xmax,
                                        Standard_Real& Ymin, Standard_Real& Ymax,
                                        Standard_Real& Zmin, Standard_Real& Zmax);
 
-  Standard_EXPORT Handle(GEOM_Object) GetBoundingBox (Handle(GEOM_Object) theShape);
+  Standard_EXPORT Handle(GEOM_Object) GetBoundingBox (Handle(GEOM_Object) theShape,
+                                                      const Standard_Boolean precise);
 
   Standard_EXPORT void GetTolerance (Handle(GEOM_Object) theShape,
                                      Standard_Real& FaceMin, Standard_Real& FaceMax,
index 54989d8e2c2cd65090120b1523bbc87e98f757e6..5e77d9502c370230a5f6abb5bd83fe13c60cb991 100644 (file)
@@ -105,7 +105,7 @@ Standard_Integer GEOMImpl_MeasureDriver::Execute(TFunction_Logbook& log) const
     gp_Pnt aCenterMass = aPos.Location();
     aShape = BRepBuilderAPI_MakeVertex(aCenterMass).Shape();
   }
-  else if (aType == BND_BOX_MEASURE)
+  else if (aType == BND_BOX_MEASURE || aType == BND_BOX_MEASURE_PRECISE)
   {
     Handle(GEOM_Function) aRefBase = aCI.GetBase();
     TopoDS_Shape aShapeBase = aRefBase->GetValue();
@@ -124,6 +124,12 @@ Standard_Integer GEOMImpl_MeasureDriver::Execute(TFunction_Logbook& log) const
     Bnd_Box B;
     BRepBndLib::Add(aShapeBase, B);
 
+    if (aType == BND_BOX_MEASURE_PRECISE) {
+      if (!GEOMUtils::PreciseBoundingBox(aShapeBase, B)) {
+        Standard_NullObject::Raise("Bounding box cannot be precised");
+      }
+    }
+
     Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax;
     B.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
 
index b00671937b6d60b83dc092e4d51177d9d801cc05..7a116ddf4d9f1f161471201c26bb8099b9f091b4 100755 (executable)
 // Measures
 #define CDG_MEASURE 1
 #define BND_BOX_MEASURE 2
+#define BND_BOX_MEASURE_PRECISE 3
 #define VECTOR_FACE_NORMALE 4
 #define VERTEX_BY_INDEX 5
 
index f2c53523f3839601a246df1bd7e6e8cc04d13a23..54a7467f60cda0cb3c638aae09c423d21ca754da 100644 (file)
 #include <BRepGProp.hxx>
 #include <BRepTools.hxx>
 
+#include <BRepClass3d_SolidClassifier.hxx>
+
+#include <BRepBuilderAPI_MakeFace.hxx>
+
 #include <Bnd_Box.hxx>
 
 #include <TopAbs.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
 #include <TopTools_Array1OfShape.hxx>
 
+#include <Geom_Circle.hxx>
 #include <Geom_Surface.hxx>
 #include <Geom_Plane.hxx>
+#include <Geom_SphericalSurface.hxx>
+#include <Geom_ToroidalSurface.hxx>
+#include <Geom_RectangularTrimmedSurface.hxx>
 
 #include <GeomLProp_CLProps.hxx>
 #include <GeomLProp_SLProps.hxx>
@@ -72,6 +80,9 @@
 #include <gp_Pln.hxx>
 #include <gp_Lin.hxx>
 
+#include <ShapeAnalysis.hxx>
+#include <ShapeFix_Shape.hxx>
+
 #include <vector>
 
 #include <Standard_Failure.hxx>
@@ -600,3 +611,343 @@ TopoDS_Shape GEOMUtils::GetEdgeNearPoint (const TopoDS_Shape& theShape,
 
   return aResult;
 }
+
+//=======================================================================
+//function : PreciseBoundingBox
+//purpose  : 
+//=======================================================================
+Standard_Boolean GEOMUtils::PreciseBoundingBox
+                          (const TopoDS_Shape &theShape, Bnd_Box &theBox)
+{
+  Standard_Real aBound[6];
+
+  theBox.Get(aBound[0], aBound[2], aBound[4], aBound[1], aBound[3], aBound[5]);
+
+  Standard_Integer i;
+  const gp_Pnt aMid(0.5*(aBound[1] + aBound[0]),  // XMid
+                    0.5*(aBound[3] + aBound[2]),  // YMid
+                    0.5*(aBound[5] + aBound[4])); // ZMid
+  const gp_XYZ aSize(aBound[1] - aBound[0],       // DX
+                     aBound[3] - aBound[2],       // DY
+                     aBound[5] - aBound[4]);      // DZ
+  const gp_Pnt aPnt[6] =
+    {
+      gp_Pnt(aBound[0] - (aBound[1] - aBound[0]), aMid.Y(), aMid.Z()), // XMin
+      gp_Pnt(aBound[1] + (aBound[1] - aBound[0]), aMid.Y(), aMid.Z()), // XMax
+      gp_Pnt(aMid.X(), aBound[2] - (aBound[3] - aBound[2]), aMid.Z()), // YMin
+      gp_Pnt(aMid.X(), aBound[3] + (aBound[3] - aBound[2]), aMid.Z()), // YMax
+      gp_Pnt(aMid.X(), aMid.Y(), aBound[4] - (aBound[5] - aBound[4])), // ZMin
+      gp_Pnt(aMid.X(), aMid.Y(), aBound[5] + (aBound[5] - aBound[4]))  // ZMax
+    };
+  const gp_Dir aDir[3] = { gp::DX(), gp::DY(), gp::DZ() };
+  const Standard_Real aPlnSize[3] =
+    {
+      0.5*Max(aSize.Y(), aSize.Z()), // XMin, XMax planes
+      0.5*Max(aSize.X(), aSize.Z()), // YMin, YMax planes
+      0.5*Max(aSize.X(), aSize.Y())  // ZMin, ZMax planes
+    };
+  gp_Pnt aPMin[2];
+
+  for (i = 0; i < 6; i++) {
+    const Standard_Integer iHalf = i/2;
+    const gp_Pln aPln(aPnt[i], aDir[iHalf]);
+    BRepBuilderAPI_MakeFace aMkFace(aPln, -aPlnSize[iHalf], aPlnSize[iHalf],
+                                          -aPlnSize[iHalf], aPlnSize[iHalf]);
+
+    if (!aMkFace.IsDone()) {
+      return Standard_False;
+    }
+
+    TopoDS_Shape aFace = aMkFace.Shape();
+
+    // Get minimal distance between planar face and shape.
+    Standard_Real aMinDist =
+      GEOMUtils::GetMinDistance(aFace, theShape, aPMin[0], aPMin[1]);
+
+    if (aMinDist < 0.) {
+      return Standard_False;
+    }
+
+    aBound[i] = aPMin[1].Coord(iHalf + 1);
+  }
+
+  // Update Bounding box with the new values.
+  theBox.SetVoid();
+  theBox.Update(aBound[0], aBound[2], aBound[4], aBound[1], aBound[3], aBound[5]);
+
+  return Standard_True;
+}
+
+//=======================================================================
+//function : GetMinDistanceSingular
+//purpose  : 
+//=======================================================================
+double GEOMUtils::GetMinDistanceSingular(const TopoDS_Shape& aSh1,
+                                         const TopoDS_Shape& aSh2,
+                                         gp_Pnt& Ptmp1, gp_Pnt& Ptmp2)
+{
+  bool IsChange1 = false;
+  double AddDist1 = 0.0;
+  TopExp_Explorer anExp;
+  TopoDS_Shape tmpSh1, tmpSh2;
+  int nbf = 0;
+  for ( anExp.Init( aSh1, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
+    nbf++;
+    tmpSh1 = anExp.Current();
+  }
+  if(nbf==1) {
+    TopoDS_Shape sh = aSh1;
+    while(sh.ShapeType()==TopAbs_COMPOUND) {
+      TopoDS_Iterator it(sh);
+      sh = it.Value();
+    }
+    Handle(Geom_Surface) S = BRep_Tool::Surface(TopoDS::Face(tmpSh1));
+    if( S->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
+        S->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ) {
+      if( sh.ShapeType()==TopAbs_SHELL || sh.ShapeType()==TopAbs_FACE ) {
+        // non solid case
+        double U1,U2,V1,V2;
+        // changes for 0020677: EDF 1219 GEOM: MinDistance gives 0 instead of 20.88
+        //S->Bounds(U1,U2,V1,V2); changed by
+        ShapeAnalysis::GetFaceUVBounds(TopoDS::Face(tmpSh1),U1,U2,V1,V2);
+        // end of changes for 020677 (dmv)
+        Handle(Geom_RectangularTrimmedSurface) TrS1 =
+          new Geom_RectangularTrimmedSurface(S,U1,(U1+U2)/2.,V1,V2);
+        Handle(Geom_RectangularTrimmedSurface) TrS2 =
+          new Geom_RectangularTrimmedSurface(S,(U1+U2)/2.,U2,V1,V2);
+        BRep_Builder B;
+        TopoDS_Face F1,F2;
+        TopoDS_Compound Comp;
+        B.MakeCompound(Comp);
+        B.MakeFace(F1,TrS1,1.e-7);
+        B.Add(Comp,F1);
+        B.MakeFace(F2,TrS2,1.e-7);
+        B.Add(Comp,F2);
+        Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape;
+        sfs->Init(Comp);
+        sfs->SetPrecision(1.e-6);
+        sfs->SetMaxTolerance(1.0);
+        sfs->Perform();
+        tmpSh1 = sfs->Shape();
+        IsChange1 = true;
+      }
+      else {
+        if( S->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ) {
+          Handle(Geom_SphericalSurface) SS = Handle(Geom_SphericalSurface)::DownCast(S);
+          gp_Pnt PC = SS->Location();
+          BRep_Builder B;
+          TopoDS_Vertex V;
+          B.MakeVertex(V,PC,1.e-7);
+          tmpSh1 = V;
+          AddDist1 = SS->Radius();
+          IsChange1 = true;
+        }
+        else {
+          Handle(Geom_ToroidalSurface) TS = Handle(Geom_ToroidalSurface)::DownCast(S);
+          gp_Ax3 ax3 = TS->Position();
+          Handle(Geom_Circle) C = new Geom_Circle(ax3.Ax2(),TS->MajorRadius());
+          BRep_Builder B;
+          TopoDS_Edge E;
+          B.MakeEdge(E,C,1.e-7);
+          tmpSh1 = E;
+          AddDist1 = TS->MinorRadius();
+          IsChange1 = true;
+        }
+      }
+    }
+    else
+      tmpSh1 = aSh1;
+  }
+  else
+    tmpSh1 = aSh1;
+  bool IsChange2 = false;
+  double AddDist2 = 0.0;
+  nbf = 0;
+  for ( anExp.Init( aSh2, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
+    nbf++;
+    tmpSh2 = anExp.Current();
+  }
+  if(nbf==1) {
+    TopoDS_Shape sh = aSh2;
+    while(sh.ShapeType()==TopAbs_COMPOUND) {
+      TopoDS_Iterator it(sh);
+      sh = it.Value();
+    }
+    Handle(Geom_Surface) S = BRep_Tool::Surface(TopoDS::Face(tmpSh2));
+    if( S->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
+        S->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ) {
+      if( sh.ShapeType()==TopAbs_SHELL || sh.ShapeType()==TopAbs_FACE ) {
+        // non solid case
+        double U1,U2,V1,V2;
+        //S->Bounds(U1,U2,V1,V2);
+        ShapeAnalysis::GetFaceUVBounds(TopoDS::Face(tmpSh2),U1,U2,V1,V2);
+        Handle(Geom_RectangularTrimmedSurface) TrS1 =
+          new Geom_RectangularTrimmedSurface(S,U1,(U1+U2)/2.,V1,V2);
+        Handle(Geom_RectangularTrimmedSurface) TrS2 =
+          new Geom_RectangularTrimmedSurface(S,(U1+U2)/2.,U2,V1,V2);
+        BRep_Builder B;
+        TopoDS_Face F1,F2;
+        TopoDS_Compound Comp;
+        B.MakeCompound(Comp);
+        B.MakeFace(F1,TrS1,1.e-7);
+        B.Add(Comp,F1);
+        B.MakeFace(F2,TrS2,1.e-7);
+        B.Add(Comp,F2);
+        Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape;
+        sfs->Init(Comp);
+        sfs->SetPrecision(1.e-6);
+        sfs->SetMaxTolerance(1.0);
+        sfs->Perform();
+        tmpSh2 = sfs->Shape();
+        IsChange2 = true;
+      }
+      else {
+        if( S->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ) {
+          Handle(Geom_SphericalSurface) SS = Handle(Geom_SphericalSurface)::DownCast(S);
+          gp_Pnt PC = SS->Location();
+          BRep_Builder B;
+          TopoDS_Vertex V;
+          B.MakeVertex(V,PC,1.e-7);
+          tmpSh2 = V;
+          AddDist2 = SS->Radius();
+          IsChange2 = true;
+        }
+        else if( S->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ) {
+          Handle(Geom_ToroidalSurface) TS = Handle(Geom_ToroidalSurface)::DownCast(S);
+          gp_Ax3 ax3 = TS->Position();
+          Handle(Geom_Circle) C = new Geom_Circle(ax3.Ax2(),TS->MajorRadius());
+          BRep_Builder B;
+          TopoDS_Edge E;
+          B.MakeEdge(E,C,1.e-7);
+          tmpSh2 = E;
+          AddDist2 = TS->MinorRadius();
+          IsChange2 = true;
+        }
+      }
+    }
+    else
+      tmpSh2 = aSh2;
+  }
+  else
+    tmpSh2 = aSh2;
+
+  if( !IsChange1 && !IsChange2 )
+    return -2.0;
+
+  BRepExtrema_DistShapeShape dst(tmpSh1,tmpSh2);
+  if (dst.IsDone()) {
+    double MinDist = 1.e9;
+    gp_Pnt PMin1, PMin2, P1, P2;
+    for (int i = 1; i <= dst.NbSolution(); i++) {
+      P1 = dst.PointOnShape1(i);
+      P2 = dst.PointOnShape2(i);
+      Standard_Real Dist = P1.Distance(P2);
+      if (MinDist > Dist) {
+        MinDist = Dist;
+        PMin1 = P1;
+        PMin2 = P2;
+      }
+    }
+    if(MinDist<1.e-7) {
+      Ptmp1 = PMin1;
+      Ptmp2 = PMin2;
+    }
+    else {
+      gp_Dir aDir(gp_Vec(PMin1,PMin2));
+      if( MinDist > (AddDist1+AddDist2) ) {
+        Ptmp1 = gp_Pnt( PMin1.X() + aDir.X()*AddDist1,
+                        PMin1.Y() + aDir.Y()*AddDist1,
+                        PMin1.Z() + aDir.Z()*AddDist1 );
+        Ptmp2 = gp_Pnt( PMin2.X() - aDir.X()*AddDist2,
+                        PMin2.Y() - aDir.Y()*AddDist2,
+                        PMin2.Z() - aDir.Z()*AddDist2 );
+        return (MinDist - AddDist1 - AddDist2);
+      }
+      else {
+        if( AddDist1 > 0 ) {
+          Ptmp1 = gp_Pnt( PMin1.X() + aDir.X()*AddDist1,
+                          PMin1.Y() + aDir.Y()*AddDist1,
+                          PMin1.Z() + aDir.Z()*AddDist1 );
+          Ptmp2 = Ptmp1;
+        }
+        else {
+          Ptmp2 = gp_Pnt( PMin2.X() - aDir.X()*AddDist2,
+                          PMin2.Y() - aDir.Y()*AddDist2,
+                          PMin2.Z() - aDir.Z()*AddDist2 );
+          Ptmp1 = Ptmp2;
+        }
+      }
+    }
+    double res = MinDist - AddDist1 - AddDist2;
+    if(res<0.) res = 0.0;
+    return res;
+  }
+  return -2.0;
+}
+
+//=======================================================================
+//function : GetMinDistance
+//purpose  : 
+//=======================================================================
+Standard_Real GEOMUtils::GetMinDistance
+                               (const TopoDS_Shape& theShape1,
+                                const TopoDS_Shape& theShape2,
+                                gp_Pnt& thePnt1, gp_Pnt& thePnt2)
+{
+  Standard_Real aResult = 1.e9;
+
+  // Issue 0020231: A min distance bug with torus and vertex.
+  // Make GetMinDistance() return zero if a sole VERTEX is inside any of SOLIDs
+
+  // which of shapes consists of only one vertex?
+  TopExp_Explorer exp1(theShape1,TopAbs_VERTEX), exp2(theShape2,TopAbs_VERTEX);
+  TopoDS_Shape V1 = exp1.More() ? exp1.Current() : TopoDS_Shape();
+  TopoDS_Shape V2 = exp2.More() ? exp2.Current() : TopoDS_Shape();
+  exp1.Next(); exp2.Next();
+  if ( exp1.More() ) V1.Nullify();
+  if ( exp2.More() ) V2.Nullify();
+  // vertex and container of solids
+  TopoDS_Shape V = V1.IsNull() ? V2 : V1;
+  TopoDS_Shape S = V1.IsNull() ? theShape1 : theShape2;
+  if ( !V.IsNull() ) {
+    // classify vertex against solids
+    gp_Pnt p = BRep_Tool::Pnt( TopoDS::Vertex( V ) );
+    for ( exp1.Init( S, TopAbs_SOLID ); exp1.More(); exp1.Next() ) {
+      BRepClass3d_SolidClassifier classifier( exp1.Current(), p, 1e-6);
+      if ( classifier.State() == TopAbs_IN ) {
+        thePnt1 = p;
+        thePnt2 = p;
+        return 0.0;
+      }
+    }
+  }
+  // End Issue 0020231
+
+  // skl 30.06.2008
+  // additional workaround for bugs 19899, 19908 and 19910 from Mantis
+  double dist = GEOMUtils::GetMinDistanceSingular
+      (theShape1, theShape2, thePnt1, thePnt2);
+
+  if (dist > -1.0) {
+    return dist;
+  }
+
+  BRepExtrema_DistShapeShape dst (theShape1, theShape2);
+  if (dst.IsDone()) {
+    gp_Pnt P1, P2;
+
+    for (int i = 1; i <= dst.NbSolution(); i++) {
+      P1 = dst.PointOnShape1(i);
+      P2 = dst.PointOnShape2(i);
+
+      Standard_Real Dist = P1.Distance(P2);
+      if (aResult > Dist) {
+        aResult = Dist;
+        thePnt1 = P1;
+        thePnt2 = P2;
+      }
+    }
+  }
+
+  return aResult;
+}
index 64c34bd857040dc3b7b1a0bc9feb3d513e1dc4c7..3b586d69373db59297930cb9775f2914a502d042 100644 (file)
@@ -37,6 +37,8 @@
 
 #include <functional>
 
+class Bnd_Box;
+
 inline Standard_Boolean IsEqual (const TopoDS_Shape& S1, const TopoDS_Shape& S2)
 {
   return S1.IsSame(S2);
@@ -132,6 +134,45 @@ class GEOMUtils {
   Standard_EXPORT static TopoDS_Shape GetEdgeNearPoint (const TopoDS_Shape&  theShape,
                                                         const TopoDS_Vertex& thePoint);
 
+  /*!
+   * \brief Compute precise bounding box of the shape based on the rough bounding box.
+   *
+   * \param theShape the shape.
+   * \param theBox rough bounding box on input; precise bounding box on output.
+   * \retval Standard_True in case of success; Standard_False otherwise.
+   */
+  Standard_EXPORT static Standard_Boolean PreciseBoundingBox
+                          (const TopoDS_Shape &theShape, Bnd_Box &theBox);
+
+  /*!
+   * \brief Computes minumal distance between two shapes for singular cases
+   *        (workaround for bugs 19899, 19908 and 19910 from Mantis).
+   *
+   * \param aSh1 the first shape
+   * \param aSh2 the second shape
+   * \param Ptmp1 the output result point on the first shape
+   * \param Ptmp2 the output result point on the second shape
+   * \retval negative value if it is not a singular case; actual distance for singular case.
+   */
+  Standard_EXPORT static Standard_Real GetMinDistanceSingular
+                               (const TopoDS_Shape& aSh1,
+                                const TopoDS_Shape& aSh2,
+                                gp_Pnt& Ptmp1, gp_Pnt& Ptmp2);
+
+  /*!
+   * \brief Computes minumal distance between two shapes.
+   *
+   * \param theShape1 the first shape
+   * \param theShape2 the second shape
+   * \param thePnt1 the output result point on the first shape
+   * \param thePnt2 the output result point on the second shape
+   * \retval negative value in case of failure; otherwise the real distance.
+   */
+  Standard_EXPORT static Standard_Real GetMinDistance
+                               (const TopoDS_Shape& theShape1,
+                                const TopoDS_Shape& theShape2,
+                                gp_Pnt& thePnt1, gp_Pnt& thePnt2);
+
 };
 
 #endif
index 9035dc9cad3c0784f7d34fb36caec76cab6fe8b5..3b5575f4362bca9c93639abb9e99f3e36ab99cd9 100644 (file)
@@ -258,6 +258,7 @@ void GEOM_IMeasureOperations_i::GetInertia
  */
 //=============================================================================
 void GEOM_IMeasureOperations_i::GetBoundingBox (GEOM::GEOM_Object_ptr theShape,
+                                                CORBA::Boolean precise,
                                                 CORBA::Double& Xmin, CORBA::Double& Xmax,
                                                 CORBA::Double& Ymin, CORBA::Double& Ymax,
                                                 CORBA::Double& Zmin, CORBA::Double& Zmax)
@@ -270,7 +271,8 @@ void GEOM_IMeasureOperations_i::GetBoundingBox (GEOM::GEOM_Object_ptr theShape,
   if (aShape.IsNull()) return;
 
   // Get shape parameters
-  GetOperations()->GetBoundingBox(aShape, Xmin, Xmax, Ymin, Ymax, Zmin, Zmax);
+  GetOperations()->GetBoundingBox
+    (aShape, precise, Xmin, Xmax, Ymin, Ymax, Zmin, Zmax);
 }
 
 //=============================================================================
@@ -279,7 +281,8 @@ void GEOM_IMeasureOperations_i::GetBoundingBox (GEOM::GEOM_Object_ptr theShape,
  */
 //=============================================================================
 GEOM::GEOM_Object_ptr GEOM_IMeasureOperations_i::MakeBoundingBox
-                                              (GEOM::GEOM_Object_ptr theShape)
+                                              (GEOM::GEOM_Object_ptr theShape,
+                                               CORBA::Boolean precise)
 {
   GEOM::GEOM_Object_var aGEOMObject;
 
@@ -291,7 +294,8 @@ GEOM::GEOM_Object_ptr GEOM_IMeasureOperations_i::MakeBoundingBox
   if (aShape.IsNull()) return aGEOMObject._retn();
 
   // Make Box - bounding box of theShape
-  Handle(GEOM_Object) anObject = GetOperations()->GetBoundingBox(aShape);
+  Handle(GEOM_Object) anObject =
+    GetOperations()->GetBoundingBox(aShape, precise);
   if (!GetOperations()->IsDone() || anObject.IsNull())
     return aGEOMObject._retn();
 
index b5bc384c367dacadc659df3f501f32b7c8749432..3fd992489a3ac3e8288e5ff864b6b304fa8f7207 100644 (file)
@@ -71,11 +71,13 @@ class GEOM_I_EXPORT GEOM_IMeasureOperations_i :
                    CORBA::Double& Ix , CORBA::Double& Iy , CORBA::Double& Iz);
 
   void GetBoundingBox (GEOM::GEOM_Object_ptr theShape,
+                       CORBA::Boolean precise,
                        CORBA::Double& Xmin, CORBA::Double& Xmax,
                        CORBA::Double& Ymin, CORBA::Double& Ymax,
                        CORBA::Double& Zmin, CORBA::Double& Zmax);
 
-  GEOM::GEOM_Object_ptr MakeBoundingBox (GEOM::GEOM_Object_ptr theShape);
+  GEOM::GEOM_Object_ptr MakeBoundingBox (GEOM::GEOM_Object_ptr theShape,
+                                         CORBA::Boolean precise);
 
   void GetTolerance (GEOM::GEOM_Object_ptr theShape,
                      CORBA::Double& FaceMin, CORBA::Double& FaceMax,
index 28dab6b5e21cdc6210fd83a0f90c10306d791cea..05e3d674f6ccff57bfa5ae71bd96731f45c57134 100644 (file)
@@ -9031,18 +9031,20 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen):
 
         ## Get parameters of bounding box of the given shape
         #  @param theShape Shape to obtain bounding box of.
+        #  @param precise TRUE for precise computation; FALSE for fast one.
         #  @return [Xmin,Xmax, Ymin,Ymax, Zmin,Zmax]
         #  Xmin,Xmax: Limits of shape along OX axis.
         #  Ymin,Ymax: Limits of shape along OY axis.
         #  Zmin,Zmax: Limits of shape along OZ axis.
         #
         #  @ref tui_measurement_tools_page "Example"
-        def BoundingBox (self, theShape):
+        def BoundingBox (self, theShape, precise=False):
             """
             Get parameters of bounding box of the given shape
 
             Parameters: 
                 theShape Shape to obtain bounding box of.
+                precise TRUE for precise computation; FALSE for fast one.
 
             Returns:
                 [Xmin,Xmax, Ymin,Ymax, Zmin,Zmax]
@@ -9051,12 +9053,13 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen):
                  Zmin,Zmax: Limits of shape along OZ axis.
             """
             # Example: see GEOM_TestMeasures.py
-            aTuple = self.MeasuOp.GetBoundingBox(theShape)
+            aTuple = self.MeasuOp.GetBoundingBox(theShape, precise)
             RaiseIfFailed("GetBoundingBox", self.MeasuOp)
             return aTuple
 
         ## Get bounding box of the given shape
         #  @param theShape Shape to obtain bounding box of.
+        #  @param precise TRUE for precise computation; FALSE for fast one.
         #  @param theName Object name; when specified, this parameter is used
         #         for result publication in the study. Otherwise, if automatic
         #         publication is switched on, default value is used for result name.
@@ -9064,12 +9067,13 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen):
         #  @return New GEOM.GEOM_Object, containing the created box.
         #
         #  @ref tui_measurement_tools_page "Example"
-        def MakeBoundingBox (self, theShape, theName=None):
+        def MakeBoundingBox (self, theShape, precise=False, theName=None):
             """
             Get bounding box of the given shape
 
             Parameters: 
                 theShape Shape to obtain bounding box of.
+                precise TRUE for precise computation; FALSE for fast one.
                 theName Object name; when specified, this parameter is used
                         for result publication in the study. Otherwise, if automatic
                         publication is switched on, default value is used for result name.
@@ -9078,7 +9082,7 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen):
                 New GEOM.GEOM_Object, containing the created box.
             """
             # Example: see GEOM_TestMeasures.py
-            anObj = self.MeasuOp.MakeBoundingBox(theShape)
+            anObj = self.MeasuOp.MakeBoundingBox(theShape, precise)
             RaiseIfFailed("MakeBoundingBox", self.MeasuOp)
             self._autoPublish(anObj, theName, "bndbox")
             return anObj
index 9c75ad8ed2ac347bc7e6807a81784eb6b473423c..5d0ebc3a86d228e3f8478f595c22377b2befa418 100644 (file)
@@ -220,7 +220,7 @@ bool MeasureGUI_BndBoxDlg::getParameters (double& theXmin, double& theXmax,
     return false;
 
   GEOM::GEOM_IMeasureOperations_var anOper = GEOM::GEOM_IMeasureOperations::_narrow(getOperation());
-  anOper->GetBoundingBox(myObj, theXmin, theXmax, theYmin, theYmax, theZmin, theZmax);
+  anOper->GetBoundingBox(myObj, true, theXmin, theXmax, theYmin, theYmax, theZmin, theZmax);
 
   return anOper->IsDone();
 }
@@ -300,7 +300,7 @@ bool MeasureGUI_BndBoxDlg::isValid (QString&)
 bool MeasureGUI_BndBoxDlg::execute (ObjectList& objects)
 {
   GEOM::GEOM_IMeasureOperations_var anOper = GEOM::GEOM_IMeasureOperations::_narrow(getOperation());
-  GEOM::GEOM_Object_var anObj = anOper->MakeBoundingBox(myObj);
+  GEOM::GEOM_Object_var anObj = anOper->MakeBoundingBox(myObj, true);
 
   if (!anObj->_is_nil())
     objects.push_back(anObj._retn());
index d3d6d40e96d4cc74ee4cf1ead636e13698b8740d..6ac1ca9232ae1d232490b38d179604ea99a4e871 100644 (file)
@@ -270,7 +270,7 @@ void TransformationGUI_MultiRotationDlg::SelectionIntoArgument()
       // recompute myAng and myStep (Mantis issue 0021718)
       GEOM::GEOM_IMeasureOperations_var anOper = getGeomEngine()->GetIMeasureOperations(getStudyId());
       double Xmin, Xmax, Ymin, Ymax, Zmin, Zmax;
-      anOper->GetBoundingBox(myBase.get(), Xmin, Xmax, Ymin, Ymax, Zmin, Zmax);
+      anOper->GetBoundingBox(myBase.get(), true, Xmin, Xmax, Ymin, Ymax, Zmin, Zmax);
       if (anOper->IsDone()) {
         // angular step
         double diag = sqrt((Xmax-Xmin)*(Xmax-Xmin) + (Ymax-Ymin)*(Ymax-Ymin));
index dc0c73589de46c16981409380affb642a1fe549c..f03968be1ad09a517f466e04024385d044faae9e 100644 (file)
@@ -335,7 +335,7 @@ void TransformationGUI_MultiTranslationDlg::SelectionIntoArgument()
       // recompute myStepU (Mantis issue 0021718)
       GEOM::GEOM_IMeasureOperations_var anOper = getGeomEngine()->GetIMeasureOperations(getStudyId());
       double Xmin, Xmax, Ymin, Ymax, Zmin, Zmax;
-      anOper->GetBoundingBox(myBase.get(), Xmin, Xmax, Ymin, Ymax, Zmin, Zmax);
+      anOper->GetBoundingBox(myBase.get(), true, Xmin, Xmax, Ymin, Ymax, Zmin, Zmax);
       if (anOper->IsDone()) {
         myStepU = floor(1.5 * (Xmax - Xmin));
         GroupPoints->SpinBox_DX->setValue(myStepU);
@@ -355,7 +355,7 @@ void TransformationGUI_MultiTranslationDlg::SelectionIntoArgument()
       // recompute myStepU and myStepV (Mantis issue 0021718)
       GEOM::GEOM_IMeasureOperations_var anOper = getGeomEngine()->GetIMeasureOperations(getStudyId());
       double Xmin, Xmax, Ymin, Ymax, Zmin, Zmax;
-      anOper->GetBoundingBox(myBase.get(), Xmin, Xmax, Ymin, Ymax, Zmin, Zmax);
+      anOper->GetBoundingBox(myBase.get(), true, Xmin, Xmax, Ymin, Ymax, Zmin, Zmax);
       if (anOper->IsDone()) {
         myStepU = floor(1.5 * (Xmax - Xmin));
         myStepV = floor(1.5 * (Ymax - Ymin));