Salome HOME
[bos #39942] EDF 25230 - New problem with XYZtoUV
[modules/geom.git] / src / BlockFix / BlockFix_UnionFaces.cxx
index 7406cd4df92bd148c47498d4eec5992e34e7c66d..5ec25bc92ca5f99bddb5762293021a7958b196d0 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2016  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 <TColGeom_HArray2OfSurface.hxx>
 
+#if OCC_VERSION_LARGE < 0x07070000
 #include <GeomAdaptor_HSurface.hxx>
-#include <GeomLib_IsPlanarSurface.hxx>
+#else
+#include <GeomAdaptor_Surface.hxx>
+#endif
 
+#include <GeomLib_IsPlanarSurface.hxx>
 #include <Geom_Surface.hxx>
 #include <Geom_Plane.hxx>
 #include <Geom_OffsetSurface.hxx>
 #include <Geom_SurfaceOfLinearExtrusion.hxx>
 #include <Geom_RectangularTrimmedSurface.hxx>
 #include <BRepAdaptor_Surface.hxx>
+#if OCC_VERSION_LARGE < 0x07070000
 #include <BRepAdaptor_HSurface.hxx>
+#endif
 #include <LocalAnalysis_SurfaceContinuity.hxx>
 #include <GeomConvert_ApproxSurface.hxx>
+#include <Bnd_Box.hxx>
+#include <BRepBndLib.hxx>
 
+#include <Geom_TrimmedCurve.hxx>
 #include <Geom_Curve.hxx>
 #include <Geom_Line.hxx>
 #include <Geom_Circle.hxx>
@@ -239,8 +248,34 @@ static Standard_Boolean IsFacesOfSameSolids
   return isSame;
 }
 
-#if OCC_VERSION_LARGE > 0x07020001
-// for Mantis issue 0023451 by JGV
+//=======================================================================
+//function : DefineMaxTolerance
+//purpose  : calculates maximum possible tolerance on edges of shape
+//=======================================================================
+static Standard_Real DefineMaxTolerance(const TopoDS_Shape& theShape)
+{
+  Standard_Real aTol = Precision::Confusion();
+
+  Standard_Real MinSize = RealLast();
+  TopExp_Explorer Explo(theShape, TopAbs_EDGE);
+  for (; Explo.More(); Explo.Next())
+  {
+    const TopoDS_Edge& anEdge = TopoDS::Edge(Explo.Current());
+    Bnd_Box aBox;
+    BRepBndLib::Add(anEdge, aBox);
+    Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax;
+    aBox.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
+    Standard_Real MaxSize = Max(Xmax - Xmin, Max(Ymax - Ymin, Zmax - Zmin));
+    if (MaxSize < MinSize)
+      MinSize = MaxSize;
+  }
+
+  if (!Precision::IsInfinite(MinSize))
+    aTol = 0.1 * MinSize;
+
+  return aTol;
+}
+
 //=======================================================================
 //function : IsTangentFaces
 //purpose  : decides: is edge on closed surface tangent or not
@@ -271,7 +306,11 @@ static Standard_Boolean IsTangentFaces(const TopoDS_Edge& theEdge,
 
 // Computation of the number of samples on the edge.
   BRepAdaptor_Surface              aBAS(theFace);
+#if OCC_VERSION_LARGE < 0x07070000
   Handle(BRepAdaptor_HSurface)     aBAHS      = new BRepAdaptor_HSurface(aBAS);
+#else
+  Handle(BRepAdaptor_Surface)      aBAHS      = new BRepAdaptor_Surface(aBAS);
+#endif
   Handle(BRepTopAdaptor_TopolTool) aTool      = new BRepTopAdaptor_TopolTool(aBAHS);
   Standard_Integer                 aNbSamples =     aTool->NbSamples();
   const Standard_Integer           aNbSamplesMax =   23;
@@ -322,15 +361,13 @@ static Standard_Boolean HasSeamEdge(const TopoDS_Face& theFace)
 
   return Standard_False;
 }
-#endif
+
 
 //=======================================================================
 //function : IsEdgeValidToMerge
 //purpose  : Edge is valid if it is not seam or if it is a seam and the face
 //           has another seam edge.
 //=======================================================================
