Salome HOME
[bos #36177] [FORUM] - Remove extra-edge on hemisphere
authorjfa <jfa@opencascade.com>
Thu, 17 Aug 2023 21:17:57 +0000 (22:17 +0100)
committerjfa <jfa@opencascade.com>
Thu, 17 Aug 2023 21:17:57 +0000 (22:17 +0100)
doc/salome/gui/GEOM/input/tui_test_others.doc
src/BlockFix/BlockFix.cxx
src/BlockFix/BlockFix.hxx
src/BlockFix/BlockFix_BlockFixAPI.cxx
src/BlockFix/BlockFix_SphereSpaceModifier.cxx
src/BlockFix/BlockFix_SphereSpaceModifier.hxx
src/GEOM_SWIG/GEOM_TestOthers.py

index 9eebe0f4232b84d2834182acca6aab4356a2480f..fc6c050242e887fa4258e97b9e107a2874db1f94 100644 (file)
@@ -23,7 +23,7 @@
 \until id_Orientation
 
 \anchor swig_MakeCommon
-\until id_Section
+\until id_Fuse2
 
 \anchor swig_Partition
 \until id_Partition
@@ -47,7 +47,7 @@
 \until id_MakeBlockExplode
 
 \anchor swig_CheckCompoundOfBlocks
-\until The Box is VALID
+\until VALID Blocks Compound
 
 \anchor swig_GetSame
 \until id_Cone_ss
@@ -68,7 +68,7 @@
 \until Now contains
 
 \anchor swig_GetObjectIDs
-\until print(" ", ObjectID)
+\until sorted
 
 \anchor swig_GetMainShape
 \until BoxCopy
 \until Now contains
 
 \anchor swig_UnionIDs
-\until print(" ", ObjectID)
+\until sorted
 
 \anchor swig_bop_on_groups
 \until Box, Group_CL_2_4
 
 \anchor swig_GetType
-\until Type of elements
+\until assert
 
 \until freeFaces, "freeFaces"
 
+\until Solid_1 = geompy.MakeSolid
+
 \anchor swig_RemoveExtraEdges
 \until "freeFacesWithoutExtra"
 
 \until subBlackWhite[1]
 
 \anchor swig_CheckAndImprove
-\until "blocksComp"
+\until "CheckCompoundOfBlocks"
 
 \anchor swig_Propagate
 \until "propagation chain"
index 489506357da0f7ef00d0dd636a3c79fb6b93222a..b333211e812b35a2534b6a2cf138cf43b2c2b501 100644 (file)
@@ -201,27 +201,29 @@ static void FixResult(const TopoDS_Shape& result,
 //purpose  :
 //=======================================================================
 TopoDS_Shape BlockFix::RotateSphereSpace (const TopoDS_Shape& S,
-                                          const Standard_Real Tol)
+                                          const Standard_Real Tol,
+                                          const Standard_Boolean theTrySmallRotation)
 {
   // Create a modification description
   Handle(BlockFix_SphereSpaceModifier) SR = new BlockFix_SphereSpaceModifier;
   SR->SetTolerance(Tol);
+  SR->SetTrySmallRotation(theTrySmallRotation);
 
   TopTools_DataMapOfShapeShape context;
   BRepTools_Modifier MD;
-  TopoDS_Shape result = ShapeCustom::ApplyModifier ( S, SR, context,MD );
+  TopoDS_Shape result = ShapeCustom::ApplyModifier ( S, SR, context, MD );
 
   Handle(ShapeBuild_ReShape) RS = new ShapeBuild_ReShape;
   FixResult(result,RS,Tol);
   result = RS->Apply(result);
 
   ShapeFix_Edge sfe;
-  for(TopExp_Explorer exp(result,TopAbs_EDGE); exp.More(); exp.Next()) {
+  for (TopExp_Explorer exp (result, TopAbs_EDGE); exp.More(); exp.Next()) {
     TopoDS_Edge E = TopoDS::Edge(exp.Current());
     sfe.FixVertexTolerance (E);
   }
 
-  ShapeFix::SameParameter(result,Standard_False);
+  ShapeFix::SameParameter(result, Standard_False);
   return result;
 }
 
index 64fd7c3f4fe0a6693126907b21ebbe4089804a88..4219c81461ebe40d4809b7c5e918a8a0bdd64490 100644 (file)
@@ -39,7 +39,10 @@ class BlockFix_CheckTool;
 class BlockFix {
 
 public:
-  Standard_EXPORT static  TopoDS_Shape RotateSphereSpace(const TopoDS_Shape& S,const Standard_Real Tol);
+  Standard_EXPORT static  TopoDS_Shape RotateSphereSpace
+                                      (const TopoDS_Shape& S,
+                                       const Standard_Real Tol,
+                                       const Standard_Boolean theTrySmallRotation = Standard_True);
   Standard_EXPORT static  TopoDS_Shape RefillProblemFaces(const TopoDS_Shape& S);
   Standard_EXPORT static  TopoDS_Shape FixRanges(const TopoDS_Shape& S,const Standard_Real Tol);
 
index ea30cc5321501575be699e12c6ac63dd22d852b6..103124a4fbf35fa05f9b6927391e495cbde85a9b 100644 (file)
 
 #include <Precision.hxx>
 
+#include <BRepTools.hxx>
+#include <BRepBuilderAPI_Copy.hxx>
+#include <BRepCheck_Analyzer.hxx>
+
 #include <Basics_OCCTVersion.hxx>
 
 IMPLEMENT_STANDARD_RTTIEXT(BlockFix_BlockFixAPI, Standard_Transient)
@@ -64,7 +68,22 @@ void BlockFix_BlockFixAPI::Perform()
 {
   // processing spheres with degenerativities
   TopoDS_Shape aShape = Shape();
-  myShape = BlockFix::RotateSphereSpace(aShape,myTolerance);
+  // Copy the shape to avoid modification of initial shape
+  // while trying the approach with small rotation
+  BRepBuilderAPI_Copy aMC (aShape);
+  if (!aMC.IsDone()) return;
+  TopoDS_Shape aSCopy = aMC.Shape();
+  TopoDS_Shape aNewShape = BlockFix::RotateSphereSpace(aSCopy, myTolerance, Standard_True);
+  BRepCheck_Analyzer ana (aNewShape, false);
+  if (ana.IsValid()) {
+    if (aNewShape == aSCopy)
+      myShape = aShape;
+    else
+      myShape = aNewShape;
+  }
+  else {
+    myShape = BlockFix::RotateSphereSpace(aShape, myTolerance, Standard_False);
+  }
 
   // try to approximate non-canonic surfaces
   // with singularities on boundaries by filling
index 13c6c9b21a0940feed76f7f3016820db3402d04f..7054e59d0d9798be343044f845762cf451d4b679 100644 (file)
 #include <TopoDS_Vertex.hxx>
 #include <TopoDS_Iterator.hxx>
 
+#include <BRepGProp.hxx>
+#include <GProp_GProps.hxx>
+
 #include <BRep_Tool.hxx>
 #include <BRep_Builder.hxx>
 #include <BRepTools.hxx>
 #include <BRepAdaptor_Curve2d.hxx>
 #include <BRepTopAdaptor_FClass2d.hxx>
+#include <BRepClass_FaceClassifier.hxx>
 
 #include <ElSLib.hxx>
 #include <Geom_Circle.hxx>
 #include <Geom_TrimmedCurve.hxx>
 #include <Geom_SphericalSurface.hxx>
 #include <Geom_RectangularTrimmedSurface.hxx>
-
 #include <Geom_Curve.hxx>
 #include <Geom_Surface.hxx>
 
@@ -65,6 +68,8 @@ IMPLEMENT_STANDARD_RTTIEXT(BlockFix_SphereSpaceModifier, BRepTools_Modification)
 //purpose  :
 //=======================================================================
 BlockFix_SphereSpaceModifier::BlockFix_SphereSpaceModifier()
+: myTolerance(Precision::Confusion()),
+  mySmallRotation(Standard_True)
 {
   myMapOfFaces.Clear();
   myMapOfSpheres.Clear();
@@ -85,19 +90,24 @@ void BlockFix_SphereSpaceModifier::SetTolerance(const Standard_Real Tol)
   myTolerance = Tol;
 }
 
+//=======================================================================
+//function : SetTrySmallRotation
+//purpose  :
+//=======================================================================
+void BlockFix_SphereSpaceModifier::SetTrySmallRotation(const Standard_Boolean isSmallRotation)
+{
+  mySmallRotation = isSmallRotation;
+}
+
 //=======================================================================
 //function : NewSurface
 //purpose  :
 //=======================================================================
 static Standard_Boolean ModifySurface(const TopoDS_Face&          theFace,
                                       const Handle(Geom_Surface)& theSurface,
-                                      Handle(Geom_Surface)&       theNewSurface)
+                                      Handle(Geom_Surface)&       theNewSurface,
+                                      const Standard_Boolean      theTrySmallRotation)
 {
-  TopoDS_Face aFace = theFace;
-  aFace.Orientation (TopAbs_FORWARD);
-
-  Handle(Geom_Surface) aNewSurface;
-  
   Handle(Geom_Surface) aSurf = theSurface;
   if (aSurf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
     Handle(Geom_RectangularTrimmedSurface) RTS =
@@ -105,142 +115,189 @@ static Standard_Boolean ModifySurface(const TopoDS_Face&          theFace,
     aSurf = RTS->BasisSurface();
   }
 
-  if (aSurf->IsKind(STANDARD_TYPE(Geom_SphericalSurface))) {
-    Standard_Real Umin, Umax, Vmin, Vmax;
-    BRepTools::UVBounds(aFace, Umin, Umax, Vmin, Vmax);
-    Standard_Real PI2 = M_PI/2.;
-    Handle(Geom_SphericalSurface) aSphere = Handle(Geom_SphericalSurface)::DownCast(aSurf);
-    gp_Sphere sp = aSphere->Sphere();
-    Standard_Real Radius = sp.Radius();
-    gp_Ax3 ax3 = sp.Position();
-    gp_Pnt aCentre = sp.Location();
-    
-    TopoDS_Wire aWire = BRepTools::OuterWire (aFace);
-    BRepTopAdaptor_FClass2d aClassifier (aFace, Precision::PConfusion());
-    TopTools_MapOfShape aEmap;
-    const Standard_Real anOffsetValue = 0.01*M_PI;
-    for (Standard_Integer ii = 1; ii <= 2; ii++)
-    {
-      TopoDS_Iterator itw (aWire);
-      for (; itw.More(); itw.Next())
-      {
-        const TopoDS_Edge& anEdge = TopoDS::Edge (itw.Value());
-        if (aEmap.Contains (anEdge) ||
-            anEdge.Orientation() == TopAbs_INTERNAL ||
-            anEdge.Orientation() == TopAbs_EXTERNAL ||
-            BRep_Tool::Degenerated (anEdge) ||
-            BRepTools::IsReallyClosed (anEdge, aFace))
-          continue;
-        
-        BRepAdaptor_Curve2d aBAcurve2d (anEdge, aFace);
-        GeomAbs_CurveType aType = aBAcurve2d.GetType();
-        if (ii == 1 && aType == GeomAbs_Line) //first pass: consider only curvilinear edges
-          continue;
-        
-        Standard_Real aMidPar = (aBAcurve2d.FirstParameter() + aBAcurve2d.LastParameter())/2;
-        gp_Pnt2d aMidP2d;
-        gp_Vec2d aTangent;
-        aBAcurve2d.D1 (aMidPar, aMidP2d, aTangent);
-        if (anEdge.Orientation() == TopAbs_REVERSED)
-          aTangent.Reverse();
-        
-        aTangent.Normalize();
-        gp_Vec2d aNormal (aTangent.Y(), -aTangent.X());
-        aNormal *= anOffsetValue;
-        gp_Pnt2d anUpperPole = aMidP2d.Translated (aNormal);
-        if (anUpperPole.Y() < -PI2 || anUpperPole.Y() > PI2)
-        {
-          aEmap.Add(anEdge);
-          continue;
-        }
-        if (anUpperPole.X() < 0.)
-          anUpperPole.SetX (anUpperPole.X() + 2.*M_PI);
-        else if (anUpperPole.X() > 2.*M_PI)
-          anUpperPole.SetX (anUpperPole.X() - 2.*M_PI);
-        
-        TopAbs_State aStatus = aClassifier.Perform (anUpperPole);
-        if (aStatus != TopAbs_OUT)
-        {
-          aEmap.Add(anEdge);
-          continue;
-        }
-        
-        gp_Pnt anUpperPole3d = aSphere->Value (anUpperPole.X(), anUpperPole.Y());
-        gp_Vec aVec (aCentre, anUpperPole3d);
-        aVec.Reverse();
-        gp_Pnt aLowerPole3d = aCentre.Translated (aVec);
-        Standard_Real aU, aV;
-        ElSLib::Parameters (sp, aLowerPole3d, aU, aV);
-        gp_Pnt2d aLowerPole (aU, aV);
-        aStatus = aClassifier.Perform (aLowerPole);
-        if (aStatus != TopAbs_OUT)
-        {
-          aEmap.Add(anEdge);
-          continue;
+  if (!aSurf->IsKind(STANDARD_TYPE(Geom_SphericalSurface)))
+    return Standard_False;
+
+  Standard_Real PI2 = M_PI/2.;
+  Handle(Geom_SphericalSurface) aSphere = Handle(Geom_SphericalSurface)::DownCast(aSurf);
+  gp_Sphere sp = aSphere->Sphere();
+  Standard_Real Radius = sp.Radius();
+  Standard_Real Umin, Umax, Vmin, Vmax;
+
+  // try with small rotation (old implementation, giving better result in some cases
+  if (theTrySmallRotation) {
+    BRepTools::UVBounds(theFace, Umin, Umax, Vmin, Vmax);
+    if (Vmax > PI2 - Precision::PConfusion() || Vmin < -PI2 + Precision::PConfusion()) {
+      //modified by jgv, 12.11.2012 for issue 21777//
+      Standard_Real HalfArea = 2.*M_PI*Radius*Radius;
+      GProp_GProps Properties;
+      BRepGProp::SurfaceProperties(theFace, Properties);
+      Standard_Real anArea = Properties.Mass();
+      Standard_Real AreaTol = Radius*Radius*1.e-6;
+      if (anArea < HalfArea - AreaTol) { // a chance to avoid singularity
+        gp_Ax3 ax3 = sp.Position();
+        if (Abs(Vmax-Vmin) < PI2) {
+          gp_Ax3 axnew3 (ax3.Axis().Location(), ax3.Direction()^ax3.XDirection(), ax3.XDirection());
+          sp.SetPosition(axnew3);
+          Handle(Geom_SphericalSurface) aNewSphere = new Geom_SphericalSurface(sp);
+          theNewSurface = aNewSphere;
+          return Standard_True;
         }
-        
-        //Build a meridian
-        gp_Vec anUp (aCentre, anUpperPole3d);
-        anUp.Normalize();
-        gp_Pnt aMidPnt = aSphere->Value (aMidP2d.X(), aMidP2d.Y());
-        gp_Vec aMidOnEdge (aCentre, aMidPnt);
-        aMidOnEdge.Normalize();
-        gp_Vec AxisOfCircle = anUp ^ aMidOnEdge;
-        gp_Vec XDirOfCircle = anUp ^ AxisOfCircle;
-        gp_Ax2 anAxis (aCentre, AxisOfCircle, XDirOfCircle);
-        Handle(Geom_Circle) aCircle = new Geom_Circle (anAxis, Radius);
-        Handle(Geom_TrimmedCurve) aMeridian = new Geom_TrimmedCurve (aCircle, -PI2, PI2);
-        
-        //Check the meridian
-        Standard_Boolean IsInnerPointFound = Standard_False;
-        Standard_Integer NbSamples = 10;
-        Standard_Real aDelta = M_PI / NbSamples;
-        for (Standard_Integer jj = 1; jj < NbSamples; jj++)
-        {
-          Standard_Real aParam = -PI2 + jj*aDelta;
-          gp_Pnt aPnt = aMeridian->Value (aParam);
-          ElSLib::Parameters (sp, aPnt, aU, aV);
-          gp_Pnt2d aP2d (aU, aV);
-          aStatus = aClassifier.Perform (aP2d);
-          if (aStatus != TopAbs_OUT)
-          {
-            IsInnerPointFound = Standard_True;
-            break;
+        else {
+          gp_Pnt PC = ax3.Location();
+          Standard_Real Vpar;
+          if (fabs(PI2-Vmax) > fabs(-PI2-Vmin))
+            Vpar = (PI2+Vmax)/2.;
+          else
+            Vpar = (-PI2+Vmin)/2.;
+          Standard_Real Upar = (Umin+Umax)/2.;
+          gp_Pnt PN,PX;
+          aSurf->D0(Upar,Vpar,PN);
+          aSurf->D0(Upar+PI2,0.,PX);
+          gp_Dir newNorm(gp_Vec(PC,PN));
+          gp_Dir newDirX(gp_Vec(PC,PX));
+          gp_Ax3 axnew3(ax3.Axis().Location(), newNorm, newDirX);
+          sp.SetPosition(axnew3);
+
+          // check if both new poles are outside theFace
+          gp_Pnt LP; // lowest pole (opposite to PN)
+          aSurf->D0(Upar + M_PI, -Vpar, LP);
+          BRepClass_FaceClassifier aClsf (theFace, LP, Precision::PConfusion());
+          if (aClsf.State() != TopAbs_IN && aClsf.State() != TopAbs_ON) {
+            Handle(Geom_SphericalSurface) aNewSphere = new Geom_SphericalSurface(sp);
+            theNewSurface = aNewSphere;
+            return Standard_True;
           }
         }
-        if (IsInnerPointFound)
-        {
-          aEmap.Add(anEdge);
-          continue;
-        }
-        
-        gp_Ax3 anAxisOfNewSphere (aCentre, anUp, XDirOfCircle);
-        aNewSurface = new Geom_SphericalSurface (anAxisOfNewSphere, Radius);
-        break;
-      } //for (; itw.More(); itw.Next()) (iteration on outer wire)
-      if (!aNewSurface.IsNull())
-        break;
-    } //for (Standard_Integer ii = 1; ii <= 2; ii++) (two passes)
+      }
+    }
+    else {
+      // no rotation needed
+      return Standard_False;
+    }
   }
 
-  if (aNewSurface.IsNull())
-    return Standard_False;
+  // try with big rotation (new implementation)
+  TopoDS_Face aFace = theFace;
+  aFace.Orientation (TopAbs_FORWARD);
+  BRepTools::UVBounds(aFace, Umin, Umax, Vmin, Vmax);
+
+  gp_Pnt aCentre = sp.Location();
+
+  TopoDS_Wire aWire = BRepTools::OuterWire (aFace);
+  BRepTopAdaptor_FClass2d aClassifier (aFace, Precision::PConfusion());
+  TopTools_MapOfShape aEmap;
+  const Standard_Real anOffsetValue = 0.01*M_PI;
+  for (Standard_Integer ii = 1; ii <= 2; ii++) {
+    TopoDS_Iterator itw (aWire);
+    for (; itw.More(); itw.Next()) {
+      const TopoDS_Edge& anEdge = TopoDS::Edge (itw.Value());
+      if (aEmap.Contains (anEdge) ||
+          anEdge.Orientation() == TopAbs_INTERNAL ||
+          anEdge.Orientation() == TopAbs_EXTERNAL ||
+          BRep_Tool::Degenerated (anEdge) ||
+          BRepTools::IsReallyClosed (anEdge, aFace))
+        continue;
+
+      BRepAdaptor_Curve2d aBAcurve2d (anEdge, aFace);
+      GeomAbs_CurveType aType = aBAcurve2d.GetType();
+      if (ii == 1 && aType == GeomAbs_Line) //first pass: consider only curvilinear edges
+        continue;
+
+      Standard_Real aMidPar = (aBAcurve2d.FirstParameter() + aBAcurve2d.LastParameter())/2;
+      gp_Pnt2d aMidP2d;
+      gp_Vec2d aTangent;
+      aBAcurve2d.D1 (aMidPar, aMidP2d, aTangent);
+      if (anEdge.Orientation() == TopAbs_REVERSED)
+        aTangent.Reverse();
+
+      aTangent.Normalize();
+      gp_Vec2d aNormal (aTangent.Y(), -aTangent.X());
+      aNormal *= anOffsetValue;
+      gp_Pnt2d anUpperPole = aMidP2d.Translated (aNormal);
+      if (anUpperPole.Y() < -PI2 || anUpperPole.Y() > PI2) {
+        aEmap.Add(anEdge);
+        continue;
+      }
+      if (anUpperPole.X() < 0.)
+        anUpperPole.SetX (anUpperPole.X() + 2.*M_PI);
+      else if (anUpperPole.X() > 2.*M_PI)
+        anUpperPole.SetX (anUpperPole.X() - 2.*M_PI);
+
+      TopAbs_State aStatus = aClassifier.Perform (anUpperPole);
+      if (aStatus != TopAbs_OUT) {
+        aEmap.Add(anEdge);
+        continue;
+      }
+
+      gp_Pnt anUpperPole3d = aSphere->Value (anUpperPole.X(), anUpperPole.Y());
+      gp_Vec aVec (aCentre, anUpperPole3d);
+      aVec.Reverse();
+      gp_Pnt aLowerPole3d = aCentre.Translated (aVec);
+      Standard_Real aU, aV;
+      ElSLib::Parameters (sp, aLowerPole3d, aU, aV);
+      gp_Pnt2d aLowerPole (aU, aV);
+      aStatus = aClassifier.Perform (aLowerPole);
+      if (aStatus != TopAbs_OUT) {
+        aEmap.Add(anEdge);
+        continue;
+      }
+
+      //Build a meridian
+      gp_Vec anUp (aCentre, anUpperPole3d);
+      anUp.Normalize();
+      gp_Pnt aMidPnt = aSphere->Value (aMidP2d.X(), aMidP2d.Y());
+      gp_Vec aMidOnEdge (aCentre, aMidPnt);
+      aMidOnEdge.Normalize();
+      gp_Vec AxisOfCircle = anUp ^ aMidOnEdge;
+      gp_Vec XDirOfCircle = anUp ^ AxisOfCircle;
+      gp_Ax2 anAxis (aCentre, AxisOfCircle, XDirOfCircle);
+      Handle(Geom_Circle) aCircle = new Geom_Circle (anAxis, Radius);
+      Handle(Geom_TrimmedCurve) aMeridian = new Geom_TrimmedCurve (aCircle, -PI2, PI2);
+
+      //Check the meridian
+      Standard_Boolean IsInnerPointFound = Standard_False;
+      Standard_Integer NbSamples = 10;
+      Standard_Real aDelta = M_PI / NbSamples;
+      for (Standard_Integer jj = 1; jj < NbSamples; jj++) {
+        Standard_Real aParam = -PI2 + jj*aDelta;
+        gp_Pnt aPnt = aMeridian->Value (aParam);
+        ElSLib::Parameters (sp, aPnt, aU, aV);
+        gp_Pnt2d aP2d (aU, aV);
+        aStatus = aClassifier.Perform (aP2d);
+        if (aStatus != TopAbs_OUT) {
+          IsInnerPointFound = Standard_True;
+          break;
+        }
+      }
+      if (IsInnerPointFound) {
+        aEmap.Add(anEdge);
+        continue;
+      }
+
+      gp_Ax3 anAxisOfNewSphere (aCentre, anUp, XDirOfCircle);
+      theNewSurface = new Geom_SphericalSurface (anAxisOfNewSphere, Radius);
+      break;
+    } //for (; itw.More(); itw.Next()) (iteration on outer wire)
+    if (!theNewSurface.IsNull())
+      break;
+  } //for (Standard_Integer ii = 1; ii <= 2; ii++) (two passes)
 
-  theNewSurface = aNewSurface;
-  return Standard_True;
+  return (!theNewSurface.IsNull());
 }
 
 Standard_Boolean BlockFix_SphereSpaceModifier::NewSurface(const TopoDS_Face& F,
-                                                        Handle(Geom_Surface)& S,
-                                                        TopLoc_Location& L,Standard_Real& Tol,
-                                                        Standard_Boolean& RevWires,
-                                                        Standard_Boolean& RevFace)
+                                                          Handle(Geom_Surface)& S,
+                                                          TopLoc_Location& L,
+                                                          Standard_Real& Tol,
+                                                          Standard_Boolean& RevWires,
+                                                          Standard_Boolean& RevFace)
 {
   TopLoc_Location LS;
   Handle(Geom_Surface) SIni = BRep_Tool::Surface(F, LS);
 
   //check if pole of the sphere in the parametric space
-  if(ModifySurface(F, SIni, S)) {
+  if (ModifySurface(F, SIni, S, mySmallRotation)) {
 
     RevWires = Standard_False;
     RevFace = Standard_False;
index ea6773f59ff20d063b54b838e4c64b5c0c7b0de4..4d10a1bdc5c99a5709b08e251557a8cd33797d56 100644 (file)
@@ -51,6 +51,8 @@ public:
   Standard_EXPORT ~BlockFix_SphereSpaceModifier();
 
   Standard_EXPORT void SetTolerance (const Standard_Real Toler);
+  Standard_EXPORT void SetTrySmallRotation (const Standard_Boolean isSmallRotation);
+
   Standard_EXPORT Standard_Boolean NewSurface (const TopoDS_Face& F, Handle(Geom_Surface)& S,
                                                TopLoc_Location& L, Standard_Real& Tol,
                                                Standard_Boolean& RevWires, Standard_Boolean& RevFace);
@@ -72,6 +74,7 @@ public:
 
 private:
   Standard_Real myTolerance;
+  Standard_Boolean mySmallRotation;
   TopTools_DataMapOfShapeInteger myMapOfFaces;
   TColStd_IndexedMapOfTransient myMapOfSpheres;
 
index 74801d626d627dec1271b64e6332b93d9e41f69f..b368c204ccb304db840d8cead33559ba7792d905 100644 (file)
 #  Module : GEOM
 #
 # ! Please, if you edit this example file, update also
-# ! GEOM_SRC/doc/salome/gui/GEOM/input/tui_test_others.doc
+# ! GEOM/doc/salome/gui/GEOM/input/tui_test_others.doc
 # ! as some sequences of symbols from this example are used during
 # ! documentation generation to identify certain places of this file
 
 import os
 import GEOM
+import tempfile
 
 def TestExportImport (geompy, shape):
 
   print("Test Export/Import ...", end=' ')
 
-  tmpDir = os.getenv("TEMP")
-  if tmpDir == None:
-    tmpDir = "/tmp"
-
-  # Files for Export/Import testing
-  fileExportImport = tmpDir + "/testExportImport.brep"
-  fileExportImportBREP = tmpDir + "/testExportImportBREP.brep"
-  fileExportImportIGES = tmpDir + "/testExportImportIGES.iges"
-  fileExportImportSTEP = tmpDir + "/testExportImportSTEP.step"
-
-  if os.access(fileExportImport, os.F_OK):
-    if os.access(fileExportImport, os.W_OK):
-      os.remove(fileExportImport)
-    else:
-      fileExportImport = tmpDir + "/testExportImport1.brep"
-
-    if os.access(fileExportImportBREP, os.W_OK):
-      os.remove(fileExportImportBREP)
-    else:
-      fileExportImportBREP = tmpDir + "/testExportImportBREP1.brep"
-
-    if os.access(fileExportImportIGES, os.W_OK):
-      os.remove(fileExportImportIGES)
-    else:
-      fileExportImportIGES = tmpDir + "/testExportImportIGES1.iges"
-
-    if os.access(fileExportImportSTEP, os.W_OK):
-      os.remove(fileExportImportSTEP)
-    else:
-      fileExportImportSTEP = tmpDir + "/testExportImportSTEP1.step"
-
-  # Export
-  geompy.Export(shape, fileExportImport, "BREP")
-
-  # ExportBREP, ExportIGES, ExportSTEP
-  geompy.ExportBREP(shape, fileExportImportBREP)
-  geompy.ExportIGES(shape, fileExportImportIGES)
-  geompy.ExportSTEP(shape, fileExportImportSTEP)
-
-  # Import
-  Import = geompy.ImportFile(fileExportImport, "BREP")
-
-  geompy.addToStudy(Import, "Import")
-
-  # ImportBREP, ImportIGES, ImportSTEP
-  ImportBREP = geompy.ImportBREP(fileExportImportBREP)
-  ImportIGES = geompy.ImportIGES(fileExportImportIGES)
-  ImportSTEP = geompy.ImportSTEP(fileExportImportSTEP)
-
-  geompy.addToStudy(ImportBREP, "ImportBREP")
-  geompy.addToStudy(ImportIGES, "ImportIGES")
-  geompy.addToStudy(ImportSTEP, "ImportSTEP")
-
-  # GetIGESUnit and GetSTEPUnit
-  if geompy.GetIGESUnit(fileExportImportIGES) != "M":
-    ImportIGES_scaled = geompy.ImportIGES(fileExportImportIGES, True)
-    geompy.addToStudy(ImportIGES_scaled, "ImportIGES_scaled")
-
-  if geompy.GetSTEPUnit(fileExportImportSTEP) != "M":
-    ImportSTEP_scaled = geompy.ImportSTEP(fileExportImportSTEP, True)
-    geompy.addToStudy(ImportSTEP_scaled, "ImportSTEP_scaled")
-
-  # Remove files for Export/Import testing
-  os.remove(fileExportImport)
-  os.remove(fileExportImportBREP)
-  os.remove(fileExportImportIGES)
-  os.remove(fileExportImportSTEP)
+  with tempfile.TemporaryDirectory() as tmpDir:
+    # Files for Export/Import testing
+    fileExportImportBREP = os.path.join(tmpDir, "testExportImportBREP.brep")
+    fileExportImportIGES = os.path.join(tmpDir, "testExportImportIGES.iges")
+    fileExportImportSTEP = os.path.join(tmpDir, "testExportImportSTEP.step")
+
+    # ExportBREP, ExportIGES, ExportSTEP
+    geompy.ExportBREP(shape, fileExportImportBREP)
+    geompy.ExportIGES(shape, fileExportImportIGES)
+    geompy.ExportSTEP(shape, fileExportImportSTEP)
+
+    # ImportBREP, ImportIGES, ImportSTEP
+    ImportBREP = geompy.ImportBREP(fileExportImportBREP)
+    ImportIGES = geompy.ImportIGES(fileExportImportIGES)
+    ImportSTEP = geompy.ImportSTEP(fileExportImportSTEP)
+
+    geompy.addToStudy(ImportBREP, "ImportBREP")
+    geompy.addToStudy(ImportIGES, "ImportIGES")
+    geompy.addToStudy(ImportSTEP, "ImportSTEP")
+
+    # GetIGESUnit and GetSTEPUnit
+    if geompy.GetIGESUnit(fileExportImportIGES) != "M":
+      ImportIGES_scaled = geompy.ImportIGES(fileExportImportIGES, True)
+      geompy.addToStudy(ImportIGES_scaled, "ImportIGES_scaled")
+      pass
+
+    if geompy.GetSTEPUnit(fileExportImportSTEP) != "M":
+      ImportSTEP_scaled = geompy.ImportSTEP(fileExportImportSTEP, True)
+      geompy.addToStudy(ImportSTEP_scaled, "ImportSTEP_scaled")
+      pass
+    pass
 
   # Test RestoreShape from binary BRep stream
   aStream = shape.GetShapeStream()
@@ -191,7 +156,6 @@ def TestOtherOperations (geompy, math):
   p100 = geompy.MakeVertex(100, 100, 100)
   p300 = geompy.MakeVertex(300, 300, 300)
   Box1 = geompy.MakeBoxTwoPnt(p100, p300)
-  #Partition = geompy.Partition([Box], [Box1], [], [Box])
   Partition = geompy.Partition([Box], [Box1])
   id_Partition = geompy.addToStudy(Partition, "Partition of Box by Box1")
 
@@ -238,20 +202,14 @@ def TestOtherOperations (geompy, math):
 
   # NumberOf
   NumberOfFaces = geompy.NumberOfFaces(Box)
-  if NumberOfFaces != 6:
-    print("Bad number of faces in BOX!")
-
   NumberOfEdges = geompy.NumberOfEdges(Box)
-  if NumberOfEdges != 12:
-    print("Bad number of edges in BOX!")
-
   NumberOfSolids = geompy.NumberOfSolids(Box)
-  if NumberOfSolids != 1:
-    print("Bad number of solids in BOX!")
-
   NumberOfShapes = geompy.NumberOfSubShapes(Box, geompy.ShapeType["SHAPE"])
-  if NumberOfShapes != 34:
-    print("Bad number of shapes in BOX!")
+
+  assert (NumberOfFaces  ==  6), "Bad number of faces in BOX!"
+  assert (NumberOfEdges  == 12), "Bad number of edges in BOX!"
+  assert (NumberOfSolids ==  1), "Bad number of solids in BOX!"
+  assert (NumberOfShapes == 34), "Bad number of shapes in BOX!"
 
   # MakeBlockExplode
   Compound = geompy.MakeCompound([Box, Sphere])
@@ -270,24 +228,20 @@ def TestOtherOperations (geompy, math):
   Cyl  = geompy.MakeCylinderRH(50, 300)
   Cone = geompy.MakeConeR1R2H(150, 10, 400)
 
-  Compound1 = geompy.MakeCompound([Box, Cyl, Cone, Box3, Box2])
+  Compound1 = geompy.MakeCompound([Box, Cyl, Cone, Box3, Box2], "Compound1")
 
+  print("Printing errors of not valid Blocks Compound (EXPECTED):")
   IsValid = geompy.CheckCompoundOfBlocks(Compound1)
-  if IsValid == 0:
-    print("The Blocks Compound is NOT VALID")
-    (NonBlocks, NonQuads) = geompy.GetNonBlocks(Compound1)
-    if NonBlocks is not None:
-      geompy.addToStudyInFather(Compound1, NonBlocks, "Group of non-hexahedral solids")
-    if NonQuads is not None:
-      geompy.addToStudyInFather(Compound1, NonQuads, "Group of non-quadrangular faces")
-  else:
-    print("The Blocks Compound is VALID")
+  # This Blocks Compound is NOT VALID
+  assert (not IsValid)
+  (NonBlocks, NonQuads) = geompy.GetNonBlocks(Compound1)
+  if NonBlocks is not None:
+    geompy.addToStudyInFather(Compound1, NonBlocks, "Group of non-hexahedral solids")
+  if NonQuads is not None:
+    geompy.addToStudyInFather(Compound1, NonQuads, "Group of non-quadrangular faces")
 
   IsValid = geompy.CheckCompoundOfBlocks(Box)
-  if IsValid == 0:
-    print("The Box is NOT VALID")
-  else:
-    print("The Box is VALID")
+  assert (IsValid) # Box is a VALID Blocks Compound
 
   # GetSame
   Cone_ss = geompy.GetSame(Compound1, Cone)
@@ -324,11 +278,7 @@ def TestOtherOperations (geompy, math):
 
   # GetObjectIDs
   GetObjectIDs = geompy.GetObjectIDs(CreateGroup)
-
-  print("Group of Box's faces includes the following IDs:")
-  print("(must be ", f_ind_6, ", ", f_ind_3, " and ", f_ind_5, ")")
-  for ObjectID in GetObjectIDs:
-    print(" ", ObjectID)
+  assert (sorted(GetObjectIDs) == sorted([f_ind_6, f_ind_3, f_ind_5]))
 
   # GetMainShape
   BoxCopy = geompy.GetMainShape(CreateGroup)
@@ -343,10 +293,7 @@ def TestOtherOperations (geompy, math):
 
   # Check
   GetObjectIDs = geompy.GetObjectIDs(CreateGroup)
-  print("Group of Box's faces includes the following IDs:")
-  print("(must be ", f_ind_6, ", ", f_ind_1, " and ", f_ind_2, ")")
-  for ObjectID in GetObjectIDs:
-    print(" ", ObjectID)
+  assert (sorted(GetObjectIDs) == sorted([f_ind_6, f_ind_1, f_ind_2]))
 
   # Boolean Operations on Groups (Union, Intersection, Cut)
   Group_1 = geompy.CreateGroup(Box, geompy.ShapeType["FACE"])
@@ -384,16 +331,10 @@ def TestOtherOperations (geompy, math):
   geompy.addToStudyInFather(Box, Group_C_2_4, 'Group_C_2_4')
   geompy.addToStudyInFather(Box, Group_CL_2_4, 'Group_CL_2_4')
 
-  # -----------------------------------------------------------------------------
-  # enumeration ShapeTypeString as a dictionary
-  # -----------------------------------------------------------------------------
-  ShapeTypeString = {'0':"COMPOUND", '1':"COMPSOLID", '2':"SOLID", '3':"SHELL",
-                     '4':"FACE", '5':"WIRE", '6':"EDGE", '7':"VERTEX", '8':"SHAPE"}
-
   GroupType = geompy.GetType(CreateGroup)
-  print("Type of elements of the created group is ", ShapeTypeString[repr(GroupType)])
+  assert (GroupType == geompy.ShapeType["FACE"])
 
-  # Prepare data for the following operations
+  # Example of sphere partitioning into hexahedral blocks
   p0 = geompy.MakeVertex(0, 0, 0)
   b0 = geompy.MakeBox(-50, -50, -50, 50, 50, 50)
   s0 = geompy.MakeSphereR(100)
@@ -402,88 +343,55 @@ def TestOtherOperations (geompy, math):
   id_s0 = geompy.addToStudy(s0, "s0")
 
   v_0pp = geompy.MakeVectorDXDYDZ( 0,  1,  1)
-  #v_0np = geompy.MakeVectorDXDYDZ( 0, -1,  1)
+  v_0np = geompy.MakeVectorDXDYDZ( 0, -1,  1)
   v_p0p = geompy.MakeVectorDXDYDZ( 1,  0,  1)
-  v_p0n = geompy.MakeVectorDXDYDZ(1,  0,  -1)
+  v_p0n = geompy.MakeVectorDXDYDZ( 1,  0, -1)
   v_pp0 = geompy.MakeVectorDXDYDZ( 1,  1,  0)
-  v_pn0 = geompy.MakeVectorDXDYDZ(1,  -1,  0)
+  v_pn0 = geompy.MakeVectorDXDYDZ( 1, -1,  0)
 
-  #pln_0pp = geompy.MakePlane(p0, v_0pp, 300)
-  #pln_0np = geompy.MakePlane(p0, v_0np, 300)
+  pln_0pp = geompy.MakePlane(p0, v_0pp, 300)
+  pln_0np = geompy.MakePlane(p0, v_0np, 300)
   pln_p0p = geompy.MakePlane(p0, v_p0p, 300)
   pln_p0n = geompy.MakePlane(p0, v_p0n, 300)
   pln_pp0 = geompy.MakePlane(p0, v_pp0, 300)
   pln_pn0 = geompy.MakePlane(p0, v_pn0, 300)
-  #
-  #part_objs = [b0, pln_0pp, pln_0np, pln_p0p, pln_n0p, pln_pp0, pln_np0]
-  #part_tool_1 = geompy.MakePartition(part_objs, [], [], [b0])
-  #part_tool_1 = geompy.MakePartition(part_objs)
-  #
-  #id_part_tool_1 = geompy.addToStudy(part_tool_1, "part_tool_1")
-  #
-  #pt_pnt_1  = geompy.MakeVertex( 55,   0,  55)
-  #pt_pnt_2  = geompy.MakeVertex(  0,  55,  55)
-  #pt_pnt_3  = geompy.MakeVertex(-55,   0,  55)
-  #pt_pnt_4  = geompy.MakeVertex(  0, -55,  55)
-  #pt_pnt_5  = geompy.MakeVertex( 55,  55,   0)
-  #pt_pnt_6  = geompy.MakeVertex( 55, -55,   0)
-  #pt_pnt_7  = geompy.MakeVertex(-55,  55,   0)
-  #pt_pnt_8  = geompy.MakeVertex(-55, -55,   0)
-  #pt_pnt_9  = geompy.MakeVertex( 55,   0, -55)
-  #pt_pnt_10 = geompy.MakeVertex(  0,  55, -55)
-  #pt_pnt_11 = geompy.MakeVertex(-55,   0, -55)
-  #pt_pnt_12 = geompy.MakeVertex(  0, -55, -55)
-  #
-  #pt_face_1  = geompy.GetFaceNearPoint(part_tool_1, pt_pnt_1)
-  #pt_face_2  = geompy.GetFaceNearPoint(part_tool_1, pt_pnt_2)
-  #pt_face_3  = geompy.GetFaceNearPoint(part_tool_1, pt_pnt_3)
-  #pt_face_4  = geompy.GetFaceNearPoint(part_tool_1, pt_pnt_4)
-  #pt_face_5  = geompy.GetFaceNearPoint(part_tool_1, pt_pnt_5)
-  #pt_face_6  = geompy.GetFaceNearPoint(part_tool_1, pt_pnt_6)
-  #pt_face_7  = geompy.GetFaceNearPoint(part_tool_1, pt_pnt_7)
-  #pt_face_8  = geompy.GetFaceNearPoint(part_tool_1, pt_pnt_8)
-  #pt_face_9  = geompy.GetFaceNearPoint(part_tool_1, pt_pnt_9)
-  #pt_face_10 = geompy.GetFaceNearPoint(part_tool_1, pt_pnt_10)
-  #pt_face_11 = geompy.GetFaceNearPoint(part_tool_1, pt_pnt_11)
-  #pt_face_12 = geompy.GetFaceNearPoint(part_tool_1, pt_pnt_12)
-  #
-  #pt_box = geompy.GetBlockNearPoint(part_tool_1, p0)
-  #
-  #comp_parts = [pt_face_1, pt_face_4, pt_face_7, pt_face_10,
-  #              pt_face_2, pt_face_5, pt_face_8, pt_face_11,
-  #              #pt_face_3, pt_face_6, pt_face_9, pt_face_12, pt_box]
-  #              pt_face_3, pt_face_6, pt_face_9, pt_face_12]
-  #part_tool = geompy.MakeCompound(comp_parts)
-  #id_part_tool = geompy.addToStudy(part_tool, "part_tool")
-  #
-  #part = geompy.MakePartition([s0], [part_tool])
-  #
-  #part_tools = [pt_face_1, pt_face_4, pt_face_7, pt_face_10,
-  #              pt_face_2, pt_face_5, pt_face_8, pt_face_11,
-  #              pt_face_3, pt_face_6, pt_face_9, pt_face_12, b0]
-  #part = geompy.MakePartition([s0], part_tools)
-
-  p1 = geompy.MakeVertex(50, 0, 0)
-  p2 = geompy.MakeVertex(-50, 0, 0)
-  p3 = geompy.MakeVertex(0, 50, 0)
-  p4 = geompy.MakeVertex(0, -50, 0)
-  p5 = geompy.MakeVertex(0, 0, 50)
-  p6 = geompy.MakeVertex(0, 0, -50)
-
-  plnX1 = geompy.MakePlane(p1, vx, 300)
-  plnX2 = geompy.MakePlane(p2, vx, 300)
-  plnY1 = geompy.MakePlane(p3, vy, 300)
-  plnY2 = geompy.MakePlane(p4, vy, 300)
-  plnZ1 = geompy.MakePlane(p5, vz, 300)
-  plnZ2 = geompy.MakePlane(p6, vz, 300)
-
-  #part = geompy.MakePartition([s0], [plnX1,plnX2,plnY1,plnY2,plnZ1,plnZ2])
-  part = geompy.MakePartition([s0], [plnX1])
-  part = geompy.MakePartition([part], [plnX2])
-  part = geompy.MakePartition([part], [plnY1])
-  part = geompy.MakePartition([part], [plnY2])
-  part = geompy.MakePartition([part], [plnZ1])
-  part = geompy.MakePartition([part], [plnZ2])
+
+  part_objs = [b0, pln_0pp, pln_0np, pln_p0p, pln_p0n, pln_pp0, pln_pn0]
+  part_tool_1 = geompy.MakePartition(part_objs, KeepNonlimitShapes=1)
+  geompy.addToStudy(part_tool_1, "part_tool_1")
+
+  pt_pnt_1  = geompy.MakeVertex( 55,   0,  55)
+  pt_pnt_2  = geompy.MakeVertex(  0,  55,  55)
+  pt_pnt_3  = geompy.MakeVertex(-55,   0,  55)
+  pt_pnt_4  = geompy.MakeVertex(  0, -55,  55)
+  pt_pnt_5  = geompy.MakeVertex( 55,  55,   0)
+  pt_pnt_6  = geompy.MakeVertex( 55, -55,   0)
+  pt_pnt_7  = geompy.MakeVertex(-55,  55,   0)
+  pt_pnt_8  = geompy.MakeVertex(-55, -55,   0)
+  pt_pnt_9  = geompy.MakeVertex( 55,   0, -55)
+  pt_pnt_10 = geompy.MakeVertex(  0,  55, -55)
+  pt_pnt_11 = geompy.MakeVertex(-55,   0, -55)
+  pt_pnt_12 = geompy.MakeVertex(  0, -55, -55)
+
+  pt_face_1  = geompy.GetFaceNearPoint(part_tool_1, pt_pnt_1)
+  pt_face_2  = geompy.GetFaceNearPoint(part_tool_1, pt_pnt_2)
+  pt_face_3  = geompy.GetFaceNearPoint(part_tool_1, pt_pnt_3)
+  pt_face_4  = geompy.GetFaceNearPoint(part_tool_1, pt_pnt_4)
+  pt_face_5  = geompy.GetFaceNearPoint(part_tool_1, pt_pnt_5)
+  pt_face_6  = geompy.GetFaceNearPoint(part_tool_1, pt_pnt_6)
+  pt_face_7  = geompy.GetFaceNearPoint(part_tool_1, pt_pnt_7)
+  pt_face_8  = geompy.GetFaceNearPoint(part_tool_1, pt_pnt_8)
+  pt_face_9  = geompy.GetFaceNearPoint(part_tool_1, pt_pnt_9)
+  pt_face_10 = geompy.GetFaceNearPoint(part_tool_1, pt_pnt_10)
+  pt_face_11 = geompy.GetFaceNearPoint(part_tool_1, pt_pnt_11)
+  pt_face_12 = geompy.GetFaceNearPoint(part_tool_1, pt_pnt_12)
+
+  part_tools = [pt_face_1, pt_face_4, pt_face_7, pt_face_10,
+                pt_face_2, pt_face_5, pt_face_8, pt_face_11,
+                pt_face_3, pt_face_6, pt_face_9, pt_face_12, b0]
+  part_tool = geompy.MakeCompound(part_tools)
+  geompy.addToStudy(part_tool, "part_tool")
+  part = geompy.MakePartition([s0], [part_tool])
   geompy.addToStudy(part, "part")
 
   # GetFreeFacesIDs
@@ -492,9 +400,9 @@ def TestOtherOperations (geompy, math):
 
   geompy.addToStudy(freeFaces, "freeFaces")
 
-  # RemoveExtraEdges with union of all faces, sharing common surfaces
+  # Example of hexahedral sphere creation
+  # (spherical surface of solid is made of six quasi-quadrangular faces)
   tools = [pln_pp0, pln_pn0, pln_p0p, pln_p0n]
-
   Partition_1 = geompy.MakePartition([Sphere], tools, [], [], geompy.ShapeType["SOLID"], 0, [])
   geompy.addToStudy(Partition_1, "Partition_1")
 
@@ -529,8 +437,8 @@ def TestOtherOperations (geompy, math):
 
   Shell_1 = geompy.MakeShell([Face_1, Rotation_1, Rotation_2, Rotation_3, Rotation_4, Rotation_5])
   Solid_1 = geompy.MakeSolid([Shell_1])
-  #NoExtraEdges_1 = geompy.RemoveExtraEdges(Solid_1, True) # doUnionFaces = True
 
+  # RemoveExtraEdges with union of all faces, sharing common surfaces
   box10 = geompy.MakeBoxDXDYDZ(10, 10, 10, "box10")
   box11 = geompy.MakeTranslation(box10, 10, 0, 0, "box11")
   FuseB = geompy.MakeFuse(box10, box11, checkSelfInte=False, rmExtraEdges=False, theName="FuseB")
@@ -580,9 +488,8 @@ def TestOtherOperations (geompy, math):
   geompy.addToStudyInFather( blackWhiteCopy, subBlackWhite[1], "" )
 
   # CheckAndImprove
-  blocksComp = geompy.CheckAndImprove(part)
-
-  geompy.addToStudy(blocksComp, "blocksComp")
+  blocksComp = geompy.CheckAndImprove(part, "blocksComp")
+  assert (geompy.CheckCompoundOfBlocks(blocksComp))
 
   # Propagate
   listChains = geompy.Propagate(blocksComp)
@@ -717,8 +624,7 @@ def TestOtherOperations (geompy, math):
                                                  tl, tr, bl, br, GEOM.ST_ONIN)
   comp = geompy.MakeCompound(edges_onin_quad)
   geompy.addToStudy(comp, "Edges of F12 ONIN Quadrangle")
-  if len( edges_onin_quad ) != 4:
-    print("Error in GetShapesOnQuadrangle()")
+  assert (len( edges_onin_quad ) == 4), "Error in GetShapesOnQuadrangle()"
 
   # GetShapesOnQuadrangleIDs
   vertices_on_quad_ids = geompy.GetShapesOnQuadrangleIDs(f12, geompy.ShapeType["VERTEX"],
@@ -732,8 +638,7 @@ def TestOtherOperations (geompy, math):
                                        GEOM.ST_ON)
   comp = geompy.MakeCompound(edges_on_box)
   geompy.addToStudy(comp, "Edges of part ON box b0")
-  if len( edges_on_box ) != 12:
-    print("Error in GetShapesOnBox()")
+  assert (len( edges_on_box ) == 12), "Error in GetShapesOnBox()"
 
   # GetShapesOnBoxIDs
   faces_on_box_ids = geompy.GetShapesOnBoxIDs(b0, part, geompy.ShapeType["FACE"],
@@ -742,24 +647,13 @@ def TestOtherOperations (geompy, math):
   geompy.UnionIDs(faces_on_box, faces_on_box_ids)
   geompy.addToStudyInFather(part, faces_on_box, "Group of faces on box b0")
 
-  # Prepare arguments for GetShapesOnShape
-  sph1 = geompy.MakeSphere(50, 50,  50, 40)
-  sph2 = geompy.MakeSphere(50, 50, -50, 40)
-  pcyl = geompy.MakeVertex(50, 50, -50)
-  cyli = geompy.MakeCylinder(pcyl, vz, 40, 100)
-  sh_1 = geompy.MakeFuseList([sph1, cyli, sph2])
-  # As after Fuse we have a compound, we need to obtain a solid from it
-  #shsh = geompy.SubShapeAll(sh_1, geompy.ShapeType["SOLID"])
-  #sh_1 = shsh[0]
-  geompy.addToStudy(sh_1, "sh_1")
-
   # GetShapesOnShape
+  sh_1 = geompy.MakeTranslation(s0, 100, 0, 0, "sh_1")
   faces_in_sh = geompy.GetShapesOnShape(sh_1, part, geompy.ShapeType["FACE"],
                                         GEOM.ST_IN)
   comp = geompy.MakeCompound(faces_in_sh)
   geompy.addToStudy(comp, "Faces of part IN shape sh_1")
-  if len(faces_in_sh) != 11:
-    print("Error in GetShapesOnShape()")
+  assert (len(faces_in_sh) == 7), "Error in GetShapesOnShape()"
 
   # GetShapesOnShapeAsCompound
   faces_in_sh_c = geompy.GetShapesOnShapeAsCompound(sh_1, part, geompy.ShapeType["FACE"],
@@ -772,16 +666,11 @@ def TestOtherOperations (geompy, math):
   edges_in_sh = geompy.CreateGroup(part, geompy.ShapeType["EDGE"])
   geompy.UnionIDs(edges_in_sh, edges_in_sh_ids)
   geompy.addToStudyInFather(part, edges_in_sh, "Group of edges in shape sh_1")
-  if len(edges_in_sh_ids) != 15:
-    print("Error in GetShapesOnShapeIDs()")
+  assert (len(edges_in_sh_ids) == 15), "Error in GetShapesOnShapeIDs()"
 
   # Prepare arguments for GetInPlace and GetInPlaceByHistory
-  box5 = geompy.MakeBoxDXDYDZ(100, 100, 100)
-  box6 = geompy.MakeTranslation(box5, 50, 50, 0)
-
-  geompy.addToStudy(box5, "Box 5")
-  geompy.addToStudy(box6, "Box 6")
-
+  box5 = geompy.MakeBoxDXDYDZ(100, 100, 100, "Box 5")
+  box6 = geompy.MakeTranslation(box5, 50, 50, 0, "Box 6")
   part = geompy.MakePartition([box5], [box6])
   geompy.addToStudy(part, "Partitioned")