0025406: BRepOffset_MakeOffset algorithm fails on the face with two degenerated edges...
authorjgv <jgv@opencascade.com>
Thu, 23 Oct 2014 11:31:47 +0000 (15:31 +0400)
committerbugmaster <bugmaster@opencascade.com>
Thu, 23 Oct 2014 12:20:56 +0000 (16:20 +0400)
Test cases for issue CR25406

src/BRepOffset/BRepOffset_MakeOffset.cxx
src/BRepOffset/BRepOffset_Offset.cxx
tests/bugs/modalg_5/bug25406_1 [new file with mode: 0644]
tests/bugs/modalg_5/bug25406_2 [new file with mode: 0644]

index bed4c6a..7f42a32 100644 (file)
@@ -1850,58 +1850,58 @@ void BRepOffset_MakeOffset::CorrectConicalFaces()
   //TopTools_DataMapOfShapeShape DegEdges;
   TopExp_Explorer Explo( myOffsetShape, TopAbs_FACE );
   if (myJoin == GeomAbs_Arc)
+  {
+    for (; Explo.More(); Explo.Next())
     {
-      for (; Explo.More(); Explo.Next())
-       {
-         TopoDS_Face aFace = TopoDS::Face( Explo.Current() );
-         Handle(Geom_Surface) aSurf = BRep_Tool::Surface( aFace );
-         //if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
-         //aSurf = (Handle(Geom_OffsetSurface)::DownCast(aSurf))->BasisSurface(); //???
-         
-         TopTools_IndexedMapOfShape Emap;
-         TopExp::MapShapes( aFace, TopAbs_EDGE, Emap );
-         for (i = 1; i <= Emap.Extent(); i++)
-           {
-             TopoDS_Edge anEdge = TopoDS::Edge( Emap(i) );
-             //Standard_Real f, l;
-             //Handle(Geom_Curve) theCurve = BRep_Tool::Curve( anEdge, f, l );
-             //Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &anEdge.TShape());
-             if (BRep_Tool::Degenerated(anEdge))
-               {
-                 //Check if anEdge is a really degenerated edge or not
-                 BRepAdaptor_Curve BACurve(anEdge, aFace);
-                 gp_Pnt Pfirst, Plast, Pmid;
-                 Pfirst = BACurve.Value(BACurve.FirstParameter());
-                 Plast  = BACurve.Value(BACurve.LastParameter());
-                 Pmid   = BACurve.Value((BACurve.FirstParameter()+BACurve.LastParameter())/2.);
-                 if (Pfirst.Distance(Plast) <= TolApex &&
-                     Pfirst.Distance(Pmid)  <= TolApex)
-                   continue;
-                 //Cones.Append( aFace );
-                 //Circs.Append( anEdge );
-                 //TopoDS_Vertex Vdeg = TopExp::FirstVertex( anEdge );
-                 TopoDS_Edge OrEdge = 
-                   TopoDS::Edge( myInitOffsetEdge.Root( anEdge) );
-                 TopoDS_Vertex VF = TopExp::FirstVertex( OrEdge );
-                 if ( FacesOfCone.IsBound(VF) )
-                   {
-                     //add a face to the existing list
-                     TopTools_ListOfShape& aFaces = FacesOfCone.ChangeFind(VF);
-                     aFaces.Append (aFace);
-                     //DegEdges.Bind(aFace, anEdge);
-                   }
-                 else
-                   {
-                     //the vertex is not in the map => create a new key and items
-                     TopTools_ListOfShape aFaces;
-                     aFaces.Append (aFace);
-                     FacesOfCone.Bind(VF, aFaces);
-                     //DegEdges.Bind(aFace, anEdge);
-                   }
-               }
-           } //for (i = 1; i <= Emap.Extent(); i++)
-       } //for (; fexp.More(); fexp.Next())
-    } //if (myJoin == GeomAbs_Arc)
+      TopoDS_Face aFace = TopoDS::Face( Explo.Current() );
+      Handle(Geom_Surface) aSurf = BRep_Tool::Surface( aFace );
+      //if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
+      //aSurf = (Handle(Geom_OffsetSurface)::DownCast(aSurf))->BasisSurface(); //???
+      
+      TopTools_IndexedMapOfShape Emap;
+      TopExp::MapShapes( aFace, TopAbs_EDGE, Emap );
+      for (i = 1; i <= Emap.Extent(); i++)
+      {
+        TopoDS_Edge anEdge = TopoDS::Edge( Emap(i) );
+        //Standard_Real f, l;
+        //Handle(Geom_Curve) theCurve = BRep_Tool::Curve( anEdge, f, l );
+        //Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &anEdge.TShape());
+        if (BRep_Tool::Degenerated(anEdge))
+        {
+          //Check if anEdge is a really degenerated edge or not
+          BRepAdaptor_Curve BACurve(anEdge, aFace);
+          gp_Pnt Pfirst, Plast, Pmid;
+          Pfirst = BACurve.Value(BACurve.FirstParameter());
+          Plast  = BACurve.Value(BACurve.LastParameter());
+          Pmid   = BACurve.Value((BACurve.FirstParameter()+BACurve.LastParameter())/2.);
+          if (Pfirst.Distance(Plast) <= TolApex &&
+              Pfirst.Distance(Pmid)  <= TolApex)
+            continue;
+          //Cones.Append( aFace );
+          //Circs.Append( anEdge );
+          //TopoDS_Vertex Vdeg = TopExp::FirstVertex( anEdge );
+          TopoDS_Edge OrEdge = 
+            TopoDS::Edge( myInitOffsetEdge.Root( anEdge) );
+          TopoDS_Vertex VF = TopExp::FirstVertex( OrEdge );
+          if ( FacesOfCone.IsBound(VF) )
+          {
+            //add a face to the existing list
+            TopTools_ListOfShape& aFaces = FacesOfCone.ChangeFind(VF);
+            aFaces.Append (aFace);
+            //DegEdges.Bind(aFace, anEdge);
+          }
+          else
+          {
+            //the vertex is not in the map => create a new key and items
+            TopTools_ListOfShape aFaces;
+            aFaces.Append (aFace);
+            FacesOfCone.Bind(VF, aFaces);
+            //DegEdges.Bind(aFace, anEdge);
+          }
+        }
+      } //for (i = 1; i <= Emap.Extent(); i++)
+    } //for (; fexp.More(); fexp.Next())
+  } //if (myJoin == GeomAbs_Arc)
 
   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape Cone(FacesOfCone);
   BRep_Builder BB;
@@ -1918,218 +1918,218 @@ void BRepOffset_MakeOffset::CorrectConicalFaces()
     gp_Pnt FirstPoint;
     TopoDS_Vertex theFirstVertex, CurFirstVertex;
     for (; itFaces.More(); itFaces.Next())
