]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Remove param "precise" in BoundingBox feature and modif unit test and example
authorlucasjerome <jerome.lucas@cegsenslab.fr>
Fri, 5 Feb 2021 15:13:20 +0000 (16:13 +0100)
committerlucasjerome <jerome.lucas@cegsenslab.fr>
Fri, 5 Feb 2021 15:13:20 +0000 (16:13 +0100)
src/FeaturesPlugin/FeaturesPlugin_BoundingBox.cpp
src/FeaturesPlugin/FeaturesPlugin_BoundingBox.h
src/FeaturesPlugin/FeaturesPlugin_CreateBoundingBox.cpp
src/FeaturesPlugin/FeaturesPlugin_CreateBoundingBox.h
src/FeaturesPlugin/Test/TestBoundingBox.py
src/FeaturesPlugin/doc/examples/create_bounding_box.py
src/GeomAlgoAPI/GeomAlgoAPI_BoundingBox.cpp
src/GeomAlgoAPI/GeomAlgoAPI_BoundingBox.h

index 6e30b6f5469853c0f6bf62b3d3e7d5c64854cbc8..928d1c492f0569ca9e643c61e5a55de75f3bf519 100644 (file)
@@ -74,7 +74,8 @@ void FeaturesPlugin_BoundingBox::initAttributes()
 //=================================================================================================
 void FeaturesPlugin_BoundingBox::execute()
 {
-  updateValues();
+  if (!updateValues())
+    return;
   createBoxByTwoPoints();
 
   if (boolean(CREATEBOX_ID())->value()) {
@@ -108,7 +109,7 @@ AttributePtr FeaturesPlugin_BoundingBox::attributResultValues()
 }
 
 //=================================================================================================
-void FeaturesPlugin_BoundingBox::updateValues()
+bool FeaturesPlugin_BoundingBox::updateValues()
 {
   AttributeSelectionPtr aSelection = selection(OBJECT_ID());
   if (aSelection->isInitialized()) {
@@ -132,12 +133,13 @@ void FeaturesPlugin_BoundingBox::updateValues()
       double aXmin, aXmax, aYmin,aYmax,aZmin,aZmax;
       std::string aError;
       if (!GetBoundingBox(aShape,
-                          true,
                           aXmin, aXmax,
                           aYmin,aYmax,
                           aZmin,aZmax,
-                          aError))
+                          aError)) {
           setError("Error in bounding box calculation :" +  aError);
+          return false;
+      }
 
       myShape = aShape;
       streamxmin << std::setprecision(14) << aXmin;
@@ -160,6 +162,7 @@ void FeaturesPlugin_BoundingBox::updateValues()
       string(Z_MAX_COORD_ID() )->setValue( "Z = " +  streamzmax.str() );
     }
   }
+  return true;
 }
 
 //=================================================================================================
index ef12a579f71b154e8995c866bdf237a841002eaf..e81dacef8c97f5db6c6e478c4279de928a3f7591 100644 (file)
@@ -126,7 +126,7 @@ private:
   virtual AttributePtr attributResultValues();
 
   /// Update values displayed.
-  void updateValues();
+  bool updateValues();
   /// Create Box
   void createBox();
   /// Update Box
index f59d98b94fb420056619eab92cc70e7ed6bc6d81..b8c4111a9045316c6159dfaa8180308aa12681aa 100644 (file)
@@ -73,7 +73,8 @@ void FeaturesPlugin_CreateBoundingBox::initAttributes()
 //=================================================================================================
 void FeaturesPlugin_CreateBoundingBox::execute()
 {
-  updateValues();
+  if (!updateValues())
+    return;
   createBoxByTwoPoints();
 }
 
@@ -83,7 +84,7 @@ void FeaturesPlugin_CreateBoundingBox::attributeChanged(const std::string& theID
 }
 
 //=================================================================================================