-#if OCC_VERSION_LARGE > 0x07020001
-// for Mantis issue 0023451 by JGV
 static Standard_Boolean IsEdgeValidToMerge(const TopoDS_Edge& theEdge,
                                            const TopoDS_Face& theFace,
                                            const Handle(Geom_Surface)& theSurface,
@@ -396,37 +433,6 @@ static Standard_Boolean IsEdgeValidToMerge(const TopoDS_Edge& theEdge,
 
   return isValid;
 }
-#else
-static Standard_Boolean IsEdgeValidToMerge(const TopoDS_Edge &theEdge,
-                                           const TopoDS_Face &theFace)
-{
-  Standard_Boolean isValid = Standard_True;
-
-  if (BRep_Tool::IsClosed(theEdge, theFace)) {
-    // This is a seam edge. Check if there are another seam edges on the face.
-    TopExp_Explorer anExp(theFace, TopAbs_EDGE);
-
-    for (; anExp.More(); anExp.Next()) {
-      const TopoDS_Shape &aShEdge = anExp.Current();
-
-      // Skip same edge.
-      if (theEdge.IsSame(aShEdge)) {
-        continue;
-      }
-
-      // Check if this edge is a seam.
-      TopoDS_Edge anEdge = TopoDS::Edge(aShEdge);
-
-      if (BRep_Tool::IsClosed(anEdge, theFace)) {
-        isValid = Standard_False;
-        break;
-      }
-    }
-  }
-
-  return isValid;
-}
-#endif
 
 //=======================================================================
 //function : Perform
@@ -494,26 +500,16 @@ TopoDS_Shape BlockFix_UnionFaces::Perform(const TopoDS_Shape& Shape)
       Handle(Geom_Surface) aBaseSurface = BRep_Tool::Surface(aFace,aBaseLocation);
       aBaseSurface = ClearRts(aBaseSurface);
       aBaseSurface = Handle(Geom_Surface)::DownCast(aBaseSurface->Copy());
-#if OCC_VERSION_LARGE > 0x07020001
-// for Mantis issue 0023451 by JGV
       Standard_Boolean ToMakeUPeriodic = Standard_False, ToMakeVPeriodic = Standard_False;
-#endif
 
       // find adjacent faces to union
       Standard_Integer i;
       for (i = 1; i <= edges.Length(); i++) {
         TopoDS_Edge edge = TopoDS::Edge(edges(i));
-#if OCC_VERSION_LARGE > 0x07020001
-// for Mantis issue 0023451 by JGV
         Standard_Boolean IsEdgeOnSeam = Standard_False;
-#endif
         if (BRep_Tool::Degenerated(edge) ||
-#if OCC_VERSION_LARGE > 0x07020001
-// for Mantis issue 0023451 by JGV
-            !IsEdgeValidToMerge(edge, aFace, aBaseSurface, IsEdgeOnSeam, ToMakeUPeriodic, ToMakeVPeriodic))
-#else
-            !IsEdgeValidToMerge(edge, aFace))
-#endif
+            !IsEdgeValidToMerge(edge, aFace, aBaseSurface,
+                                IsEdgeOnSeam, ToMakeUPeriodic, ToMakeVPeriodic))
           continue;
 
         const TopTools_ListOfShape& aList = aMapEdgeFaces.FindFromKey(edge);
@@ -526,13 +522,8 @@ TopoDS_Shape BlockFix_UnionFaces::Perform(const TopoDS_Shape& Shape)
           if (aProcessed.Contains(anCheckedFace))
             continue;
 
-#if OCC_VERSION_LARGE > 0x07020001
-// for Mantis issue 0023451 by JGV
           if (!IsEdgeValidToMerge(edge, anCheckedFace, aBaseSurface,
                                   IsEdgeOnSeam, ToMakeUPeriodic, ToMakeVPeriodic)) {
-#else
-          if (!IsEdgeValidToMerge(edge, anCheckedFace)) {
-#endif
             // Skip seam edge.
             continue;
           }
@@ -549,13 +540,10 @@ TopoDS_Shape BlockFix_UnionFaces::Perform(const TopoDS_Shape& Shape)
               continue;
             }
 
-#if OCC_VERSION_LARGE > 0x07020001
-// for Mantis issue 0023451 by JGV
             //Prevent creating a face with parametric range more than period
             if (IsEdgeOnSeam &&
                 (HasSeamEdge(aFace) || HasSeamEdge(anCheckedFace)))
               continue;
-#endif
 
             // replacing pcurves
             TopoDS_Face aMockUpFace;
@@ -580,8 +568,6 @@ TopoDS_Shape BlockFix_UnionFaces::Perform(const TopoDS_Shape& Shape)
         NbModif++;
         TopoDS_Face aResult;
         BRep_Builder B;