+    {
+      TopoDS_Face aFace = TopoDS::Face(itFaces.Value()); //TopoDS::Face(Faces.First());
+      TopoDS_Edge DegEdge; // = TopoDS::Edge(DegEdges(aFace));
+      for (Explo.Init(aFace, TopAbs_EDGE); Explo.More(); Explo.Next())
       {
-       TopoDS_Face aFace = TopoDS::Face(itFaces.Value()); //TopoDS::Face(Faces.First());
-       TopoDS_Edge DegEdge; // = TopoDS::Edge(DegEdges(aFace));
-       for (Explo.Init(aFace, TopAbs_EDGE); Explo.More(); Explo.Next())
-         {
-           DegEdge = TopoDS::Edge(Explo.Current());
-           if (BRep_Tool::Degenerated(DegEdge))
-             {
-               TopoDS_Edge OrEdge = TopoDS::Edge( myInitOffsetEdge.Root( DegEdge) );
-               TopoDS_Vertex VF = TopExp::FirstVertex( OrEdge );
-               if (VF.IsSame(anApex))
-                 break;
-             }
-         }
-       TopoDS_Shape aLocalDegShape = DegEdge.Oriented(TopAbs_FORWARD);
-       TopoDS_Edge CurEdge = TopoDS::Edge(aLocalDegShape);
-       BB.Degenerated(CurEdge, Standard_False);
-       BB.SameRange(CurEdge, Standard_False);
-       BB.SameParameter(CurEdge, Standard_False);
-       gp_Pnt fPnt, lPnt, mPnt;
-       GetEdgePoints(CurEdge, aFace, fPnt, mPnt, lPnt);
-       Standard_Real f, l;
-       BRep_Tool::Range(CurEdge, f, l);
-       if (isFirstFace)
-         {
-           gp_Vec aVec1(fPnt, mPnt);
-           gp_Vec aVec2(fPnt, lPnt);
-           gp_Vec aNorm = aVec1.Crossed(aVec2);
-           gp_Pnt theApex = BRep_Tool::Pnt(anApex);
-           gp_Vec ApexToFpnt(theApex, fPnt);
-           gp_Vec Ydir = aNorm ^ ApexToFpnt;
-           gp_Vec Xdir = Ydir ^ aNorm;
-           //Xdir.Rotate(gp_Ax1(theApex, aNorm), -f);
-           gp_Ax2 anAx2(theApex, gp_Dir(aNorm), gp_Dir(Xdir));
-           theSphere.SetRadius(myOffset);
-           theSphere.SetPosition(gp_Ax3(anAx2) /*gp_Ax3(theApex, gp_Dir(aNorm))*/);
-           aSphSurf = new Geom_SphericalSurface(theSphere);
-           FirstPoint = fPnt;
-           theFirstVertex = BRepLib_MakeVertex(fPnt);
-           CurFirstVertex = theFirstVertex;
-         }
-
-       TopoDS_Vertex v1, v2, FirstVert, EndVert;
-       TopExp::Vertices(CurEdge, v1, v2);
-       FirstVert = CurFirstVertex;
-       if (lPnt.Distance(FirstPoint) <= Precision::Confusion())
-         EndVert = theFirstVertex;
-       else
-         EndVert = BRepLib_MakeVertex(lPnt);
-       CurEdge.Free( Standard_True );
-       BB.Remove(CurEdge, v1);
-       BB.Remove(CurEdge, v2);
-       BB.Add(CurEdge, FirstVert.Oriented(TopAbs_FORWARD));
-       BB.Add(CurEdge, EndVert.Oriented(TopAbs_REVERSED));
-       //take the curve from sphere an put it to the edge
-       Standard_Real Uf, Vf, Ul, Vl;
-       ElSLib::Parameters( theSphere, fPnt, Uf, Vf );
-       ElSLib::Parameters( theSphere, lPnt, Ul, Vl );
-       if (Abs(Ul) <= Precision::Confusion())
-         Ul = 2.*M_PI;
-       Handle(Geom_Curve) aCurv = aSphSurf->VIso(Vf);
-       /*
+        DegEdge = TopoDS::Edge(Explo.Current());
+        if (BRep_Tool::Degenerated(DegEdge))
+        {
+          TopoDS_Edge OrEdge = TopoDS::Edge( myInitOffsetEdge.Root( DegEdge) );
+          TopoDS_Vertex VF = TopExp::FirstVertex( OrEdge );
+          if (VF.IsSame(anApex))
+            break;
+        }
+      }
+      TopoDS_Shape aLocalDegShape = DegEdge.Oriented(TopAbs_FORWARD);
+      TopoDS_Edge CurEdge = TopoDS::Edge(aLocalDegShape);
+      BB.Degenerated(CurEdge, Standard_False);
+      BB.SameRange(CurEdge, Standard_False);
+      BB.SameParameter(CurEdge, Standard_False);
+      gp_Pnt fPnt, lPnt, mPnt;
+      GetEdgePoints(CurEdge, aFace, fPnt, mPnt, lPnt);
+      Standard_Real f, l;
+      BRep_Tool::Range(CurEdge, f, l);
+      if (isFirstFace)
+      {
+        gp_Vec aVec1(fPnt, mPnt);
+        gp_Vec aVec2(fPnt, lPnt);
+        gp_Vec aNorm = aVec1.Crossed(aVec2);
+        gp_Pnt theApex = BRep_Tool::Pnt(anApex);
+        gp_Vec ApexToFpnt(theApex, fPnt);
+        gp_Vec Ydir = aNorm ^ ApexToFpnt;
+        gp_Vec Xdir = Ydir ^ aNorm;
+        //Xdir.Rotate(gp_Ax1(theApex, aNorm), -f);
+        gp_Ax2 anAx2(theApex, gp_Dir(aNorm), gp_Dir(Xdir));
+        theSphere.SetRadius(myOffset);
+        theSphere.SetPosition(gp_Ax3(anAx2) /*gp_Ax3(theApex, gp_Dir(aNorm))*/);
+        aSphSurf = new Geom_SphericalSurface(theSphere);
+        FirstPoint = fPnt;
+        theFirstVertex = BRepLib_MakeVertex(fPnt);
+        CurFirstVertex = theFirstVertex;
+      }
+      
+      TopoDS_Vertex v1, v2, FirstVert, EndVert;
+      TopExp::Vertices(CurEdge, v1, v2);
+      FirstVert = CurFirstVertex;
+      if (lPnt.Distance(FirstPoint) <= Precision::Confusion())
+        EndVert = theFirstVertex;
+      else
+        EndVert = BRepLib_MakeVertex(lPnt);
+      CurEdge.Free( Standard_True );
+      BB.Remove(CurEdge, v1);
+      BB.Remove(CurEdge, v2);
+      BB.Add(CurEdge, FirstVert.Oriented(TopAbs_FORWARD));
+      BB.Add(CurEdge, EndVert.Oriented(TopAbs_REVERSED));
+      //take the curve from sphere an put it to the edge
+      Standard_Real Uf, Vf, Ul, Vl;
+      ElSLib::Parameters( theSphere, fPnt, Uf, Vf );
+      ElSLib::Parameters( theSphere, lPnt, Ul, Vl );
+      if (Abs(Ul) <= Precision::Confusion())
+        Ul = 2.*M_PI;
+      Handle(Geom_Curve) aCurv = aSphSurf->VIso(Vf);
+      /*
        if (!isFirstFace)
-         {
-           gp_Circ aCircle = (Handle(Geom_Circle)::DownCast(aCurv))->Circ();
-           if (Abs(Uf - f) > Precision::Confusion())
-             {
-               aCircle.Rotate(aCircle.Axis(), f - Uf);
-               aCurv = new Geom_Circle(aCircle);
-             }
-         }
-       */
-       Handle(Geom_TrimmedCurve) aTrimCurv = new Geom_TrimmedCurve(aCurv, Uf, Ul);
-       BB.UpdateEdge(CurEdge, aTrimCurv, Precision::Confusion());
-       BB.Range(CurEdge, Uf, Ul, Standard_True);
-       Handle(Geom2d_Line) theLin2d = new Geom2d_Line( gp_Pnt2d( 0., Vf ), gp::DX2d() );
-       Handle(Geom2d_TrimmedCurve) theTrimLin2d = new Geom2d_TrimmedCurve(theLin2d, Uf, Ul);
-       BB.UpdateEdge(CurEdge, theTrimLin2d, aSphSurf, L, Precision::Confusion());
-       BB.Range(CurEdge, aSphSurf, L, Uf, Ul);
-       BRepLib::SameParameter(CurEdge);
-       BB.Add(SphereWire, CurEdge);
-       //Modifying correspondent edges in aFace: substitute vertices common with CurEdge
-       BRepAdaptor_Curve2d BAc2d(CurEdge, aFace);
-       gp_Pnt2d fPnt2d, lPnt2d;
-       fPnt2d = BAc2d.Value(BAc2d.FirstParameter());
-       lPnt2d = BAc2d.Value(BAc2d.LastParameter());
-       TopTools_IndexedMapOfShape Emap;
-       TopExp::MapShapes(aFace, TopAbs_EDGE, Emap);
-       TopoDS_Edge EE [2];
-       Standard_Integer j = 0, k;
-       for (k = 1; k <= Emap.Extent(); k++)
-         {
-           const TopoDS_Edge& anEdge = TopoDS::Edge(Emap(k));
-           if (!BRep_Tool::Degenerated(anEdge))
-             {
-               TopoDS_Vertex V1, V2;
-               TopExp::Vertices(anEdge, V1, V2);
-               if (V1.IsSame(v1) || V2.IsSame(v1))
-                 EE[j++] = anEdge;
-             }
-         }
-       for (k = 0; k < j; k++)
-         {
-           TopoDS_Shape aLocalShape = EE[k].Oriented(TopAbs_FORWARD);
-           TopoDS_Edge Eforward = TopoDS::Edge(aLocalShape);
-           Eforward.Free(Standard_True);
-           TopoDS_Vertex V1, V2;
-           TopExp::Vertices( Eforward, V1, V2 );
-           BRepAdaptor_Curve2d EEc( Eforward, aFace );
-           gp_Pnt2d p2d1, p2d2;
-           p2d1 = EEc.Value(EEc.FirstParameter());
-           p2d2 = EEc.Value(EEc.LastParameter());
-           if (V1.IsSame(v1))
-             {
-               TopoDS_Vertex NewV = (p2d1.Distance(fPnt2d) <= Precision::Confusion())?
-                 FirstVert : EndVert;
-               BB.Remove( Eforward, V1 );
-               BB.Add( Eforward, NewV.Oriented(TopAbs_FORWARD) );
-             }
-           else
-             {
-               TopoDS_Vertex NewV = (p2d2.Distance(fPnt2d) <= Precision::Confusion())?
-                 FirstVert : EndVert;
-               BB.Remove( Eforward, V2 );
-               BB.Add( Eforward, NewV.Oriented(TopAbs_REVERSED) );
-             }
-         }
-
-       isFirstFace = Standard_False;
-       CurFirstVertex = EndVert;
+        {
+        gp_Circ aCircle = (Handle(Geom_Circle)::DownCast(aCurv))->Circ();
+        if (Abs(Uf - f) > Precision::Confusion())
+        {
+        aCircle.Rotate(aCircle.Axis(), f - Uf);
+        aCurv = new Geom_Circle(aCircle);
+        }
+        }
+      */
+      Handle(Geom_TrimmedCurve) aTrimCurv = new Geom_TrimmedCurve(aCurv, Uf, Ul);
+      BB.UpdateEdge(CurEdge, aTrimCurv, Precision::Confusion());
+      BB.Range(CurEdge, Uf, Ul, Standard_True);
+      Handle(Geom2d_Line) theLin2d = new Geom2d_Line( gp_Pnt2d( 0., Vf ), gp::DX2d() );
+      Handle(Geom2d_TrimmedCurve) theTrimLin2d = new Geom2d_TrimmedCurve(theLin2d, Uf, Ul);
+      BB.UpdateEdge(CurEdge, theTrimLin2d, aSphSurf, L, Precision::Confusion());
+      BB.Range(CurEdge, aSphSurf, L, Uf, Ul);
+      BRepLib::SameParameter(CurEdge);
+      BB.Add(SphereWire, CurEdge);
+      //Modifying correspondent edges in aFace: substitute vertices common with CurEdge
+      BRepAdaptor_Curve2d BAc2d(CurEdge, aFace);
+      gp_Pnt2d fPnt2d, lPnt2d;
+      fPnt2d = BAc2d.Value(BAc2d.FirstParameter());
+      lPnt2d = BAc2d.Value(BAc2d.LastParameter());
+      TopTools_IndexedMapOfShape Emap;
+      TopExp::MapShapes(aFace, TopAbs_EDGE, Emap);
+      TopoDS_Edge EE [2];
+      Standard_Integer j = 0, k;
+      for (k = 1; k <= Emap.Extent(); k++)
+      {
+        const TopoDS_Edge& anEdge = TopoDS::Edge(Emap(k));
+        if (!BRep_Tool::Degenerated(anEdge))
+        {
+          TopoDS_Vertex V1, V2;
+          TopExp::Vertices(anEdge, V1, V2);
+          if (V1.IsSame(v1) || V2.IsSame(v1))
+            EE[j++] = anEdge;
+        }
       }
