0027065: BRepOffsetAPI_MakePipe misses definition of virtual method Generated()
[occt.git] / src / BRepFill / BRepFill_Pipe.cxx
index 5c4f579..46bee4d 100644 (file)
@@ -5,8 +5,8 @@
 //
 // This file is part of Open CASCADE Technology software library.
 //
-// This library is free software; you can redistribute it and / or modify it
-// under the terms of the GNU Lesser General Public version 2.1 as published
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
 // by the Free Software Foundation, with special exception defined in the file
 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
 // distribution for complete text of the license and disclaimer of any warranty.
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-#include <BRepFill_Pipe.ixx>
 
-#include <Standard_ErrorHandler.hxx>
-
-#include <BRep_Tool.hxx>
+#include <Adaptor3d_CurveOnSurface.hxx>
 #include <BRep_Builder.hxx>
+#include <BRep_Tool.hxx>
+#include <BRepBuilderAPI_Copy.hxx>
+#include <BRepBuilderAPI_Transform.hxx>
 #include <BRepClass3d_SolidClassifier.hxx>
-#include <BRepLib_MakeVertex.hxx>
-#include <BRepTools_Substitution.hxx>
-
-#include <GeomFill_CorrectedFrenet.hxx>
-#include <GeomFill_Frenet.hxx>
-#include <GeomFill_DiscreteTrihedron.hxx>
-#include <GeomFill_CurveAndTrihedron.hxx>
-
+#include <BRepFill_Edge3DLaw.hxx>
+#include <BRepFill_LocationLaw.hxx>
+#include <BRepFill_Pipe.hxx>
 #include <BRepFill_SectionPlacement.hxx>
 #include <BRepFill_ShapeLaw.hxx>
-#include <BRepFill_Edge3DLaw.hxx>
 #include <BRepFill_Sweep.hxx>
-
+#include <BRepLib.hxx>
+#include <BRepLib_MakeVertex.hxx>
+#include <BRepTools_Substitution.hxx>
+#include <Geom2dAdaptor_HCurve.hxx>
+#include <Geom_BSplineCurve.hxx>
+#include <Geom_OffsetCurve.hxx>
+#include <Geom_TrimmedCurve.hxx>
 #include <GeomAbs_Shape.hxx>
-#include <TopExp.hxx>
+#include <GeomAdaptor_HSurface.hxx>
+#include <GeomFill_CorrectedFrenet.hxx>
+#include <GeomFill_CurveAndTrihedron.hxx>
+#include <GeomFill_DiscreteTrihedron.hxx>
+#include <GeomFill_Frenet.hxx>
+#include <gp_Pnt.hxx>
+#include <Precision.hxx>
+#include <ShapeUpgrade_RemoveLocations.hxx>
+#include <Standard_DomainError.hxx>
+#include <Standard_ErrorHandler.hxx>
+#include <Standard_NotImplemented.hxx>
+#include <StdFail_NotDone.hxx>
+#include <TColStd_DataMapIteratorOfDataMapOfIntegerInteger.hxx>
+#include <TColStd_DataMapOfIntegerInteger.hxx>
 #include <TopAbs_ShapeEnum.hxx>
+#include <TopExp.hxx>
 #include <TopoDS.hxx>
-#include <TopoDS_Shell.hxx>
-#include <TopoDS_Solid.hxx>
 #include <TopoDS_Compound.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Face.hxx>
 #include <TopoDS_Iterator.hxx>
+#include <TopoDS_Shape.hxx>
+#include <TopoDS_Shell.hxx>
+#include <TopoDS_Solid.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <TopoDS_Wire.hxx>
 #include <TopTools_DataMapOfShapeInteger.hxx>
-#include <TColStd_DataMapOfIntegerInteger.hxx>
-#include <TColStd_DataMapIteratorOfDataMapOfIntegerInteger.hxx>
-
-#include <Precision.hxx>
-#include <Standard_NotImplemented.hxx>
-
-#include <Geom_TrimmedCurve.hxx>
-#include <Geom_OffsetCurve.hxx>
-#include <Geom_BSplineCurve.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_SequenceOfShape.hxx>
 
 #ifdef DRAW
 #include <DBRep.hxx>
 static Standard_Boolean Affich = 0;
 #endif
 
