0029204: BRepOffsetAPI_MakePipeShell produces invalid result and raises exception...
authorjgv <jgv@opencascade.com>
Wed, 18 Oct 2017 14:35:58 +0000 (17:35 +0300)
committerbugmaster <bugmaster@opencascade.com>
Tue, 14 Nov 2017 12:57:57 +0000 (15:57 +0300)
1.The algorithm searching the section in the corner (ChooseSection) is modified to be able to find simple cases with rather big tolerance.

2. The constructor of BRepFill_Section is modified: now it removes locations in the shape of section like it was done in BRepFill_Pipe.

3. Correction of U-edges by Same Parameter has been added to the method BRepFill_Sweep::Build.

src/BRepFill/BRepFill_Pipe.cxx
src/BRepFill/BRepFill_PipeShell.cxx
src/BRepFill/BRepFill_Section.cxx
src/BRepFill/BRepFill_Section.hxx
src/BRepFill/BRepFill_Section.lxx
src/BRepFill/BRepFill_Sweep.cxx
src/BRepFill/BRepFill_TrimShellCorner.cxx
src/BRepFill/BRepFill_TrimShellCorner.hxx
tests/bugs/modalg_7/bug29204 [new file with mode: 0644]

index c514052..db46764 100644 (file)
@@ -102,40 +102,6 @@ static Standard_Boolean UpdateMap(const TopoDS_Shape&                 theKey,
   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)
 {
@@ -739,9 +705,6 @@ TopoDS_Shape BRepFill_Pipe::MakeShape(const TopoDS_Shape& S,
       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()) {
index 519c6b5..65ff2b2 100644 (file)
@@ -583,28 +583,15 @@ void BRepFill_PipeShell::SetForceApproxC1(const Standard_Boolean ForceApproxC1)
 //=======================================================================
  void BRepFill_PipeShell::DeleteProfile(const TopoDS_Shape&  Profile)
 {
-  Standard_Boolean isVertex = (Profile.ShapeType() == TopAbs_VERTEX);
-
   Standard_Boolean Trouve=Standard_False;
   Standard_Integer ii;
   for (ii=1; ii<=mySeq.Length() && !Trouve; ii++) {
-    Standard_Boolean found = Standard_False;
-    const TopoDS_Wire& aWire = mySeq.Value(ii).Wire();
-    if (isVertex)
-      {
-       TopExp_Explorer Explo(aWire, TopAbs_VERTEX);
-       for (; Explo.More(); Explo.Next())
-         if (Profile.IsSame(Explo.Current()))
-           found = Standard_True;
-      }
-    else if (Profile.IsSame(aWire))
-      found = Standard_True;
-    
-    if (found)
-      {
-       Trouve = Standard_True;
-       mySeq.Remove(ii);
-      }
+    const TopoDS_Shape& aSection = mySeq.Value(ii).OriginalShape();
+    if (Profile.IsSame(aSection))
+    {
+      Trouve = Standard_True;
+      mySeq.Remove(ii);
+    }
   }
 
   if (Trouve) mySection.Nullify();
@@ -914,13 +901,9 @@ const TopoDS_Shape& BRepFill_PipeShell::LastShape() const
 //function : Generated
 //purpose  : 
 //=======================================================================
-//  void BRepFill_PipeShell::Generated(const TopoDS_Shape& ,
-//                                 TopTools_ListOfShape& ) 
 void BRepFill_PipeShell::Generated(const TopoDS_Shape&   theShape,
                                   TopTools_ListOfShape& theList) 
 {
-  //   throw Standard_NotImplemented("Generated:Pas Fait");
-  
   theList.Clear();
 
   if(myGenMap.IsBound(theShape)) {
@@ -1197,9 +1180,6 @@ void BRepFill_PipeShell::Place(const BRepFill_Section& Sec,
                                  Sec.WithCorrection());
   TopoDS_Wire TmpWire =  Sec.Wire();
   aTrsf = Place.Transformation();
-  //TopLoc_Location Loc2(Place.Transformation()), Loc1;
-  //Loc1 = TmpWire.Location();
-  //W.Location(Loc2.Multiplied(Loc1));
   //Transform the copy
   W = TopoDS::Wire(BRepBuilderAPI_Transform(TmpWire, aTrsf, Standard_True));
   ////////////////////////////////////
@@ -1240,37 +1220,40 @@ void BRepFill_PipeShell::BuildHistory(const BRepFill_Sweep& theSweep)
   TopoDS_Iterator itw;
   for (indw = 1; indw <= mySeq.Length(); indw++)
   {
-    const TopoDS_Wire& aSection = mySeq(indw).Wire();
+    const TopoDS_Shape& Section = mySeq(indw).OriginalShape();
+    TopoDS_Wire aSection;
     Standard_Boolean IsPunctual = mySeq(indw).IsPunctual();
     if (IsPunctual)
     {
       //for punctual sections (first or last)
       //we take all the wires generated along the path
-      TopExp_Explorer Explo(aSection, TopAbs_VERTEX);
-      const TopoDS_Shape& VerSection = Explo.Current();
+      
       TopTools_ListOfShape Elist;
       for (Standard_Integer i = 1; i <= anUEdges->UpperRow(); i++)
         for (Standard_Integer j = 1; j <= anUEdges->UpperCol(); j++)
           Elist.Append(anUEdges->Value(i,j));
-      myGenMap.Bind(VerSection, Elist);
+      myGenMap.Bind(Section, Elist);
       continue;
     }
+    else
+      aSection = TopoDS::Wire(Section);
     //Take the real index of section on the path
     Standard_Integer IndOfW = myIndOfSec(indw);
     const TopoDS_Wire& theWire = TopoDS::Wire(WSeq(IndOfW));
     BRepTools_WireExplorer wexp_sec(aSection);
     for (inde = 1; wexp_sec.More(); wexp_sec.Next())
     {
-      const TopoDS_Edge& anEdge = TopoDS::Edge(wexp_sec.Current());
+      const TopoDS_Edge& anOriginalEdge = TopoDS::Edge(wexp_sec.Current());
+      TopoDS_Edge anEdge = TopoDS::Edge(mySeq(indw).ModifiedShape(anOriginalEdge));
       if (BRep_Tool::Degenerated(anEdge))
         continue;
 
       TopoDS_Shell aShell;
       BB.MakeShell(aShell);
       TopoDS_Vertex aVertex [2];
-      TopExp::Vertices(anEdge, aVertex[0], aVertex[1]);
+      TopExp::Vertices(anOriginalEdge, aVertex[0], aVertex[1]);
       Standard_Integer SignOfAnEdge =
-        (anEdge.Orientation() == TopAbs_FORWARD)? 1 : -1;
+        (anOriginalEdge.Orientation() == TopAbs_FORWARD)? 1 : -1;
       
       //For each non-degenerated inde-th edge of <aSection>
       //we find inde-th edge in <theWire>
@@ -1422,7 +1405,7 @@ void BRepFill_PipeShell::BuildHistory(const BRepFill_Sweep& theSweep)
       
       TopTools_ListOfShape ListShell;
       ListShell.Append(aShell);
-      myGenMap.Bind(anEdge, ListShell);
+      myGenMap.Bind(anOriginalEdge, ListShell);
       ////////////////////////
 
       inde++;
index b65b5f8..09e5d6f 100644 (file)
@@ -22,6 +22,9 @@
 #include <TopoDS_Shape.hxx>
 #include <TopoDS_Vertex.hxx>
 #include <TopoDS_Wire.hxx>
+#include <TopoDS_Iterator.hxx>
+#include <TopExp_Explorer.hxx>
+#include <ShapeUpgrade_RemoveLocations.hxx>
 
 BRepFill_Section::BRepFill_Section() :islaw(0),
                                       ispunctual(0),
@@ -41,12 +44,19 @@ BRepFill_Section::BRepFill_Section(const TopoDS_Shape& Profile,
                                     contact(WithContact),
                                    correction(WithCorrection)
 {
-  if (Profile.ShapeType() == TopAbs_WIRE)
-    wire = TopoDS::Wire(Profile);
-  else if (Profile.ShapeType() == TopAbs_VERTEX)
+  myOriginalShape = Profile;
+  
+  ShapeUpgrade_RemoveLocations RemLoc;
+  RemLoc.SetRemoveLevel(TopAbs_COMPOUND);
+  RemLoc.Remove(Profile);
+  TopoDS_Shape aProfile = RemLoc.GetResult();
+  
+  if (aProfile.ShapeType() == TopAbs_WIRE)
+    wire = TopoDS::Wire(aProfile);
+  else if (aProfile.ShapeType() == TopAbs_VERTEX)
     {
       ispunctual = Standard_True;
-      TopoDS_Vertex aVertex = TopoDS::Vertex(Profile);
+      TopoDS_Vertex aVertex = TopoDS::Vertex(aProfile);
       BRep_Builder BB;
       
       TopoDS_Edge DegEdge;
@@ -67,3 +77,58 @@ void BRepFill_Section::Set(const Standard_Boolean IsLaw)
 {
   islaw = IsLaw;
 }
+
+TopoDS_Shape BRepFill_Section::ModifiedShape(const TopoDS_Shape& theShape) const
+{
+  TopoDS_Shape aModifiedShape;
+  
+  switch (theShape.ShapeType())
+  {
+  case TopAbs_WIRE:
+    if (theShape.IsSame(myOriginalShape))
+      aModifiedShape = wire;
+    break;
+  case TopAbs_EDGE:
+    {
+      TopoDS_Iterator itor(myOriginalShape);
+      TopoDS_Iterator itw(wire);
+      for (; itor.More(); itor.Next(),itw.Next())
+      {
+        const TopoDS_Shape& anOriginalEdge = itor.Value();
+        const TopoDS_Shape& anEdge         = itw.Value();
+        if (anOriginalEdge.IsSame(theShape))
+        {
+          aModifiedShape = anEdge;
+          break;
+        }
+      }
+    }
+    break;
+  case TopAbs_VERTEX:
+    if (theShape.IsSame(myOriginalShape))
+    {
+      TopExp_Explorer Explo(wire, TopAbs_VERTEX);
+      aModifiedShape = Explo.Current();
+    }
+    else
+    {
+      TopExp_Explorer ExpOrig(myOriginalShape, TopAbs_VERTEX);
+      TopExp_Explorer ExpWire(wire, TopAbs_VERTEX);
+      for (; ExpOrig.More(); ExpOrig.Next(),ExpWire.Next())
+      {
+        const TopoDS_Shape& anOriginalVertex = ExpOrig.Current();
+        const TopoDS_Shape& aVertex          = ExpWire.Current();
+        if (anOriginalVertex.IsSame(theShape))
+        {
+          aModifiedShape = aVertex;
+          break;
+        }
+      }
+    }
+    break;
+  default:
+    break;
+  }
+
+  return aModifiedShape;
+}
index ede9091..10acf1d 100644 (file)
@@ -43,10 +43,14 @@ public:
   
   Standard_EXPORT void Set (const Standard_Boolean IsLaw);
   
+    const TopoDS_Shape& OriginalShape() const;
+  
     const TopoDS_Wire& Wire() const;
   
     const TopoDS_Vertex& Vertex() const;
   
+  Standard_EXPORT TopoDS_Shape ModifiedShape(const TopoDS_Shape& theShape) const;
+  
     Standard_Boolean IsLaw() const;
   
     Standard_Boolean IsPunctual() const;
@@ -68,6 +72,7 @@ private:
 
 
 
+  TopoDS_Shape myOriginalShape;
   TopoDS_Wire wire;
   TopoDS_Vertex vertex;
   Standard_Boolean islaw;
index 5b80bc9..c96eaec 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
+inline const TopoDS_Shape& BRepFill_Section::OriginalShape() const
+{
+  return myOriginalShape; 
+}
+
 inline const TopoDS_Wire& BRepFill_Section::Wire() const
 {
   return wire; 
index 9e35334..8b628e1 100644 (file)
@@ -366,6 +366,56 @@ static Standard_Boolean SameParameter(TopoDS_Edge&    E,
   return Standard_True;
 }
 
+static void CorrectSameParameter(TopoDS_Edge&       theEdge,
+                                 const TopoDS_Face& theFace1,
+                                 const TopoDS_Face& theFace2)
+{
+  if (BRep_Tool::Degenerated(theEdge))
+    return;
+  
+  Standard_Real fpar, lpar;
+  Handle(Geom_Curve) aCurve = BRep_Tool::Curve(theEdge, fpar, lpar);
+
+  Standard_Boolean PCurveExists [2] = {Standard_False, Standard_False};
+  BRepAdaptor_Curve BAcurve [2];
+  
+  if (!theFace1.IsNull())
+  {
+    PCurveExists[0] = Standard_True;
+    BAcurve[0].Initialize(theEdge, theFace1);
+  }
+  if (!theFace1.IsNull() &&
+      theFace1.IsSame(theFace2))
+    theEdge.Reverse();
+  if (!theFace2.IsNull())
+  {
+    PCurveExists[1] = Standard_True;
+    BAcurve[1].Initialize(theEdge, theFace2);
+  }
+
+  Standard_Real MaxSqDist = 0.;
+  const Standard_Integer NCONTROL = 23;
+  Standard_Real delta = (lpar - fpar)/NCONTROL;
+
+  for (Standard_Integer i = 0; i <= NCONTROL; i++)
+  {
+    Standard_Real aParam = fpar + i*delta;
+    gp_Pnt aPnt = aCurve->Value(aParam);
+    for (Standard_Integer j = 0; j < 2; j++)
+      if (PCurveExists[j])
+      {
+        gp_Pnt aPntFromFace = BAcurve[j].Value(aParam);
+        Standard_Real aSqDist = aPnt.SquareDistance(aPntFromFace);
+        if (aSqDist > MaxSqDist)
+          MaxSqDist = aSqDist;
+      }
+  }
+
+  Standard_Real aTol = sqrt(MaxSqDist);
+  BRep_Builder BB;
+  BB.UpdateEdge(theEdge, aTol);
+}
+
 //=======================================================================
 //Objet : Orientate an edge of natural restriction 
 //      : General
@@ -1661,6 +1711,60 @@ static Standard_Boolean IsDegen(const Handle(Geom_Surface)& S,
   return B;
 }
 
+static void ReverseEdgeInFirstOrLastWire(TopoDS_Shape&       theWire,
+                                         const TopoDS_Shape& theEdge)
+{
+  TopoDS_Shape EdgeToReverse;
+  TopoDS_Iterator itw(theWire);
+
+  for (; itw.More(); itw.Next())
+  {
+    const TopoDS_Shape& anEdge = itw.Value();
+    if (anEdge.IsSame(theEdge))
+    {
+      EdgeToReverse = anEdge;
+      break;
+    }
+  }
+
+  if (!EdgeToReverse.IsNull())
+  {
+    BRep_Builder BB;
+    theWire.Free(Standard_True);
+    BB.Remove(theWire, EdgeToReverse);
+    EdgeToReverse.Reverse();
+    BB.Add(theWire, EdgeToReverse);
+  }
+}
+
+static void ReverseModifiedEdges(TopoDS_Wire&               theWire,
+                                 const TopTools_MapOfShape& theEmap)
+{
+  if (theEmap.IsEmpty())
+    return;
+  
+  TopoDS_Iterator itw(theWire);
+  BRep_Builder BB;
+  
+  TopTools_ListOfShape Ledges;
+  for (; itw.More(); itw.Next())
+    Ledges.Append(itw.Value());
+  
+  theWire.Free(Standard_True);
+  TopTools_ListIteratorOfListOfShape itl(Ledges);
+  for (; itl.More(); itl.Next())
+    BB.Remove(theWire, itl.Value());
+        
+  for (itl.Initialize(Ledges); itl.More(); itl.Next())
+  {
+    TopoDS_Shape anEdge = itl.Value();
+    if (theEmap.Contains(anEdge))
+      anEdge.Reverse();
+    BB.Add(theWire, anEdge);
+  }
+}
+
+
 //=======================================================================
 //function : Constructeur
 //purpose  : 
@@ -2064,6 +2168,10 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section,
   Standard_Boolean exuv, singu, singv;
   Handle(Geom_Surface) S;
 
+  //Correct <FirstShape> and <LastShape>: reverse modified edges
+  ReverseModifiedEdges(FirstShape, ReversedEdges);
+  ReverseModifiedEdges(LastShape,  ReversedEdges);
+
   // (2.0) return preexisting Edges and vertices
   TopoDS_Edge E;
   TColStd_Array1OfBoolean IsBuilt(1, NbLaw);
@@ -2293,7 +2401,6 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section,
 
  
   // ---------- Creation of Vertex and edge ------------
-  ReversedEdges.Clear();
   for (ipath=1, IPath=IFirst; ipath<=NbPath; 
        ipath++, IPath++) {
     for (isec=1; isec <=NbLaw; isec++) {
@@ -2496,7 +2603,10 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section,
                                    TopoDS::Edge(VEdge(isec, ipath)),
                                    ReversedEdges);
             if (ReversedEdges.Contains(VEdge(isec, ipath)))
+            {
+              ReverseEdgeInFirstOrLastWire(FirstShape, VEdge(isec, ipath));
               StartEdges(isec).Reverse();
+            }
           }
         }
        
@@ -2536,6 +2646,8 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section,
             RebuildTopOrBottomEdge(aNewLastEdge,
                                    TopoDS::Edge(VEdge(isec, ipath+1)),
                                    ReversedEdges);
+            if (ReversedEdges.Contains(VEdge(isec, ipath+1)))
+              ReverseEdgeInFirstOrLastWire(LastShape, VEdge(isec, ipath+1));
           }
         }
       }
@@ -2877,6 +2989,30 @@ void BRepFill_Sweep::Build(TopTools_MapOfShape& ReversedEdges,
       }
     }
 
+    //Ensure Same Parameter on U-edges
+    for (ii = myUEdges->LowerRow(); ii <= myUEdges->UpperRow(); ii++)
+    {
+      if (mySec->IsUClosed() && ii == myUEdges->UpperRow())
+        continue;
+      for (jj = myUEdges->LowerCol(); jj <= myUEdges->UpperCol(); jj++)
+      {
+       TopoDS_Edge anEdge = TopoDS::Edge(myUEdges->Value(ii, jj));
+        if (anEdge.IsNull())
+          continue;
+        TopoDS_Face Face1, Face2;
+        Standard_Integer i1 = ii-1, i2 = ii;
+        if (i1 == 0 && mySec->IsUClosed())
+          i1 = myFaces->UpperRow();
+        if (i2 > myFaces->UpperRow())
+          i2 = 0;
+        if (i1 != 0)
+          Face1 = TopoDS::Face(myFaces->Value(i1, jj));
+        if (i2 != 0)
+          Face2 = TopoDS::Face(myFaces->Value(i2, jj));
+        CorrectSameParameter(anEdge, Face1, Face2);
+      }
+    }
+
     for (ii = 1; ii <= NbLaw; ii++)
       for (jj = 1; jj <= NbPath; jj++)
       {
@@ -3083,7 +3219,7 @@ TopoDS_Shape BRepFill_Sweep::Tape(const Standard_Integer Index) const
     }
   }
 
-  BRepFill_TrimShellCorner aTrim(aFaces, AxeOfBisPlane, aPlaneF);
+  BRepFill_TrimShellCorner aTrim(aFaces, Transition, AxeOfBisPlane);
   aTrim.AddBounds(Bounds);
   aTrim.AddUEdges(aUEdges);
   aTrim.Perform();
index 9d3e925..0083bf8 100644 (file)
@@ -25,6 +25,7 @@
 #include <BRepFill_TrimShellCorner.hxx>
 #include <BRepLib_MakeEdge.hxx>
 #include <BRepLib_MakeWire.hxx>
+#include <BRepLib_MakeVertex.hxx>
 #include <BRepTools_ReShape.hxx>
 #include <gce_MakeLin.hxx>
 #include <GCPnts_UniformAbscissa.hxx>
 #include <TopTools_ListOfShape.hxx>
 #include <TopTools_MapOfShape.hxx>
 #include <TopTools_SequenceOfShape.hxx>
+#include <BRepExtrema_ExtCC.hxx>
+
+static TopoDS_Edge FindEdgeCloseToBisectorPlane(const TopoDS_Vertex& theVertex,
+                                                TopoDS_Compound&     theComp,
+                                                const gp_Ax1&        theAxis);
+
+static Standard_Boolean FindMiddleEdges(const TopoDS_Vertex&  theVertex1,
+                                        const TopoDS_Vertex&  theVertex2,
+                                        const gp_Ax1&         theAxis,
+                                        TopoDS_Compound&      theComp,
+                                        TopTools_ListOfShape& theElist);
+
+static Standard_Boolean FindCommonVertex(const TopoDS_Edge&   theFirstEdge,
+                                         const TopoDS_Edge&   theLastEdge,
+                                         const TopoDS_Vertex& theFirstVertex,
+                                         const TopoDS_Vertex& theLastVertex,
+                                         TopoDS_Vertex&       theCommonVertex);
 
 static Standard_Boolean FindCommonVertex(const BOPDS_PDS&         theDS,
                                          const Standard_Integer   theEIndex1,
@@ -71,24 +89,6 @@ static Standard_Boolean FindCommonVertex(const BOPDS_PDS&         theDS,
                                          Standard_Real&           theParamOnE1,
                                          Standard_Real&           theParamOnE2);
 
-static Standard_Boolean MakeFacesNonSec(const Standard_Integer                     theIndex,
-                                        const Handle(TopTools_HArray2OfShape)&     theUEdges, 
-                                        const Handle(TopTools_HArray2OfShape)&     theBounds, 
-                                        const BOPDS_PDS&                           theDS,
-                                        const Standard_Integer                     theFaceIndex1, 
-                                        const Standard_Integer                     theFaceIndex2, 
-                                        TopTools_DataMapOfShapeListOfShape&        theHistMap);
-
-static Standard_Boolean MakeFacesSec(const Standard_Integer                     theIndex,
-                                     const Handle(TopTools_HArray2OfShape)&     theUEdges, 
-                                     const Handle(TopTools_HArray2OfShape)&     theBounds, 
-                                     const BOPDS_PDS&                           theDS,
-                                     const Standard_Integer                     theFaceIndex1, 
-                                     const Standard_Integer                     theFaceIndex2, 
-                                     const Standard_Integer                     theSSInterfIndex,
-                                     const gp_Ax2&                              AxeOfBisPlane,
-                                     TopTools_DataMapOfShapeListOfShape&        theHistMap);
-
 static Standard_Boolean SplitUEdges(const Handle(TopTools_HArray2OfShape)&     theUEdges, 
                                     const BOPDS_PDS&                           theDS,
                                     TopTools_DataMapOfShapeListOfShape&        theHistMap);
@@ -186,55 +186,27 @@ static Standard_Real ComputeAveragePlaneAndMaxDeviation(const TopoDS_Shape& aWir
                                                         gp_Pln& thePlane,
                                                         Standard_Boolean& IsSingular);
 
-static Standard_Boolean ChooseSection(const TopoDS_Shape& Comp,
-                                      const gp_Ax2& bis,
-                                      TopoDS_Shape& resWire,
-                                      gp_Pln& resPlane,
-                                      Standard_Boolean& IsSingular);
-
-// ===========================================================================================
-// function: Constructor
-// purpose:
-// ===========================================================================================
-BRepFill_TrimShellCorner::BRepFill_TrimShellCorner(const Handle(TopTools_HArray2OfShape)& theFaces,
-                                                   const gp_Ax2&                          theAxeOfBisPlane,
-                                                   const TopoDS_Face&                     theSecPlane) :
-myAxeOfBisPlane(theAxeOfBisPlane),
-myDone(Standard_False),
-myHasSection(Standard_False)
-{
-  myFaces = new TopTools_HArray2OfShape(theFaces->LowerRow(), theFaces->UpperRow(), 
-                                        theFaces->LowerCol(), theFaces->UpperCol());
-  myFaces->ChangeArray2() = theFaces->Array2();
-  mySecPln = theSecPlane;
-}
+static void UpdateSectionEdge(TopoDS_Edge&         theEdge,
+                              const TopoDS_Vertex& theConstVertex,
+                              TopoDS_Vertex&       theVertex,
+                              const Standard_Real  theParam);
 
+  
 // ===========================================================================================
 // function: Constructor
 // purpose:
 // ===========================================================================================
 BRepFill_TrimShellCorner::BRepFill_TrimShellCorner(const Handle(TopTools_HArray2OfShape)& theFaces,
-                                                   const gp_Ax2&                          theAxeOfBisPlane,
-                                                   const TopoDS_Wire&                     theSpine,
-                                                   const TopoDS_Face&                     theSecPlane):
-myAxeOfBisPlane(theAxeOfBisPlane),
-myDone(Standard_False),
-myHasSection(Standard_False)
+                                                   const BRepFill_TransitionStyle         theTransition,
+                                                   const gp_Ax2&                          theAxeOfBisPlane) :
+  myTransition(theTransition),
+  myAxeOfBisPlane(theAxeOfBisPlane),
+  myDone(Standard_False),
+  myHasSection(Standard_False)
 {
   myFaces = new TopTools_HArray2OfShape(theFaces->LowerRow(), theFaces->UpperRow(), 
                                         theFaces->LowerCol(), theFaces->UpperCol());
   myFaces->ChangeArray2() = theFaces->Array2();
-  mySpine = theSpine;
-  mySecPln = theSecPlane;
-}
-
-// ===========================================================================================
-// function: SetSpine
-// purpose:
-// ===========================================================================================
-void BRepFill_TrimShellCorner::SetSpine(const TopoDS_Wire& theSpine) 
-{
-  mySpine = theSpine;
 }
 
 // ===========================================================================================
@@ -351,14 +323,13 @@ void BRepFill_TrimShellCorner::Perform()
         }
 
         if(!bhassec) {
-          if(!MakeFacesNonSec(ii, myUEdges, myBounds, theDS, anIndex1, anIndex2, myHistMap)) {
+          if(!MakeFacesNonSec(ii, theDS, anIndex1, anIndex2)) {
             myHistMap.Clear();
             return;
           }
         }
         else {
-          if(!MakeFacesSec(ii, myUEdges, myBounds, theDS, anIndex1, anIndex2, 
-                           i, myAxeOfBisPlane, myHistMap)) {
+          if(!MakeFacesSec(ii, theDS, anIndex1, anIndex2, i)) {
             myHistMap.Clear();
             return;
           }
@@ -403,23 +374,21 @@ void BRepFill_TrimShellCorner::Modified(const TopoDS_Shape&   theShape,
 }
 
 // ----------------------------------------------------------------------------------------------------
-// static function: MakeFacesNonSec
-// purpose:
+// function: MakeFacesNonSec
+// purpose:         Updates <myHistMap> by new faces in the case when old faces do not intersect
 // ----------------------------------------------------------------------------------------------------
-Standard_Boolean MakeFacesNonSec(const Standard_Integer                     theIndex,
-                                 const Handle(TopTools_HArray2OfShape)&     theUEdges, 
-                                 const Handle(TopTools_HArray2OfShape)&     theBounds, 
-                                 const BOPDS_PDS&                           theDS,
-                                 const Standard_Integer                     theFaceIndex1, 
-                                 const Standard_Integer                     theFaceIndex2, 
-                                 TopTools_DataMapOfShapeListOfShape&        theHistMap)
+Standard_Boolean
+BRepFill_TrimShellCorner::MakeFacesNonSec(const Standard_Integer                     theIndex,
+                                          const BOPDS_PDS&                           theDS,
+                                          const Standard_Integer                     theFaceIndex1, 
+                                          const Standard_Integer                     theFaceIndex2)
 {
   Standard_Boolean bHasNewEdge = Standard_False;
   TopoDS_Edge aNewEdge;
 
   BRep_Builder aBB;
-  const TopoDS_Shape& aE1 = theBounds->Value(theIndex, 1);
-  const TopoDS_Shape& aE2 = theBounds->Value(theIndex, 2);
+  const TopoDS_Shape& aE1 = myBounds->Value(theIndex, 1);
+  const TopoDS_Shape& aE2 = myBounds->Value(theIndex, 2);
 
   // search common vertex between bounds. begin
   TopoDS_Vertex aCommonVertex;
@@ -439,20 +408,20 @@ Standard_Boolean MakeFacesNonSec(const Standard_Integer                     theI
   Standard_Integer ueit = 0, eindex = 0;
 
   for(ueit = 1, eindex = theIndex; ueit <= 2; ueit++, eindex++) {
-    const TopoDS_Shape& aShape1 = theUEdges->Value(eindex, theUEdges->LowerCol());
-    const TopoDS_Shape& aShape2 = theUEdges->Value(eindex, theUEdges->UpperCol());
+    const TopoDS_Shape& aShape1 = myUEdges->Value(eindex, myUEdges->LowerCol());
+    const TopoDS_Shape& aShape2 = myUEdges->Value(eindex, myUEdges->UpperCol());
     TopoDS_Edge aUE1 = TopoDS::Edge(aShape1);
     TopoDS_Edge aUE2 = TopoDS::Edge(aShape2);
 
-    if(theHistMap.IsBound(aShape1)) {
-      const TopTools_ListOfShape& lst = theHistMap.Find(aShape1);
+    if (myHistMap.IsBound(aShape1)) {
+      const TopTools_ListOfShape& lst = myHistMap.Find(aShape1);
 
       if(!lst.IsEmpty())
         aUE1 = TopoDS::Edge(lst.First());
     }
 
-    if(theHistMap.IsBound(aShape2)) {
-      const TopTools_ListOfShape& lst = theHistMap.Find(aShape2);
+    if (myHistMap.IsBound(aShape2)) {
+      const TopTools_ListOfShape& lst = myHistMap.Find(aShape2);
 
       if(!lst.IsEmpty())
         aUE2 = TopoDS::Edge(lst.First());
@@ -499,11 +468,11 @@ Standard_Boolean MakeFacesNonSec(const Standard_Integer                     theI
     aBB.MakeCompound(aComp);
 
     for(ueit = 1, eindex = theIndex; ueit <= 2; ueit++, eindex++) {
-      const TopoDS_Shape& aShape = theUEdges->Value(eindex, theUEdges->LowerCol() + fit - 1);
+      const TopoDS_Shape& aShape = myUEdges->Value(eindex, myUEdges->LowerCol() + fit - 1);
       TopoDS_Shape aUE = aShape;
 
-      if(theHistMap.IsBound(aShape)) {
-        const TopTools_ListOfShape& lst = theHistMap.Find(aShape);
+      if(myHistMap.IsBound(aShape)) {
+        const TopTools_ListOfShape& lst = myHistMap.Find(aShape);
 
         if(!lst.IsEmpty())
           aUE = TopoDS::Edge(lst.First());
@@ -638,7 +607,7 @@ Standard_Boolean MakeFacesNonSec(const Standard_Integer                     theI
     aNewFace.Orientation(aFaceOri);
     TopTools_ListOfShape atmpList;
     atmpList.Append(aNewFace);
-    theHistMap.Bind(aFace, atmpList);
+    myHistMap.Bind(aFace, atmpList);
 
     anExpE.Init(aFace, TopAbs_EDGE);
 
@@ -648,7 +617,7 @@ Standard_Boolean MakeFacesNonSec(const Standard_Integer                     theI
       if(aNewValue.IsNull() || aNewValue.IsSame(anExpE.Current()))
         continue;
 
-      if(theHistMap.IsBound(anExpE.Current()))
+      if (myHistMap.IsBound(anExpE.Current()))
         continue;
       TopTools_ListOfShape aListOfNewEdge;
       TopExp_Explorer anExpE2(aNewValue, TopAbs_EDGE);
@@ -656,7 +625,7 @@ Standard_Boolean MakeFacesNonSec(const Standard_Integer                     theI
       for(; anExpE2.More(); anExpE2.Next()) {
         aListOfNewEdge.Append(anExpE2.Current());
       }
-      theHistMap.Bind(anExpE.Current(), aListOfNewEdge);
+      myHistMap.Bind(anExpE.Current(), aListOfNewEdge);
     }
   }
 
@@ -664,18 +633,15 @@ Standard_Boolean MakeFacesNonSec(const Standard_Integer                     theI
 }
 
 // ----------------------------------------------------------------------------------------------------
-// static function: MakeFacesSec
-// purpose:
+// function: MakeFacesSec
+// purpose:  Updates <myHistMap> by new faces in the case when old faces intersect each other
 // ----------------------------------------------------------------------------------------------------
-Standard_Boolean MakeFacesSec(const Standard_Integer                     theIndex,
-                              const Handle(TopTools_HArray2OfShape)&     theUEdges, 
-                              const Handle(TopTools_HArray2OfShape)&     theBounds, 
-                              const BOPDS_PDS&                           theDS,
-                              const Standard_Integer                     theFaceIndex1, 
-                              const Standard_Integer                     theFaceIndex2, 
-                              const Standard_Integer                     theSSInterfIndex,
-                              const gp_Ax2&                              AxeOfBisPlane,
-                              TopTools_DataMapOfShapeListOfShape&        theHistMap)
+Standard_Boolean
+BRepFill_TrimShellCorner::MakeFacesSec(const Standard_Integer                     theIndex,
+                                       const BOPDS_PDS&                           theDS,
+                                       const Standard_Integer                     theFaceIndex1, 
+                                       const Standard_Integer                     theFaceIndex2, 
+                                       const Standard_Integer                     theSSInterfIndex)
 {
   const BOPDS_VectorOfInterfFF& aFFs = theDS->InterfFF();
   const BOPDS_InterfFF& aFFi = aFFs(theSSInterfIndex);
@@ -687,10 +653,30 @@ Standard_Boolean MakeFacesSec(const Standard_Integer                     theInde
   if(!FilterSectionEdges(aBCurves, aSecPlane, theDS, aSecEdges))
     return Standard_False;
 
+  //Extract vertices on the intersection of correspondent U-edges
+  const TopoDS_Shape& LeftE1  = myUEdges->Value(theIndex, 1);
+  const TopoDS_Shape& LeftE2  = myUEdges->Value(theIndex, 2);
+  const TopoDS_Shape& RightE1 = myUEdges->Value(theIndex+1, 1);
+  const TopoDS_Shape& RightE2 = myUEdges->Value(theIndex+1, 2);
+
+  Standard_Integer IndexOfLeftE1  = theDS->Index(LeftE1);
+  Standard_Integer IndexOfLeftE2  = theDS->Index(LeftE2);
+  Standard_Integer IndexOfRightE1 = theDS->Index(RightE1);
+  Standard_Integer IndexOfRightE2 = theDS->Index(RightE2);
+
+  TopoDS_Vertex FirstVertex, LastVertex;
+  Standard_Real ParamOnLeftE1, ParamOnLeftE2, ParamOnRightE1, ParamOnRightE2;
+  FindCommonVertex(theDS, IndexOfLeftE1, IndexOfLeftE2,
+                   FirstVertex, ParamOnLeftE1, ParamOnLeftE2);
+  FindCommonVertex(theDS, IndexOfRightE1, IndexOfRightE2,
+                   LastVertex, ParamOnRightE1, ParamOnRightE2);
+
   TopoDS_Shape SecWire;
   gp_Pln SecPlane;
   Standard_Boolean IsSingular;
-  Standard_Boolean WireFound = ChooseSection( aSecEdges, AxeOfBisPlane, SecWire, SecPlane, IsSingular );
+  Standard_Boolean WireFound = ChooseSection(aSecEdges,
+                                             FirstVertex, LastVertex,
+                                             SecWire, SecPlane, IsSingular );
 
   if(WireFound) {
     //aSecEdges = SecWire;
@@ -715,19 +701,19 @@ Standard_Boolean MakeFacesSec(const Standard_Integer                     theInde
     TopAbs_Orientation aFaceOri = aFace.Orientation();
     TopoDS_Face aFaceF = aFace;
     aFaceF.Orientation(TopAbs_FORWARD);
-    TopoDS_Edge aBoundEdge = TopoDS::Edge(theBounds->Value(theIndex, theBounds->LowerCol() +fit));
+    TopoDS_Edge aBoundEdge = TopoDS::Edge(myBounds->Value(theIndex, myBounds->LowerCol() +fit));
     Standard_Integer aBoundEdgeIndex = theDS->Index(aBoundEdge);
     TopoDS_Edge aUE1;
     TopoDS_Edge aUE2;
 
-    if(!GetUEdges(theIndex, fit, theUEdges, aBoundEdge, aFaceF, aUE1, aUE2))
+    if(!GetUEdges(theIndex, fit, myUEdges, aBoundEdge, aFaceF, aUE1, aUE2))
       return Standard_False;
 
     TopoDS_Edge aUE1old = aUE1;
     TopoDS_Edge aUE2old = aUE2;
 
-    if(theHistMap.IsBound(aUE1)) {
-      const TopTools_ListOfShape& lst = theHistMap.Find(aUE1);
+    if (myHistMap.IsBound(aUE1)) {
+      const TopTools_ListOfShape& lst = myHistMap.Find(aUE1);
 
       if(!lst.IsEmpty()) {
         const TopoDS_Shape& anEdge = lst.First().Oriented(aUE1.Orientation());
@@ -738,8 +724,8 @@ Standard_Boolean MakeFacesSec(const Standard_Integer                     theInde
       }
     }
 
-    if(theHistMap.IsBound(aUE2)) {
-      const TopTools_ListOfShape& lst = theHistMap.Find(aUE2);
+    if (myHistMap.IsBound(aUE2)) {
+      const TopTools_ListOfShape& lst = myHistMap.Find(aUE2);
 
       if(!lst.IsEmpty()) {
         const TopoDS_Shape& anEdge = lst.First().Oriented(aUE2.Orientation());
@@ -757,12 +743,12 @@ Standard_Boolean MakeFacesSec(const Standard_Integer                     theInde
     Standard_Boolean isPave1OnUEdge = Standard_True;
 
     if(FindFromUEdge(aUE1old, aUE2old, aUE1, aUE2, aFace, aSecEdges, fit, aBoundEdge, aBoundEdgeIndex, 
-                     theDS, theHistMap, aCompOfSecEdges, aListOfWireEdges, aPave1, isPave1OnUEdge)) {
+                     theDS, myHistMap, aCompOfSecEdges, aListOfWireEdges, aPave1, isPave1OnUEdge)) {
       TopTools_ListOfShape aSecondListOfEdges;
       Standard_Boolean bisSectionFound = Standard_False;
 
       if(!FindFromVEdge(aPave1, isPave1OnUEdge, aUE1old, aUE2old, aFace, aCompOfSecEdges, fit, aBoundEdge, 
-                        aBoundEdgeIndex, theDS, theHistMap, aSecondListOfEdges, bisSectionFound)) {
+                        aBoundEdgeIndex, theDS, myHistMap, aSecondListOfEdges, bisSectionFound)) {
         return Standard_False;
       }
 
@@ -792,7 +778,7 @@ Standard_Boolean MakeFacesSec(const Standard_Integer                     theInde
     aNewFace.Orientation(aFaceOri);
     TopTools_ListOfShape atmpList;
     atmpList.Append(aNewFace);
-    theHistMap.Bind(aFace, atmpList);
+    myHistMap.Bind(aFace, atmpList);
 
     TopExp_Explorer anExpE(aFace, TopAbs_EDGE);
 
@@ -802,7 +788,7 @@ Standard_Boolean MakeFacesSec(const Standard_Integer                     theInde
       if(aNewValue.IsNull() || aNewValue.IsSame(anExpE.Current()))
         continue;
 
-      if(theHistMap.IsBound(anExpE.Current()))
+      if (myHistMap.IsBound(anExpE.Current()))
         continue;
       TopTools_ListOfShape aListOfNewEdge;
       TopExp_Explorer anExpE2(aNewValue, TopAbs_EDGE);
@@ -810,12 +796,240 @@ Standard_Boolean MakeFacesSec(const Standard_Integer                     theInde
       for(; anExpE2.More(); anExpE2.Next()) {
         aListOfNewEdge.Append(anExpE2.Current());
       }
-      theHistMap.Bind(anExpE.Current(), aListOfNewEdge);
+      myHistMap.Bind(anExpE.Current(), aListOfNewEdge);
     }
   }
   return Standard_True;
 }
 
+//=======================================================================
+//function : ChooseSection
+//purpose  : 
+//=======================================================================
+Standard_Boolean BRepFill_TrimShellCorner::ChooseSection(const TopoDS_Shape& Comp,
+                                                         const TopoDS_Vertex& theFirstVertex,
+                                                         const TopoDS_Vertex& theLastVertex,
+                                                         TopoDS_Shape& resWire,
+                                                         gp_Pln& resPlane,
+                                                         Standard_Boolean& IsSingular)
+{
+  IsSingular = Standard_False;
+
+  Standard_Integer ind, i, j;
+  BRep_Builder BB;
+
+  if (myTransition == BRepFill_Right &&
+      !theFirstVertex.IsNull() &&
+      !theLastVertex.IsNull()) //the case where section wire goes from
+    //its known first vertex to its known last vertex
+  {
+    TopoDS_Wire NewWire;
+    BB.MakeWire(NewWire);
+    
+    TopoDS_Compound OldComp;
+    BB.MakeCompound( OldComp );
+    TopoDS_Iterator iter( Comp );
+    for (; iter.More(); iter.Next())
+      BB.Add( OldComp, iter.Value() );
+
+    TopoDS_Edge FirstEdge = FindEdgeCloseToBisectorPlane(theFirstVertex,
+                                                          OldComp,
+                                                          myAxeOfBisPlane.Axis());
+    iter.Initialize(OldComp);
+    if (!iter.More())
+    {
+      iter.Initialize(Comp);
+      BB.Add( OldComp, iter.Value() );
+    }
+    TopoDS_Edge LastEdge  = FindEdgeCloseToBisectorPlane(theLastVertex,
+                                                          OldComp,
+                                                          myAxeOfBisPlane.Axis());
+    
+    BB.Add(NewWire, FirstEdge);
+
+    if (!FirstEdge.IsSame(LastEdge))
+    {
+      TopoDS_Vertex aCommonVertex;
+      Standard_Boolean CommonVertexExists = FindCommonVertex(FirstEdge, LastEdge,
+                                                             theFirstVertex, theLastVertex,
+                                                             aCommonVertex);
+      if (CommonVertexExists)
+        BB.Add(NewWire, LastEdge);
+      else
+      {
+        TopoDS_Vertex Vertex1, Vertex2, V1, V2;
+        TopExp::Vertices(FirstEdge, V1, V2);
+        Vertex1 = (theFirstVertex.IsSame(V1))? V2 : V1;
+        TopExp::Vertices(LastEdge, V1, V2);
+        Vertex2 = (theLastVertex.IsSame(V1))? V2 : V1;
+        
+        TopTools_ListOfShape MiddleEdges;
+        if (FindMiddleEdges(Vertex1, Vertex2, myAxeOfBisPlane.Axis(), OldComp, MiddleEdges))
+        {
+          TopTools_ListIteratorOfListOfShape itl(MiddleEdges);
+          for (; itl.More(); itl.Next())
+            BB.Add(NewWire, itl.Value());
+          BB.Add(NewWire, LastEdge);
+        }
+        else
+        {
+          //trim <FirstEdge> and <LastEdge> in the points of extrema
+          //these points become new vertex with centre between them
+          BRepExtrema_ExtCC Extrema(FirstEdge, LastEdge);
+          if (Extrema.IsDone() && Extrema.NbExt() > 0)
+          {
+            Standard_Integer imin = 1;
+            for (i = 2; i <= Extrema.NbExt(); i++)
+              if (Extrema.SquareDistance(i) < Extrema.SquareDistance(imin))
+                imin = i;
+            
+            Standard_Real aMinDist = sqrt(Extrema.SquareDistance(imin));
+            Standard_Real ParamOnFirstEdge = Extrema.ParameterOnE1(imin);
+            Standard_Real ParamOnLastEdge  = Extrema.ParameterOnE2(imin);
+            gp_Pnt PointOnFirstEdge = Extrema.PointOnE1(imin);
+            gp_Pnt PointOnLastEdge  = Extrema.PointOnE2(imin);
+            gp_Pnt MidPnt((PointOnFirstEdge.XYZ() + PointOnLastEdge.XYZ())/2);
+            aCommonVertex = BRepLib_MakeVertex(MidPnt);
+            BB.UpdateVertex(aCommonVertex, 1.001*aMinDist/2);
+            
+            UpdateSectionEdge(FirstEdge, theFirstVertex, aCommonVertex, ParamOnFirstEdge);
+            UpdateSectionEdge(LastEdge,  theLastVertex,  aCommonVertex, ParamOnLastEdge);
+            
+            BB.Add(NewWire, LastEdge);
+          }
+        }
+      }
+    }
+
+    resWire = NewWire;
+    resPlane = gp_Pln(myAxeOfBisPlane);
+    return Standard_True;
+  }
+
+  //General case: try to find continuous section closest to bisector plane
+  TopoDS_Compound OldComp;
+  BRep_Builder B;
+  B.MakeCompound( OldComp );
+  TopoDS_Iterator iter( Comp );
+  for (; iter.More(); iter.Next())
+    B.Add( OldComp, iter.Value() );
+
+  Standard_Boolean anError = Standard_False;
+  //TopoDS_Wire NewWire [2];
+  TopTools_SequenceOfShape Wseq;
+  for (;;)
+  {
+    TopExp_Explorer explo( OldComp, TopAbs_EDGE );
+    if (!explo.More())
+      break;
+    TopoDS_Edge FirstEdge = TopoDS::Edge( explo.Current() );
+    TopoDS_Wire NewWire = BRepLib_MakeWire( FirstEdge );
+    B.Remove( OldComp, FirstEdge );
+    if (NewWire.Closed())
+    {
+      Wseq.Append(NewWire);
+      continue;
+    }
+    
+    for (;;)
+    {
+      TopoDS_Vertex Extremity [2];
+      TopExp::Vertices( NewWire, Extremity[0], Extremity[1] );
+      if (Extremity[0].IsNull() || Extremity[1].IsNull())
+      {
+        anError = Standard_True;
+        break;
+      }
+      TopTools_IndexedDataMapOfShapeListOfShape VEmap;
+      TopExp::MapShapesAndAncestors( OldComp, TopAbs_VERTEX, TopAbs_EDGE, VEmap );
+      TopTools_ListOfShape Vedges [2];
+      for (j = 0; j < 2; j++)
+        if (VEmap.Contains( Extremity[j] ))
+          Vedges[j] = VEmap.FindFromKey( Extremity[j] );
+      if (Vedges[0].IsEmpty() && Vedges[1].IsEmpty())
+        //no more edges in OldComp to continue NewWire
+        break;
+      Standard_Boolean Modified = Standard_False;
+      for (j = 0; j < 2; j++)
+      {
+        if (Vedges[j].Extent() == 1)
+        {
+          const TopoDS_Edge& anEdge = TopoDS::Edge( Vedges[j].First() );
+          NewWire = BRepLib_MakeWire( NewWire, anEdge );
+          B.Remove( OldComp, anEdge );
+          Modified = Standard_True;
+        }
+      }
+      if (!Modified) //only multiple connections
+      {
+        ind = (Vedges[0].IsEmpty())? 1 : 0;
+        TopTools_SequenceOfShape Edges;
+        TopTools_ListIteratorOfListOfShape itl( Vedges[ind] );
+        for (; itl.More(); itl.Next())
+          Edges.Append( itl.Value() );
+        Standard_Integer theind=0;
+        Standard_Real MinDeviation = RealLast();
+        for (j = 1; j <= Edges.Length(); j++)
+        {
+          TopoDS_Wire aWire = BRepLib_MakeWire( NewWire, TopoDS::Edge(Edges(j)) );
+          gp_Pln aPlane;
+          Standard_Boolean issing;
+          Standard_Real Deviation = ComputeAveragePlaneAndMaxDeviation( aWire, aPlane, issing );
+          if (Deviation < MinDeviation)
+          {
+            MinDeviation = Deviation;
+            theind = j;
+          }
+        }
+        NewWire = BRepLib_MakeWire( NewWire, TopoDS::Edge(Edges(theind)) );
+        B.Remove( OldComp, Edges(theind) );
+      }
+      if (NewWire.Closed())
+        break;
+    }
+    Wseq.Append(NewWire);
+    if (anError)
+      break;
+  }
+  
+  Standard_Real MinAngle = RealLast();
+  TopExp_Explorer Explo( OldComp, TopAbs_EDGE );
+  if (!anError && !Explo.More()) //wires are built successfully and compound <OldComp> is empty
+  {
+    if (Wseq.Length() == 1) //only one wire => it becomes result
+    {
+      resWire = Wseq.First();
+      ComputeAveragePlaneAndMaxDeviation( resWire, resPlane, IsSingular );
+      return Standard_True;
+    }
+    else //we must choose the wire which average plane is closest to bisector plane
+    {    //(check angle between axes)
+      for (i = 1; i <= Wseq.Length(); i++)
+      {
+        TopoDS_Wire aWire = TopoDS::Wire( Wseq(i) );
+        gp_Pln aPln;
+        Standard_Boolean issing;
+        ComputeAveragePlaneAndMaxDeviation( aWire, aPln, issing );
+        if (issing)
+          continue;
+        
+        Standard_Real Angle = aPln.Axis().Angle( myAxeOfBisPlane.Axis() );
+        if (Angle > M_PI/2)
+          Angle = M_PI - Angle;
+        
+        if (Angle < MinAngle)
+        {
+          MinAngle = Angle;
+          resWire = aWire;
+          resPlane = aPln;
+        }
+      }
+      return Standard_True;
+    }
+  }
+  return Standard_False;
+}
+
 
 // ------------------------------------------------------------------------------------------
 // static function: SplitUEdges
@@ -966,13 +1180,15 @@ Standard_Boolean FindCommonVertex(const BOPDS_PDS&         theDS,
         continue;
 
       IntTools_CommonPrt aCP = aEE.CommonPart();
-      if(aCP.Type() == TopAbs_VERTEX) {
+      if(aCP.Type() == TopAbs_VERTEX)
+      {
         theCommonVertex = *(TopoDS_Vertex*)&theDS->Shape(aEE.IndexNew());
-        if (theEIndex1 == aEE.Index1()) {
+        
+        if (theEIndex1 == aEE.Index1())
           IntTools_Tools::VertexParameters(aCP, theParamOnE1, theParamOnE2);
-        } else {
+        else
           IntTools_Tools::VertexParameters(aCP, theParamOnE2, theParamOnE1);
-        }
+       
         //
         bvertexfound = Standard_True;
         break;
@@ -2004,147 +2220,182 @@ static Standard_Real ComputeAveragePlaneAndMaxDeviation(const TopoDS_Shape& aWir
   return MaxDeviation;
 }
 
-//=======================================================================
-//function : ChooseSection
-//purpose  : 
-//=======================================================================
-static Standard_Boolean ChooseSection(const TopoDS_Shape& Comp,
-                                      const gp_Ax2& bis,
-                                      TopoDS_Shape& resWire,
-                                      gp_Pln& resPlane,
-                                      Standard_Boolean& IsSingular)
+
+static void UpdateSectionEdge(TopoDS_Edge&         theEdge,
+                              const TopoDS_Vertex& theConstVertex,
+                              TopoDS_Vertex&       theVertex,
+                              const Standard_Real  theParam)
 {
-  IsSingular = Standard_False;
-  Standard_Real TolDeviation = 0.01; //, TolConf = 1.e-4, TolAng = 1.e-5;
+  TopoDS_Edge F_Edge = theEdge;
+  F_Edge.Orientation(TopAbs_FORWARD);
+  
+  TopAbs_Orientation OrOfVertex;
+  TopoDS_Vertex V1, V2, AnotherVertex;
+  TopExp::Vertices(F_Edge, V1, V2);
+  if (theConstVertex.IsSame(V1))
+  {
+    //OrOfConst = TopAbs_FORWARD;
+    OrOfVertex = TopAbs_REVERSED;
+    AnotherVertex = V2;
+  }
+  else
+  {
+    //OrOfConst = TopAbs_REVERSED;
+    OrOfVertex = TopAbs_FORWARD;
+    AnotherVertex = V1;
+  }
 
-//  Standard_Integer N = 100;
-  Standard_Integer ind, i, j;
+  BRep_Builder BB;
+  Standard_Real fpar, lpar;
+  BRep_Tool::Range(F_Edge, fpar, lpar);
+  if (OrOfVertex == TopAbs_FORWARD)
+    fpar = theParam;
+  else
+    lpar = theParam;
+  BB.Range(F_Edge, fpar, lpar);
+
+  F_Edge.Free(Standard_True);
+  BB.Remove(F_Edge, AnotherVertex);
+  theVertex.Orientation(OrOfVertex);
+  BB.Add(F_Edge, theVertex);
+}
 
-  //Simplest case
-  TopoDS_Compound OldComp;
-  BRep_Builder B;
-  B.MakeCompound( OldComp );
-  TopoDS_Iterator iter( Comp );
-  for (; iter.More(); iter.Next())
-    B.Add( OldComp, iter.Value() );
+//Finds the edge connected to <theVertex> in the compound <theComp>
+//that is closest to bisector plane angularly.
+//Removes found edge from <theComp>
+//<theAxis> is the axis of bisector plane
+static TopoDS_Edge FindEdgeCloseToBisectorPlane(const TopoDS_Vertex& theVertex,
+                                                TopoDS_Compound&     theComp,
+                                                const gp_Ax1&        theAxis)
+{
+  TopTools_IndexedDataMapOfShapeListOfShape VEmap;
+  TopExp::MapShapesAndAncestors( theComp, TopAbs_VERTEX, TopAbs_EDGE, VEmap );
+  
+  TopoDS_Edge MinEdge;
+  if (!VEmap.Contains(theVertex))
+    return MinEdge;
+  
+  BRep_Builder BB;
+  
+  const TopTools_ListOfShape& Edges = VEmap.FindFromKey(theVertex);
+  if (Edges.Extent() == 1)
+    MinEdge = TopoDS::Edge(Edges.First());
+  else
+  {
+    TopTools_ListIteratorOfListOfShape itl(Edges);
+    Standard_Real MinAngle = RealLast();
+    for (; itl.More(); itl.Next())
+    {
+      const TopoDS_Edge& anEdge = TopoDS::Edge(itl.Value());
+      TopoDS_Wire aWire;
+      BB.MakeWire(aWire);
+      BB.Add(aWire, anEdge);
+      gp_Pln aPln;
+      Standard_Boolean issing;
+      ComputeAveragePlaneAndMaxDeviation( aWire, aPln, issing );
+      Standard_Real anAngle;
+      if (issing) //edge is a segment of line
+      {
+        //<anAngle> is angle between <anEdge> and its projection on bisector plane
+        BRepAdaptor_Curve BAcurve(anEdge);
+        gp_Pnt FirstPnt = BAcurve.Value(BAcurve.FirstParameter());
+        gp_Pnt LastPnt  = BAcurve.Value(BAcurve.LastParameter());
+        gp_Vec EdgeVec(FirstPnt, LastPnt);
+        gp_Ax1 EdgeAxis(FirstPnt, EdgeVec);
+        anAngle = EdgeAxis.Direction().Angle(theAxis.Direction());
+        if (anAngle > M_PI/2)
+          anAngle = M_PI - anAngle;
+        anAngle = M_PI/2 - anAngle;
+      }
+      else
+      {
+        anAngle = aPln.Axis().Angle( theAxis );
+        if (anAngle > M_PI/2)
+          anAngle = M_PI - anAngle;
+      }
+      
+      if (anAngle < MinAngle)
+      {
+        MinAngle = anAngle;
+        MinEdge  = anEdge;
+      }
+    }
+  } //else (more than one edge)
 
-  Standard_Boolean anError = Standard_False;
-  //TopoDS_Wire NewWire [2];
-  TopTools_SequenceOfShape Wseq;
+  BB.Remove(theComp, MinEdge);
+  return MinEdge;
+}
+
+static Standard_Boolean FindMiddleEdges(const TopoDS_Vertex&  theVertex1,
+                                        const TopoDS_Vertex&  theVertex2,
+                                        const gp_Ax1&         theAxis,
+                                        TopoDS_Compound&      theComp,
+                                        TopTools_ListOfShape& theElist)
+{
+  TopTools_IndexedDataMapOfShapeListOfShape VEmap;
+  TopExp::MapShapesAndAncestors( theComp, TopAbs_VERTEX, TopAbs_EDGE, VEmap );
+  if (VEmap.IsEmpty())
+    return Standard_False;
+
+  if (!VEmap.Contains(theVertex1) ||
+      !VEmap.Contains(theVertex2))
+    return Standard_False;
+
+  TopoDS_Vertex CurVertex = theVertex1;
   for (;;)
-    {
-      TopExp_Explorer explo( OldComp, TopAbs_EDGE );
-      if (!explo.More())
-        break;
-      TopoDS_Edge FirstEdge = TopoDS::Edge( explo.Current() );
-      TopoDS_Wire NewWire = BRepLib_MakeWire( FirstEdge );
-      B.Remove( OldComp, FirstEdge );
-      if (NewWire.Closed())
-        {
-          Wseq.Append(NewWire);
-          continue;
-        }
+  {
+    TopoDS_Edge CurEdge;
+    
+    CurEdge = FindEdgeCloseToBisectorPlane(CurVertex, theComp, theAxis);
+    if (CurEdge.IsNull())
+      return Standard_False;
+    
+    TopoDS_Vertex V1, V2;
+    TopExp::Vertices(CurEdge, V1, V2);
+    CurVertex = (V1.IsSame(CurVertex))? V2 : V1;
 
-      for (;;)
-        {
-          TopoDS_Vertex Extremity [2];
-          TopExp::Vertices( NewWire, Extremity[0], Extremity[1] );
-          if (Extremity[0].IsNull() || Extremity[1].IsNull())
-            {
-              anError = Standard_True;
-              break;
-            }
-          TopTools_IndexedDataMapOfShapeListOfShape VEmap;
-          TopExp::MapShapesAndAncestors( OldComp, TopAbs_VERTEX, TopAbs_EDGE, VEmap );
-          TopTools_ListOfShape Vedges [2];
-          for (j = 0; j < 2; j++)
-            if (VEmap.Contains( Extremity[j] ))
-              Vedges[j] = VEmap.FindFromKey( Extremity[j] );
-          if (Vedges[0].IsEmpty() && Vedges[1].IsEmpty())
-            //no more edges in OldComp to continue NewWire
-            break;
-          Standard_Boolean Modified = Standard_False;
-          for (j = 0; j < 2; j++)
-            {
-              if (Vedges[j].Extent() == 1)
-                {
-                  const TopoDS_Edge& anEdge = TopoDS::Edge( Vedges[j].First() );
-                  NewWire = BRepLib_MakeWire( NewWire, anEdge );
-                  B.Remove( OldComp, anEdge );
-                  Modified = Standard_True;
-                }
-            }
-          if (!Modified) //only multiple connections
-            {
-              ind = (Vedges[0].IsEmpty())? 1 : 0;
-              TopTools_SequenceOfShape Edges;
-              TopTools_ListIteratorOfListOfShape itl( Vedges[ind] );
-              for (; itl.More(); itl.Next())
-                Edges.Append( itl.Value() );
-              Standard_Integer theind=0;
-              Standard_Real MinDeviation = RealLast();
-              for (j = 1; j <= Edges.Length(); j++)
-                {
-                  TopoDS_Wire aWire = BRepLib_MakeWire( NewWire, TopoDS::Edge(Edges(j)) );
-                  gp_Pln aPlane;
-                  Standard_Boolean issing;
-                  Standard_Real Deviation = ComputeAveragePlaneAndMaxDeviation( aWire, aPlane, issing );
-                  if (Deviation < MinDeviation)
-                    {
-                      MinDeviation = Deviation;
-                      theind = j;
-                    }
-                }
-              NewWire = BRepLib_MakeWire( NewWire, TopoDS::Edge(Edges(theind)) );
-              B.Remove( OldComp, Edges(theind) );
-            }
-          if (NewWire.Closed())
-            break;
-        }
-      Wseq.Append(NewWire);
-      if (anError)
-        break;
-    }
+    theElist.Append(CurEdge);
+    if (CurVertex.IsSame(theVertex2))
+      return Standard_True;
+  }
+}
 
-  Standard_Real Deviation=0.;
-  Standard_Real MinAngle = RealLast();
-  TopExp_Explorer Explo( OldComp, TopAbs_EDGE );
-  if (!anError && !Explo.More())
+static Standard_Boolean FindCommonVertex(const TopoDS_Edge&   theFirstEdge,
+                                         const TopoDS_Edge&   theLastEdge,
+                                         const TopoDS_Vertex& theFirstVertex,
+                                         const TopoDS_Vertex& theLastVertex,
+                                         TopoDS_Vertex&       theCommonVertex)
+{
+  if (!theFirstVertex.IsSame(theLastVertex))
+  {
+    Standard_Boolean CommonVertexExists = TopExp::CommonVertex(theFirstEdge,
+                                                               theLastEdge,
+                                                               theCommonVertex);
+    return CommonVertexExists;
+  }
+
+  TopoDS_Vertex V1, V2, V3, V4;
+  TopExp::Vertices(theFirstEdge, V1, V2);
+  TopExp::Vertices(theLastEdge, V3, V4);
+
+  if (V1.IsSame(theFirstVertex))
+  {
+    if (V2.IsSame(V3) ||
+        V2.IsSame(V4))
     {
-      if (Wseq.Length() == 1)
-        {
-          resWire = Wseq.First();
-          Deviation = ComputeAveragePlaneAndMaxDeviation( resWire, resPlane, IsSingular );
-          return Standard_True;
-        }
-      else
-        {
-          for (i = 1; i <= Wseq.Length(); i++)
-            {
-              TopoDS_Wire aWire = TopoDS::Wire( Wseq(i) );
-              gp_Pln aPln;
-              Standard_Boolean issing;
-              Standard_Real aDeviation =
-                ComputeAveragePlaneAndMaxDeviation( aWire, aPln, issing );
-              if (issing)
-                continue;
-
-              Standard_Real Angle = aPln.Axis().Angle( bis.Axis() );
-              if (Angle > M_PI/2)
-                Angle = M_PI - Angle;
-              
-              if (Angle < MinAngle)
-                {
-                  MinAngle = Angle;
-                  resWire = aWire;
-                  resPlane = aPln;
-                  Deviation = aDeviation;
-                }
-            }
-          if (Deviation <= TolDeviation)
-            return Standard_True;
-        }
+      theCommonVertex = V2;
+      return Standard_True;
     }
+  }
+  else
+  {
+    if (V1.IsSame(V3) ||
+        V1.IsSame(V4))
+    {
+      theCommonVertex = V1;
+      return Standard_True;
+    }
+  }
+
   return Standard_False;
-  //end of simplest case
 }
index 2298d7c..a134916 100644 (file)
@@ -20,6 +20,7 @@
 #include <Standard_DefineAlloc.hxx>
 #include <Standard_Handle.hxx>
 
+#include <BRepFill_TransitionStyle.hxx>
 #include <gp_Ax2.hxx>
 #include <TopoDS_Shape.hxx>
 #include <TopoDS_Wire.hxx>
 #include <Standard_Boolean.hxx>
 #include <TopTools_DataMapOfShapeListOfShape.hxx>
 #include <TopTools_ListOfShape.hxx>
+#include <BOPDS_PDS.hxx>
 class gp_Ax2;
 class TopoDS_Face;
 class TopoDS_Wire;
 class TopoDS_Shape;
 
 
-
+//! Trims sets of faces in the corner to make proper parts of pipe
 class BRepFill_TrimShellCorner 
 {
 public:
@@ -42,12 +44,13 @@ public:
   DEFINE_STANDARD_ALLOC
 
   
-  Standard_EXPORT BRepFill_TrimShellCorner(const Handle(TopTools_HArray2OfShape)& theFaces, const gp_Ax2& theAxeOfBisPlane, const TopoDS_Face& theSecPlane);
-  
-  Standard_EXPORT BRepFill_TrimShellCorner(const Handle(TopTools_HArray2OfShape)& theFaces, const gp_Ax2& theAxeOfBisPlane, const TopoDS_Wire& theSpine, const TopoDS_Face& theSecPlane);
-  
-  Standard_EXPORT void SetSpine (const TopoDS_Wire& theSpine);
-  
+  //! Constructor: takes faces to intersect,
+  //! type of transition (it can be RightCorner or RoundCorner)
+  //! and axis of bisector plane
+  Standard_EXPORT BRepFill_TrimShellCorner(const Handle(TopTools_HArray2OfShape)& theFaces,
+                                           const BRepFill_TransitionStyle         theTransition,
+                                           const gp_Ax2&                          theAxeOfBisPlane);
+
   Standard_EXPORT void AddBounds (const Handle(TopTools_HArray2OfShape)& Bounds);
   
   Standard_EXPORT void AddUEdges (const Handle(TopTools_HArray2OfShape)& theUEdges);
@@ -71,13 +74,29 @@ protected:
 
 private:
 
+  Standard_Boolean MakeFacesSec(const Standard_Integer                     theIndex,
+                                const BOPDS_PDS&                           theDS,
+                                const Standard_Integer                     theFaceIndex1, 
+                                const Standard_Integer                     theFaceIndex2, 
+                                const Standard_Integer                     theSSInterfIndex);
+  
+  Standard_Boolean MakeFacesNonSec(const Standard_Integer                     theIndex,
+                                   const BOPDS_PDS&                           theDS,
+                                   const Standard_Integer                     theFaceIndex1, 
+                                   const Standard_Integer                     theFaceIndex2);
+  
+  Standard_Boolean ChooseSection(const TopoDS_Shape& Comp,
+                                 const TopoDS_Vertex& theFirstVertex,
+                                 const TopoDS_Vertex& theLastVertex,
+                                 TopoDS_Shape& resWire,
+                                 gp_Pln& resPlane,
+                                 Standard_Boolean& IsSingular);
 
 
+  BRepFill_TransitionStyle myTransition;
   gp_Ax2 myAxeOfBisPlane;
   TopoDS_Shape myShape1;
   TopoDS_Shape myShape2;
-  TopoDS_Wire mySpine;
-  TopoDS_Face mySecPln;
   Handle(TopTools_HArray2OfShape) myBounds;
   Handle(TopTools_HArray2OfShape) myUEdges;
   Handle(TopTools_HArray2OfShape) myFaces;
diff --git a/tests/bugs/modalg_7/bug29204 b/tests/bugs/modalg_7/bug29204
new file mode 100644 (file)
index 0000000..8ce39b7
--- /dev/null
@@ -0,0 +1,26 @@
+puts "============"
+puts "OCC29204"
+puts "============"
+puts ""
+##################################################################################
+# BRepOffsetAPI_MakePipeShell produces invalid result and raises exception in Draw
+##################################################################################
+
+restore [locate_data_file bug29204_sweep_spine.brep] sp
+restore [locate_data_file bug29204_sweep_profile.brep] pr
+
+mksweep sp
+addsweep pr
+buildsweep result -C -S
+
+checkshape result
+
+checknbshapes result -solid 1 -shell 1 -face 28 -wire 28 -edge 64 -vertex 36 -shape 158
+
+set tolres [checkmaxtol result]
+
+if { ${tolres} > 0.001} {
+   puts "Error: bad tolerance of result"
+}
+
+checkprops result -v 1.16577e+007