+      for (k = 0; k < j; k++)
+      {
+        TopoDS_Shape aLocalShape = EE[k].Oriented(TopAbs_FORWARD);
+        TopoDS_Edge Eforward = TopoDS::Edge(aLocalShape);
+        Eforward.Free(Standard_True);
+        TopoDS_Vertex V1, V2;
+        TopExp::Vertices( Eforward, V1, V2 );
+        BRepAdaptor_Curve2d EEc( Eforward, aFace );
+        gp_Pnt2d p2d1, p2d2;
+        p2d1 = EEc.Value(EEc.FirstParameter());
+        p2d2 = EEc.Value(EEc.LastParameter());
+        if (V1.IsSame(v1))
+        {
+          TopoDS_Vertex NewV = (p2d1.Distance(fPnt2d) <= Precision::Confusion())?
+            FirstVert : EndVert;
+          BB.Remove( Eforward, V1 );
+          BB.Add( Eforward, NewV.Oriented(TopAbs_FORWARD) );
+        }
+        else
+        {
+          TopoDS_Vertex NewV = (p2d2.Distance(fPnt2d) <= Precision::Confusion())?
+            FirstVert : EndVert;
+          BB.Remove( Eforward, V2 );
+          BB.Add( Eforward, NewV.Oriented(TopAbs_REVERSED) );
+        }
+      }
+      
+      isFirstFace = Standard_False;
+      CurFirstVertex = EndVert;
+    }
     //Building new spherical face
     Standard_Real Ufirst = RealLast(), Ulast = RealFirst();
     gp_Pnt2d p2d1, p2d2;
     TopTools_ListOfShape EdgesOfWire;
     TopoDS_Iterator itw(SphereWire);
     for (; itw.More(); itw.Next())
-      {
-       const TopoDS_Edge& anEdge = TopoDS::Edge(itw.Value());
-       EdgesOfWire.Append(anEdge);
-       Standard_Real f, l;
-       Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface(anEdge, aSphSurf, L, f, l);
-       p2d1 = aC2d->Value(f);
-       p2d2 = aC2d->Value(l);
-       if (p2d1.X() < Ufirst)
-         Ufirst = p2d1.X();
-       if (p2d1.X() > Ulast)
-         Ulast = p2d1.X();
-       if (p2d2.X() < Ufirst)
-         Ufirst = p2d2.X();
-       if (p2d2.X() > Ulast)
-         Ulast = p2d2.X();
-      }
+    {
+      const TopoDS_Edge& anEdge = TopoDS::Edge(itw.Value());
+      EdgesOfWire.Append(anEdge);
+      Standard_Real f, l;
+      Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface(anEdge, aSphSurf, L, f, l);
+      p2d1 = aC2d->Value(f);
+      p2d2 = aC2d->Value(l);
+      if (p2d1.X() < Ufirst)
+        Ufirst = p2d1.X();
+      if (p2d1.X() > Ulast)
+        Ulast = p2d1.X();
+      if (p2d2.X() < Ufirst)
+        Ufirst = p2d2.X();
+      if (p2d2.X() > Ulast)
+        Ulast = p2d2.X();
+    }
     TopTools_ListOfShape NewEdges;
     TopoDS_Edge FirstEdge;
     TopTools_ListIteratorOfListOfShape itl(EdgesOfWire);
     for (; itl.More(); itl.Next())
+    {
+      FirstEdge = TopoDS::Edge(itl.Value());
+      Standard_Real f, l;
+      Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface(FirstEdge, aSphSurf, L, f, l);
+      p2d1 = aC2d->Value(f);
+      p2d2 = aC2d->Value(l);
+      if (Abs(p2d1.X() - Ufirst) <= Precision::Confusion())
       {
-       FirstEdge = TopoDS::Edge(itl.Value());
-       Standard_Real f, l;
-       Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface(FirstEdge, aSphSurf, L, f, l);
-       p2d1 = aC2d->Value(f);
-       p2d2 = aC2d->Value(l);
-       if (Abs(p2d1.X() - Ufirst) <= Precision::Confusion())
-         {
-           EdgesOfWire.Remove(itl);
-           break;
-         }
+        EdgesOfWire.Remove(itl);
+        break;
       }
+    }
     NewEdges.Append(FirstEdge);
     TopoDS_Vertex Vf1, CurVertex;
     TopExp::Vertices(FirstEdge, Vf1, CurVertex);
     itl.Initialize(EdgesOfWire);
     while (itl.More())
+    {
+      const TopoDS_Edge& anEdge = TopoDS::Edge(itl.Value());
+      TopoDS_Vertex V1, V2;
+      TopExp::Vertices(anEdge, V1, V2);
+      if (V1.IsSame(CurVertex) || V2.IsSame(CurVertex))
       {
-       const TopoDS_Edge& anEdge = TopoDS::Edge(itl.Value());
-       TopoDS_Vertex V1, V2;
-       TopExp::Vertices(anEdge, V1, V2);
-       if (V1.IsSame(CurVertex) || V2.IsSame(CurVertex))
-         {
-           NewEdges.Append(anEdge);
-           CurVertex = (V1.IsSame(CurVertex))? V2 : V1;
-           EdgesOfWire.Remove(itl);
-         }
-       else
-         itl.Next();
+        NewEdges.Append(anEdge);
+        CurVertex = (V1.IsSame(CurVertex))? V2 : V1;
+        EdgesOfWire.Remove(itl);
       }
-
+      else
+        itl.Next();
+    }
+    
     Standard_Real Vfirst, Vlast;
     if (p2d1.Y() > 0.)
-      {
-       Vfirst = p2d1.Y(); Vlast = M_PI/2.;
-      }
+    {
+      Vfirst = p2d1.Y(); Vlast = M_PI/2.;
+    }
     else
-      {
-       Vfirst = -M_PI/2.; Vlast = p2d1.Y();
-      }
+    {
+      Vfirst = -M_PI/2.; Vlast = p2d1.Y();
+    }
     TopoDS_Face NewSphericalFace = BRepLib_MakeFace(aSphSurf, Ufirst, Ulast, Vfirst, Vlast, Precision::Confusion());
     TopoDS_Edge OldEdge;
     for (Explo.Init(NewSphericalFace, TopAbs_EDGE); Explo.More(); Explo.Next())
