Salome HOME
[bos #39942] EDF 25230 - New problem with XYZtoUV
[modules/geom.git] / src / GEOMImpl / GEOMImpl_Fillet1dDriver.cxx
index cce147164ee25931a0c3ef704f76a1256b79e08f..7d5bb0bc1baadac324ba7684d85ccd181100b68e 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
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
@@ -48,6 +48,7 @@
 #include <TopTools_IndexedMapOfShape.hxx>
 
 #include <BRep_Tool.hxx>
+#include <BRep_Builder.hxx>
 #include <BRepTools.hxx>
 #include <BRepBuilderAPI_MakeWire.hxx>
 #include <BRepCheck_Analyzer.hxx>
@@ -124,7 +125,7 @@ static Standard_Boolean takePlane( const TopoDS_Edge& theE1,
       return false;
     thePlane = gp_Pln( gp_Pnt(aXYZ), aDir1^ aDir2);
   }
-  catch (Standard_Failure) {
+  catch (Standard_Failure&) {
     return false;
   }
   return true;
@@ -148,7 +149,7 @@ static void addEdgeRelation(TopTools_DataMapOfShapeShape& theMap,
 //function : Execute
 //purpose  :
 //=======================================================================
-Standard_Integer GEOMImpl_Fillet1dDriver::Execute(TFunction_Logbook& log) const
+Standard_Integer GEOMImpl_Fillet1dDriver::Execute(Handle(TFunction_Logbook)& log) const
 {
   if (Label().IsNull()) return 0;
   Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
@@ -257,7 +258,7 @@ Standard_Integer GEOMImpl_Fillet1dDriver::Execute(TFunction_Logbook& log) const
   }
 
   aFunction->SetValue(aResult);
-  log.SetTouched(Label());
+  log->SetTouched(Label());
 
   return 1;
 }
@@ -266,11 +267,11 @@ Standard_Integer GEOMImpl_Fillet1dDriver::Execute(TFunction_Logbook& log) const
 //function : MakeFillet
 //purpose  :
 //=======================================================================
-bool GEOMImpl_Fillet1dDriver::MakeFillet(const TopoDS_Wire& aWire,
-                                         const TopTools_ListOfShape& aVertexList,
-                                         const Standard_Real rad,
+bool GEOMImpl_Fillet1dDriver::MakeFillet(const TopoDS_Wire& theWire,
+                                         const TopTools_ListOfShape& theVertexList,
+                                         const Standard_Real theRadius,
                                          bool isFinalPass,
-                                         TopoDS_Wire& aResult) const
+                                         TopoDS_Wire& theResult) const
 {
   // this variable is needed to break execution
   // in case of fillet failure and try to fuse edges
@@ -286,8 +287,8 @@ bool GEOMImpl_Fillet1dDriver::MakeFillet(const TopoDS_Wire& aWire,
   TopTools_ListOfShape aListOfNewEdge;
   // remember relation between initial and modified map
   TopTools_IndexedDataMapOfShapeListOfShape aMapVToEdges;
-  TopExp::MapShapesAndAncestors( aWire, TopAbs_VERTEX, TopAbs_EDGE, aMapVToEdges );
-  TopTools_ListIteratorOfListOfShape anIt( aVertexList );
+  TopExp::MapShapesAndAncestors( theWire, TopAbs_VERTEX, TopAbs_EDGE, aMapVToEdges );
+  TopTools_ListIteratorOfListOfShape anIt( theVertexList );
   for ( ; anIt.More(); anIt.Next() ) {
     TopoDS_Vertex aV = TopoDS::Vertex( anIt.Value() );
     if ( aV.IsNull() || !aMapVToEdges.Contains( aV ) )
@@ -309,7 +310,7 @@ bool GEOMImpl_Fillet1dDriver::MakeFillet(const TopoDS_Wire& aWire,
       continue; // seems edges does not belong to same plane or parallel (fillet can not be build)
 
     GEOMImpl_Fillet1d aFilletAlgo (anEdge1, anEdge2, aPlane);
-    if (!aFilletAlgo.Perform(rad)) {
+    if (!aFilletAlgo.Perform(theRadius)) {
       if (isFinalPass)
         continue; // can not create fillet with given radius
       else {
@@ -352,23 +353,59 @@ bool GEOMImpl_Fillet1dDriver::MakeFillet(const TopoDS_Wire& aWire,
     return false;
 
   // create new wire instead of original
-  for (TopExp_Explorer anExp (aWire, TopAbs_EDGE); anExp.More(); anExp.Next()) {
+  Standard_Real aTol;
+  Standard_Real aVertMaxTol = -RealLast();
+  for (TopExp_Explorer anExp (theWire, TopAbs_EDGE); anExp.More(); anExp.Next()) {
     TopoDS_Shape anEdge = anExp.Current();
     if (!anEdgeToEdgeMap.IsBound(anEdge))
       aListOfNewEdge.Append(anEdge);
     else if (!anEdgeToEdgeMap.Find(anEdge).IsNull())
       aListOfNewEdge.Append(anEdgeToEdgeMap.Find(anEdge));
-  }
-
-  GEOMUtils::SortShapes(aListOfNewEdge);
 
-  BRepBuilderAPI_MakeWire aWireTool;
-  aWireTool.Add(aListOfNewEdge);
-  aWireTool.Build();
-  if (!aWireTool.IsDone())
-    return 0;
+    // calculate maximum vertex tolerance of the initial wire
+    // to be used for resulting wire fixing (some gaps are possible)
+    for (TopExp_Explorer anExV (anEdge, TopAbs_VERTEX); anExV.More(); anExV.Next()) {
+      TopoDS_Vertex aVert = TopoDS::Vertex(anExV.Current());
+      aTol = BRep_Tool::Tolerance(aVert);
+      if (aTol > aVertMaxTol)
+        aVertMaxTol = aTol;
+    }
+  }
 
-  aResult = aWireTool.Wire();
+  // Fix for Mantis issue 0023411: BEGIN
+  BRep_Builder B;
+  TopoDS_Wire aResWire;
+  B.MakeWire(aResWire);
+  TopTools_ListIteratorOfListOfShape anItNewEdge (aListOfNewEdge);
+  for (; anItNewEdge.More(); anItNewEdge.Next()) {
+    B.Add(aResWire, TopoDS::Edge(anItNewEdge.Value()));
+  }
+  Handle(ShapeFix_Wire) aFW = new ShapeFix_Wire;
+  aFW->Load(aResWire);
+  aFW->FixReorder();
+  aFW->ClosedWireMode() = theWire.Closed();
+  // Fix for Mantis issue 0023411
+  // We forced to do this because of fillet 1d algorithm feature
+  // (see function DivideEdge in file GEOMImpl_Fillet1d.cxx):
+  // a distance (gap) from new arc end to a vertex of original wire
+  // can reach (aVertexTolerance + Precision::Confusion()),
+  // so a distance between two adjacent arcs will be covered by value below
+  aFW->FixConnected(aVertMaxTol*2.0 + Precision::Confusion()*3.0);
+  theResult = aFW->WireAPIMake();
+  GEOMUtils::FixShapeTolerance(theResult, TopAbs_VERTEX, Precision::Confusion());
+
+  // In OCCT 7.0.0 and earlier this gap was successfully covered by
+  // implementation of BRepBuilderAPI_MakeWire::Add(TopTools_ListOfShape)
+  // (in the case described in Mantis issue 0023411)
+
+  //GEOMUtils::SortShapes(aListOfNewEdge);
+  //BRepBuilderAPI_MakeWire aWireTool;
+  //aWireTool.Add(aListOfNewEdge);
+  //aWireTool.Build();
+  //if (!aWireTool.IsDone())
+  //  return 0;
+  //theResult = aWireTool.Wire();
+  // Fix for Mantis issue 0023411: END
 
   return isAllStepsOk;
 }
@@ -404,9 +441,8 @@ GetCreationInformation(std::string&             theOperationName,
   default:
     return false;
   }
-  
+
   return true;
 }
 
-IMPLEMENT_STANDARD_HANDLE (GEOMImpl_Fillet1dDriver,GEOM_BaseDriver);
-IMPLEMENT_STANDARD_RTTIEXT (GEOMImpl_Fillet1dDriver,GEOM_BaseDriver);
+IMPLEMENT_STANDARD_RTTIEXT (GEOMImpl_Fillet1dDriver,GEOM_BaseDriver)