-void FeaturesPlugin_CreateBoundingBox::updateValues()
+bool FeaturesPlugin_CreateBoundingBox::updateValues()
 {
   AttributeSelectionPtr aSelection = selection(OBJECT_ID());
   AttributeDoubleArrayPtr aValues =
@@ -114,12 +115,13 @@ void FeaturesPlugin_CreateBoundingBox::updateValues()
       double aXmin, aXmax, aYmin,aYmax,aZmin,aZmax;
       std::string aError;
       if (!GetBoundingBox(aShape,
-                          true,
                           aXmin, aXmax,
                           aYmin,aYmax,
                           aZmin,aZmax,
-                          aError))
+                          aError)) {
           setError("Error in bounding box calculation :" +  aError);
+          return false;
+      }
       myShape = aShape;
       streamxmin << std::setprecision(14) << aXmin;
       aValues->setValue(0, aXmin);
@@ -149,6 +151,7 @@ void FeaturesPlugin_CreateBoundingBox::updateValues()
     string(Y_MAX_COORD_ID() )->setValue( "Y = " +  streamymax.str() );
     string(Z_MAX_COORD_ID() )->setValue( "Z = " +  streamzmax.str() );
   }
+  return true;
 }
 
 //=================================================================================================
index 6884ac0db27b4f2f5d9824efef6c98972f0d64b5..be797af76927c4d70c0cdcbb70755fd3b9c8396a 100644 (file)
@@ -123,7 +123,7 @@ public:
 
 private:
   /// Update values displayed.
-  void updateValues();
+  bool updateValues();
 
 };
 
index 673445e8641e016a3ef9be1ca9ba6a5c82c3be76..49f90f8e06854893c03dd687b7ccbddf5eaf13ff 100644 (file)
@@ -41,14 +41,15 @@ __updated__ = "2020-11-12"
 def test_Bounding_Box():
 
     model.begin()
-    file_path = os.path.join(os.getenv("DATA_DIR"),"Shapes","Step","screw.step")
     partSet = model.moduleDocument()
     Part_1 = model.addPart(partSet)
     Part_1_doc = Part_1.document()
-    Import_1 = model.addImport(Part_1_doc,file_path)
+    ### Create Cone
+    Cone_1 = model.addCone(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 10, 5, 10)
+
     model.do()
     ### Create BoundingBox
-    BoundingBox_1 = model.getBoundingBox(Part_1_doc, model.selection("SOLID", "screw_1"))
+    BoundingBox_1 = model.getBoundingBox(Part_1_doc, model.selection("SOLID", "Cone_1_1"))
     model.end()
 
     myDelta = 1e-6
@@ -59,15 +60,15 @@ def test_Bounding_Box():
     print(" Surface area: ", Props[1])
     print(" Volume      : ", Props[2]) 
     
-    aReflength = 0.32855301948678
+    aReflength = 200
     aReslength = Props[0]
     assert (math.fabs(aReslength - aReflength) < myDelta), "The surface is wrong: expected = {0}, real = {1}".format(aReflength, aReslength)
 
-    aRefSurface = 0.0041640657342782
+    aRefSurface = 1600
     aResSurface = Props[1]
     assert (math.fabs(aResSurface - aRefSurface) < myDelta), "The surface is wrong: expected = {0}, real = {1}".format(aRefSurface, aResSurface)
 
-    aRefVolume = 1.6785355394103e-05
+    aRefVolume = 4000
     aResVolume = Props[2]
     assert (math.fabs(aResVolume - aRefVolume) < myDelta), "The volume is wrong: expected = {0}, real = {1}".format(aRefVolume, aResVolume)
 
index d904006ae6003b76f0f136ee89e4dde3d31fc05f..fa14ebaf2cd0fb4114ec03cb1650d8b8581abc8e 100644 (file)
@@ -2,12 +2,13 @@ from salome.shaper import model
 import os
 
 model.begin()