+    {
+      OldEdge = TopoDS::Edge(Explo.Current());
+      if (!BRep_Tool::Degenerated(OldEdge))
       {
-       OldEdge = TopoDS::Edge(Explo.Current());
-       if (!BRep_Tool::Degenerated(OldEdge))
-         {
-           BRepAdaptor_Curve2d BAc2d(OldEdge, NewSphericalFace);
-           p2d1 = BAc2d.Value(BAc2d.FirstParameter());
-           p2d2 = BAc2d.Value(BAc2d.LastParameter());
-           if (Abs(p2d1.X() - Ufirst) <= Precision::Confusion() &&
-               Abs(p2d2.X() - Ulast)  <= Precision::Confusion())
-             break;
-         }
+        BRepAdaptor_Curve2d BAc2d(OldEdge, NewSphericalFace);
+        p2d1 = BAc2d.Value(BAc2d.FirstParameter());
+        p2d2 = BAc2d.Value(BAc2d.LastParameter());
+        if (Abs(p2d1.X() - Ufirst) <= Precision::Confusion() &&
+            Abs(p2d2.X() - Ulast)  <= Precision::Confusion())
+          break;
       }
+    }
     TopoDS_Vertex V1, V2;
     TopExp::Vertices(OldEdge, V1, V2);
     TopTools_ListOfShape LV1, LV2;
@@ -2142,11 +2142,11 @@ void BRepOffset_MakeOffset::CorrectConicalFaces()
     theSubstitutor.Substitute(OldEdge, NewEdges);
     theSubstitutor.Build(NewSphericalFace);
     if (theSubstitutor.IsCopied(NewSphericalFace))
-      {
-       const TopTools_ListOfShape& listSh = theSubstitutor.Copy(NewSphericalFace);
-       NewSphericalFace = TopoDS::Face(listSh.First());
-      }
-
+    {
+      const TopTools_ListOfShape& listSh = theSubstitutor.Copy(NewSphericalFace);
+      NewSphericalFace = TopoDS::Face(listSh.First());
+    }
+    
     //Adding NewSphericalFace to the shell
     Explo.Init( myOffsetShape, TopAbs_SHELL );
     TopoDS_Shape theShell = Explo.Current();
@@ -2154,415 +2154,39 @@ void BRepOffset_MakeOffset::CorrectConicalFaces()
     BB.Add( theShell, NewSphericalFace );
   }
 