+// ---------------------------------------------------------------------------------
+// static function: UpdateMap
+// purpose:
+// ---------------------------------------------------------------------------------
+static Standard_Boolean UpdateMap(const TopoDS_Shape&                 theKey,
+                                  const TopoDS_Shape&                 theValue,
+                                  TopTools_DataMapOfShapeListOfShape& theMap)
+{
+  if(!theMap.IsBound(theKey))
+  {
+    TopTools_ListOfShape thelist;
+    theMap.Bind(theKey, thelist);
+  }
+  TopTools_ListOfShape& aList = theMap.ChangeFind(theKey);
+  TopTools_ListIteratorOfListOfShape anIt(aList);
+  Standard_Boolean found = Standard_False;
+
+  for(; anIt.More(); anIt.Next())
+  {
+    if(theValue.IsSame(anIt.Value()))
+    {
+      found = Standard_True;
+      break;
+    }
+  }
+
+  if(!found)
+    aList.Append(theValue);
+  
+  return !found;
+}
+
+static void ReverseModifiedEdges(TopoDS_Shape& aShape,
+                                 TopTools_MapOfShape& Emap)
+{
+  TopExp_Explorer Explo(aShape, TopAbs_FACE);
+  BRep_Builder BB;
+  
+  for (; Explo.More(); Explo.Next())
+  {
+    TopoDS_Shape aFace = Explo.Current();
+    TopoDS_Iterator itf(aFace);
+    for (; itf.More(); itf.Next())
+    {
+      TopoDS_Shape aWire = itf.Value();
+      TopTools_ListOfShape Ledges;
+      TopoDS_Iterator itw(aWire);
+      for (; itw.More(); itw.Next())
+        Ledges.Append(itw.Value());
+
+      aWire.Free(Standard_True);
+      TopTools_ListIteratorOfListOfShape itl(Ledges);
+      for (; itl.More(); itl.Next())
+        BB.Remove(aWire, itl.Value());
+        
+      for (itl.Initialize(Ledges); itl.More(); itl.Next())
+      {
+        TopoDS_Shape anEdge = itl.Value();
+        if (Emap.Contains(anEdge))
+          anEdge.Reverse();
+        BB.Add(aWire, anEdge);
+      }
+    }
+  }
+}
+
+static void UpdateTolFromTopOrBottomPCurve(const TopoDS_Face& aFace,
+                                           TopoDS_Edge& anEdge)
+{
+  Standard_Real fpar, lpar;
+  Handle(Geom2d_Curve) aPCurve = BRep_Tool::CurveOnSurface(anEdge, aFace, fpar, lpar);
+  if (aPCurve.IsNull())
+    return;
+
+  Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, fpar, lpar);
+  if (aCurve.IsNull())
+    return;
+
+  Handle(Geom2dAdaptor_HCurve) GAHC2d = new Geom2dAdaptor_HCurve(aPCurve, fpar, lpar);
+  Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
+  Handle(GeomAdaptor_HSurface) GAHS = new GeomAdaptor_HSurface(aSurf);
+  Adaptor3d_CurveOnSurface ConS(GAHC2d, GAHS);
+
+  Standard_Real Tol = BRep_Tool::Tolerance(anEdge);
+  Standard_Real InitTol = Tol;
+  Standard_Real TolTol = Tol*Tol;
+  const Standard_Integer NCONTROL = 22;
+  Standard_Real delta = (lpar - fpar)/NCONTROL;
+  for (Standard_Integer i = 0; i <= NCONTROL; i++)
+  {
+    Standard_Real par = fpar + i*delta;
+    gp_Pnt pnt = aCurve->Value(par);
+    gp_Pnt prj = ConS.Value(par);
+    Standard_Real sqdist = pnt.SquareDistance(prj);
+    if (sqdist > TolTol)
+      TolTol = sqdist;
+  }
+  Tol = 1.00005 * Sqrt(TolTol);
+  if (Tol >= InitTol)
+  {
+    BRep_Builder BB;
+    BB.UpdateEdge(anEdge, Tol);
+    TopoDS_Iterator itv(anEdge);
+    for (; itv.More(); itv.Next())
+    {
+      TopoDS_Vertex aVertex = TopoDS::Vertex(itv.Value());
+      BB.UpdateVertex(aVertex, Tol);
+    }
+  }
+}
+
 //=======================================================================
 //function : BRepFill_Pipe
 //purpose  : 
@@ -70,6 +193,8 @@ BRepFill_Pipe::BRepFill_Pipe()
   myContinuity = GeomAbs_C2;
   myMode = GeomFill_IsCorrectedFrenet;
   myForceApproxC1 = Standard_False;
+
+  myCurIndexOfSectionEdge = 1;
 }
 
 
@@ -99,6 +224,9 @@ BRepFill_Pipe::BRepFill_Pipe(const TopoDS_Wire&  Spine,
     myContinuity = GeomAbs_C0;
   
   myForceApproxC1 = ForceApproxC1;
+
+  myCurIndexOfSectionEdge = 1;
+  
   Perform(Spine, Profile, KPart);
 }
 