-#if OCC_VERSION_LARGE > 0x07020001
-// for Mantis issue 0023451 by JGV
         if (ToMakeUPeriodic || ToMakeVPeriodic)
         {
           Handle(Geom_BSplineSurface) aBSplineSurface = Handle(Geom_BSplineSurface)::DownCast(aBaseSurface);
@@ -603,7 +589,6 @@ TopoDS_Shape BlockFix_UnionFaces::Perform(const TopoDS_Shape& Shape)
           
           aBaseSurface = aBSplineSurface;
         }
-#endif
         B.MakeFace(aResult,aBaseSurface,aBaseLocation,0);
         Standard_Integer nbWires = 0;
 
@@ -670,7 +655,7 @@ TopoDS_Shape BlockFix_UnionFaces::Perform(const TopoDS_Shape& Shape)
           TopoDS_Wire aWireFixed = sfw->Wire();
           aContext->Replace(aWire,aWireFixed);
           // add resulting wire
-          if(isEdge3d) {
+          if (isEdge3d) {
             B.Add(aResult,aWireFixed);
           }
           else  {
@@ -681,40 +666,42 @@ TopoDS_Shape BlockFix_UnionFaces::Perform(const TopoDS_Shape& Shape)
             ShapeAnalysis_WireOrder sawo(Standard_False, 0);
             ShapeAnalysis_Edge sae;
             Standard_Integer aLastEdge = nbEdges;
-            for(Standard_Integer j = 1; j <= nbEdges; j++) {
+            for (Standard_Integer j = 1; j <= nbEdges; j++) {
               Standard_Real f,l;
               //smh protection on NULL pcurve
               Handle(Geom2d_Curve) c2d;
-              if(!sae.PCurve(sbwd->Edge(j),aResult,c2d,f,l)) {
+              if (!sae.PCurve(sbwd->Edge(j),aResult,c2d,f,l)) {
                 aLastEdge--;
                 continue;
               }
               sawo.Add(c2d->Value(f).XY(),c2d->Value(l).XY());
             }
-            sawo.Perform();
-
-            // constructind one degenerative edge
-            gp_XY aStart, anEnd, tmp;
-            Standard_Integer nbFirst = sawo.Ordered(1);
-            TopoDS_Edge anOrigE = TopoDS::Edge(sbwd->Edge(nbFirst).Oriented(TopAbs_FORWARD));
-            ShapeBuild_Edge sbe;
-            TopoDS_Vertex aDummyV;
-            TopoDS_Edge E = sbe.CopyReplaceVertices(anOrigE,aDummyV,aDummyV);
-            sawo.XY(nbFirst,aStart,tmp);
-            sawo.XY(sawo.Ordered(aLastEdge),tmp,anEnd);
-
-            gp_XY aVec = anEnd-aStart;
-            Handle(Geom2d_Line) aLine = new Geom2d_Line(aStart,gp_Dir2d(anEnd-aStart));
-
-            B.UpdateEdge(E,aLine,aResult,0.);
-            B.Range(E,aResult,0.,aVec.Modulus());
-            Handle(Geom_Curve) C3d;
-            B.UpdateEdge(E,C3d,0.);
-            B.Degenerated(E,Standard_True);
-            TopoDS_Wire aW;
-            B.MakeWire(aW);
-            B.Add(aW,E);
-            B.Add(aResult,aW);
+            if (aLastEdge > 0) {
+              sawo.Perform();
+
+              // constructing one degenerative edge
+              gp_XY aStart, anEnd, tmp;
+              Standard_Integer nbFirst = sawo.Ordered(1);
+              TopoDS_Edge anOrigE = TopoDS::Edge(sbwd->Edge(nbFirst).Oriented(TopAbs_FORWARD));
+              ShapeBuild_Edge sbe;
+              TopoDS_Vertex aDummyV;
+              TopoDS_Edge E = sbe.CopyReplaceVertices(anOrigE,aDummyV,aDummyV);
+              sawo.XY(nbFirst,aStart,tmp);
+              sawo.XY(sawo.Ordered(aLastEdge),tmp,anEnd);
+
+              gp_XY aVec = anEnd-aStart;
+              Handle(Geom2d_Line) aLine = new Geom2d_Line(aStart,gp_Dir2d(anEnd-aStart));
+
+              B.UpdateEdge(E,aLine,aResult,0.);
+              B.Range(E,aResult,0.,aVec.Modulus());
+              Handle(Geom_Curve) C3d;
+              B.UpdateEdge(E,C3d,0.);
+              B.Degenerated(E,Standard_True);
+              TopoDS_Wire aW;
+              B.MakeWire(aW);
+              B.Add(aW,E);
+              B.Add(aResult,aW);
+            }
           }
         }
 
@@ -722,15 +709,13 @@ TopoDS_Shape BlockFix_UnionFaces::Perform(const TopoDS_Shape& Shape)
         aContext->Replace(aContext->Apply(aFace),aResult);
 
         ShapeFix_Face sff (aResult);
-        //Intializing by tolerances
+        //Initializing by tolerances
         sff.SetPrecision(myTolerance);
         sff.SetMinTolerance(tol);
-        sff.SetMaxTolerance(Max(1.,myTolerance*1000.));
+        Standard_Real MaxTol = DefineMaxTolerance(aResult);
+        sff.SetMaxTolerance(MaxTol);
         //Setting modes
         sff.FixOrientationMode() = 0;
-#if OCC_VERSION_LARGE > 0x07020001
-        sff.FixWireTool()->CheckMissingEdgesMode() = Standard_False;
-#endif
         //sff.FixWireMode() = 0;
         sff.SetContext(aContext);
         // Applying the fixes
@@ -840,6 +825,13 @@ bool getCylinder (Handle(Geom_Surface)& theInSurface, gp_Cylinder& theOutCylinde
     Handle(Geom_SurfaceOfRevolution) aRS =
       Handle(Geom_SurfaceOfRevolution)::DownCast(theInSurface);
     Handle(Geom_Curve) aBasis = aRS->BasisCurve();
+
+    while (aBasis->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
+      Handle(Geom_TrimmedCurve) aTc =
+        Handle(Geom_TrimmedCurve)::DownCast(aBasis);
+      aBasis = aTc->BasisCurve();
+    }
+
     if (aBasis->IsKind(STANDARD_TYPE(Geom_Line))) {
       Handle(Geom_Line) aBasisLine = Handle(Geom_Line)::DownCast(aBasis);
       gp_Dir aDir = aRS->Direction();
@@ -859,6 +851,13 @@ bool getCylinder (Handle(Geom_Surface)& theInSurface, gp_Cylinder& theOutCylinde
     Handle(Geom_SurfaceOfLinearExtrusion) aLES =
       Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(theInSurface);
     Handle(Geom_Curve) aBasis = aLES->BasisCurve();
+
+    while (aBasis->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
+      Handle(Geom_TrimmedCurve) aTc =
+        Handle(Geom_TrimmedCurve)::DownCast(aBasis);
+      aBasis = aTc->BasisCurve();
+    }
+
     if (aBasis->IsKind(STANDARD_TYPE(Geom_Circle))) {
       Handle(Geom_Circle) aBasisCircle = Handle(Geom_Circle)::DownCast(aBasis);
       gp_Dir aDir = aLES->Direction();
@@ -914,8 +913,13 @@ Standard_Boolean BlockFix_UnionFaces::IsSameDomain(const TopoDS_Face& aFace,
   if (S1->IsKind(STANDARD_TYPE(Geom_ElementarySurface)) &&
       S2->IsKind(STANDARD_TYPE(Geom_ElementarySurface)))
   {
+#if OCC_VERSION_LARGE < 0x07070000
     Handle(GeomAdaptor_HSurface) aGA1 = new GeomAdaptor_HSurface(S1);
     Handle(GeomAdaptor_HSurface) aGA2 = new GeomAdaptor_HSurface(S2);
+#else
+    Handle(GeomAdaptor_Surface) aGA1 = new GeomAdaptor_Surface(S1);
+    Handle(GeomAdaptor_Surface) aGA2 = new GeomAdaptor_Surface(S2);
+#endif
 
     Handle(BRepTopAdaptor_TopolTool) aTT1 = new BRepTopAdaptor_TopolTool();
     Handle(BRepTopAdaptor_TopolTool) aTT2 = new BRepTopAdaptor_TopolTool();
@@ -930,7 +934,7 @@ Standard_Boolean BlockFix_UnionFaces::IsSameDomain(const TopoDS_Face& aFace,
 
       return anIIInt.TangentFaces();
     }
-    catch (Standard_Failure) {
+    catch (Standard_Failure&) {
       return false;
     }
   }