-  Explo.Init( myOffsetShape, TopAbs_SHELL );
-
-  if (Explo.More()) {
-    TopoDS_Shape theShell = Explo.Current();
-    theShell.Closed( Standard_True );
-  }
-
-/*
-  //Reconstructing
-  BRep_Builder BB;
-  for (i = 1; i <= Cones.Length(); i++)
-    {
-      TopoDS_Face Cone = TopoDS::Face( Cones(i) );
-      TopoDS_Edge Circ = TopoDS::Edge( Circs(i) );
-      TopoDS_Edge Seam = TopoDS::Edge( Seams(i) );
-      if (Circ.IsNull()) //case 1 with big offset
-       {
-         //ExtraFace is absent
-         
-         Handle(Geom_Surface) aSurf = BRep_Tool::Surface( Cone ), OffSurf = aSurf;
-
-         if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
-           aSurf = (Handle(Geom_OffsetSurface)::DownCast(aSurf))->BasisSurface();
-         gp_Cone theCone = (Handle(Geom_ConicalSurface)::DownCast(aSurf))->Cone();
-         gp_Pnt apex = theCone.Apex();
-         Standard_Real Uapex, Vapex;
-         ElSLib::Parameters( theCone, apex, Uapex, Vapex );
-         if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
-           apex = OffSurf->Value( Uapex, Vapex );
-
-         //Making new degenerated edge
-         Handle(Geom2d_Line) theLine = GCE2d_MakeLine( gp_Pnt2d( 0., Vapex ), gp_Pnt2d( 2.*M_PI, Vapex ) );
-         TopoDS_Edge NewEdge;
-         BB.MakeEdge( NewEdge );
-         NewEdge.Orientation(TopAbs_FORWARD);
-         BB.UpdateEdge( NewEdge, theLine, Cone, Precision::Confusion() );
-         BB.Range( NewEdge, 0., 2.*M_PI );
-         BB.SameParameter( NewEdge, Standard_True );
-         BB.SameRange( NewEdge, Standard_True );
-         BB.Degenerated( NewEdge, Standard_True );
-         TopoDS_Vertex Apex = BRepLib_MakeVertex( apex );
-         BB.Add( NewEdge, Apex.Oriented(TopAbs_FORWARD) );
-         BB.Add( NewEdge, Apex.Oriented(TopAbs_REVERSED) );
-
-         //Reconstructing Seam
-         Standard_Real f, l, par, cpar;
-         Handle(Geom2d_Curve) theCurve = BRep_Tool::CurveOnSurface( Seam, Cone, f, l );
-         gp_Lin2d aLine = (Handle(Geom2d_Line)::DownCast(theCurve))->Lin2d();
-         par = ElCLib::Parameter( aLine, gp_Pnt2d( Uapex, Vapex ) );
-         TopoDS_Shape aLocalShape = Seam.Oriented(TopAbs_FORWARD);
-         TopoDS_Vertex cver = TopExp::LastVertex( TopoDS::Edge(aLocalShape) );
-         cpar = BRep_Tool::Parameter( cver, Seam, Cone );
-         if (Abs(f-cpar) < Abs(l-cpar))
-           BB.Range( Seam, par, l );
-         else
-           BB.Range( Seam, f, par );
-         Seam.Free( Standard_True );
-         TopoDS_Shape cver1;
-         TopoDS_Iterator iter( Seam );
-         for (; iter.More(); iter.Next())
-           {
-             cver1 = iter.Value();
-             if (cver1.IsSame(cver))
-               break;
-           }
-         BB.Remove( Seam, cver1 );
-         if (Abs(f-cpar) < Abs(l-cpar))
-           BB.Add( Seam, Apex.Oriented( TopAbs::Compose(Seam.Orientation(),TopAbs_FORWARD) ) );
-         else
-           BB.Add( Seam, Apex.Oriented( TopAbs::Compose(Seam.Orientation(),TopAbs_REVERSED) ) );
-
-         //Adding NewEdge into Cone
-         TopoDS_Shape theWire;
-         for (fexp.Init( Cone, TopAbs_WIRE ); fexp.More(); fexp.Next())
-           {
-             theWire = fexp.Current();
-             Standard_Boolean found = Standard_False;
-             for (iter.Initialize( theWire ); iter.More(); iter.Next())
-               {
-                 if (Seam.IsSame( iter.Value() ))
-                   {
-                     found = Standard_True;
-                     break;
-                   }
-               }
-             if (found)
-               break;
-           }
-         theWire.Free( Standard_True );
-         NewEdge.Orientation( TopAbs::Compose(theWire.Orientation(),TopAbs_REVERSED) );
-         BB.Add( theWire, NewEdge );
-       } //end of case 1 with big offset
-      else
-       {
-         Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &Circ.TShape());
-         if (! TE->Degenerated()) //case 1
-           {
-             //Find ExtraFace
-             TopoDS_Face ExtraFace;
-             for (fexp.Init( myOffsetShape, TopAbs_FACE ); fexp.More(); fexp.Next())
-               {
-                 ExtraFace = TopoDS::Face( fexp.Current() );
-                 if (ExtraFace.IsSame( Cone ))
-                   continue;
-                 Standard_Boolean found = Standard_False;
-                 TopExp_Explorer eexp( ExtraFace, TopAbs_EDGE );
-                 for (; eexp.More(); eexp.Next())
-                   if (Circ.IsSame( eexp.Current() ))
-                     {
-                       found = Standard_True;
-                       break;
-                     }
-                 if (found)
-                   break;
-               }
-             
-             Handle(Geom_Surface) aSurf = BRep_Tool::Surface( Cone ), OffSurf = aSurf;
-             if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
-               aSurf = (Handle(Geom_OffsetSurface)::DownCast(aSurf))->BasisSurface();
-             gp_Cone theCone = (Handle(Geom_ConicalSurface)::DownCast(aSurf))->Cone();
-             gp_Pnt apex = theCone.Apex();
-             Standard_Real Uapex, Vapex;
-             ElSLib::Parameters( theCone, apex, Uapex, Vapex );
-             if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
-               apex = OffSurf->Value( Uapex, Vapex );
-             
-             //Making new degenerated edge
-             Handle(Geom2d_Line) theLine = GCE2d_MakeLine( gp_Pnt2d( 0., Vapex ), gp_Pnt2d( 2.*M_PI, Vapex ) );
-             TopoDS_Edge NewEdge;
-             BB.MakeEdge( NewEdge );
-             NewEdge.Orientation(TopAbs_FORWARD);
-             BB.UpdateEdge( NewEdge, theLine, Cone, BRep_Tool::Tolerance( Circ ) );
-             BB.Range( NewEdge, 0., 2.*M_PI );
-             BB.SameParameter( NewEdge, Standard_True );
-             BB.SameRange( NewEdge, Standard_True );
-             BB.Degenerated( NewEdge, Standard_True );
-             TopoDS_Vertex Apex = BRepLib_MakeVertex( apex );
-             BB.Add( NewEdge, Apex.Oriented(TopAbs_FORWARD) );
-             BB.Add( NewEdge, Apex.Oriented(TopAbs_REVERSED) );
-             
-             TopoDS_Vertex cver = TopExp::FirstVertex( Circ );
-             
-             //Reconstructing Seam
-             Standard_Real f, l, par, cpar;
-             Handle(Geom2d_Curve) theCurve = BRep_Tool::CurveOnSurface( Seam, Cone, f, l );
-             gp_Lin2d aLine = (Handle(Geom2d_Line)::DownCast(theCurve))->Lin2d();
-             par = ElCLib::Parameter( aLine, gp_Pnt2d( Uapex, Vapex ) );
-             cpar = BRep_Tool::Parameter( cver, Seam, Cone );
-             if (Abs(f-cpar) < Abs(l-cpar))
-               BB.Range( Seam, par, l );
-             else
-               BB.Range( Seam, f, par );
-             Seam.Free( Standard_True );
-             TopoDS_Shape cver1;
-             TopoDS_Iterator iter( Seam );
-             for (; iter.More(); iter.Next())
-               {
-                 cver1 = iter.Value();
-                 if (cver1.IsSame(cver))
-                   break;
-               }
-             BB.Remove( Seam, cver1 );
-             if (Abs(f-cpar) < Abs(l-cpar))
-               BB.Add( Seam, Apex.Oriented( TopAbs::Compose(Seam.Orientation(),TopAbs_FORWARD) ) );
-             else
-               BB.Add( Seam, Apex.Oriented( TopAbs::Compose(Seam.Orientation(),TopAbs_REVERSED) ) );
-             
-             //Removing ExtraFace from the shell
-             fexp.Init( myOffsetShape, TopAbs_SHELL );
-             TopoDS_Shape theShell = fexp.Current();
-             theShell.Free( Standard_True );
-             TopoDS_Shape ExtraFace1;
-             for (iter.Initialize( theShell ); iter.More(); iter.Next())
-               {
-                 ExtraFace1 = iter.Value();
-                 if (ExtraFace1.IsSame(ExtraFace))
-                   break;
-               }
-             BB.Remove( theShell, ExtraFace1 );
-             
-             //Substitute Circ by NewEdge in Cone
-             TopoDS_Shape theWire;
-             TopoDS_Shape Circ1;
-             for (fexp.Init( Cone, TopAbs_WIRE ); fexp.More(); fexp.Next())
-               {
-                 theWire = fexp.Current();
-                 Standard_Boolean found = Standard_False;
-                 for (iter.Initialize( theWire ); iter.More(); iter.Next())
-                   {
-                     Circ1 = iter.Value();
-                     if (Circ1.IsSame(Circ))
-                       {
-                         found = Standard_True;
-                         break;
-                       }
-                   }
-                 if (found)
-                   break;
-               }
-             TopAbs_Orientation Or = Circ1.Orientation();
-             theWire.Free( Standard_True );
-             BB.Remove( theWire, Circ1 );
-             BB.Add( theWire, NewEdge.Oriented(Or) );
-           } //end of case 1
-         else // Circ is degenerated
-           {
-             if (myOffset > 0. && myJoin == GeomAbs_Arc) //case 2
-               {
-                 TopoDS_Vertex cver = TopExp::FirstVertex( Circ );
-                 
-                 TopoDS_Face OrCone = TopoDS::Face( myInitOffsetFace.Root( Cone ) );
-                 Handle(Geom_Surface) aSurf = BRep_Tool::Surface( OrCone ), OffSurf = aSurf;
-                 if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
-                   aSurf = (Handle(Geom_OffsetSurface)::DownCast(aSurf))->BasisSurface();
-                 gp_Cone theCone = (Handle(Geom_ConicalSurface)::DownCast(aSurf))->Cone();
-                 gp_Pnt apex = theCone.Apex();
-                 if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
-                   {
-                     Standard_Real Uapex, Vapex;
-                     ElSLib::Parameters( theCone, apex, Uapex, Vapex );
-                     apex = OffSurf->Value( Uapex, Vapex );
-                   }
-
-                 Standard_Real f, l;
-                 Handle(Geom_Curve) ccur = BRep_Tool::Curve( Circ, f, l );
-                 gp_Ax2 Axe2 = (Handle(Geom_Circle)::DownCast(ccur))->Circ().Position();
-                 gp_Ax3 Axe3( Axe2 );
-                 Axe3.SetLocation( apex );
-                 gp_Sphere theSphere( Axe3, myOffset );
-
-                 gp_Pnt OrPnt = BRep_Tool::Pnt(cver);
-                 Standard_Real Uor, Vor;
-                 ElSLib::Parameters( theSphere, OrPnt, Uor, Vor );
-                 TopoDS_Face NewFace;
-                 if (Vor > 0.)
-                   NewFace = BRepLib_MakeFace( theSphere, 0., 2.*M_PI, Vor, M_PI/2. );
-                 else
-                   NewFace = BRepLib_MakeFace( theSphere, 0., 2.*M_PI, -M_PI/2., Vor );
-                 
-                 //Updating the bound of NewFace
-                 TopoDS_Edge Bound;
-                 TopExp_Explorer eexp( NewFace, TopAbs_EDGE );
-                 for (; eexp.More(); eexp.Next())
-                   {
-                     Bound = TopoDS::Edge( eexp.Current() );
-                     Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &Bound.TShape());
-                     if (!TE->Degenerated() && !BRepTools::IsReallyClosed( Bound, NewFace ))
-                       break;
-                   }
-                 Handle(Geom2d_Curve) pcurve = BRep_Tool::CurveOnSurface( Circ, Cone, f, l );
-                 BB.UpdateEdge( Bound, pcurve, Cone, BRep_Tool::Tolerance(Circ) );
-                 TopoDS_Vertex bver = TopExp::FirstVertex( Bound );
-                 BB.UpdateVertex( bver, BRep_Tool::Tolerance(cver) );
-                 
-                 //Updating cver in Seam
-                 TopoDS_Vertex cver1;
-                 TopoDS_Iterator iter( Seam );
-                 for (; iter.More(); iter.Next())
-                   {
-                     cver1 = TopoDS::Vertex( iter.Value() );
-                     if (cver1.IsSame(cver))
-                       break;
-                   }
-                 TopAbs_Orientation Or = cver1.Orientation();
-                 Seam.Free( Standard_True );
-                 BB.Remove( Seam, cver1 );
-                 BB.Add( Seam, bver.Oriented(Or) );
-                 
-                 //Substitute Circ by Bound in Cone
-                 TopoDS_Shape theWire;
-                 TopoDS_Shape Circ1;
-                 for (fexp.Init( Cone, TopAbs_WIRE ); fexp.More(); fexp.Next())
-                   {
-                     theWire = fexp.Current();
-                     Standard_Boolean found = Standard_False;
-                     for (iter.Initialize( theWire ); iter.More(); iter.Next())
-                       {
-                         Circ1 = iter.Value();
-                         if (Circ1.IsSame(Circ))
-                           {
-                             found = Standard_True;
-                             break;
-                           }
-                       }
-                     if (found)
-                       break;
-                   }
-                 Or = Circ1.Orientation();
-                 theWire.Free( Standard_True );
-                 BB.Remove( theWire, Circ1 );
-                 BB.Add( theWire, Bound.Oriented(Or) );
-                 
-                 //Adding NewFace to the shell
-                 fexp.Init( myOffsetShape, TopAbs_SHELL );
-                 TopoDS_Shape theShell = fexp.Current();
-                 theShell.Free( Standard_True );
-                 BB.Add( theShell, NewFace );
-                 
-                 theShell.Closed( Standard_True );
-               } //end of case 2
-             else // if ((myOffset > 0. && myJoin == GeomAbs_Intersection) || myOffset < 0.) //case 3, 4
-               {
-                 Handle(Geom_Surface) aSurf = BRep_Tool::Surface( Cone ), OffSurf = aSurf;
-                 if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
-                   aSurf = (Handle(Geom_OffsetSurface)::DownCast(aSurf))->BasisSurface();
-                 gp_Cone theCone = (Handle(Geom_ConicalSurface)::DownCast(aSurf))->Cone();
-                 gp_Pnt apex = theCone.Apex();
-                 Standard_Real Uapex, Vapex;
-                 ElSLib::Parameters( theCone, apex, Uapex, Vapex );
-                 if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
-                   apex = OffSurf->Value( Uapex, Vapex );
-                 
-                 //Making new degenerated edge
-                 Handle(Geom2d_Line) theLine = GCE2d_MakeLine( gp_Pnt2d( 0., Vapex ), gp_Pnt2d( 2.*M_PI, Vapex ) );
-                 TopoDS_Edge NewEdge;
-                 BB.MakeEdge( NewEdge );
-                 NewEdge.Orientation(TopAbs_FORWARD);
-                 BB.UpdateEdge( NewEdge, theLine, Cone, BRep_Tool::Tolerance( Circ ) );
-                 BB.Range( NewEdge, 0., 2.*M_PI );
-                 BB.SameParameter( NewEdge, Standard_True );
-                 BB.SameRange( NewEdge, Standard_True );
-                 BB.Degenerated( NewEdge, Standard_True );
-                 TopoDS_Vertex Apex = BRepLib_MakeVertex( apex );
-                 BB.Add( NewEdge, Apex.Oriented(TopAbs_FORWARD) );
-                 BB.Add( NewEdge, Apex.Oriented(TopAbs_REVERSED) );
-                 
-                 TopoDS_Vertex cver = TopExp::FirstVertex( Circ );
-                 
-                 //Reconstructing Seam
-                 Standard_Real f, l, par, cpar;
-                 Handle(Geom2d_Curve) theCurve = BRep_Tool::CurveOnSurface( Seam, Cone, f, l );
-                 gp_Lin2d aLine = (Handle(Geom2d_Line)::DownCast(theCurve))->Lin2d();
-                 par = ElCLib::Parameter( aLine, gp_Pnt2d( Uapex, Vapex ) );
-                 cpar = BRep_Tool::Parameter( cver, Seam, Cone );
-                 if (Abs(f-cpar) < Abs(l-cpar))
-                   BB.Range( Seam, par, l );
-                 else
-                   BB.Range( Seam, f, par );
-                 Seam.Free( Standard_True );
-                 TopoDS_Shape cver1;
-                 TopoDS_Iterator iter( Seam );
-                 for (; iter.More(); iter.Next())
-                   {
-                     cver1 = iter.Value();
-                     if (cver1.IsSame(cver))
-                       break;
-                   }
-                 BB.Remove( Seam, cver1 );
-                 if (Abs(f-cpar) < Abs(l-cpar))
-                   BB.Add( Seam, Apex.Oriented( TopAbs::Compose(Seam.Orientation(),TopAbs_FORWARD) ) );
-                 else
-                   BB.Add( Seam, Apex.Oriented( TopAbs::Compose(Seam.Orientation(),TopAbs_REVERSED) ) );
-                 
-                 //Substitute Circ by NewEdge in Cone
-                 TopoDS_Shape theWire;
-                 TopoDS_Shape Circ1;
-                 for (fexp.Init( Cone, TopAbs_WIRE ); fexp.More(); fexp.Next())
-                   {
-                     theWire = fexp.Current();
-                     Standard_Boolean found = Standard_False;
-                     for (iter.Initialize( theWire ); iter.More(); iter.Next())
-                       {
-                         Circ1 = iter.Value();
-                         if (Circ1.IsSame(Circ))
-                           {
-                             found = Standard_True;
-                             break;
-                           }
-                       }
-                     if (found)
-                       break;
-                   }
-                 TopAbs_Orientation Or = Circ1.Orientation();
-                 theWire.Free( Standard_True );
-                 BB.Remove( theWire, Circ1 );
-                 BB.Add( theWire, NewEdge.Oriented(Or) );
-                 
-                 fexp.Init( myOffsetShape, TopAbs_SHELL );
-                 TopoDS_Shape theShell = fexp.Current();
-                 theShell.Closed( Standard_True );
-               } //end of case 3, 4
-           }
-       } //else (! Circ.IsNull())
-    }
-*/
-
-  Standard_Integer            NbShell = 0;
-  TopoDS_Compound             NC;
-  TopoDS_Shape                S1;
-  BB.MakeCompound (NC);
-  
-  for (Explo.Init(myOffsetShape,TopAbs_SHELL); Explo.More(); Explo.Next()) {
-    const TopoDS_Shell& Sh = TopoDS::Shell(Explo.Current());
-    NbShell++;
-    if (Sh.Closed()) {
-      TopoDS_Solid  Sol;
-      BB.MakeSolid  (Sol);
-      BB.Add        (Sol,Sh);
-      Sol.Closed(Standard_True);
-      BB.Add (NC,Sol);
-      if (NbShell == 1) S1 = Sol;
+  if (myShape.ShapeType() == TopAbs_SOLID || myThickening)
+  {
+    Explo.Init( myOffsetShape, TopAbs_SHELL );
+    
+    if (Explo.More()) {
+      TopoDS_Shape theShell = Explo.Current();
+      theShell.Closed( Standard_True );
     }
-    else {
-      BB.Add (NC,Sh);
-      if (NbShell == 1) S1 = Sh;
+    
+    Standard_Integer            NbShell = 0;
+    TopoDS_Compound             NC;
+    TopoDS_Shape                S1;
+    BB.MakeCompound (NC);
+    
+    for (Explo.Init(myOffsetShape,TopAbs_SHELL); Explo.More(); Explo.Next()) {
+      const TopoDS_Shell& Sh = TopoDS::Shell(Explo.Current());
+      NbShell++;
+      if (Sh.Closed()) {
+        TopoDS_Solid  Sol;
+        BB.MakeSolid  (Sol);
+        BB.Add        (Sol,Sh);
+        Sol.Closed(Standard_True);
+        BB.Add (NC,Sol);
+        if (NbShell == 1) S1 = Sol;
+      }
+      else {
+        BB.Add (NC,Sh);
+        if (NbShell == 1) S1 = Sh;
+      }
     }
+    if (NbShell == 1) myOffsetShape = S1;
+    else              myOffsetShape = NC;
   }
-  if (NbShell == 1) myOffsetShape = S1;
-  else              myOffsetShape = NC;
 }
 
 
index c572047..7e0b8e6 100644 (file)
@@ -557,8 +557,12 @@ void BRepOffset_Offset::Init(const TopoDS_Face&                  Face,
     BRepOffset::Surface( S, myOffset, myStatus);
 
   //processing offsets of faces with possible degenerated edges
+  Standard_Boolean UminDegen = Standard_False;
+  Standard_Boolean UmaxDegen = Standard_False;
   Standard_Boolean VminDegen = Standard_False;
   Standard_Boolean VmaxDegen = Standard_False;
+  Standard_Boolean UisoDegen = Standard_False;
+  Standard_Boolean VisoDegen = Standard_False;
   gp_Pnt MinApex, MaxApex;
   Standard_Boolean HasSingularity = Standard_False;
   Standard_Real uf1, uf2, vf1, vf2, fpar, lpar;
@@ -578,20 +582,41 @@ void BRepOffset_Offset::Init(const TopoDS_Face&                  Face,
       if (!DegEdges.IsEmpty())
        {
          const Standard_Real TolApex = 1.e-5;
+          //define the iso of singularity (u or v)
+          const TopoDS_Edge& theDegEdge = TopoDS::Edge(DegEdges(1));
+          Handle(Geom2d_Curve) aCurve = BRep_Tool::CurveOnSurface(theDegEdge, Face, fpar, lpar);
+          gp_Pnt2d fp2d = aCurve->Value(fpar);
+          gp_Pnt2d lp2d = aCurve->Value(lpar);
+          if (Abs(fp2d.X() - lp2d.X()) <= Precision::PConfusion())
+            UisoDegen = Standard_True;
+          else
+            VisoDegen = Standard_True;
+          
          if (DegEdges.Length() == 2)
            {
-             VminDegen = Standard_True;
-             VmaxDegen = Standard_True;
+              if (UisoDegen)
+              { UminDegen = Standard_True; UmaxDegen = Standard_True; }
+              else
+              { VminDegen = Standard_True; VmaxDegen = Standard_True; }
            }
          else //DegEdges.Length() == 1
            {
              const TopoDS_Edge& theDegEdge = TopoDS::Edge(DegEdges(1));
              Handle(Geom2d_Curve) aCurve = BRep_Tool::CurveOnSurface(theDegEdge, Face, fpar, lpar);
-             gp_Pnt2d aPnt2d = aCurve->Value(fpar);
-             if (Abs(aPnt2d.Y() - vf1) <= Precision::Confusion())
-               VminDegen = Standard_True;
-             else
-               VmaxDegen = Standard_True;
+              if (UisoDegen)
+              {
+                if (Abs(fp2d.X() - uf1) <= Precision::Confusion())
+                  UminDegen = Standard_True;
+                else
+                  UmaxDegen = Standard_True;
+              }
+              else
+              {
+                if (Abs(fp2d.Y() - vf1) <= Precision::Confusion())
+                  VminDegen = Standard_True;
+                else
+                  VmaxDegen = Standard_True;
+              }
            }
          if (TheSurf->DynamicType() == STANDARD_TYPE(Geom_ConicalSurface))
            {
@@ -614,88 +639,166 @@ void BRepOffset_Offset::Init(const TopoDS_Face&                  Face,
            }
          else //TheSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface)
            {
+              if (UminDegen)
+              {
+                Handle(Geom_Curve) uiso = TheSurf->UIso( uf1 );
+                if (BRepOffset_Tool::Gabarit( uiso ) > TolApex)
+                {
+                  Handle(Geom_Surface) BasisSurf = (*((Handle(Geom_OffsetSurface)*)&TheSurf))->BasisSurface();
+                  gp_Pnt Papex, Pfirst, Pquart, Pmid;
+                  Papex = BasisSurf->Value( uf1, vf1 );
+                  Pfirst = TheSurf->Value( uf1, vf1 );
+                  Pquart = TheSurf->Value( uf1, 0.75*vf1+0.25*vf2 );
+                  Pmid   = TheSurf->Value( uf1, 0.5*(vf1+vf2) );
+                  gp_Vec DirApex = gp_Vec(Pfirst,Pquart) ^ gp_Vec(Pfirst,Pmid);
+                  Handle(Geom_Line) LineApex = new Geom_Line( Papex, DirApex );
+                  gp_Vec DirGeneratrix = BasisSurf->DN( uf1, vf1, 1, 0 );
+                  Handle(Geom_Line) LineGeneratrix = new Geom_Line( Pfirst, DirGeneratrix );
+                  GeomAPI_ExtremaCurveCurve theExtrema( LineGeneratrix, LineApex );
+                  gp_Pnt Pint1, Pint2;
+                  theExtrema.NearestPoints(Pint1, Pint2);
+                  Standard_Real length = Pfirst.Distance(Pint1);
+                  if (OffsetOutside)
+                  {
+                    TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1, vf2);
+                    GeomLib::ExtendSurfByLength(*((Handle(Geom_BoundedSurface)*)&TheSurf), length, 1,
+                                                Standard_True, Standard_False);
+                    Standard_Real u1, u2, v1, v2;
+                    TheSurf->Bounds( u1, u2, v1, v2 );
+                    MinApex = TheSurf->Value( u1, vf1 );
+                  }
+                  else
+                  {
+                    Handle(Geom_Curve) viso = TheSurf->VIso( vf1 );
+                    GeomAPI_ProjectPointOnCurve Projector( Pint1, viso );
+                    Standard_Real NewFirstU = Projector.LowerDistanceParameter();
+                    TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, NewFirstU, uf2, vf1, vf2);
+                    MinApex = TheSurf->Value( NewFirstU, vf1 );
+                  }
+                  HasSingularity = Standard_True;
+                }
+              } //end of if (UminDegen)
+             if (UmaxDegen)
+              {
+                Handle(Geom_Curve) uiso = TheSurf->UIso( uf2 );
+                if (BRepOffset_Tool::Gabarit( uiso ) > TolApex)
+                {
+                  Handle(Geom_Surface) BasisSurf = (*((Handle(Geom_OffsetSurface)*)&TheSurf))->BasisSurface();
+                  gp_Pnt Papex, Pfirst, Pquart, Pmid;
+                  Papex  = BasisSurf->Value( uf2, vf1 );
+                  Pfirst = TheSurf->Value( uf2, vf1 );
+                  Pquart = TheSurf->Value( uf2, 0.75*vf1+0.25*vf2 );
+                  Pmid   = TheSurf->Value( uf2, 0.5*(vf1+vf2) );
+                  gp_Vec DirApex = gp_Vec(Pfirst,Pquart) ^ gp_Vec(Pfirst,Pmid);
+                  Handle(Geom_Line) LineApex = new Geom_Line( Papex, DirApex );
+                  gp_Vec DirGeneratrix = BasisSurf->DN( uf2, vf1, 1, 0 );
+                  Handle(Geom_Line) LineGeneratrix = new Geom_Line( Pfirst, DirGeneratrix );
+                  GeomAPI_ExtremaCurveCurve theExtrema( LineGeneratrix, LineApex );
+                  gp_Pnt Pint1, Pint2;
+                  theExtrema.NearestPoints(Pint1, Pint2);
+                  Standard_Real length = Pfirst.Distance(Pint1);
+                  if (OffsetOutside)
+                  {
+                    TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1, vf2);
+                    GeomLib::ExtendSurfByLength(*((Handle(Geom_BoundedSurface)*)&TheSurf), length, 1,
+                                                Standard_True, Standard_True);
+                    Standard_Real u1, u2, v1, v2;
+                    TheSurf->Bounds( u1, u2, v1, v2 );
+                    MaxApex = TheSurf->Value( u2, vf1 );
+                  }
+                  else
+                  {
+                    Handle(Geom_Curve) viso = TheSurf->VIso( vf1 );
+                    GeomAPI_ProjectPointOnCurve Projector( Pint1, viso );
+                    Standard_Real NewLastU = Projector.LowerDistanceParameter();
+                    TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, NewLastU, vf1, vf2);
+                    MaxApex = TheSurf->Value( NewLastU, vf1 );
+                  }
+                  HasSingularity = Standard_True;
+                }
+              } //end of if (UmaxDegen)
              if (VminDegen)
-               {
-                 Handle(Geom_Curve) viso = TheSurf->VIso( vf1 );
-                 if (BRepOffset_Tool::Gabarit( viso ) > TolApex)
-                   {
-                     Handle(Geom_Surface) BasisSurf = (*((Handle(Geom_OffsetSurface)*)&TheSurf))->BasisSurface();
-                     gp_Pnt Papex, Pfirst, Plast, Pmid;
-                     Papex = BasisSurf->Value( uf1, vf1 );
-                     Pfirst = TheSurf->Value( uf1, vf1 );
-                     Plast  = TheSurf->Value( uf2, vf1 );
-                     Pmid   = TheSurf->Value( (uf1+uf2)/2., vf1 );
-                     gp_Vec DirApex = gp_Vec(Pfirst,Pmid) ^ gp_Vec(Pfirst,Plast);
-                     Handle(Geom_Line) LineApex = new Geom_Line( Papex, DirApex );
-                     gp_Vec DirGeneratrix = BasisSurf->DN( uf1, vf1, 0, 1 );
-                     Handle(Geom_Line) LineGeneratrix = new Geom_Line( Pfirst, DirGeneratrix );
-                     GeomAPI_ExtremaCurveCurve theExtrema( LineGeneratrix, LineApex );
-                     gp_Pnt Pint1, Pint2;
-                     theExtrema.NearestPoints(Pint1, Pint2);
-                     Standard_Real length = Pfirst.Distance(Pint1);
-                     if (OffsetOutside)
-                       {
-                         TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1, vf2);
-                         GeomLib::ExtendSurfByLength(*((Handle(Geom_BoundedSurface)*)&TheSurf), length, 1,
-                                                     Standard_False, Standard_False);
-                         Standard_Real u1, u2, v1, v2;
-                         TheSurf->Bounds( u1, u2, v1, v2 );
-                         MinApex = TheSurf->Value( uf1, v1 );
-                       }
-                     else
-                       {
-                         Handle(Geom_Curve) uiso = TheSurf->UIso( uf1 );
-                         GeomAPI_ProjectPointOnCurve Projector( Pint1, uiso );
-                         Standard_Real NewFirstV = Projector.LowerDistanceParameter();
-                         TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, NewFirstV, vf2);
-                         MinApex = TheSurf->Value( uf1, NewFirstV );
-                         //TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1+length, vf2);
-                         //MinApex = TheSurf->Value( uf1, vf1+length );
-                       }
-                     HasSingularity = Standard_True;
-                   }
-               } //end of if (VminDegen)
+              {
+                Handle(Geom_Curve) viso = TheSurf->VIso( vf1 );
+                if (BRepOffset_Tool::Gabarit( viso ) > TolApex)
+                {
+                  Handle(Geom_Surface) BasisSurf = (*((Handle(Geom_OffsetSurface)*)&TheSurf))->BasisSurface();
+                  gp_Pnt Papex, Pfirst, Pquart, Pmid;
+                  Papex = BasisSurf->Value( uf1, vf1 );
+                  Pfirst = TheSurf->Value( uf1, vf1 );
+                  Pquart = TheSurf->Value( 0.75*uf1+0.25*uf2, vf1 );
+                  Pmid   = TheSurf->Value( 0.5*(uf1+uf2), vf1 );
+                  gp_Vec DirApex = gp_Vec(Pfirst,Pquart) ^ gp_Vec(Pfirst,Pmid);
+                  Handle(Geom_Line) LineApex = new Geom_Line( Papex, DirApex );
+                  gp_Vec DirGeneratrix = BasisSurf->DN( uf1, vf1, 0, 1 );
+                  Handle(Geom_Line) LineGeneratrix = new Geom_Line( Pfirst, DirGeneratrix );
+                  GeomAPI_ExtremaCurveCurve theExtrema( LineGeneratrix, LineApex );
+                  gp_Pnt Pint1, Pint2;
+                  theExtrema.NearestPoints(Pint1, Pint2);
+                  Standard_Real length = Pfirst.Distance(Pint1);
+                  if (OffsetOutside)
+                  {
+                    TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1, vf2);
+                    GeomLib::ExtendSurfByLength(*((Handle(Geom_BoundedSurface)*)&TheSurf), length, 1,
+                                                Standard_False, Standard_False);
+                    Standard_Real u1, u2, v1, v2;
+                    TheSurf->Bounds( u1, u2, v1, v2 );
+                    MinApex = TheSurf->Value( uf1, v1 );
+                  }
+                  else
+                  {
+                    Handle(Geom_Curve) uiso = TheSurf->UIso( uf1 );
+                    GeomAPI_ProjectPointOnCurve Projector( Pint1, uiso );
+                    Standard_Real NewFirstV = Projector.LowerDistanceParameter();
+                    TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, NewFirstV, vf2);
+                    MinApex = TheSurf->Value( uf1, NewFirstV );
+                    //TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1+length, vf2);
+                    //MinApex = TheSurf->Value( uf1, vf1+length );
+                  }
+                  HasSingularity = Standard_True;
+                }
+              } //end of if (VminDegen)
              if (VmaxDegen)
