]> SALOME platform Git repositories - modules/geom.git/commitdiff
Salome HOME
Mantis issue 0021466: Healing no effect, Glue faces no effect. A fix by JGV.
authorjfa <jfa@opencascade.com>
Thu, 26 Apr 2012 10:07:48 +0000 (10:07 +0000)
committerjfa <jfa@opencascade.com>
Thu, 26 Apr 2012 10:07:48 +0000 (10:07 +0000)
src/GEOMAlgo_NEW/BlockFix.cxx
src/GEOMAlgo_NEW/BlockFix.hxx
src/GEOMAlgo_NEW/BlockFix_BlockFixAPI.cxx
src/GEOMAlgo_NEW/BlockFix_UnionEdges.cxx

index 22f230b9d96ce4e47a047224108ed9f5a8235ab7..0e4f9bb21a40503c3a52314024acce0b92666051 100644 (file)
 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-//
 
 // File:        BlockFix.cxx
 // Created:     Tue Dec  7 11:59:05 2004
 // Author:      Pavel DURANDIN
-//
+
 #include <BlockFix.hxx>
-#include <TopoDS_Shape.hxx>
-#include <TopTools_DataMapOfShapeShape.hxx>
-#include <ShapeCustom.hxx>
-#include <BRepTools.hxx>
-#include <ShapeBuild_ReShape.hxx>
-#include <TopoDS_Face.hxx>
+
+#include <BlockFix_SphereSpaceModifier.hxx>
+#include <BlockFix_PeriodicSurfaceModifier.hxx>
+
+#include <TopExp.hxx>
 #include <TopExp_Explorer.hxx>
-#include <TopoDS.hxx>
+
 #include <TopLoc_Location.hxx>
-#include <Geom_Surface.hxx>
-#include <Geom_CylindricalSurface.hxx>
-#include <Geom_ConicalSurface.hxx>
-#include <ShapeFix_Wire.hxx>
+
+#include <TopoDS.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Face.hxx>
 #include <TopoDS_Wire.hxx>
-#include <BRepTools_Modifier.hxx>
-#include <Geom_SphericalSurface.hxx>
-#include <Geom_ToroidalSurface.hxx>
+#include <TopoDS_Shape.hxx>
+#include <TopoDS_Solid.hxx>
+#include <TopoDS_Vertex.hxx>
+
+#include <TopTools_ListOfShape.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_MapOfShape.hxx>
+#include <TopTools_DataMapOfShapeShape.hxx>
+#include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
+
 #include <BRep_Tool.hxx>
-#include <TopoDS_Edge.hxx>
-#include <Geom2d_Curve.hxx>
 #include <BRep_Builder.hxx>
-#include <ShapeAnalysis_Edge.hxx>
-#include <ShapeFix_Edge.hxx>
+
+#include <BRepAdaptor_Surface.hxx>
+
+#include <BRepTools.hxx>
+#include <BRepTools_Modifier.hxx>
+#include <BRepTools_Substitution.hxx>
+
+#include <BRepOffsetAPI_MakeFilling.hxx>
+
 #include <ShapeFix.hxx>
+#include <ShapeFix_Edge.hxx>
 #include <ShapeFix_Face.hxx>
-#include <ShapeAnalysis.hxx>
 
-#include <TColgp_SequenceOfPnt2d.hxx>
+#include <ShapeAnalysis.hxx>
+#include <ShapeAnalysis_Edge.hxx>
 #include <ShapeAnalysis_Curve.hxx>
-#include <TopoDS_Vertex.hxx>
+#include <ShapeAnalysis_Surface.hxx>
+
+#include <ShapeCustom.hxx>
+
 #include <ShapeBuild_Edge.hxx>
+#include <ShapeBuild_ReShape.hxx>
 
-#include <BlockFix_SphereSpaceModifier.hxx>
-#include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
-#include <TopTools_MapOfShape.hxx>
-#include <BlockFix_PeriodicSurfaceModifier.hxx>
+#include <ShapeFix_Wire.hxx>
 