@@ -168,34 +296,43 @@ void BRepFill_Pipe::Perform(const TopoDS_Wire&  Spine,
   myLoc->Law(1)->D0(first, M, V);
     fila.SetValues(M(1,1), M(1,2), M(1,3), V.X(),
                   M(2,1), M(2,2), M(2,3), V.Y(),
-                  M(3,1), M(3,2), M(3,3), V.Z(),
-                  1.e-12, 1.e-14);
+                  M(3,1), M(3,2), M(3,3), V.Z());
 
   fila.Multiply(myTrsf);
   TopLoc_Location LocFirst(fila);
   myFirst = myProfile;
   if ( ! LocFirst.IsIdentity()) {
-    myFirst.Location( LocFirst.Multiplied(myProfile.Location()) );
+    //myFirst.Location( LocFirst.Multiplied(myProfile.Location()) );
+    myFirst = BRepBuilderAPI_Transform(myProfile, fila, Standard_True); //copy
   }
 
+  ShapeUpgrade_RemoveLocations RemLoc;
+  RemLoc.SetRemoveLevel(TopAbs_COMPOUND);
+  RemLoc.Remove(myFirst);
+  myFirst = RemLoc.GetResult();
+  
   myLoc->Law(myLoc->NbLaw())->GetDomain(first, last);
   myLoc->Law(myLoc->NbLaw())->D0(last,M, V);
 //    try { // Not good, but there are no other means to test SetValues
   fila.SetValues(M(1,1), M(1,2), M(1,3), V.X(),
                 M(2,1), M(2,2), M(2,3), V.Y(),
-                M(3,1), M(3,2), M(3,3), V.Z(),
-                1.e-12, 1.e-14);
+                M(3,1), M(3,2), M(3,3), V.Z());
   fila.Multiply(myTrsf);
   TopLoc_Location LocLast(fila);
   if (! myLoc->IsClosed() || LocFirst != LocLast) {
     myLast = myProfile;
     if ( ! LocLast.IsIdentity()) {
-      myLast.Location(LocLast.Multiplied(myProfile.Location()) );
+      //myLast.Location(LocLast.Multiplied(myProfile.Location()) );
+      myLast = BRepBuilderAPI_Transform(myProfile, fila, Standard_True); //copy
     }
   }
   else {
     myLast = myFirst;
   }
+
+  RemLoc.Remove(myLast);
+  myLast = RemLoc.GetResult();
+  
 #if DRAW
   if (Affich) {
     DBRep::Set("theprof",  TheProf);
@@ -238,6 +375,16 @@ const TopoDS_Shape& BRepFill_Pipe::Shape() const
   return myShape;
 }
 
+//=======================================================================
+//function : ErrorOnSurface
+//purpose  : 
+//=======================================================================
+
+Standard_Real BRepFill_Pipe::ErrorOnSurface() const 
+{
+  return myErrorOnSurf;
+}
+
 
 //=======================================================================
 //function : FirstShape
@@ -260,6 +407,47 @@ const TopoDS_Shape& BRepFill_Pipe::LastShape() const
   return myLast;
 }
 
+//=======================================================================
+//function : Generated
+//purpose  : 
+//=======================================================================
+void BRepFill_Pipe::Generated(const TopoDS_Shape&   theShape,
+                              TopTools_ListOfShape& theList) 
+{
+  theList.Clear();
+
+  if (theShape.IsSame(myProfile))
+    theList.Append(myShape);
+  else
+  {
+    if (theShape.ShapeType() == TopAbs_FACE ||
+        theShape.ShapeType() == TopAbs_WIRE)
+    {
+      if(myGenMap.IsBound(theShape))
+        theList = myGenMap.Find(theShape);
+    }
+    else if (theShape.ShapeType() == TopAbs_EDGE)
+    {
+      TopoDS_Iterator itw(mySpine);
+      for (; itw.More(); itw.Next())
+      {
+        const TopoDS_Edge& aSpineEdge = TopoDS::Edge(itw.Value());
+        const TopoDS_Shape& aFace = Face(aSpineEdge, TopoDS::Edge(theShape));
+        theList.Append(aFace);
+      }
+    }
+    else if (theShape.ShapeType() == TopAbs_VERTEX)
+    {
+      TopoDS_Iterator itw(mySpine);
+      for (; itw.More(); itw.Next())
+      {
+        const TopoDS_Edge& aSpineEdge = TopoDS::Edge(itw.Value());
+        const TopoDS_Shape& anEdge = Edge(aSpineEdge, TopoDS::Vertex(theShape));
+        theList.Append(anEdge);
+      }
+    }
+  }
+}
 
 //=======================================================================
 //function : Face
@@ -379,7 +567,7 @@ TopoDS_Shape BRepFill_Pipe::Section(const TopoDS_Vertex& VSpine) const
 //purpose  : Construct a wire by sweeping of a point
 //=======================================================================
 