-               {
-                 Handle(Geom_Curve) viso = TheSurf->VIso( vf2 );
-                 if (BRepOffset_Tool::Gabarit( viso ) > TolApex)
-                   {
-                     Handle(Geom_Surface) BasisSurf = (*((Handle(Geom_OffsetSurface)*)&TheSurf))->BasisSurface();
-                     gp_Pnt Papex, Pfirst, Plast, Pmid;
-                     Papex = BasisSurf->Value( uf1, vf2 );
-                     Pfirst = TheSurf->Value( uf1, vf2 );
-                     Plast  = TheSurf->Value( uf2, vf2 );
-                     Pmid   = TheSurf->Value( (uf1+uf2)/2., vf2 );
-                     gp_Vec DirApex = gp_Vec(Pfirst,Pmid) ^ gp_Vec(Pfirst,Plast);
-                     Handle(Geom_Line) LineApex = new Geom_Line( Papex, DirApex );
-                     gp_Vec DirGeneratrix = BasisSurf->DN( uf1, vf2, 0, 1 );
-                     Handle(Geom_Line) LineGeneratrix = new Geom_Line( Pfirst, DirGeneratrix );
-                     GeomAPI_ExtremaCurveCurve theExtrema( LineGeneratrix, LineApex );
-                     gp_Pnt Pint1, Pint2;
-                     theExtrema.NearestPoints(Pint1, Pint2);
-                     Standard_Real length = Pfirst.Distance(Pint1);
-                     if (OffsetOutside)
-                       {
-                         TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1, vf2);
-                         GeomLib::ExtendSurfByLength(*((Handle(Geom_BoundedSurface)*)&TheSurf), length, 1,
-                                                     Standard_False, Standard_True);
-                         Standard_Real u1, u2, v1, v2;
-                         TheSurf->Bounds( u1, u2, v1, v2 );
-                         MaxApex = TheSurf->Value( uf1, v2 );
-                       }
-                     else
-                       {
-                         Handle(Geom_Curve) uiso = TheSurf->UIso( uf1 );
-                         GeomAPI_ProjectPointOnCurve Projector( Pint1, uiso );
-                         Standard_Real NewLastV = Projector.LowerDistanceParameter();
-                         TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1, NewLastV);
-                         MaxApex = TheSurf->Value( uf1, NewLastV );
-                         //TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1, vf2-length);
-                         //MaxApex = TheSurf->Value( uf1, vf2-length );
-                       }
-                     HasSingularity = Standard_True;
-                   }
-               } //end of if (VmaxDegen)
+              {
+                Handle(Geom_Curve) viso = TheSurf->VIso( vf2 );
+                if (BRepOffset_Tool::Gabarit( viso ) > TolApex)
+                {
+                  Handle(Geom_Surface) BasisSurf = (*((Handle(Geom_OffsetSurface)*)&TheSurf))->BasisSurface();
+                  gp_Pnt Papex, Pfirst, Pquart, Pmid;
+                  Papex = BasisSurf->Value( uf1, vf2 );
+                  Pfirst = TheSurf->Value( uf1, vf2 );
+                  Pquart = TheSurf->Value( 0.75*uf1+0.25*uf2, vf2 );
+                  Pmid   = TheSurf->Value( 0.5*(uf1+uf2), vf2 );
+                  gp_Vec DirApex = gp_Vec(Pfirst,Pquart) ^ gp_Vec(Pfirst,Pmid);
+                  Handle(Geom_Line) LineApex = new Geom_Line( Papex, DirApex );
+                  gp_Vec DirGeneratrix = BasisSurf->DN( uf1, vf2, 0, 1 );
+                  Handle(Geom_Line) LineGeneratrix = new Geom_Line( Pfirst, DirGeneratrix );
+                  GeomAPI_ExtremaCurveCurve theExtrema( LineGeneratrix, LineApex );
+                  gp_Pnt Pint1, Pint2;
+                  theExtrema.NearestPoints(Pint1, Pint2);
+                  Standard_Real length = Pfirst.Distance(Pint1);
+                  if (OffsetOutside)
+                  {
+                    TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1, vf2);
+                    GeomLib::ExtendSurfByLength(*((Handle(Geom_BoundedSurface)*)&TheSurf), length, 1,
+                                                Standard_False, Standard_True);
+                    Standard_Real u1, u2, v1, v2;
+                    TheSurf->Bounds( u1, u2, v1, v2 );
+                    MaxApex = TheSurf->Value( uf1, v2 );
+                  }
+                  else
+                  {
+                    Handle(Geom_Curve) uiso = TheSurf->UIso( uf1 );
+                    GeomAPI_ProjectPointOnCurve Projector( Pint1, uiso );
+                    Standard_Real NewLastV = Projector.LowerDistanceParameter();
+                    TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1, NewLastV);
+                    MaxApex = TheSurf->Value( uf1, NewLastV );
+                    //TheSurf = new Geom_RectangularTrimmedSurface(TheSurf, uf1, uf2, vf1, vf2-length);
+                    //MaxApex = TheSurf->Value( uf1, vf2-length );
+                  }
+                  HasSingularity = Standard_True;
+                }
+              } //end of if (VmaxDegen)
            } //end of else (case of Geom_OffsetSurface)
        } //end of if (!DegEdges.IsEmpty())
     } //end of processing offsets of faces with possible degenerated edges