-#include <TopoDS_Solid.hxx>
+#include <Geom_Surface.hxx>
+#include <Geom_CylindricalSurface.hxx>
+#include <Geom_ConicalSurface.hxx>
+#include <Geom_SphericalSurface.hxx>
+#include <Geom_ToroidalSurface.hxx>
+
+#include <Geom2d_Curve.hxx>
 
+#include <TColgp_SequenceOfPnt2d.hxx>
 
 //=======================================================================
 //function : FixResult
@@ -130,7 +149,6 @@ static void FixResult(const TopoDS_Shape& result,
           }
         }
 
-
         if(isDone) {
           TopoDS_Wire ResWire = sfw->Wire();
           Context->Replace(ex_w.Current(), ResWire);
@@ -143,24 +161,17 @@ static void FixResult(const TopoDS_Shape& result,
         if(sff->FixOrientation())
           Context->Replace(aFixedFace,sff->Face());
       }
-
     }
   }
 }
 
-
-
-
-
 //=======================================================================
-//function : ConvertToAnalytical
+//function : RotateSphereSpace
 //purpose  :
 //=======================================================================
-
 TopoDS_Shape BlockFix::RotateSphereSpace (const TopoDS_Shape& S,
                                           const Standard_Real Tol)
 {
-
   // Create a modification description
   Handle(BlockFix_SphereSpaceModifier) SR = new BlockFix_SphereSpaceModifier;
   SR->SetTolerance(Tol);
@@ -183,12 +194,129 @@ TopoDS_Shape BlockFix::RotateSphereSpace (const TopoDS_Shape& S,
   return result;
 }
 
+//=======================================================================
+//function : RefillProblemFaces
+//purpose  :
+//=======================================================================
+TopoDS_Shape BlockFix::RefillProblemFaces (const TopoDS_Shape& aShape)
+{
+  Standard_Integer NbSamples = 10;
+
+  TopTools_ListOfShape theFaces;
+
+  TopExp_Explorer Explo(aShape, TopAbs_FACE);
+  for (; Explo.More(); Explo.Next())
+  {
+    TopoDS_Face aFace = TopoDS::Face(Explo.Current());
+    BRepAdaptor_Surface BAsurf(aFace);
+    GeomAbs_SurfaceType SurfType = BAsurf.GetType();
+    if (SurfType >= GeomAbs_BezierSurface)
+    {
+      TopExp_Explorer fexp(aFace, TopAbs_EDGE);
+      for (; fexp.More(); fexp.Next())
+      {
+        const TopoDS_Edge& anEdge = TopoDS::Edge(fexp.Current());
+        if (BRep_Tool::Degenerated(anEdge))
+        {
+          TopoDS_Vertex V1, V2;
+          TopExp::Vertices(anEdge, V1, V2);
+          if (V1.IsSame(V2))
+          {
+            gp_Pnt aPnt = BRep_Tool::Pnt(V1);
+            Standard_Real TolV = BRep_Tool::Tolerance(V1);
+            Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
+            Handle(ShapeAnalysis_Surface) Analyser = new ShapeAnalysis_Surface(aSurf);
+            if (Analyser->IsDegenerated(aPnt, TolV))
+            {
+              theFaces.Append(aFace);
+              break;
+            }
+          }
+        }
+      }
+    }
+  }
+
+  //Now all problem faces are collected in the list "theFaces"
+  BRepTools_Substitution aSubst;
+  TopTools_ListIteratorOfListOfShape itl(theFaces);
+  for (; itl.More(); itl.Next())
+  {
+    const TopoDS_Face& aFace = TopoDS::Face(itl.Value());
+    BRepOffsetAPI_MakeFilling Filler;
+    for (Explo.Init(aFace, TopAbs_EDGE); Explo.More(); Explo.Next())
+    {
+      const TopoDS_Edge& anEdge = TopoDS::Edge(Explo.Current());
+      if (!BRep_Tool::Degenerated(anEdge))
+        Filler.Add(anEdge, GeomAbs_C0);
+    }
+    Standard_Real Umin, Umax, Vmin, Vmax;
+    BRepTools::UVBounds(aFace, Umin, Umax, Vmin, Vmax);
+    //Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
+    Standard_Integer i, j;
+    for (i = 1; i < NbSamples; i++)
+      for (j = 1; j < NbSamples; j++) {
+        /*
+        gp_Pnt aPoint = aSurf->Value(Umin + i*(Umax-Umin)/NbSamples,
+                                     Vmin + j*(Vmax-Vmin)/NbSamples);
+        Filler.Add(aPoint);
+        */
+        Filler.Add(Umin + i*(Umax-Umin)/NbSamples,
+                   Vmin + j*(Vmax-Vmin)/NbSamples,
+                   aFace, GeomAbs_G1);
+      }
+
+    Filler.Build();
+    if (Filler.IsDone())
+    {
+      for (Explo.Init(aFace, TopAbs_EDGE); Explo.More(); Explo.Next())
+      {
+        const TopoDS_Edge& anEdge = TopoDS::Edge(Explo.Current());
+        TopTools_ListOfShape Ledge;
+        if (!BRep_Tool::Degenerated(anEdge))
+        {
+          const TopTools_ListOfShape& Ledges = Filler.Generated(anEdge);
+          if (!Ledges.IsEmpty()) {
+            TopoDS_Shape NewEdge = Ledges.First();
+            Ledge.Append(NewEdge.Oriented(TopAbs_FORWARD));
+          }
+        }
+        aSubst.Substitute(anEdge, Ledge);
+      }
+      TopTools_ListOfShape Lface;
+      TopoDS_Face NewFace = TopoDS::Face(Filler.Shape());
+      NewFace.Orientation(TopAbs_FORWARD);
+      BRepAdaptor_Surface NewBAsurf(NewFace);
+      gp_Pnt MidPnt;
+      gp_Vec D1U, D1V, Normal, NewNormal;
+      Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
+      aSurf->D1((Umin+Umax)*0.5, (Vmin+Vmax)*0.5, MidPnt, D1U, D1V);
+      Normal = D1U ^ D1V;
+      NewBAsurf.D1((NewBAsurf.FirstUParameter() + NewBAsurf.LastUParameter())*0.5,
+                   (NewBAsurf.FirstVParameter() + NewBAsurf.LastVParameter())*0.5,
+                   MidPnt, D1U, D1V);
+      NewNormal = D1U ^ D1V;
+      if (Normal * NewNormal < 0.)
+        NewFace.Reverse();
+      Lface.Append(NewFace);
+      aSubst.Substitute(aFace, Lface);
+    }
+  }
+  aSubst.Build(aShape);
+
+  TopoDS_Shape Result = aShape;
+  if (aSubst.IsCopied(aShape))
+    Result = aSubst.Copy(aShape).First();
+
+  BRepTools::RemoveUnusedPCurves(Result);
+
+  return Result;
+}
 
 //=======================================================================
 //function : FixRanges
 //purpose  :
 //=======================================================================
-
 TopoDS_Shape BlockFix::FixRanges (const TopoDS_Shape& S,
                                   const Standard_Real Tol)
 {
index a6a35727653a2c26fc8d04663e49c052919fb381..34007be5c48d5c2514022b0df4dc77cb12b0f8c3 100644 (file)
@@ -26,6 +26,7 @@
 #ifndef _Standard_Real_HeaderFile
 #include <Standard_Real.hxx>
 #endif
+
 class TopoDS_Shape;
 class BlockFix_SphereSpaceModifier;
 class BlockFix_UnionFaces;
@@ -34,7 +35,6 @@ class BlockFix_BlockFixAPI;
 class BlockFix_PeriodicSurfaceModifier;
 class BlockFix_CheckTool;
 
-
 #ifndef _Standard_HeaderFile
 #include <Standard.hxx>
 #endif
@@ -46,46 +46,27 @@ class BlockFix  {
 
 public:
 
-    void* operator new(size_t,void* anAddress)
-      {
-        return anAddress;
-      }
-    void* operator new(size_t size)
-      {
-        return Standard::Allocate(size);
-      }
-    void  operator delete(void *anAddress)
-      {
-        if (anAddress) Standard::Free((Standard_Address&)anAddress);
-      }
- // Methods PUBLIC
- //
-Standard_EXPORT static  TopoDS_Shape RotateSphereSpace(const TopoDS_Shape& S,const Standard_Real Tol) ;
-Standard_EXPORT static  TopoDS_Shape FixRanges(const TopoDS_Shape& S,const Standard_Real Tol) ;
-
-
-
-
+  void* operator new(size_t,void* anAddress)
+  {
+    return anAddress;
+  }
+  void* operator new(size_t size)
+  {
+    return Standard::Allocate(size);
+  }
+  void  operator delete(void *anAddress)
+  {
+    if (anAddress) Standard::Free((Standard_Address&)anAddress);
+  }
+
+  Standard_EXPORT static  TopoDS_Shape RotateSphereSpace(const TopoDS_Shape& S,const Standard_Real Tol);
+  Standard_EXPORT static  TopoDS_Shape RefillProblemFaces(const TopoDS_Shape& S);
+  Standard_EXPORT static  TopoDS_Shape FixRanges(const TopoDS_Shape& S,const Standard_Real Tol);
 
 protected:
 
- // Methods PROTECTED
- //
-
-
- // Fields PROTECTED
- //
-
-
 private:
 
- // Methods PRIVATE
- //
-
-
- // Fields PRIVATE
- //
-
 friend class BlockFix_SphereSpaceModifier;
 friend class BlockFix_UnionFaces;
 friend class BlockFix_UnionEdges;
@@ -95,12 +76,6 @@ friend class BlockFix_CheckTool;
 
 };
 
-
-
-
-
 // other Inline functions and methods (like "C++: function call" methods)
-//
-
 
 #endif
index 2aefa654ec6d304ad225652c453766351ad088bb..3c82e4a84c4ba653c5609304548216de1dd6e678 100644 (file)
 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-//
 
 //  File:    BlockFix_BlockFixAPI.cxx
 //  Created: Tue Dec  7 11:59:05 2004
 //  Author:  Pavel DURANDIN
-//
+
 #include <BlockFix_BlockFixAPI.ixx>
+
 #include <BlockFix.hxx>
 #include <BlockFix_UnionFaces.hxx>
 #include <BlockFix_UnionEdges.hxx>
+
+#include <Basics_OCCTVersion.hxx>
+
+#include <ShapeUpgrade_RemoveLocations.hxx>
+
 #include <Precision.hxx>
 
 //=======================================================================
@@ -52,12 +57,23 @@ void BlockFix_BlockFixAPI::Perform()
   TopoDS_Shape aShape = Shape();
   myShape = BlockFix::RotateSphereSpace(aShape,myTolerance);
 
+  // try to approximate non-canonic surfaces
+  // with singularities on boundaries by filling
+  myShape = BlockFix::RefillProblemFaces(myShape);
+
   // faces unification
   BlockFix_UnionFaces aFaceUnifier;
   aFaceUnifier.GetTolerance() = myTolerance;
   aFaceUnifier.GetOptimumNbFaces() = myOptimumNbFaces;
   TopoDS_Shape aResult = aFaceUnifier.Perform(myShape);
 
+  // avoid problem with degenerated edges appearance
+  // due to shape quality regress
+  ShapeUpgrade_RemoveLocations RemLoc;
+  RemLoc.Remove(aResult);
+  aResult = RemLoc.GetResult();
+
+  // edges unification
   BlockFix_UnionEdges anEdgeUnifier;
   myShape = anEdgeUnifier.Perform(aResult,myTolerance);
 
index 7c5d2a186d8b2fcf13b057d2a45730bd7a817086..95a1a713ee60d5866840ce0dad2d80dd5db75d49 100644 (file)
@@ -18,7 +18,6 @@
 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-//
 
 // File:      BlockFix_UnionEdges.cxx
 // Created:   07.12.04 15:27:30
 
 #include <BlockFix_UnionEdges.ixx>
 
-#include <Approx_Curve3d.hxx>
-#include <BRepAdaptor_HCompCurve.hxx>
-#include <BRep_Builder.hxx>
-#include <BRep_Tool.hxx>
-#include <GC_MakeCircle.hxx>
-#include <Geom_BSplineCurve.hxx>
-#include <Geom_Circle.hxx>
-#include <Geom_Curve.hxx>
-#include <Geom_Line.hxx>
-#include <Geom_TrimmedCurve.hxx>
 #include <ShapeAnalysis_Edge.hxx>
+
 #include <ShapeFix_Edge.hxx>
 #include <ShapeFix_Face.hxx>
 #include <ShapeFix_Shell.hxx>
-#include <TColgp_SequenceOfPnt.hxx>
-#include <TColStd_MapOfInteger.hxx>
+
+#include <BRep_Builder.hxx>
+#include <BRep_CurveRepresentation.hxx>
+#include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
+#include <BRep_TEdge.hxx>
+#include <BRep_Tool.hxx>
+#include <BRepAdaptor_HCompCurve.hxx>
+#include <BRepLib.hxx>
+#include <BRepLib_MakeEdge.hxx>
+
 #include <TopExp.hxx>
 #include <TopExp_Explorer.hxx>
+
 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
 #include <TopTools_IndexedMapOfShape.hxx>
 #include <TopTools_ListOfShape.hxx>
 #include <TopTools_MapOfShape.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
 #include <TopTools_SequenceOfShape.hxx>
+
 #include <TopoDS.hxx>
 #include <TopoDS_Edge.hxx>
 #include <TopoDS_Face.hxx>
 #include <TopoDS_Vertex.hxx>
 #include <TopoDS_Iterator.hxx>
 
+#include <Approx_Curve3d.hxx>
+
+#include <GC_MakeCircle.hxx>
+
+#include <Geom_BSplineCurve.hxx>
+#include <Geom_Circle.hxx>
+#include <Geom_Curve.hxx>
+#include <Geom_Line.hxx>
+#include <Geom_TrimmedCurve.hxx>
+#include <GeomConvert.hxx>
+#include <GeomConvert_CompCurveToBSplineCurve.hxx>
+
+#include <Geom2dConvert.hxx>
+#include <Geom2dConvert_CompCurveToBSplineCurve.hxx>
+#include <Geom2d_TrimmedCurve.hxx>
+#include <Geom2d_BSplineCurve.hxx>
+
+#include <TColGeom_SequenceOfSurface.hxx>
+#include <TColGeom_Array1OfBSplineCurve.hxx>
+#include <TColGeom_HArray1OfBSplineCurve.hxx>
+#include <TColGeom2d_Array1OfBSplineCurve.hxx>
+#include <TColGeom2d_HArray1OfBSplineCurve.hxx>
+#include <TColGeom2d_SequenceOfBoundedCurve.hxx>
+#include <TColgp_SequenceOfPnt.hxx>
+#include <TColStd_Array1OfReal.hxx>
+#include <TColStd_MapOfInteger.hxx>
+
 #include "utilities.h"
 
 //=======================================================================
 //function : BlockFix_UnionEdges()
 //purpose  : Constructor
 //=======================================================================
-
 BlockFix_UnionEdges::BlockFix_UnionEdges (  )
 {
 }
 
+//=======================================================================
+//function : GlueEdgesWithPCurves
+//purpose  : Glues the pcurves of the sequence of edges
+//           and glues their 3d curves
+//=======================================================================
+static TopoDS_Edge GlueEdgesWithPCurves(const TopTools_SequenceOfShape& aChain,
+                                        const TopoDS_Vertex& FirstVertex,
+                                        const TopoDS_Vertex& LastVertex)
+{
+  Standard_Integer i, j;
+
+  TopoDS_Edge FirstEdge = TopoDS::Edge(aChain(1));
+  //TColGeom2d_SequenceOfCurve PCurveSeq;
+  TColGeom_SequenceOfSurface SurfSeq;
+  //TopTools_SequenceOfShape LocSeq;
+  
+  BRep_ListIteratorOfListOfCurveRepresentation itr( (Handle(BRep_TEdge)::DownCast(FirstEdge.TShape()))->Curves() );
+  for (; itr.More(); itr.Next())
+  {
+    Handle(BRep_CurveRepresentation) CurveRep = itr.Value();
+    if (CurveRep->IsCurveOnSurface())
+    {
+      //PCurveSeq.Append(CurveRep->PCurve());
+      SurfSeq.Append(CurveRep->Surface());
+      /*
+      TopoDS_Shape aLocShape;
+      aLocShape.Location(CurveRep->Location());
+      LocSeq.Append(aLocShape);
+      */
+    }
+  }
+
+  Standard_Real fpar, lpar;
+  BRep_Tool::Range(FirstEdge, fpar, lpar);
+  TopoDS_Edge PrevEdge = FirstEdge;
+  TopoDS_Vertex CV;
+  Standard_Real MaxTol = 0.;
+  
+  TopoDS_Edge ResEdge;
+  BRep_Builder BB;
+
+  Standard_Integer nb_curve = aChain.Length();   //number of curves
+  TColGeom_Array1OfBSplineCurve tab_c3d(0,nb_curve-1);                    //array of the curves
+  TColStd_Array1OfReal tabtolvertex(0,nb_curve-1); //(0,nb_curve-2);  //array of the tolerances
+    
+  TopoDS_Vertex PrevVertex = FirstVertex;
+  for (i = 1; i <= nb_curve; i++)
+  {
+    TopoDS_Edge anEdge = TopoDS::Edge(aChain(i));
+    TopoDS_Vertex VF, VL;
+    TopExp::Vertices(anEdge, VF, VL);
+    Standard_Boolean ToReverse = (!VF.IsSame(PrevVertex));
+    
+    Standard_Real Tol1 = BRep_Tool::Tolerance(VF);
+    Standard_Real Tol2 = BRep_Tool::Tolerance(VL);
+    if (Tol1 > MaxTol)
+      MaxTol = Tol1;
+    if (Tol2 > MaxTol)
+      MaxTol = Tol2;
+    
+    if (i > 1)
+    {
+      TopExp::CommonVertex(PrevEdge, anEdge, CV);
+      Standard_Real Tol = BRep_Tool::Tolerance(CV);
+      tabtolvertex(i-2) = Tol;
+    }
+    
+    Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, fpar, lpar);
+    Handle(Geom_TrimmedCurve) aTrCurve = new Geom_TrimmedCurve(aCurve, fpar, lpar);
+    tab_c3d(i-1) = GeomConvert::CurveToBSplineCurve(aTrCurve);
+    GeomConvert::C0BSplineToC1BSplineCurve(tab_c3d(i-1), Precision::Confusion());
+    if (ToReverse)
+      tab_c3d(i-1)->Reverse();
+    PrevVertex = (ToReverse)? VF : VL;
+    PrevEdge = anEdge;
+  }
+  Handle(TColGeom_HArray1OfBSplineCurve)  concatcurve;     //array of the concatenated curves
+  Handle(TColStd_HArray1OfInteger)        ArrayOfIndices;  //array of the remining Vertex
+  GeomConvert::ConcatC1(tab_c3d,
+                        tabtolvertex,
+                        ArrayOfIndices,
+                        concatcurve,
+                        Standard_False,
+                        Precision::Confusion());   //C1 concatenation
+  
+  if (concatcurve->Length() > 1)
+  {
+    GeomConvert_CompCurveToBSplineCurve Concat(concatcurve->Value(concatcurve->Lower()));
+    
+    for (i = concatcurve->Lower()+1; i <= concatcurve->Upper(); i++)
+      Concat.Add( concatcurve->Value(i), MaxTol, Standard_True );
+    
+    concatcurve->SetValue(concatcurve->Lower(), Concat.BSplineCurve());
+  }
+  Handle(Geom_BSplineCurve) ResCurve = concatcurve->Value(concatcurve->Lower());
+  
+  TColGeom2d_SequenceOfBoundedCurve ResPCurves;
+  TopLoc_Location aLoc;
+  for (j = 1; j <= SurfSeq.Length(); j++)
+  {
+    TColGeom2d_Array1OfBSplineCurve tab_c2d(0,nb_curve-1); //array of the pcurves
+    
+    PrevVertex = FirstVertex;
+    PrevEdge = FirstEdge;
+    //TopLoc_Location theLoc = LocSeq(j).Location();
+    for (i = 1; i <= nb_curve; i++)
+    {
+      TopoDS_Edge anEdge = TopoDS::Edge(aChain(i));
+      TopoDS_Vertex VF, VL;
+      TopExp::Vertices(anEdge, VF, VL);
+      Standard_Boolean ToReverse = (!VF.IsSame(PrevVertex));
+
+      /*
+      Handle(Geom2d_Curve) aPCurve =
+        BRep_Tool::CurveOnSurface(anEdge, SurfSeq(j), anEdge.Location()*theLoc, fpar, lpar);
+      */
+      Handle(Geom2d_Curve) aPCurve =
+        BRep_Tool::CurveOnSurface(anEdge, SurfSeq(j), aLoc, fpar, lpar);
+      Handle(Geom2d_TrimmedCurve) aTrPCurve = new Geom2d_TrimmedCurve(aPCurve, fpar, lpar);
+      tab_c2d(i-1) = Geom2dConvert::CurveToBSplineCurve(aTrPCurve);
+      Geom2dConvert::C0BSplineToC1BSplineCurve(tab_c2d(i-1), Precision::Confusion());
+      if (ToReverse)
+        tab_c2d(i-1)->Reverse();
+      PrevVertex = (ToReverse)? VF : VL;
+      PrevEdge = anEdge;
+    }
+    Handle(TColGeom2d_HArray1OfBSplineCurve)  concatc2d;     //array of the concatenated curves
+    Handle(TColStd_HArray1OfInteger)        ArrayOfInd2d;  //array of the remining Vertex
+    Geom2dConvert::ConcatC1(tab_c2d,
+                            tabtolvertex,
+                            ArrayOfInd2d,
+                            concatc2d,
+                            Standard_False,
+                            Precision::Confusion());   //C1 concatenation
+    
+    if (concatc2d->Length() > 1)
+    {
+      Geom2dConvert_CompCurveToBSplineCurve Concat2d(concatc2d->Value(concatc2d->Lower()));
+      
+      for (i = concatc2d->Lower()+1; i <= concatc2d->Upper(); i++)
+        Concat2d.Add( concatc2d->Value(i), MaxTol, Standard_True );
+      
+      concatc2d->SetValue(concatc2d->Lower(), Concat2d.BSplineCurve());
+    }
+    Handle(Geom2d_BSplineCurve) aResPCurve = concatc2d->Value(concatc2d->Lower());
+    ResPCurves.Append(aResPCurve);
+  }
+  
+  ResEdge = BRepLib_MakeEdge(ResCurve,
+                             FirstVertex, LastVertex,
+                             ResCurve->FirstParameter(), ResCurve->LastParameter());
+  BB.SameRange(ResEdge, Standard_False);
+  BB.SameParameter(ResEdge, Standard_False);
+  for (j = 1; j <= ResPCurves.Length(); j++)
+  {
+    BB.UpdateEdge(ResEdge, ResPCurves(j), SurfSeq(j), aLoc, MaxTol);
+    BB.Range(ResEdge, SurfSeq(j), aLoc, ResPCurves(j)->FirstParameter(), ResPCurves(j)->LastParameter());
+  }
+
+  BRepLib::SameParameter(ResEdge, MaxTol, Standard_True);
+  
+  return ResEdge;
+}
 
 //=======================================================================
 //function : MergeEdges
@@ -252,6 +441,8 @@ static Standard_Boolean MergeEdges(const TopTools_SequenceOfShape& SeqEdges,
     }
     if(NeedUnion) {
       MESSAGE ("can not make analitical union => make approximation");
+      TopoDS_Edge E = GlueEdgesWithPCurves(aChain, VF, VL);
+      /*
       TopoDS_Wire W;
       B.MakeWire(W);
       for(j=1; j<=aChain.Length(); j++) {
@@ -265,6 +456,7 @@ static Standard_Boolean MergeEdges(const TopTools_SequenceOfShape& SeqEdges,
       B.MakeEdge (E,bc,Precision::Confusion());
       B.Add (E,VF);
       B.Add (E,VL);
+      */
       aChain.SetValue(1,E);
     }
     else {
@@ -277,12 +469,10 @@ static Standard_Boolean MergeEdges(const TopTools_SequenceOfShape& SeqEdges,
   return Standard_True;
 }
 
-
 //=======================================================================
 //function : Perform
 //purpose  :
 //=======================================================================
-
 TopoDS_Shape BlockFix_UnionEdges::Perform(const TopoDS_Shape& Shape,
                                           const Standard_Real Tol)
 {