Salome HOME
[bos #36177] [FORUM] - Remove extra-edge on hemisphere
[modules/geom.git] / src / BlockFix / BlockFix_BlockFixAPI.cxx
index 6693599271aa2bc5c856d1cc364833ab118a7160..103124a4fbf35fa05f9b6927391e495cbde85a9b 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2019  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2023  CEA, EDF, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 #include <BlockFix_UnionEdges.hxx>
 
 #include <ShapeUpgrade_RemoveLocations.hxx>
+#include <TopoDS_Edge.hxx>
+#include <ShapeUpgrade_UnifySameDomain.hxx>
 
 #include <Precision.hxx>
 
-IMPLEMENT_STANDARD_RTTIEXT(BlockFix_BlockFixAPI, Standard_Transient);
+#include <BRepTools.hxx>
+#include <BRepBuilderAPI_Copy.hxx>
+#include <BRepCheck_Analyzer.hxx>
+
+#include <Basics_OCCTVersion.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(BlockFix_BlockFixAPI, Standard_Transient)
 
 //=======================================================================
 //function : BlockFix_BlockFixAPI
@@ -60,17 +68,62 @@ 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
   myShape = BlockFix::RefillProblemFaces(myShape);
 
   // faces unification
+  TopoDS_Shape aResult = myShape;
+#if OCC_VERSION_LARGE < 0x07050301
   BlockFix_UnionFaces aFaceUnifier;
   aFaceUnifier.GetTolerance() = myTolerance;
   aFaceUnifier.GetOptimumNbFaces() = myOptimumNbFaces;
-  TopoDS_Shape aResult = aFaceUnifier.Perform(myShape);
+  aResult = aFaceUnifier.Perform(aResult);
+#else
+  if (myOptimumNbFaces > 1) {
+    // use old algo BlockFix_UnionFaces for exactly given resulting number of faces
+    BlockFix_UnionFaces aFaceUnifier;
+    aFaceUnifier.GetTolerance() = myTolerance;
+    aFaceUnifier.GetOptimumNbFaces() = myOptimumNbFaces;
+    aResult = aFaceUnifier.Perform(aResult);
+  }
+  else if (myOptimumNbFaces != -1) {
+    // use OCCT algo ShapeUpgrade_UnifySameDomain
+    ShapeUpgrade_UnifySameDomain Unifier;
+    //only faces
+    Standard_Boolean isUnifyEdges = Standard_False;
+    Standard_Boolean isUnifyFaces = Standard_True;
+    Standard_Boolean isConcatBSplines = Standard_True;
+    Unifier.Initialize(myShape, isUnifyEdges, isUnifyFaces, isConcatBSplines);
+    //Unifier.SetLinearTolerance(myTolerance);
+    Unifier.SetLinearTolerance(Precision::Confusion());
+    Unifier.SetAngularTolerance(Precision::Confusion());
+    //Unifier.SetAngularTolerance(1e-5);
+    //Unifier.SetAngularTolerance(0.1);
+    Unifier.Build();
+    aResult = Unifier.Shape();
+  }
+  else {
+    // myOptimumNbFaces == -1 means do not union faces
+  }
+#endif
 
   // avoid problem with degenerated edges appearance
   // due to shape quality regress
@@ -79,8 +132,20 @@ void BlockFix_BlockFixAPI::Perform()
   aResult = RemLoc.GetResult();
 
   // edges unification
+#if OCC_VERSION_LARGE < 0x07050301
   BlockFix_UnionEdges anEdgeUnifier;
   myShape = anEdgeUnifier.Perform(aResult,myTolerance);
+#else
+  ShapeUpgrade_UnifySameDomain Unifier;
+  Standard_Boolean isUnifyEdges = Standard_True;
+  Standard_Boolean isUnifyFaces = Standard_False; //only edges
+  Standard_Boolean isConcatBSplines = Standard_True;
+  Unifier.Initialize(aResult, isUnifyEdges, isUnifyFaces, isConcatBSplines);
+  Unifier.SetLinearTolerance(myTolerance);
+  Unifier.SetAngularTolerance(1e-5);
+  Unifier.Build();
+  myShape = Unifier.Shape();
+#endif
 
   TopoDS_Shape aRes = BlockFix::FixRanges(myShape,myTolerance);
   myShape = aRes;