diff --git a/tests/bugs/modalg_5/bug25406_1 b/tests/bugs/modalg_5/bug25406_1
new file mode 100644 (file)
index 0000000..73419c6
--- /dev/null
@@ -0,0 +1,27 @@
+puts "================"
+puts "OCC25406"
+puts "================"
+puts ""
+##################################
+# BRepOffset_MakeOffset algorithm fails on the face with two degenerated edges on u-iso null curves
+##################################
+
+restore [locate_data_file bug25406_offset_shape.brep] a
+
+offsetshape result a 10
+
+set length 1875.31
+
+set nb_v_good 2
+set nb_e_good 4
+set nb_w_good 1
+set nb_f_good 1
+set nb_sh_good 1
+set nb_sol_good 0
+set nb_compsol_good 0
+set nb_compound_good 0
+set nb_shape_good 9
+
+smallview
+fit
+set only_screen_axo 1
diff --git a/tests/bugs/modalg_5/bug25406_2 b/tests/bugs/modalg_5/bug25406_2
new file mode 100644 (file)
index 0000000..ad5325e
--- /dev/null
@@ -0,0 +1,27 @@
+puts "================"
+puts "OCC25406"
+puts "================"
+puts ""
+##################################
+# BRepOffset_MakeOffset algorithm fails on the face with two degenerated edges on u-iso null curves
+##################################
+
+restore [locate_data_file bug25406_offset_shape.brep] a
+
+offsetshape result a -10
+
+set length 1875.31
+
+set nb_v_good 2
+set nb_e_good 4
+set nb_w_good 1
+set nb_f_good 1
+set nb_sh_good 1
+set nb_sol_good 0
+set nb_compsol_good 0
+set nb_compound_good 0
+set nb_shape_good 9
+
+smallview
+fit
+set only_screen_axo 1