-TopoDS_Wire BRepFill_Pipe::PipeLine(const gp_Pnt& Point) const
+TopoDS_Wire BRepFill_Pipe::PipeLine(const gp_Pnt& Point)
 {
  // Postioning 
  gp_Pnt P;
@@ -393,8 +581,10 @@ TopoDS_Wire BRepFill_Pipe::PipeLine(const gp_Pnt& Point) const
  // Sweeping
  BRepFill_Sweep MkSw(Section, myLoc, Standard_True);
  MkSw.SetForceApproxC1(myForceApproxC1);
- MkSw.Build( BRepFill_Modified, myContinuity, GeomFill_Location, myDegmax, mySegmax );
+ MkSw.Build( myReversedEdges, myTapes, myRails,
+             BRepFill_Modified, myContinuity, GeomFill_Location, myDegmax, mySegmax );
  TopoDS_Shape aLocalShape = MkSw.Shape();
+ myErrorOnSurf = MkSw.ErrorOnSurface();
  return TopoDS::Wire(aLocalShape);
 // return TopoDS::Wire(MkSw.Shape());
 }
@@ -440,20 +630,21 @@ TopoDS_Shape BRepFill_Pipe::MakeShape(const TopoDS_Shape& S,
       B.MakeShell(TopoDS::Shell(result));
       B.MakeWire(W);
       B.Add(W, S);
-      W.Closed(S.Closed());
+      W.Closed(BRep_Tool::IsClosed(S));
       TheS = W;
       if (!FirstShape.IsNull()) {
        B.MakeWire(W);
        B.Add(W, FirstShape);
-       W.Closed(FirstShape.Closed());
+       W.Closed(BRep_Tool::IsClosed(FirstShape));
        TheFirst = W;
       }
       if (!LastShape.IsNull()) {
        B.MakeWire(W);
        B.Add(W, LastShape);
-       W.Closed(LastShape.Closed());
+       W.Closed(BRep_Tool::IsClosed(LastShape));
        TheLast = W;
       }
+      result.Closed (BRep_Tool::IsClosed (result));
       break;
     }
          
@@ -468,6 +659,7 @@ TopoDS_Shape BRepFill_Pipe::MakeShape(const TopoDS_Shape& S,
       if ( !mySpine.Closed() && !TheFirst.IsNull()) {
         B.Add(result, TheFirst.Reversed());
       }
+      result.Closed (BRep_Tool::IsClosed (result));
       break;
     }
 