-file_path = os.path.join(os.getenv("DATA_DIR"),"Shapes","Step","screw.step")
 partSet = model.moduleDocument()
 Part_1 = model.addPart(partSet)
 Part_1_doc = Part_1.document()
-Import_1 = model.addImport(Part_1_doc,file_path)
+### Create Cone
+Cone_1 = model.addCone(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 10, 5, 10)
+
 model.do()
 ### Create BoundingBox
-BoundingBox_1 = model.getBoundingBox(Part_1_doc, model.selection("SOLID", "screw_1"))
+BoundingBox_1 = model.getBoundingBox(Part_1_doc, model.selection("SOLID", "Cone_1_1"))
 model.end()
index 856b2eb4d2aadde1a2792e7a47341d66ad87ab9b..47c9417b15ea47528e9dccd52f608796b1e87720 100644 (file)
 #include <Geom_SphericalSurface.hxx>
 #include <Geom_ToroidalSurface.hxx>
 
-/**
-* This function constructs and returns modified shape from the original one
-* for singular cases. It is used for the method GetMinDistanceSingular.
-*
-* \param theShape the original shape
-* \param theModifiedShape output parameter. The modified shape.
-* \param theAddDist output parameter. The added distance for modified shape.
-* \retval true if the shape is modified; false otherwise.
-*
-* \internal
-*/
-Standard_Boolean ModifyShape(const TopoDS_Shape  &theShape,
-                             TopoDS_Shape  &theModifiedShape,
-                             Standard_Real &theAddDist)
-{
-  TopExp_Explorer anExp;
-  int nbf = 0;
-
-  theAddDist = 0.;
-  theModifiedShape.Nullify();
-
-  for ( anExp.Init( theShape, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
-    nbf++;
-    theModifiedShape = anExp.Current();
-  }
-  if(nbf==1) {
-    TopoDS_Shape sh = theShape;
-    while(sh.ShapeType()==TopAbs_COMPOUND) {
-      TopoDS_Iterator it(sh);
-      sh = it.Value();
-    }
-    Handle(Geom_Surface) S = BRep_Tool::Surface(TopoDS::Face(theModifiedShape));
-    if(S->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
-       S->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ||
-       S->IsUPeriodic()) {
-      const Standard_Boolean isShell =
-        (sh.ShapeType()==TopAbs_SHELL || sh.ShapeType()==TopAbs_FACE);
-
-      if (!isShell && 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);
-          theModifiedShape = V;
-          theAddDist = SS->Radius();
-          return Standard_True;
-        }
-        if (!isShell && 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);
-          theModifiedShape = E;
-          theAddDist = TS->MinorRadius();
-          return Standard_True;
-        }
-
-        // non solid case or any periodic surface (Mantis 22454).
-        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(theModifiedShape),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);
-        TopoDS_Shape aMShape;
-
-        TopoDS_Face F1 = BRepBuilderAPI_MakeFace(TrS1, Precision::Confusion());
-        TopoDS_Face F2 = BRepBuilderAPI_MakeFace(TrS2, Precision::Confusion());
-
-        if (isShell) {
-          BRep_Builder B;
-          B.MakeCompound(TopoDS::Compound(aMShape));
-          B.Add(aMShape, F1);
-          B.Add(aMShape, F2);
-        } else {
-          // The original shape is a solid.
-          BRepBuilderAPI_Sewing aSewing (Precision::Confusion()*10.0);
-          aSewing.Add(F1);
-          aSewing.Add(F2);
-          aSewing.Perform();
-          aMShape = aSewing.SewedShape();
-          BRep_Builder B;
-          TopoDS_Solid aSolid;
-          B.MakeSolid(aSolid);
-          B.Add(aSolid, aMShape);
-          aMShape = aSolid;
-        }
-
-        Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape;
-        sfs->Init(aMShape);
-        sfs->SetPrecision(1.e-6);
-        sfs->SetMaxTolerance(1.0);
-        sfs->Perform();
-        theModifiedShape = sfs->Shape();
-        return Standard_True;
-      }
-    }
-
-    theModifiedShape = theShape;
-    return Standard_False;
-  }
-
-//=======================================================================
-// function : GetMinDistanceSingular
-//=======================================================================
-double GetMinDistanceSingular(const TopoDS_Shape& aSh1,
-                              const TopoDS_Shape& aSh2,
-                              gp_Pnt& Ptmp1, gp_Pnt& Ptmp2)
-{
-  TopoDS_Shape     tmpSh1;
-  TopoDS_Shape     tmpSh2;
-  Standard_Real    AddDist1 = 0.;
-  Standard_Real    AddDist2 = 0.;
-  Standard_Boolean IsChange1 = ModifyShape(aSh1, tmpSh1, AddDist1);
-  Standard_Boolean IsChange2 = ModifyShape(aSh2, tmpSh2, AddDist2);
-
-  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
-//=======================================================================
-Standard_Real 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;
-      }
-    }
-  }
-
-  aResult = GetMinDistanceSingular(theShape1, theShape2, thePnt1, thePnt2);
-
-
-  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 < 0 || aResult > Dist) {
-        aResult = Dist;
-        thePnt1 = P1;
-        thePnt2 = P2;
-      }
-    }
-  }
-
-  return aResult;
-}
-
-//=======================================================================
-// function : PreciseBoundingBox
-//=======================================================================
-Standard_Boolean PreciseBoundingBox
-                          (const TopoDS_Shape &theShape, Bnd_Box &theBox)
-{
-  if (theBox.IsVoid()) BRepBndLib::Add( theShape, theBox );
-  if (theBox.IsVoid()) return Standard_False;
-
-  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 = 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;
-}
-
 //=================================================================================================
 bool GetBoundingBox(const std::shared_ptr<GeomAPI_Shape>& theShape,
-                    const bool thePrecise,
                     Standard_Real& theXmin,Standard_Real& theXmax,
                     Standard_Real& theYmin,Standard_Real& theYmax,
                     Standard_Real& theZmin,Standard_Real& theZmax,
@@ -375,13 +74,13 @@ bool GetBoundingBox(const std::shared_ptr<GeomAPI_Shape>& theShape,
     // remove triangulation to obtain more exact boundaries
     BRepTools::Clean(aShape);
 
-    BRepBndLib::Add(aShape, B);
+    BRepBndLib::AddOptimal(aShape, B);
 
-    if (thePrecise) {
-      if (!PreciseBoundingBox(aShape, B)) {
-        theError = "GetBoundingBox Error: Bounding box cannot be precised";
+    if (B.IsXThin(Precision::Confusion())
+        || B.IsYThin(Precision::Confusion())
+        || B.IsZThin(Precision::Confusion())) {
+      theError = "GetBoundingBox Error: Bounding box cannot be precised";
         return false;
-      }
     }
 
     B.Get(theXmin, theYmin, theZmin, theXmax, theYmax, theZmax);
index 010c3a30b380fb96c534203b040b64ffe476ad7e..84a8dc3a5ea05e2b5e53f0cfcbba7dfdf976a39c 100644 (file)
@@ -26,7 +26,6 @@
 
 /// get the boundin box of theshape.
   /// \param theShape   the shape
-  /// \param thePrecise precise TRUE for precise computation; FALSE for fast one.
   /// \param theXmin    X min of the box
   /// \param theXmax    X max of the box
   /// \param theYmin    Y min of the box
@@ -36,7 +35,6 @@
   /// \param theError  error
 GEOMALGOAPI_EXPORT
 bool GetBoundingBox(const std::shared_ptr<GeomAPI_Shape>& theShape,
-                    const bool thePrecise,
                     Standard_Real& theXmin,Standard_Real& theXmax,
                     Standard_Real& theYmin,Standard_Real& theYmax,
                     Standard_Real& theZmin,Standard_Real& theZmax,