@@ -480,7 +672,7 @@ TopoDS_Shape BRepFill_Pipe::MakeShape(const TopoDS_Shape& S,
 
   case TopAbs_SOLID :
   case TopAbs_COMPSOLID :
-    Standard_DomainError::Raise("BRepFill_Pipe::SOLID or COMPSOLID");
+    Standard_DomainError::Raise("BRepFill_Pipe::profile contains solids");
     break;
 
   case TopAbs_COMPOUND :
@@ -519,8 +711,20 @@ TopoDS_Shape BRepFill_Pipe::MakeShape(const TopoDS_Shape& S,
        new (BRepFill_ShapeLaw) (TopoDS::Vertex(TheS));
       BRepFill_Sweep MkSw(Section, myLoc, Standard_True);
       MkSw.SetForceApproxC1(myForceApproxC1);
-      MkSw.Build( BRepFill_Modified, myContinuity, GeomFill_Location, myDegmax, mySegmax );
+      MkSw.Build( myReversedEdges, myTapes, myRails,
+                  BRepFill_Modified, myContinuity, GeomFill_Location, myDegmax, mySegmax );
       result = MkSw.Shape();
+      UpdateMap(TheS.Located(myProfile.Location()), result, myGenMap);
+      myErrorOnSurf = MkSw.ErrorOnSurface();
+
+      Handle(TopTools_HArray2OfShape) aSections = MkSw.Sections();
+
+      if (aSections.IsNull() == Standard_False) {
+        const Standard_Integer aVLast = aSections->UpperCol();
+
+        myFirst = aSections->Value(1, 1);
+        myLast  = aSections->Value(1, aVLast);
+      }
     }
 
     if (TheS.ShapeType() == TopAbs_WIRE ) {
@@ -530,8 +734,14 @@ TopoDS_Shape BRepFill_Pipe::MakeShape(const TopoDS_Shape& S,
       MkSw.SetBounds(TopoDS::Wire(TheFirst), 
                     TopoDS::Wire(TheLast));
       MkSw.SetForceApproxC1(myForceApproxC1);
-      MkSw.Build( BRepFill_Modified, myContinuity, GeomFill_Location, myDegmax, mySegmax );
+      MkSw.Build( myReversedEdges, myTapes, myRails,
+                  BRepFill_Modified, myContinuity, GeomFill_Location, myDegmax, mySegmax );
       result = MkSw.Shape();
+      UpdateMap(TheS.Located(myProfile.Location()), result, myGenMap);
+      myErrorOnSurf = MkSw.ErrorOnSurface();
+      //Correct <myFirst> and <myLast>
+      ReverseModifiedEdges(myFirst, myReversedEdges);
+      ReverseModifiedEdges(myLast, myReversedEdges);
 
       // Labeling of elements
       if (mySections.IsNull()) {
@@ -543,9 +753,6 @@ TopoDS_Shape BRepFill_Pipe::MakeShape(const TopoDS_Shape& S,
        Handle(TopTools_HArray2OfShape) Aux, Somme;
        Standard_Integer length;
         Standard_Integer ii, jj, kk;
-        const Standard_Integer aNbFaces    = myFaces->ColLength();
-        const Standard_Integer aNbEdges    = myEdges->ColLength();
-        const Standard_Integer aNbSections = mySections->ColLength();
 
        Aux = MkSw.SubShape();
        length = Aux->ColLength() + myFaces->ColLength(); 
@@ -568,7 +775,9 @@ TopoDS_Shape BRepFill_Pipe::MakeShape(const TopoDS_Shape& S,
        for (jj=1; jj<=mySections->RowLength(); jj++) {
          for (ii=1; ii<=mySections->ColLength(); ii++)
            Somme->SetValue(ii, jj, mySections->Value(ii, jj));
+
+          myCurIndexOfSectionEdge = mySections->ColLength()+1;
+          
          for (kk=1, ii=mySections->ColLength()+1; 
               kk <=Aux->ColLength(); kk++, ii++)
            Somme->SetValue(ii, jj, Aux->Value(kk, jj));   
@@ -589,15 +798,20 @@ TopoDS_Shape BRepFill_Pipe::MakeShape(const TopoDS_Shape& S,
        }
 
        myEdges = Somme;
-
-        // Perform sharing faces
-        result = ShareFaces(result, aNbFaces, aNbEdges, aNbSections);
       }
     }
   }
       
   if ( TheS.ShapeType() == TopAbs_FACE ) {
     Standard_Integer ii, jj;
+    //jgv
+    TopExp_Explorer Explo(result, TopAbs_FACE);
+    for (; Explo.More(); Explo.Next())
+    {
+      TopoDS_Shape aFace = Explo.Current();
+      RebuildTopOrBottomFace(aFace.Reversed(), Standard_True); //top face was reversed
+    }
+    /////
     TopoDS_Face F;
     for (ii=InitialLength+1; ii<=myFaces->ColLength(); ii++) {
       for (jj=1; jj<=myFaces->RowLength(); jj++) {
@@ -609,6 +823,10 @@ TopoDS_Shape BRepFill_Pipe::MakeShape(const TopoDS_Shape& S,
     if ( !mySpine.Closed()) {
       // if Spine is not closed 
       // add the last face of the solid
+
+      //jgv
+      RebuildTopOrBottomFace(TheLast, Standard_False); //bottom face
+      /////
       B.Add(result, TopoDS::Face(TheLast));
     }
 
@@ -627,6 +845,7 @@ TopoDS_Shape BRepFill_Pipe::MakeShape(const TopoDS_Shape& S,
       BS.Add(solid,TopoDS::Shell(aLocalShape));
 //      BS.Add(solid,TopoDS::Shell(result.Reversed()));
     }
+    UpdateMap(TheS.Located(myProfile.Location()), solid, myGenMap);
     return solid;
   }
   else {
@@ -656,14 +875,14 @@ Standard_Integer BRepFill_Pipe::FindEdge(const TopoDS_Shape& S,
          
   case TopAbs_WIRE :
     {
-      Standard_Integer ii = InitialLength+1;
       Handle(BRepFill_ShapeLaw) Section = 
-       new (BRepFill_ShapeLaw) (TopoDS::Wire(S), Standard_False);
-      InitialLength += Section->NbLaw();
-     
-      for (; (ii<=InitialLength) && (!result); ii++) {
-       if (E.IsSame(Section->Edge(ii)) ) result = ii;
+        new (BRepFill_ShapeLaw) (TopoDS::Wire(S), Standard_False);
+      Standard_Integer NbLaw = Section->NbLaw();
+
+      for (Standard_Integer ii = 1; (ii<=NbLaw) && (!result); ii++) {
+        if (E.IsSame(Section->Edge(ii)) ) result = InitialLength + ii;
       }
+      InitialLength += NbLaw;
       break;
     }
 
@@ -775,13 +994,13 @@ void BRepFill_Pipe::DefineRealSegmax()
             C->DynamicType() == STANDARD_TYPE(Geom_OffsetCurve))
        {
          if (C->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve))
-           C = (*((Handle(Geom_TrimmedCurve)*)&C))->BasisCurve();
+           C = Handle(Geom_TrimmedCurve)::DownCast (C)->BasisCurve();
          if (C->DynamicType() == STANDARD_TYPE(Geom_OffsetCurve))
-           C = (*((Handle(Geom_OffsetCurve)*)&C))->BasisCurve();
+           C = Handle(Geom_OffsetCurve)::DownCast (C)->BasisCurve();
        }
       if (C->DynamicType() == STANDARD_TYPE(Geom_BSplineCurve))
        {
-         const Handle(Geom_BSplineCurve)& BC = *((Handle(Geom_BSplineCurve)*)&C);
+         Handle(Geom_BSplineCurve) BC (Handle(Geom_BSplineCurve)::DownCast (C));
          Standard_Integer NbKnots = BC->NbKnots();
          Standard_Integer RealNbKnots = NbKnots;
          if (first > BC->FirstParameter())
@@ -805,280 +1024,46 @@ void BRepFill_Pipe::DefineRealSegmax()
 }
 
 //=======================================================================
-//function : ShareFaces
-//purpose  : 
+//function : RebuildTopOrBottomFace
+//purpose  : Correct orientation of v-iso edges
+//           according to new 3d and 2d curves taken from swept surfaces
 //=======================================================================
 
-TopoDS_Shape BRepFill_Pipe::ShareFaces
-                (const TopoDS_Shape &theShape,
-                 const Standard_Integer theInitialFacesLen,
-                 const Standard_Integer theInitialEdgesLen,
-                 const Standard_Integer theInitialSectionsLen)
+void BRepFill_Pipe::RebuildTopOrBottomFace(const TopoDS_Shape& aFace,
+                                           const Standard_Boolean IsTop) const
 {
-  TopoDS_Shape aResult = theShape;
-  // Check if there are shapes to be shared.
-  TopTools_DataMapOfShapeInteger aMapBndEdgeIndex;
-  TColStd_DataMapOfIntegerInteger aMapNewOldFIndex;
-  TColStd_DataMapOfIntegerInteger aMapNewOldEIndex;
-  TopTools_MapOfShape aMapUsedVtx;
-  TopExp_Explorer anExp;
-  Standard_Integer i;
-  Standard_Integer ii;
-  Standard_Integer jj;
-  BRep_Builder aBuilder;
-
-  // Check the first and last J index of myFaces.
-  for (i = 1; i <= 2; i++) {
-    // Compute jj index of faces.
-    if (i == 1) {
-      jj = 1;
-    } else {
-      jj = myFaces->RowLength();
-
-      if (jj == 1) {
-        break;
-      }
-    }
-
-    // Fill the map of boundary edges on initial faces.
-    for (ii = 1; ii <= theInitialFacesLen; ii++) {
-      anExp.Init(myFaces->Value(ii, jj), TopAbs_EDGE);
-  
-      for (; anExp.More(); anExp.Next()) {
-        aMapBndEdgeIndex.Bind(anExp.Current(), ii);
-      }
-    }
-
-    // Check if edges of newly created faces are shared with old ones.
-    for (ii = theInitialFacesLen + 1; ii <= myFaces->ColLength(); ii++) {
-      anExp.Init(myFaces->Value(ii, jj), TopAbs_EDGE);
-  
-      for (; anExp.More(); anExp.Next()) {
-        if (aMapBndEdgeIndex.IsBound(anExp.Current())) {
-          // This row should be replaced.
-          Standard_Integer anOldIndex = aMapBndEdgeIndex.Find(anExp.Current());
-
-          aMapNewOldFIndex.Bind(ii, anOldIndex);
-
-          // Find corresponding new and old edges indices.
-          TopoDS_Vertex aV[2];
-          TopExp::Vertices(TopoDS::Edge(anExp.Current()), aV[0], aV[1]);
-          Standard_Integer ie;
-
-          // Compute jj index of edges.
-          Standard_Integer je = (i == 1 ? 1 : myEdges->RowLength());
-
-          for (Standard_Integer j = 0; j < 2; j++) {
-            if (aMapUsedVtx.Contains(aV[j])) {
-              // This vertex is treated.
-              continue;
-            }
-  
-            // Find old index.
-            Standard_Integer iEOld = -1;
-            TopoDS_Vertex aVE[2];
-       
-            for (ie = 1; ie <= theInitialEdgesLen; ie++) {
-              const TopoDS_Shape &anEdge = myEdges->Value(ie, je);
-       
-              TopExp::Vertices(TopoDS::Edge(anEdge), aVE[0], aVE[1]);
-       
-              if (aV[j].IsSame(aVE[0]) || aV[j].IsSame(aVE[1])) {
-                iEOld = ie;
-                break;
-              }
-            }
-       
-            if (iEOld > 0) {
-              // Find new index.
-              for (ie = theInitialEdgesLen+1; ie <= myEdges->ColLength(); ie++) {
-                const TopoDS_Shape &anEdge = myEdges->Value(ie, je);
-       
-                TopExp::Vertices(TopoDS::Edge(anEdge), aVE[0], aVE[1]);
-       
-                if (aV[j].IsSame(aVE[0]) || aV[j].IsSame(aVE[1])) {
-                  // This row should be replaced.
-                  aMapNewOldEIndex.Bind(ie, iEOld);
-                  aMapUsedVtx.Add(aV[j]);
-                  break;
-                }
-              }
-            }
-          }
+  Standard_Integer IndexOfSection =
+    (IsTop)? 1 : mySections->RowLength();
 
+  Standard_Integer ii;
+  BRep_Builder BB;
+  TopoDS_Iterator itf(aFace);
+  for (; itf.More(); itf.Next())
+  {
+    TopoDS_Shape aWire = itf.Value();
+    TopTools_SequenceOfShape InitEdges;
+    TopTools_SequenceOfShape ResEdges;
+    TopoDS_Iterator itw(aWire);
+    for (; itw.More(); itw.Next())
+    {
+      TopoDS_Shape anEdge = itw.Value();
+      for (ii = myCurIndexOfSectionEdge; ii <= mySections->ColLength(); ii++)
+      {
+        TopoDS_Shape aVisoEdge = mySections->Value(ii, IndexOfSection);
+        if (anEdge.IsSame(aVisoEdge))
+        {
+          InitEdges.Append(anEdge);
+          ResEdges.Append(aVisoEdge);
           break;
         }
       }
     }
-  }
-
-  if (!aMapNewOldFIndex.IsEmpty()) {
-    TColStd_DataMapIteratorOfDataMapOfIntegerInteger anIter(aMapNewOldFIndex);
-    TopTools_ListOfShape   aListShape;
-    BRepTools_Substitution aSubstitute;
-
-    for (; anIter.More(); anIter.Next()) {
-      const Standard_Integer aNewIndex  = anIter.Key();
-      const Standard_Integer anOldIndex = anIter.Value();
-
-      // Change new faces by old ones.
-      for (jj = 1; jj <= myFaces->RowLength(); jj++) {
-        const TopoDS_Shape &aNewFace  = myFaces->Value(aNewIndex, jj);
-        const TopoDS_Shape &anOldFace = myFaces->Value(anOldIndex, jj);
-
-        if (!aSubstitute.IsCopied(aNewFace)) {
-          aListShape.Append(anOldFace.Oriented(TopAbs_REVERSED));
-          aSubstitute.Substitute(aNewFace, aListShape);
-          aListShape.Clear();
-        }
-      }
-    }
-
-    // Change new edges by old ones.
-    for (anIter.Initialize(aMapNewOldEIndex); anIter.More(); anIter.Next()) {
-      const Standard_Integer aNewIndex  = anIter.Key();
-      const Standard_Integer anOldIndex = anIter.Value();
-
-      for (jj = 1; jj <= myEdges->RowLength(); jj++) {
-        const TopoDS_Shape &aNewEdge  = myEdges->Value(aNewIndex, jj);
-        const TopoDS_Shape &anOldEdge = myEdges->Value(anOldIndex, jj);
-
-        if (!aSubstitute.IsCopied(aNewEdge)) {
-          aListShape.Append(anOldEdge.Oriented(TopAbs_FORWARD));
-          aSubstitute.Substitute(aNewEdge, aListShape);
-          aListShape.Clear();
-
-          // Change new vertices by old ones.
-          TopoDS_Iterator aNewIt(aNewEdge);
-          TopoDS_Iterator anOldIt(anOldEdge);
-
-          for (; aNewIt.More() && anOldIt.More();
-                                  aNewIt.Next(), anOldIt.Next()) {
-            if (!aNewIt.Value().IsSame(anOldIt.Value())) {
-              if (!aSubstitute.IsCopied(aNewIt.Value())) {
-                aListShape.Append(anOldIt.Value().Oriented(TopAbs_FORWARD));
-                aSubstitute.Substitute(aNewIt.Value(), aListShape);
-                aListShape.Clear();
-              }
-            }
-          }
-        }
-      }
-    }
-
-    // Perform substitution.
-    aSubstitute.Build(aResult);
-
-    if (aSubstitute.IsCopied(aResult)) {
-      // Get copied shape.
-      const TopTools_ListOfShape& listSh = aSubstitute.Copy(aResult);
-
-      aResult = listSh.First();
-
-      // Update original faces with copied ones.
-      for (ii = theInitialFacesLen + 1; ii <= myFaces->ColLength(); ii++) {
-        for (jj = 1; jj <= myFaces->RowLength(); jj++) {
-          TopoDS_Shape anOldFace = myFaces->Value(ii, jj); // Copy
-
-          if (aSubstitute.IsCopied(anOldFace)) {
-            const TopTools_ListOfShape& aList = aSubstitute.Copy(anOldFace);
-
-            if(!aList.IsEmpty()) {
-              // Store copied face.
-              const TopoDS_Shape &aCopyFace = aList.First();
-              TopAbs_Orientation anOri = anOldFace.Orientation();
-              const Standard_Boolean isShared = aMapNewOldFIndex.IsBound(ii);
-
-              if (isShared) {
-                // Reverse the orientation for shared face.
-                anOri = TopAbs::Reverse(anOri);
-              }
-
-              myFaces->SetValue(ii, jj, aCopyFace.Oriented(anOri));
-
-              // Check if it is necessary to update PCurves on this face.
-              if (!isShared) {
-                TopoDS_Face anOldF = TopoDS::Face(anOldFace);
-                TopoDS_Face aCopyF = TopoDS::Face(aCopyFace);
-
-                anOldF.Orientation(TopAbs_FORWARD);
-                anExp.Init(anOldF, TopAbs_EDGE);
-
-                for (; anExp.More(); anExp.Next()) {
-                  const TopoDS_Shape &anOldEdge = anExp.Current();
-
-                  if (aSubstitute.IsCopied(anOldEdge)) {
-                    const TopTools_ListOfShape& aListE =
-                      aSubstitute.Copy(anOldEdge);
-
-                    if(!aListE.IsEmpty()) {
-                      // This edge is copied. Check if there is a PCurve
-                      // on the face.
-                      TopoDS_Edge aCopyE = TopoDS::Edge(aListE.First());
-                      Standard_Real aFirst;
-                      Standard_Real aLast;
-                      Handle(Geom2d_Curve) aPCurve = BRep_Tool::CurveOnSurface
-                          (aCopyE, aCopyF, aFirst, aLast);
-
-                      if (aPCurve.IsNull()) {
-                        // There is no pcurve copy it from the old edge.
-                        TopoDS_Edge anOldE = TopoDS::Edge(anOldEdge);
-
-                        aPCurve = BRep_Tool::CurveOnSurface
-                          (anOldE, anOldF, aFirst, aLast);
-
-                        if (aPCurve.IsNull() == Standard_False) {
-                          // Update the shared edge with PCurve from new Face.
-                          Standard_Real aTol = Max(BRep_Tool::Tolerance(anOldE),
-                               BRep_Tool::Tolerance(aCopyE));
-
-                          aBuilder.UpdateEdge(aCopyE, aPCurve, aCopyF, aTol);
-                        }
-                      }
-                    }
-                  }
-                }
-              }
-            }
-          }
-       }
-      }
-
-      // Update new edges with shared ones.
-      for (ii = theInitialEdgesLen + 1; ii <= myEdges->ColLength(); ii++) {
-        for (jj = 1; jj <= myEdges->RowLength(); jj++) {
-          const TopoDS_Shape &aLocalShape = myEdges->Value(ii, jj);
-
-          if (aSubstitute.IsCopied(aLocalShape)) {
-            const TopTools_ListOfShape& aList = aSubstitute.Copy(aLocalShape);
-
-            if(!aList.IsEmpty()) {
-              const TopAbs_Orientation anOri = TopAbs_FORWARD;
-
-              myEdges->SetValue(ii, jj, aList.First().Oriented(anOri));
-            }
-          }
-        }
-      }
-
-      // Update new sections with shared ones.
-      for (ii = theInitialSectionsLen+1; ii <= mySections->ColLength(); ii++) {
-        for (jj = 1; jj <= mySections->RowLength(); jj++) {
-          const TopoDS_Shape &aLocalShape = mySections->Value(ii, jj);
-
-          if (aSubstitute.IsCopied(aLocalShape)) {
-            const TopTools_ListOfShape& aList = aSubstitute.Copy(aLocalShape);
-
-            if(!aList.IsEmpty()) {
-              const TopAbs_Orientation anOri = TopAbs_FORWARD;
-
-              mySections->SetValue(ii, jj, aList.First().Oriented(anOri));
-            }
-          }
-        }
-      }
+    aWire.Free(Standard_True);
+    for (ii = 1; ii <= InitEdges.Length(); ii++)
+    {
+      BB.Remove(aWire, InitEdges(ii));
+      UpdateTolFromTopOrBottomPCurve(TopoDS::Face(aFace), TopoDS::Edge(ResEdges(ii)));
+      BB.Add(aWire, ResEdges(ii));
     }
   }
-
-  return aResult;
 }