From 0e0f7a7cdee409894d375e60f654834c221e1131 Mon Sep 17 00:00:00 2001
From: jgv <jgv@opencascade.com>
Date: Thu, 23 Oct 2014 14:36:48 +0400
Subject: [PATCH] 0025334: BRepOffsetAPI_MakeOffset algorithm crashes on some
 customer's shape

Test cases for issue CR25334
---
 src/BRepFill/BRepFill_OffsetWire.cxx          |  69 +-
 src/BRepMAT2d/BRepMAT2d_BisectingLocus.cxx    |   7 +-
 .../BRepOffsetAPI_MakeOffset.cdl              |   9 +-
 src/BRepTest/BRepTest_CurveCommands.cxx       |  28 +-
 src/MAT2d/MAT2d_Circuit.cxx                   |  16 +-
 src/MAT2d/MAT2d_Mat2d.cdl                     |   8 +-
 src/MAT2d/MAT2d_Mat2d.cxx                     | 671 +++++++++++++++++-
 src/MAT2d/MAT2d_Tool2d.cdl                    |   6 +-
 src/MAT2d/MAT2d_Tool2d.cxx                    |  26 +-
 tests/bugs/modalg_4/bug745_10                 |   7 +-
 tests/bugs/modalg_5/bug25334_1                |  35 +
 tests/bugs/modalg_5/bug25334_10               |  35 +
 tests/bugs/modalg_5/bug25334_11               |  35 +
 tests/bugs/modalg_5/bug25334_12               |  35 +
 tests/bugs/modalg_5/bug25334_13               |  35 +
 tests/bugs/modalg_5/bug25334_14               |  35 +
 tests/bugs/modalg_5/bug25334_15               |  35 +
 tests/bugs/modalg_5/bug25334_16               |  35 +
 tests/bugs/modalg_5/bug25334_17               |  35 +
 tests/bugs/modalg_5/bug25334_18               |  35 +
 tests/bugs/modalg_5/bug25334_19               |  35 +
 tests/bugs/modalg_5/bug25334_2                |  35 +
 tests/bugs/modalg_5/bug25334_20               |  35 +
 tests/bugs/modalg_5/bug25334_3                |  35 +
 tests/bugs/modalg_5/bug25334_4                |  35 +
 tests/bugs/modalg_5/bug25334_5                |  35 +
 tests/bugs/modalg_5/bug25334_6                |  35 +
 tests/bugs/modalg_5/bug25334_7                |  35 +
 tests/bugs/modalg_5/bug25334_8                |  35 +
 tests/bugs/modalg_5/bug25334_9                |  35 +
 30 files changed, 1465 insertions(+), 82 deletions(-)
 create mode 100644 tests/bugs/modalg_5/bug25334_1
 create mode 100644 tests/bugs/modalg_5/bug25334_10
 create mode 100644 tests/bugs/modalg_5/bug25334_11
 create mode 100644 tests/bugs/modalg_5/bug25334_12
 create mode 100644 tests/bugs/modalg_5/bug25334_13
 create mode 100644 tests/bugs/modalg_5/bug25334_14
 create mode 100644 tests/bugs/modalg_5/bug25334_15
 create mode 100644 tests/bugs/modalg_5/bug25334_16
 create mode 100644 tests/bugs/modalg_5/bug25334_17
 create mode 100644 tests/bugs/modalg_5/bug25334_18
 create mode 100644 tests/bugs/modalg_5/bug25334_19
 create mode 100644 tests/bugs/modalg_5/bug25334_2
 create mode 100644 tests/bugs/modalg_5/bug25334_20
 create mode 100644 tests/bugs/modalg_5/bug25334_3
 create mode 100644 tests/bugs/modalg_5/bug25334_4
 create mode 100644 tests/bugs/modalg_5/bug25334_5
 create mode 100644 tests/bugs/modalg_5/bug25334_6
 create mode 100644 tests/bugs/modalg_5/bug25334_7
 create mode 100644 tests/bugs/modalg_5/bug25334_8
 create mode 100644 tests/bugs/modalg_5/bug25334_9

diff --git a/src/BRepFill/BRepFill_OffsetWire.cxx b/src/BRepFill/BRepFill_OffsetWire.cxx
index 1f63c8b22c..d9d96cbcbc 100644
--- a/src/BRepFill/BRepFill_OffsetWire.cxx
+++ b/src/BRepFill/BRepFill_OffsetWire.cxx
@@ -265,22 +265,34 @@ static Standard_Boolean KPartCircle
 
   TopoDS_Vertex V1,V2;
   TopExp::Vertices(E,V1,V2);
-  if (!V1.IsSame(V2)) //may be case of line
+  if (!V1.IsSame(V2) || //open result or closed circle
+      C->IsKind(STANDARD_TYPE(Geom_Circle))) 
   {
-    if (!C->IsKind(STANDARD_TYPE(Geom_Line))) return Standard_False;
-    Handle(Geom_Line) LE = Handle(Geom_Line)::DownCast(C);
     Standard_Real anOffset = myOffset;
     if (E.Orientation() == TopAbs_REVERSED) anOffset *= -1;
     
-    Handle(Geom2d_Curve) aPCurve;
-    Handle(Geom_Surface) aSurf;
-    TopLoc_Location aLoc;
-    BRep_Tool::CurveOnSurface(E, aPCurve, aSurf, aLoc, f, l);
+    Handle(Geom2d_Curve) aPCurve = BRep_Tool::CurveOnSurface(E, mySpine, f, l);
     Handle(Geom2dAdaptor_HCurve) AHC = new Geom2dAdaptor_HCurve(aPCurve, f, l);
-    Adaptor3d_OffsetCurve Off(AHC,anOffset);
-    Handle(Geom2d_Line) OLC = new Geom2d_Line(Off.Line());
+    Handle(Geom2d_Curve) OC;
+    if (AHC->GetType() == GeomAbs_Line)
+    {
+      Adaptor3d_OffsetCurve Off(AHC,anOffset);
+      OC = new Geom2d_Line(Off.Line());
+    }
+    else if (AHC->GetType() == GeomAbs_Circle)
+    {
+      gp_Circ2d theCirc = AHC->Circle();
+      if (anOffset < 0. || Abs(anOffset) < theCirc.Radius())
+        OC = new Geom2d_Circle (theCirc.Position(), theCirc.Radius() - anOffset);
+    }
+    else
+    {
+      Handle(Geom2d_TrimmedCurve) G2dT = new Geom2d_TrimmedCurve(aPCurve, f, l);
+      OC = new Geom2d_OffsetCurve( G2dT, anOffset);
+    }
+    Handle(Geom_Surface) aSurf = BRep_Tool::Surface(mySpine);
     Handle(Geom_Plane) aPlane = Handle(Geom_Plane)::DownCast(aSurf);
-    myShape = BRepLib_MakeEdge(OLC, aPlane, f, l);
+    myShape = BRepLib_MakeEdge(OC, aPlane, f, l);
     BRepLib::BuildCurve3d(TopoDS::Edge(myShape));
     
     myShape.Orientation(E.Orientation());
@@ -305,34 +317,8 @@ static Standard_Boolean KPartCircle
     myIsDone = Standard_True;
     return Standard_True;
   }
-  
-  if (!C->IsKind(STANDARD_TYPE(Geom_Circle))) return Standard_False;
-  Handle(Geom_Circle) CE = Handle(Geom_Circle)::DownCast(C);
-  Standard_Real anOffset = myOffset;
-  if (E.Orientation() == TopAbs_REVERSED) anOffset *= -1;
-  
-  if (anOffset < 0. || Abs(anOffset) < CE->Radius()) {
-    Handle(Geom_Circle) OC = new Geom_Circle (CE->Position(),CE->Radius() - anOffset);
-    myShape = BRepLib_MakeEdge(OC,f,l);
 
-    myShape.Orientation(E.Orientation());
-    myShape.Location(L);
-    if (Alt != 0.) {
-      BRepAdaptor_Surface S(mySpine,0);
-      gp_Ax1 Nor = S.Plane().Axis();
-      gp_Trsf T;
-      gp_Vec Trans(Nor.Direction());
-      Trans = Alt*Trans;
-      T.SetTranslation(Trans);
-      myShape.Move(TopLoc_Location(T));
-    }
-    
-    TopTools_ListOfShape LL;
-    LL.Append(myShape);
-    myMap.Add(E,LL);
-  }
-  myIsDone = Standard_True;
-  return Standard_True;
+  return Standard_False;
 }
 
 //=======================================================================
@@ -529,7 +515,7 @@ void BRepFill_OffsetWire::Perform (const Standard_Real Offset,
   {
     OCC_CATCH_SIGNALS
       myCallGen = Standard_False;
-    if (KPartCircle(mySpine,Offset,Alt,myShape,myMap,myIsDone)) return;
+    if (KPartCircle(myWorkSpine,Offset,Alt,myShape,myMap,myIsDone)) return;
 
     TopoDS_Face oldWorkSpain = myWorkSpine;
 
@@ -763,7 +749,7 @@ void BRepFill_OffsetWire::PerformWithBiLo
   //********************************
   // Calculate for a non null offset 
   //********************************
-  if (KPartCircle(mySpine,Offset,Alt,myShape,myMap,myIsDone))
+  if (KPartCircle(myWorkSpine,Offset,Alt,myShape,myMap,myIsDone))
     return;
 
   BRep_Builder myBuilder;
@@ -815,8 +801,9 @@ void BRepFill_OffsetWire::PerformWithBiLo
     for (Standard_Integer ie = 1; ie <= Locus.NumberOfElts(ic); ie++) {
       const TopoDS_Shape& SE = Link.GeneratingShape(Locus.BasicElt(ic,ie));
       if (SE.ShapeType() == TopAbs_VERTEX) {
-	MakeCircle (TopoDS::Edge(PE),TopoDS::Vertex(SE),
-		    myWorkSpine,myOffset,myMap,RefPlane);
+        if (!SE.IsSame(Ends[0]) && !SE.IsSame(Ends[1]))
+          MakeCircle (TopoDS::Edge(PE),TopoDS::Vertex(SE),
+                      myWorkSpine,myOffset,myMap,RefPlane);
       }
       else {
 	MakeOffset (TopoDS::Edge(SE),myWorkSpine,myOffset,myMap,RefPlane,
diff --git a/src/BRepMAT2d/BRepMAT2d_BisectingLocus.cxx b/src/BRepMAT2d/BRepMAT2d_BisectingLocus.cxx
index fa5d0e3372..d96a6d8f84 100644
--- a/src/BRepMAT2d/BRepMAT2d_BisectingLocus.cxx
+++ b/src/BRepMAT2d/BRepMAT2d_BisectingLocus.cxx
@@ -61,7 +61,7 @@ void BRepMAT2d_BisectingLocus::Compute(BRepMAT2d_Explorer&        anExplo,
                                        const GeomAbs_JoinType aJoinType,
                                        const Standard_Boolean IsOpenResult)
 {
-  MAT2d_Mat2d                        TheMAT;
+  MAT2d_Mat2d                        TheMAT( IsOpenResult );
   Handle(MAT_ListOfBisector)         TheRoots = new MAT_ListOfBisector();
   MAT2d_SequenceOfSequenceOfGeometry Figure;
   Standard_Integer                   i;
@@ -104,7 +104,10 @@ void BRepMAT2d_BisectingLocus::Compute(BRepMAT2d_Explorer&        anExplo,
   // --------------------------------------------
   // Initialisation et execution de l algorithme.
   // --------------------------------------------
-  TheMAT.CreateMat(theTool);
+  if (IsOpenResult)
+    TheMAT.CreateMatOpen(theTool);
+  else
+    TheMAT.CreateMat(theTool);
 
   isDone = TheMAT.IsDone(); if (!isDone) return;
 
diff --git a/src/BRepOffsetAPI/BRepOffsetAPI_MakeOffset.cdl b/src/BRepOffsetAPI/BRepOffsetAPI_MakeOffset.cdl
index 2d7a5ab221..861ea2aff2 100644
--- a/src/BRepOffsetAPI/BRepOffsetAPI_MakeOffset.cdl
+++ b/src/BRepOffsetAPI/BRepOffsetAPI_MakeOffset.cdl
@@ -51,9 +51,12 @@ is
 	  IsOpenResult : Boolean from Standard = Standard_False)
 	---Purpose: Initializes the algorithm to construct parallels to the spine Spine.
     	-- Join defines the type of parallel generated by the
-    	-- salient vertices of the spine. The default type is
-    	-- GeomAbs_Arc where the vertices generate sections
-    	-- of a circle. At present, this is the only construction type implemented.
+    	-- salient vertices of the spine.
+    	-- The default type is GeomAbs_Arc where the vertices generate
+    	-- sections of a circle.
+    	-- If join type is GeomAbs_Intersection, the edges that
+    	-- intersect in a salient vertex generate the edges
+    	-- prolonged until intersection.
     is static;
     
     Create( Spine : Wire from TopoDS;
diff --git a/src/BRepTest/BRepTest_CurveCommands.cxx b/src/BRepTest/BRepTest_CurveCommands.cxx
index ad290cccfc..f413e21d2c 100644
--- a/src/BRepTest/BRepTest_CurveCommands.cxx
+++ b/src/BRepTest/BRepTest_CurveCommands.cxx
@@ -1523,7 +1523,7 @@ Standard_Integer mkoffset(Draw_Interpretor& di,
   else
   {
     Base.Orientation(TopAbs_FORWARD);
-    Paral.Init(TopoDS::Face(Base));
+    Paral.Init(TopoDS::Face(Base), theJoinType);
   }
 
   Standard_Real U, dU;
@@ -1569,22 +1569,34 @@ Standard_Integer openoffset(Draw_Interpretor& di,
   if (n < 5) return 1;
   char name[100];
 
-  TopoDS_Shape Base = DBRep::Get(a[2], TopAbs_WIRE);
-
+  BRepOffsetAPI_MakeOffset Paral;
   GeomAbs_JoinType theJoinType = GeomAbs_Arc;
   if (n == 6 && strcmp(a[5], "i") == 0)
     theJoinType = GeomAbs_Intersection;
-  
-  BRepOffsetAPI_MakeOffset Paral(TopoDS::Wire(Base), theJoinType, Standard_True);
+  Paral.Init(theJoinType, Standard_True);
+  TopoDS_Shape Base = DBRep::Get(a[2] ,TopAbs_FACE);
+
+  if ( Base.IsNull())
+  {
+    Base = DBRep::Get(a[2], TopAbs_WIRE);
+    if (Base.IsNull()) return 1;
+    Paral.AddWire(TopoDS::Wire(Base));
+  }
+  else
+  {
+    Base.Orientation(TopAbs_FORWARD);
+    Paral.Init(TopoDS::Face(Base), theJoinType, Standard_True);
+  }
 
   Standard_Real U, dU;
   Standard_Integer Nb;
   dU = Draw::Atof(a[4]);
   Nb = Draw::Atoi(a[3]);
 
-  Standard_Integer Compt = 1;
-  
   Standard_Real Alt = 0.;
+
+  Standard_Integer Compt = 1;
+
   for ( Standard_Integer i = 1; i <= Nb; i++)
   {
     U = i * dU;
@@ -1872,7 +1884,7 @@ void  BRepTest::CurveCommands(Draw_Interpretor& theCommands)
     mkoffset);
 
   theCommands.Add("openoffset",
-    "openoffset result wire nboffset stepoffset [jointype(a/i)]",__FILE__,
+    "openoffset result face/wire nboffset stepoffset [jointype(a/i)]",__FILE__,
     openoffset);
 
   theCommands.Add("mkedge",
diff --git a/src/MAT2d/MAT2d_Circuit.cxx b/src/MAT2d/MAT2d_Circuit.cxx
index 49bfa1b5e3..7e4c702e59 100644
--- a/src/MAT2d/MAT2d_Circuit.cxx
+++ b/src/MAT2d/MAT2d_Circuit.cxx
@@ -480,16 +480,12 @@ void MAT2d_Circuit::InitOpen (TColGeom2d_SequenceOfGeometry& Line) const
   Handle(Geom2d_TrimmedCurve) Curve;
   Standard_Real               DotProd;
 
-  if (!myIsOpenResult)
-  {
-    Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.First());
-    Line.InsertBefore(1,new Geom2d_CartesianPoint(Curve->StartPoint()));
-    Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.Last());
-    Line.Append(new Geom2d_CartesianPoint(Curve->EndPoint()));
-  }
-
-  Standard_Integer addition = (myIsOpenResult)? 1 : 2;
-  for ( Standard_Integer i = addition; i <= Line.Length() - addition; i++) {
+  Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.First());
+  Line.InsertBefore(1,new Geom2d_CartesianPoint(Curve->StartPoint()));
+  Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.Last());
+  Line.Append(new Geom2d_CartesianPoint(Curve->EndPoint()));
+  
+  for ( Standard_Integer i = 2; i <= Line.Length() - 2; i++) {
     if ( Abs(CrossProd(Line.Value(i),Line.Value(i+1),DotProd)) > 1.E-8 ||
 	 DotProd < 0. ) {
       Curve = Handle(Geom2d_TrimmedCurve)::DownCast(Line.Value(i));
diff --git a/src/MAT2d/MAT2d_Mat2d.cdl b/src/MAT2d/MAT2d_Mat2d.cdl
index 1280d7cfb7..2d83c6a872 100644
--- a/src/MAT2d/MAT2d_Mat2d.cdl
+++ b/src/MAT2d/MAT2d_Mat2d.cdl
@@ -30,7 +30,7 @@ uses
     
 is
 
-    Create
+    Create(IsOpenResult : Boolean from Standard = Standard_False)
     ---Purpose: Empty construtor.
     returns Mat2d from MAT2d;
     
@@ -40,6 +40,11 @@ is
        ---Purpose: Algoritm of computation of the bisecting locus.
     is static;
     
+    CreateMatOpen(me : in out ; aTool : in out Tool2d from MAT2d)
+       ---Purpose: Algoritm of computation of the bisecting locus for
+       --          open wire.
+    is static;
+    
     IsDone(me) returns Boolean from Standard
        ---Purpose:  Returns <TRUE> if CreateMat has succeeded. 
     is static;
@@ -94,6 +99,7 @@ is
 
 fields
 
+    myIsOpenResult        : Boolean;
     thenumberofbisectors  : Integer;
     thenumberofedges      : Integer;
     semiInfinite          : Boolean;
diff --git a/src/MAT2d/MAT2d_Mat2d.cxx b/src/MAT2d/MAT2d_Mat2d.cxx
index cd2db7b60f..40595dd029 100644
--- a/src/MAT2d/MAT2d_Mat2d.cxx
+++ b/src/MAT2d/MAT2d_Mat2d.cxx
@@ -31,8 +31,9 @@
 //  purpose  :
 //========================================================================
 
-MAT2d_Mat2d::MAT2d_Mat2d()
+MAT2d_Mat2d::MAT2d_Mat2d(const Standard_Boolean IsOpenResult)
 {
+  myIsOpenResult = IsOpenResult;
   thenumberofbisectors = 0;
   thenumberofedges     = 0;
 }
@@ -120,6 +121,670 @@ MAT2d_Mat2d::MAT2d_Mat2d()
 //            dans la boucle.
 //
 //========================================================================
+void MAT2d_Mat2d::CreateMatOpen(MAT2d_Tool2d& atool)
+{
+
+#ifdef ICONTINUE
+  Standard_Boolean Icontinue;
+#endif
+
+  Standard_Boolean interrupt = Standard_False;
+
+  Handle(MAT_Edge) edgetoremove;
+  Handle(MAT_Edge) previousedge,currentedge;
+
+  Standard_Integer      noofbisectorstoremove;
+  Handle(MAT_Bisector)  firstbisector,secondbisector;
+  Handle(MAT_Edge)      edge;
+  Standard_Integer      intersectionpoint;
+  Standard_Integer      beginbisector;
+  Standard_Integer      noofbisectors;
+
+  Standard_Integer	NbIterBis = 0;
+  Standard_Integer	EvenNbIterBis = 10;
+  TColStd_Array1OfInteger EdgeNumbers(1, EvenNbIterBis+1);
+  EdgeNumbers.Init(-1);
+  Standard_Boolean	ToNullifyNoofbisectorstoremove = Standard_False;
+
+  Handle(MAT_ListOfBisector) currentbisectorlist;
+
+  Handle(MAT_Bisector) bisectortoremove,lastbisector,currentbisector;
+  Handle(MAT_Bisector) previousbisector;
+
+  Standard_Integer     i,j,k,narea,shift,compact,all;
+  Standard_Integer     noofedges;
+  Standard_Integer     NumberMaxOfIte;
+  Standard_Real        toleranceofconfusion;
+
+  noofedges            = atool.NumberOfItems();
+  toleranceofconfusion = atool.ToleranceOfConfusion();
+  NumberMaxOfIte       = noofedges*noofedges;
+
+  TColStd_Array1OfInteger firstarea(0, noofedges);
+  TColStd_Array1OfInteger lastarea(0, noofedges);
+  TColStd_Array1OfInteger noofarea(0, noofedges);
+
+  Standard_Integer  parama[2];
+  Standard_Integer  paramb[2];
+
+// -----------------------------------------
+// Initialisation et remise a zero des maps.
+// -----------------------------------------
+  bisectoronetoremove.Clear();
+  bisectortwotoremove.Clear();
+  typeofbisectortoremove.Clear();
+  bisectormap.Clear();
+
+  isDone        = Standard_True;
+  noofbisectors = noofedges-1;
+  beginbisector = 0;
+
+// --------------------------------------------------------------------
+// Construction de <theedgelist> un edge correspond a un element simple
+// du contour.
+// --------------------------------------------------------------------
+  theedgelist = new MAT_ListOfEdge();
+
+  for(i=0; i<noofedges; i++) {
+    edge = new MAT_Edge();
+    edge->EdgeNumber(i+1);
+    edge->Distance(-1);
+    theedgelist->BackAdd(edge);
+  }
+  
+  theedgelist->Loop();
+
+//---------------------------------------------------
+// Initialisation des bissectrices issues du contour.
+//---------------------------------------------------
+  Standard_Real Dist;
+  theedgelist->First();
+
+  for(i=0; i<theedgelist->Number()-1; i++) {
+    bisectormap.Bind(i,new MAT_Bisector());
+    bisectormap(i)->IndexNumber(i);
+    bisectormap(i)->FirstEdge(theedgelist->Current());
+    bisectormap(i)->FirstVector
+      (atool.TangentBefore(theedgelist->Current()->EdgeNumber(), myIsOpenResult));
+    theedgelist->Next();
+    bisectormap(i)->SecondEdge(theedgelist->Current());
+    bisectormap(i)->IssuePoint
+      (atool.FirstPoint(theedgelist->Current()->EdgeNumber(),Dist));  
+    bisectormap(i)->DistIssuePoint(Dist);
+    bisectormap(i)->SecondVector
+      (atool.TangentAfter(theedgelist->Current()->EdgeNumber(), myIsOpenResult));
+  }
+
+//----------------------------------------------------
+// Affectation a chaque edge de ses deux bissectrices.
+//----------------------------------------------------
+  theedgelist->First();
+  theedgelist->Current()->FirstBisector(bisectormap(0));
+  theedgelist->Current()->SecondBisector(bisectormap(0));
+  theedgelist->Next();
+
+  for(i=1; i<theedgelist->Number()-1; i++) {
+    theedgelist->Current()->FirstBisector
+      (bisectormap(i-1));
+    theedgelist->Current()->SecondBisector
+      (bisectormap(i));
+    theedgelist->Next();
+  }
+
+  theedgelist->Current()->FirstBisector(bisectormap(theedgelist->Number()-2));
+  theedgelist->Current()->SecondBisector(bisectormap(theedgelist->Number()-2));
+
+//===========================================================================
+//                         Boucle Principale   (etape 2)
+//===========================================================================
+  Standard_Integer NumberOfIte = 0;
+
+  while(theedgelist->Number()>1) {
+
+
+    // ------------------------------------------------------------------
+    //  Creation des geometries des bissectrices via le tool. (etape 2.1)
+    // -------------------------------------------------------------------
+
+    for(i=beginbisector; i<noofbisectors; i++) {
+
+      atool.CreateBisector(bisectormap(i));
+      thenumberofbisectors++;
+      
+#ifdef DEBUG_Mat
+      atool.Dump(bisectormap(i)->BisectorNumber(),1);
+#ifdef ICONTINUE
+      cin>>Icontinue;
+#endif
+#endif
+    }
+
+    // ---------------------------------------------
+    //  Condition de sortie de la boucle principale.
+    // ---------------------------------------------
+
+//  Modified by Sergey KHROMOV - Fri Nov 17 10:28:28 2000 Begin
+    if (theedgelist->Number() < 3)
+      break;
+//  Modified by Sergey KHROMOV - Fri Nov 17 10:28:37 2000 End
+    
+    //---------------------------------------------------
+    // boucle 2 Tant qu il y a des bisectrices a effacer.
+    //---------------------------------------------------
+    for(;;) {
+      NbIterBis++;
+
+      noofbisectorstoremove = 0;
+      theedgelist->First();
+      theedgelist->Next();
+
+      //--------------------------------------------------------------
+      // Calcul des intersections des bisectrices voisines.(etape 2.2)
+      //--------------------------------------------------------------
+
+      if (NbIterBis <= EvenNbIterBis+1)
+	EdgeNumbers(NbIterBis) = theedgelist->Number();
+      else
+	{
+	  for (k = 1; k <= EvenNbIterBis; k++)
+	    EdgeNumbers(k) = EdgeNumbers(k+1);
+	  EdgeNumbers(EvenNbIterBis+1) = theedgelist->Number();
+	}
+      if (EdgeNumbers(EvenNbIterBis+1) == EdgeNumbers(1))
+	ToNullifyNoofbisectorstoremove = Standard_True;
+
+      for(i=1; i<theedgelist->Number()-1; i++) {
+	edge = theedgelist->Current();
+	if(edge->Distance() == -1.) {
+	  firstbisector = edge->FirstBisector();
+	  secondbisector = edge->SecondBisector();
+	  edge->Distance(atool.IntersectBisector
+			 (firstbisector,secondbisector,intersectionpoint));
+	  edge->IntersectionPoint(intersectionpoint);
+
+	  if(edge->Distance() == Precision::Infinite()) {
+	    if(firstbisector->IndexNumber() >= beginbisector ||
+	       secondbisector->IndexNumber() >= beginbisector) 
+	      Intersect(atool,0,noofbisectorstoremove,
+			firstbisector,secondbisector );
+	  }
+	  else {
+	    if(firstbisector->IndexNumber() >= beginbisector) {
+	      Intersect(atool,1,noofbisectorstoremove,
+			firstbisector,secondbisector );
+	    }
+	    if(secondbisector->IndexNumber() >= beginbisector) {
+	      Intersect(atool,2,noofbisectorstoremove,
+			firstbisector,secondbisector );
+	    }
+	  }
+	}
+	theedgelist->Next();
+      }
+      
+      //-------------------------------
+      // Test de sortie de la boucle 2.
+      //-------------------------------
+
+      if (ToNullifyNoofbisectorstoremove)
+	noofbisectorstoremove = 0;
+      if(noofbisectorstoremove == 0) break;
+
+      //---------------------------------------------------
+      // Annulation des bissectrices a effacer. (etape 2.4)
+      //---------------------------------------------------
+
+      for(i=0; i<noofbisectorstoremove; i++) {
+
+	bisectortoremove = bisectoronetoremove(i);
+
+	//---------------------------------------------------------------
+	// Destruction des bisectrices descendantes de <bisectortoremove>
+	// On descend dans l arbre jusqu a ce qu on atteigne
+	// <bisectortwotoremove(i).
+	//---------------------------------------------------------------
+
+	for(;;){
+
+#ifdef DEBUG_Mat
+	  atool.Dump(bisectortoremove->BisectorNumber(),0);
+#endif
+	  // ----------------------------------
+	  // Annulation de <bisectortoremove>.
+	  // ----------------------------------
+	  thenumberofbisectors--;
+	  currentbisectorlist = bisectortoremove->List();
+	  currentbisectorlist->First();
+	  currentbisector = currentbisectorlist->FirstItem();
+	  previousedge = currentbisector->FirstEdge();
+	  theedgelist->Init(previousedge);
+	  previousedge->Distance(-1.);
+	  previousedge->FirstBisector()->SecondParameter(Precision::Infinite());
+	  previousedge->SecondBisector()->FirstParameter(Precision::Infinite());
+
+	  //------------------------------------------
+	  // Annulation des fils de <currentbisector>.
+	  //------------------------------------------
+
+	  while(currentbisectorlist->More()) {
+	    currentbisector = currentbisectorlist->Current();
+	    currentedge  = currentbisector->SecondEdge();
+
+	    //---------------------------------------
+	    // Reinsertion de l edge dans le contour.
+	    //---------------------------------------
+	    theedgelist->LinkAfter(currentedge);
+	    theedgelist->Next();
+	    
+	    currentedge->FirstBisector(currentbisector);
+	    previousedge->SecondBisector(currentbisector);
+#ifdef DEBUG_Mat		      
+	    atool.Dump(currentbisector->BisectorNumber(),0);
+#endif
+
+	    //------------------------------------------------------
+	    // Annulation de l intersection ie les fils qui
+	    // ont generes l intersection sont prolonges a l infini.
+	    //------------------------------------------------------
+
+	    currentbisector->FirstParameter (Precision::Infinite());
+	    currentbisector->SecondParameter(Precision::Infinite());
+		      
+	    atool.TrimBisector(currentbisector);
+	    
+#ifdef DEBUG_Mat
+	    atool.Dump(currentbisector->BisectorNumber(),1);
+#endif
+	    currentedge->Distance(-1.);
+	    currentedge->FirstBisector()->SecondParameter(Precision::Infinite());
+	    currentedge->SecondBisector()->FirstParameter(Precision::Infinite());
+	    
+	    previousedge = currentedge;
+	    currentbisectorlist->Next();
+	  }
+	  
+	  theedgelist->Unlink();
+
+	  //-----------------------------------------------------------
+	  // Test de sortie de la boucle d annulation des bissectrices.
+	  //-----------------------------------------------------------
+
+	  if(bisectortoremove->BisectorNumber() ==
+	     bisectortwotoremove(i)->BisectorNumber()) break;
+
+	  //-----------------------
+	  // Descente dans l arbre.
+	  //-----------------------
+
+	  if(typeofbisectortoremove(i) == 1)
+	    bisectortoremove = bisectortoremove->FirstBisector();
+	  else
+	    bisectortoremove = bisectortoremove->LastBisector();
+	
+	}  //----------------------------------------------------
+	   // Fin boucle d annulation des bissectrices issue de 
+	   // <bisectoronetoremove(i)>.
+	   //----------------------------------------------------
+
+      } //------------------------------------------
+        // Fin boucle d annulation des bissectrices.
+        //-------------------------------------------
+
+#ifdef ICONTINUE
+      cin>>Icontinue;
+#endif
+    } //--------------
+      // Fin Boucle 2.
+      //--------------
+    
+    // ----------------------------------------------------------------------
+    // Analyse des parametres des intersections sur les bisectrices de chaque
+    // edge et determination des portions de contour a supprimees. (etape 2.5)
+    // ----------------------------------------------------------------------
+
+    theedgelist->First();
+    theedgelist->Next();
+      
+    currentbisector = theedgelist->Current()->FirstBisector();
+    if (currentbisector->FirstParameter()  == Precision::Infinite() &&
+	currentbisector->SecondParameter() == Precision::Infinite()) {
+      parama[0] = -1;
+      paramb[0] = -1;
+    }
+    else if(currentbisector->FirstParameter() == Precision::Infinite()) {
+      parama[0] = -1;
+      paramb[0] =  1;
+    }
+    else if(currentbisector->SecondParameter() == Precision::Infinite()) {
+      paramb[0] = -1;
+      parama[0] =  1;
+    }
+    else if (atool.Distance(currentbisector,
+			    currentbisector->FirstParameter(),
+			    currentbisector->SecondParameter()) 
+	     > toleranceofconfusion) {
+      if((currentbisector->FirstParameter() - 
+	  currentbisector->SecondParameter())
+	 *currentbisector->Sense() > 0.) {      
+	parama[0] = -1;
+	paramb[0] =  1;
+      }
+      else {
+	paramb[0] = -1;
+	parama[0] =  1;
+      }
+    }
+    else {
+      parama[0] = 1;
+      paramb[0] = 1;
+    }
+    
+    narea = -1;
+    
+    for(i=1; i<theedgelist->Number()-1; i++) {
+      currentbisector = theedgelist->Current()->SecondBisector();
+      if (currentbisector->FirstParameter()  == Precision::Infinite() &&
+	  currentbisector->SecondParameter() == Precision::Infinite()) {
+	parama[1] = -1;
+	paramb[1] = -1;
+      }
+      else if(currentbisector->FirstParameter() == Precision::Infinite()) {
+	parama[1] = -1;
+	paramb[1] =  1;
+      }
+      else if(currentbisector->SecondParameter() == Precision::Infinite()) {
+	paramb[1] = -1;
+	parama[1] =  1;
+      }
+      else if (atool.Distance(currentbisector,
+			      currentbisector->FirstParameter(),
+			      currentbisector->SecondParameter()) 
+	       > toleranceofconfusion) {
+	if((currentbisector->FirstParameter() - 
+	    currentbisector->SecondParameter()) 
+	   *currentbisector->Sense() > 0.) {      
+	  parama[1] = -1;
+	  paramb[1] =  1;
+	}
+	else {
+	  paramb[1] = -1;
+	  parama[1] =  1;
+	}
+      }
+      else {
+	parama[1] = 1;
+	paramb[1] = 1;
+      }
+
+      //-----------------------------------------------------------------
+      // Test si l edge est a enlever du contour
+      // Construction des portions de contour a eliminer.
+      //
+      //  narea : nombre de portions continues du contour a eliminer.
+      //  firstarea[i] : indice premier edge de la portion i.
+      //  lastarea[i]  : indice dernier edge de la portion i.
+      //-----------------------------------------------------------------
+
+#ifdef DEBUG_Mat
+      cout <<" Test sur les parametres pour elimination"<<endl;
+      cout << " Edge number :"<<theedgelist->Current()->EdgeNumber()<<endl;
+#endif
+
+      if(paramb[0] > 0 && parama[1] > 0) {
+
+#ifdef DEBUG_Mat
+      cout <<" A ELIMINER "<<endl;
+#endif	
+	if(narea < 0) {
+	  firstarea(++narea) = theedgelist->Index();
+	  lastarea(narea) = firstarea(narea);
+	  noofarea(narea) = 1;
+	}
+	else {
+	  if(theedgelist->Index() == lastarea(narea)+1) {
+	    lastarea(narea)++;
+	    noofarea(narea)++;
+	  }
+	  else {
+	    firstarea(++narea) = theedgelist->Index();
+	    lastarea(narea) = firstarea(narea);
+	    noofarea(narea) = 1;
+	  }
+	}
+      }
+      parama[0] = parama[1];
+      paramb[0] = paramb[1];
+      theedgelist->Next();
+    
+    } 
+    
+    compact = 0;
+    if(narea > 0) {
+      if(lastarea(narea) == theedgelist->Number() && firstarea(0) == 1) {
+	firstarea(0) = firstarea(narea);
+	noofarea(0) = noofarea(0)+noofarea(narea);
+	compact = noofarea(narea);
+	narea--;
+      }
+    }
+    
+    narea++;
+
+    //------------------------------------------------------------------
+    // Sortie de la boucle principale si il n y a pas d edge a eliminer.
+    // (etape 2.6)
+    //------------------------------------------------------------------
+    if(narea == 0) {
+      interrupt = Standard_True;
+      break;
+    }
+    
+
+    //----------------------------------------------------------------
+    // Elimination des edges a enlever du contour
+    // => Mise a jour du nouveau contour.
+    // => Creation des bissectrices entre les nouvelles edges voisines.
+    //----------------------------------------------------------------
+
+    beginbisector = noofbisectors;
+    shift = 0;
+    all = 0;
+    if(narea == 1 && noofarea(0) == theedgelist->Number()) all = 1;
+
+    for(i=0; i<narea; i++) {
+      if(i == 1)shift = shift-compact;
+      theedgelist->First();
+      theedgelist->Next();
+      edgetoremove = theedgelist->Brackets(firstarea(i)-shift);
+      
+      edgetoremove->FirstBisector()->EndPoint(edgetoremove
+					      ->IntersectionPoint());
+      
+#ifdef DEBUG_Mat
+      atool.Dump(edgetoremove->FirstBisector()->BisectorNumber(),0);
+#endif
+
+      edgetoremove->FirstBisector()->FirstParameter
+	(edgetoremove->FirstBisector()->SecondParameter());
+	  
+#ifdef DEBUG_Mat
+      if(atool.TrimBisector(edgetoremove->FirstBisector()))
+	atool.Dump(edgetoremove->FirstBisector()->BisectorNumber(),1);
+#else
+      atool.TrimBisector(edgetoremove->FirstBisector());
+#endif
+
+      bisectormap.Bind(noofbisectors,new MAT_Bisector());
+      bisectormap(noofbisectors)->IndexNumber(noofbisectors);
+      bisectormap(noofbisectors)->DistIssuePoint(edgetoremove->Distance());
+      bisectormap(noofbisectors)->IssuePoint(edgetoremove
+						->IntersectionPoint());
+      bisectormap(noofbisectors)->FirstEdge(theedgelist->PreviousItem());
+      bisectormap(noofbisectors)->AddBisector(edgetoremove
+						 ->FirstBisector());
+
+      for(j=0; j<noofarea(i); j++) {
+	theedgelist->Unlink();
+	theedgelist->Next();
+	shift++;
+
+#ifdef DEBUG_Mat
+	cout<<" Suppression de l'arete : "<<edgetoremove->EdgeNumber()<<endl;
+#endif
+
+	if(all == 0 || j+1 != noofarea(i)) {
+	  bisectormap(noofbisectors)->AddBisector(edgetoremove
+						     ->SecondBisector());
+	}
+	edgetoremove->SecondBisector()->EndPoint(edgetoremove
+						 ->IntersectionPoint());
+
+#ifdef DEBUG_Mat
+	atool.Dump(edgetoremove->SecondBisector()->BisectorNumber(),0);
+#endif
+
+	edgetoremove->SecondBisector()->SecondParameter
+	  (edgetoremove->SecondBisector()->FirstParameter());
+#ifdef DEBUG_Mat
+	if(atool.TrimBisector(edgetoremove->SecondBisector()))
+	  atool.Dump(edgetoremove->SecondBisector()->BisectorNumber(),1);
+#else
+	atool.TrimBisector(edgetoremove->SecondBisector());
+#endif
+	edgetoremove = theedgelist->Current();
+      }
+      bisectormap(noofbisectors)->SecondEdge(theedgelist->Current());
+
+      theedgelist->PreviousItem()
+        ->SecondBisector(bisectormap(noofbisectors));
+      theedgelist->Current()->FirstBisector(bisectormap(noofbisectors));
+	  
+      bisectormap(noofbisectors)->FirstVector
+	(atool.Tangent
+	 (bisectormap(noofbisectors)->FirstBisector()
+	  ->BisectorNumber()));
+      
+      bisectormap(noofbisectors)->SecondVector
+	(atool.Tangent
+	 (bisectormap(noofbisectors)->LastBisector()
+	  ->BisectorNumber()));
+      
+      noofbisectors++;
+      
+      theedgelist->PreviousItem()->Distance(-1);
+      theedgelist->Current()->Distance(-1);
+
+      theedgelist->PreviousItem()->FirstBisector()
+        ->SecondParameter(Precision::Infinite());
+      theedgelist->Current()->SecondBisector()->FirstParameter(Precision::Infinite());
+    }
+
+    //-----------------------------------------------------------------------
+    // Test sur le nombre d iterations :
+    // A chaque iteration est elimine un element du contour qui ne sera plus
+    // reinsere par la suite => le nombre d iterartions doit etre < au nombre
+    // d elements.
+    // Le nombre d iteration maximum est fixe a numberofedges*numberofedges.
+    //-----------------------------------------------------------------------
+    if (NumberOfIte > NumberMaxOfIte) {
+      isDone = Standard_False;             //Echec calcul de la carte.
+      break;
+    }
+    NumberOfIte++;
+
+  }  //===============================================
+     //            Fin Boucle Principale.
+     //===============================================
+     
+  //----------
+  // etape 3.
+  //----------
+
+
+  //----------------------------------------------
+  // interupt = True => bissectrices semi_infinies.
+  //----------------------------------------------
+  
+  if(interrupt)
+    semiInfinite = Standard_True;
+  else {
+    semiInfinite = Standard_False;
+
+    //------------------------------------------------------------------
+    // Si le nombre d edge > 1 => le nombre d edge = 2 
+    //              (cf test sortie boucle principale)
+    // Les deux dernieres bisectrices separent les memes edges .
+    // Soit elles sont confondues si calcul a l interieur, soit elles
+    // sont semi-Infinies (exemple : contour compose seulement de deux
+    // arcs de cercles).			   
+    //------------------------------------------------------------------
+
+    if(theedgelist->Number() > 1) { //Now this branch is never reachable
+                                    //because the case edgenumber = 2 is processed in the main loop
+      theedgelist->First();
+      edge = theedgelist->Current();
+      if(edge->FirstBisector()->IndexNumber() == noofbisectors-1) {
+//  Modified by skv - Tue Sep 13 12:13:28 2005 IDEM Begin
+	if (atool.TrimBisector(edge->SecondBisector(),
+			       edge->FirstBisector()->IssuePoint())) {
+	  if (edge->SecondBisector()->EndPoint() == 0)
+	    edge->SecondBisector()->EndPoint(edge->FirstBisector()->IssuePoint());
+	  bisectormap(noofbisectors-1)->AddBisector(edge->SecondBisector());
+	} else
+	  semiInfinite = Standard_True;
+//  Modified by skv - Tue Sep 13 12:13:28 2005 IDEM End
+      }
+      else {
+//  Modified by skv - Tue Sep 13 12:13:28 2005 IDEM Begin
+	if (atool.TrimBisector(edge->FirstBisector(),
+			       edge->SecondBisector()->IssuePoint())) {
+	  if (edge->FirstBisector()->EndPoint() == 0)
+	    edge->FirstBisector()->EndPoint(edge->SecondBisector()->IssuePoint());
+	  bisectormap(noofbisectors-1)->AddBisector(edge->FirstBisector());
+	} else 
+	  semiInfinite = Standard_True;
+//  Modified by skv - Tue Sep 13 12:13:28 2005 IDEM End
+      }
+      if (!semiInfinite) {     
+ 	thenumberofbisectors--;
+	bisectormap(noofbisectors-1)->SecondEdge(edge);
+	bisectormap(noofbisectors-1)->BisectorNumber(-1);
+      }
+    }
+  }
+
+  if(semiInfinite) {
+    beginbisector = noofbisectors;
+    theedgelist->First();
+    for(i=1; i<theedgelist->Number(); i++) {
+      edge = theedgelist->Current();
+      bisectormap.Bind(noofbisectors,edge->SecondBisector());
+      noofbisectors++;
+      theedgelist->Next();
+    }
+
+  }
+
+  //---------------------------
+  // Recuperations des racines.
+  //---------------------------
+
+  roots = new MAT_ListOfBisector;
+  
+  if (bisectormap(noofbisectors-1)->BisectorNumber() == -1) {
+    roots = bisectormap(noofbisectors-1)->List();
+    roots->First();
+    roots->Current()->FirstEdge()
+      ->Distance(bisectormap(noofbisectors-1)->DistIssuePoint());
+  }
+  else {
+    for (i=beginbisector;i<noofbisectors;i++) {
+      roots->BackAdd(bisectormap(i));
+    }
+  }
+  
+}
+
 void MAT2d_Mat2d::CreateMat(MAT2d_Tool2d& atool)
 {
 
@@ -204,14 +869,14 @@ void MAT2d_Mat2d::CreateMat(MAT2d_Tool2d& atool)
     bisectormap(i)->IndexNumber(i);
     bisectormap(i)->FirstEdge(theedgelist->Current());
     bisectormap(i)->FirstVector
-      (atool.TangentBefore(theedgelist->Current()->EdgeNumber()));
+      (atool.TangentBefore(theedgelist->Current()->EdgeNumber(), myIsOpenResult));
     theedgelist->Next();
     bisectormap(i)->SecondEdge(theedgelist->Current());
     bisectormap(i)->IssuePoint
       (atool.FirstPoint(theedgelist->Current()->EdgeNumber(),Dist));  
     bisectormap(i)->DistIssuePoint(Dist);
     bisectormap(i)->SecondVector
-      (atool.TangentAfter(theedgelist->Current()->EdgeNumber()));
+      (atool.TangentAfter(theedgelist->Current()->EdgeNumber(), myIsOpenResult));
   }
 
 //----------------------------------------------------
diff --git a/src/MAT2d/MAT2d_Tool2d.cdl b/src/MAT2d/MAT2d_Tool2d.cdl
index a5740f072a..8f32b1a134 100644
--- a/src/MAT2d/MAT2d_Tool2d.cdl
+++ b/src/MAT2d/MAT2d_Tool2d.cdl
@@ -75,13 +75,15 @@ is
 	--            Returns the index of this point in <theGeomPnts>.    
     returns Integer is static;
     
-    TangentBefore(me : in out ; anitem : Integer) 
+    TangentBefore(me : in out ; anitem : Integer;
+    	    	    	    	IsOpenResult : Boolean)
     	--- Purpose : Creates the Tangent at the end of the Item defined
     	--            by <anitem>. Returns the index of this vector in
     	--            <theGeomVecs>
     returns Integer is static;
     
-    TangentAfter(me : in out ; anitem : Integer) 
+    TangentAfter(me : in out ; anitem : Integer;
+    	    	    	       IsOpenResult : Boolean)
     	--- Purpose : Creates the Reversed Tangent at the origin of the Item 
     	--            defined by <anitem>. Returns the index of this vector in
     	--            <theGeomVecs>
diff --git a/src/MAT2d/MAT2d_Tool2d.cxx b/src/MAT2d/MAT2d_Tool2d.cxx
index 73efc72dd6..8e149853ad 100644
--- a/src/MAT2d/MAT2d_Tool2d.cxx
+++ b/src/MAT2d/MAT2d_Tool2d.cxx
@@ -199,13 +199,17 @@ Standard_Integer MAT2d_Tool2d::FirstPoint(const Standard_Integer anitem,
 //function : TangentBefore
 //purpose  :
 //=============================================================================
-Standard_Integer MAT2d_Tool2d::TangentBefore(const Standard_Integer anitem) 
+Standard_Integer MAT2d_Tool2d::TangentBefore(const Standard_Integer anitem,
+                                             const Standard_Boolean IsOpenResult)
 {
   Standard_Integer     item;
   Handle(Geom2d_Curve) curve;
   theNumberOfVecs++;
-  
-  item  = (anitem == theCircuit->NumberOfItems()) ? 1 : (anitem + 1);
+
+  if (!IsOpenResult)
+    item  = (anitem == theCircuit->NumberOfItems()) ? 1 : (anitem + 1);
+  else
+    item = (anitem == theCircuit->NumberOfItems()) ? (anitem - 1) : (anitem + 1);
   if (theCircuit->ConnexionOn(item)){
     Standard_Real x1,y1,x2,y2;
     theCircuit->Connexion(item)->PointOnFirst().Coord(x1,y1);
@@ -222,7 +226,9 @@ Standard_Integer MAT2d_Tool2d::TangentBefore(const Standard_Integer anitem)
   }
   else {
     curve = Handle(Geom2d_Curve)::DownCast(theCircuit->Value(item));
-    theGeomVecs.Bind(theNumberOfVecs,curve->DN(curve->FirstParameter(),1));
+    Standard_Real param = (IsOpenResult && anitem == theCircuit->NumberOfItems())?
+      curve->LastParameter() : curve->FirstParameter();
+    theGeomVecs.Bind(theNumberOfVecs,curve->DN(param,1));
   }
 
   return theNumberOfVecs;
@@ -232,7 +238,8 @@ Standard_Integer MAT2d_Tool2d::TangentBefore(const Standard_Integer anitem)
 //function : TangentAfter
 //purpose  :
 //=============================================================================
-Standard_Integer MAT2d_Tool2d::TangentAfter(const Standard_Integer anitem)
+Standard_Integer MAT2d_Tool2d::TangentAfter(const Standard_Integer anitem,
+                                            const Standard_Boolean IsOpenResult)
 {
   Standard_Integer     item;
   Handle(Geom2d_Curve) curve;
@@ -254,9 +261,14 @@ Standard_Integer MAT2d_Tool2d::TangentAfter(const Standard_Integer anitem)
     thevector = curve->DN(curve->FirstParameter(),1);
   }
   else {
-    item      = (anitem == 1) ? theCircuit->NumberOfItems() : (anitem - 1);
+    if (!IsOpenResult)
+      item      = (anitem == 1) ? theCircuit->NumberOfItems() : (anitem - 1);
+    else
+      item = (anitem == 1) ? 2 : (anitem - 1);
     curve     = Handle(Geom2d_Curve)::DownCast(theCircuit->Value(item));
-    thevector = curve->DN(curve->LastParameter(),1);
+    Standard_Real param = (IsOpenResult && anitem == 1)?
+      curve->FirstParameter() : curve->LastParameter();
+    thevector = curve->DN(param,1);
   }
   theGeomVecs.Bind(theNumberOfVecs,thevector.Reversed());
   return theNumberOfVecs;
diff --git a/tests/bugs/modalg_4/bug745_10 b/tests/bugs/modalg_4/bug745_10
index 95ac508628..05379fdbf1 100755
--- a/tests/bugs/modalg_4/bug745_10
+++ b/tests/bugs/modalg_4/bug745_10
@@ -1,6 +1,3 @@
-puts "TODO OCC12345 ALL: Faulty OCC745"
-puts "TODO OCC12345 ALL: Error : The length of result shape is"
-
 puts "========"
 puts "OCC745"
 puts "========"
@@ -23,5 +20,5 @@ if { [regexp {WIRE} $list] == 0 } {
 
 renamevar result_1 result
 
-set length 0
-set 2dviewer 0
+set length 320.442
+set 2dviewer 1
diff --git a/tests/bugs/modalg_5/bug25334_1 b/tests/bugs/modalg_5/bug25334_1
new file mode 100644
index 0000000000..4cc20ca67a
--- /dev/null
+++ b/tests/bugs/modalg_5/bug25334_1
@@ -0,0 +1,35 @@
+puts "========"
+puts "OCC25334"
+puts "========"
+puts ""
+##########################################################################################################
+# BRepOffsetAPI_MakeOffset algofithm crashes on some customer's shape when option of open result is used
+##########################################################################################################
+
+restore [locate_data_file bug25334_faceProlongationCrash1.brep] a
+
+smallview
+
+explode a e
+wire ww a_1
+
+donly ww
+
+openoffset res ww 1 10
+renamevar res_1 result
+
+fit
+
+set length 613.39
+
+set nb_v_good 2
+set nb_e_good 1
+set nb_w_good 1
+set nb_f_good 0
+set nb_sh_good 0
+set nb_sol_good 0
+set nb_compsol_good 0
+set nb_compound_good  0
+set nb_shape_good 4
+
+set only_screen_axo 1
diff --git a/tests/bugs/modalg_5/bug25334_10 b/tests/bugs/modalg_5/bug25334_10
new file mode 100644
index 0000000000..4c515204b2
--- /dev/null
+++ b/tests/bugs/modalg_5/bug25334_10
@@ -0,0 +1,35 @@
+puts "========"
+puts "OCC25334"
+puts "========"
+puts ""
+##########################################################################################################
+# BRepOffsetAPI_MakeOffset algofithm crashes on some customer's shape when option of open result is used
+##########################################################################################################
+
+restore [locate_data_file bug25334_faceProlongationCrash1.brep] a
+
+smallview
+
+explode a e
+wire ww a_3 a_4
+
+donly ww
+
+openoffset res ww 1 -10
+renamevar res_1 result
+
+fit
+
+set length 548.106
+
+set nb_v_good 5
+set nb_e_good 4
+set nb_w_good 1
+set nb_f_good 0
+set nb_sh_good 0
+set nb_sol_good 0
+set nb_compsol_good 0
+set nb_compound_good  0
+set nb_shape_good 10
+
+set only_screen_axo 1
diff --git a/tests/bugs/modalg_5/bug25334_11 b/tests/bugs/modalg_5/bug25334_11
new file mode 100644
index 0000000000..0bcfcf59a3
--- /dev/null
+++ b/tests/bugs/modalg_5/bug25334_11
@@ -0,0 +1,35 @@
+puts "========"
+puts "OCC25334"
+puts "========"
+puts ""
+##########################################################################################################
+# BRepOffsetAPI_MakeOffset algofithm crashes on some customer's shape when option of open result is used
+##########################################################################################################
+
+restore [locate_data_file bug25334_faceProlongationCrash1.brep] a
+
+smallview
+
+explode a e
+wire ww a_4 a_1
+
+donly ww
+
+openoffset res ww 1 10
+renamevar res_1 result
+
+fit
+
+set length 846.702
+
+set nb_v_good 5
+set nb_e_good 4
+set nb_w_good 1
+set nb_f_good 0
+set nb_sh_good 0
+set nb_sol_good 0
+set nb_compsol_good 0
+set nb_compound_good  0
+set nb_shape_good 10
+
+set only_screen_axo 1
diff --git a/tests/bugs/modalg_5/bug25334_12 b/tests/bugs/modalg_5/bug25334_12
new file mode 100644
index 0000000000..f17d8a227b
--- /dev/null
+++ b/tests/bugs/modalg_5/bug25334_12
@@ -0,0 +1,35 @@
+puts "========"
+puts "OCC25334"
+puts "========"
+puts ""
+##########################################################################################################
+# BRepOffsetAPI_MakeOffset algofithm crashes on some customer's shape when option of open result is used
+##########################################################################################################
+
+restore [locate_data_file bug25334_faceProlongationCrash1.brep] a
+
+smallview
+
+explode a e
+wire ww a_4 a_1
+
+donly ww
+
+openoffset res ww 1 -10
+renamevar res_1 result
+
+fit
+
+set length 768.339
+
+set nb_v_good 4
+set nb_e_good 3
+set nb_w_good 1
+set nb_f_good 0
+set nb_sh_good 0
+set nb_sol_good 0
+set nb_compsol_good 0
+set nb_compound_good  0
+set nb_shape_good 8
+
+set only_screen_axo 1
diff --git a/tests/bugs/modalg_5/bug25334_13 b/tests/bugs/modalg_5/bug25334_13
new file mode 100644
index 0000000000..ac57bd70a1
--- /dev/null
+++ b/tests/bugs/modalg_5/bug25334_13
@@ -0,0 +1,35 @@
+puts "========"
+puts "OCC25334"
+puts "========"
+puts ""
+##########################################################################################################
+# BRepOffsetAPI_MakeOffset algofithm crashes on some customer's shape when option of open result is used
+##########################################################################################################
+
+restore [locate_data_file bug25334_faceProlongationCrash1.brep] a
+
+smallview
+
+explode a e
+wire ww a_1 a_2 a_3
+
+donly ww
+
+openoffset res ww 1 10
+renamevar res_1 result
+
+fit
+
+set length 1216.59
+
+set nb_v_good 6
+set nb_e_good 5
+set nb_w_good 1
+set nb_f_good 0
+set nb_sh_good 0
+set nb_sol_good 0
+set nb_compsol_good 0
+set nb_compound_good  0
+set nb_shape_good 12
+
+set only_screen_axo 1
diff --git a/tests/bugs/modalg_5/bug25334_14 b/tests/bugs/modalg_5/bug25334_14
new file mode 100644
index 0000000000..1c125b31d8
--- /dev/null
+++ b/tests/bugs/modalg_5/bug25334_14
@@ -0,0 +1,35 @@
+puts "========"
+puts "OCC25334"
+puts "========"
+puts ""
+##########################################################################################################
+# BRepOffsetAPI_MakeOffset algofithm crashes on some customer's shape when option of open result is used
+##########################################################################################################
+
+restore [locate_data_file bug25334_faceProlongationCrash1.brep] a
+
+smallview
+
+explode a e
+wire ww a_1 a_2 a_3
+
+donly ww
+
+openoffset res ww 1 -10
+renamevar res_1 result
+
+fit
+
+set length 1132.6
+
+set nb_v_good 4
+set nb_e_good 3
+set nb_w_good 1
+set nb_f_good 0
+set nb_sh_good 0
+set nb_sol_good 0
+set nb_compsol_good 0
+set nb_compound_good  0
+set nb_shape_good 8
+
+set only_screen_axo 1
diff --git a/tests/bugs/modalg_5/bug25334_15 b/tests/bugs/modalg_5/bug25334_15
new file mode 100644
index 0000000000..2a0d0debfd
--- /dev/null
+++ b/tests/bugs/modalg_5/bug25334_15
@@ -0,0 +1,35 @@
+puts "========"
+puts "OCC25334"
+puts "========"
+puts ""
+##########################################################################################################
+# BRepOffsetAPI_MakeOffset algofithm crashes on some customer's shape when option of open result is used
+##########################################################################################################
+
+restore [locate_data_file bug25334_faceProlongationCrash1.brep] a
+
+smallview
+
+explode a e
+wire ww a_1 a_2 a_4
+
+donly ww
+
+openoffset res ww 1 10
+renamevar res_1 result
+
+fit
+
+set length 1042.35
+
+set nb_v_good 6
+set nb_e_good 5
+set nb_w_good 1
+set nb_f_good 0
+set nb_sh_good 0
+set nb_sol_good 0
+set nb_compsol_good 0
+set nb_compound_good  0
+set nb_shape_good 12
+
+set only_screen_axo 1
diff --git a/tests/bugs/modalg_5/bug25334_16 b/tests/bugs/modalg_5/bug25334_16
new file mode 100644
index 0000000000..098eb6d7d4
--- /dev/null
+++ b/tests/bugs/modalg_5/bug25334_16
@@ -0,0 +1,35 @@
+puts "========"
+puts "OCC25334"
+puts "========"
+puts ""
+##########################################################################################################
+# BRepOffsetAPI_MakeOffset algofithm crashes on some customer's shape when option of open result is used
+##########################################################################################################
+
+restore [locate_data_file bug25334_faceProlongationCrash1.brep] a
+
+smallview
+
+explode a e
+wire ww a_1 a_2 a_4
+
+donly ww
+
+openoffset res ww 1 -10
+renamevar res_1 result
+
+fit
+
+set length 937.174
+
+set nb_v_good 4
+set nb_e_good 3
+set nb_w_good 1
+set nb_f_good 0
+set nb_sh_good 0
+set nb_sol_good 0
+set nb_compsol_good 0
+set nb_compound_good  0
+set nb_shape_good 8
+
+set only_screen_axo 1
diff --git a/tests/bugs/modalg_5/bug25334_17 b/tests/bugs/modalg_5/bug25334_17
new file mode 100644
index 0000000000..2ff5437431
--- /dev/null
+++ b/tests/bugs/modalg_5/bug25334_17
@@ -0,0 +1,35 @@
+puts "========"
+puts "OCC25334"
+puts "========"
+puts ""
+##########################################################################################################
+# BRepOffsetAPI_MakeOffset algofithm crashes on some customer's shape when option of open result is used
+##########################################################################################################
+
+restore [locate_data_file bug25334_faceProlongationCrash1.brep] a
+
+smallview
+
+explode a e
+wire ww a_1 a_4 a_3
+
+donly ww
+
+openoffset res ww 1 10
+renamevar res_1 result
+
+fit
+
+set length 1211.6
+
+set nb_v_good 6
+set nb_e_good 5
+set nb_w_good 1
+set nb_f_good 0
+set nb_sh_good 0
+set nb_sol_good 0
+set nb_compsol_good 0
+set nb_compound_good  0
+set nb_shape_good 12
+
+set only_screen_axo 1
diff --git a/tests/bugs/modalg_5/bug25334_18 b/tests/bugs/modalg_5/bug25334_18
new file mode 100644
index 0000000000..fe089d9757
--- /dev/null
+++ b/tests/bugs/modalg_5/bug25334_18
@@ -0,0 +1,35 @@
+puts "========"
+puts "OCC25334"
+puts "========"
+puts ""
+##########################################################################################################
+# BRepOffsetAPI_MakeOffset algofithm crashes on some customer's shape when option of open result is used
+##########################################################################################################
+
+restore [locate_data_file bug25334_faceProlongationCrash1.brep] a
+
+smallview
+
+explode a e
+wire ww a_1 a_4 a_3
+
+donly ww
+
+openoffset res ww 1 -10
+renamevar res_1 result
+
+fit
+
+set length 1143.61
+
+set nb_v_good 4
+set nb_e_good 3
+set nb_w_good 1
+set nb_f_good 0
+set nb_sh_good 0
+set nb_sol_good 0
+set nb_compsol_good 0
+set nb_compound_good  0
+set nb_shape_good 8
+
+set only_screen_axo 1
diff --git a/tests/bugs/modalg_5/bug25334_19 b/tests/bugs/modalg_5/bug25334_19
new file mode 100644
index 0000000000..8a928055d9
--- /dev/null
+++ b/tests/bugs/modalg_5/bug25334_19
@@ -0,0 +1,35 @@
+puts "========"
+puts "OCC25334"
+puts "========"
+puts ""
+##########################################################################################################
+# BRepOffsetAPI_MakeOffset algofithm crashes on some customer's shape when option of open result is used
+##########################################################################################################
+
+restore [locate_data_file bug25334_faceProlongationCrash1.brep] a
+
+smallview
+
+explode a e
+wire ww a_2 a_3 a_4
+
+donly ww
+
+openoffset res ww 1 10
+renamevar res_1 result
+
+fit
+
+set length 752.799
+
+set nb_v_good 6
+set nb_e_good 5
+set nb_w_good 1
+set nb_f_good 0
+set nb_sh_good 0
+set nb_sol_good 0
+set nb_compsol_good 0
+set nb_compound_good  0
+set nb_shape_good 12
+
+set only_screen_axo 1
diff --git a/tests/bugs/modalg_5/bug25334_2 b/tests/bugs/modalg_5/bug25334_2
new file mode 100644
index 0000000000..7361dfa7a1
--- /dev/null
+++ b/tests/bugs/modalg_5/bug25334_2
@@ -0,0 +1,35 @@
+puts "========"
+puts "OCC25334"
+puts "========"
+puts ""
+##########################################################################################################
+# BRepOffsetAPI_MakeOffset algofithm crashes on some customer's shape when option of open result is used
+##########################################################################################################
+
+restore [locate_data_file bug25334_faceProlongationCrash1.brep] a
+
+smallview
+
+explode a e
+wire ww a_1
+
+donly ww
+
+openoffset res ww 1 -10
+renamevar res_1 result
+
+fit
+
+set length 644.509
+
+set nb_v_good 2
+set nb_e_good 1
+set nb_w_good 1
+set nb_f_good 0
+set nb_sh_good 0
+set nb_sol_good 0
+set nb_compsol_good 0
+set nb_compound_good  0
+set nb_shape_good 4
+
+set only_screen_axo 1
diff --git a/tests/bugs/modalg_5/bug25334_20 b/tests/bugs/modalg_5/bug25334_20
new file mode 100644
index 0000000000..9cce2340f6
--- /dev/null
+++ b/tests/bugs/modalg_5/bug25334_20
@@ -0,0 +1,35 @@
+puts "========"
+puts "OCC25334"
+puts "========"
+puts ""
+##########################################################################################################
+# BRepOffsetAPI_MakeOffset algofithm crashes on some customer's shape when option of open result is used
+##########################################################################################################
+
+restore [locate_data_file bug25334_faceProlongationCrash1.brep] a
+
+smallview
+
+explode a e
+wire ww a_2 a_3 a_4
+
+donly ww
+
+openoffset res ww 1 -10
+renamevar res_1 result
+
+fit
+
+set length 705.994
+
+set nb_v_good 4
+set nb_e_good 3
+set nb_w_good 1
+set nb_f_good 0
+set nb_sh_good 0
+set nb_sol_good 0
+set nb_compsol_good 0
+set nb_compound_good  0
+set nb_shape_good 8
+
+set only_screen_axo 1
diff --git a/tests/bugs/modalg_5/bug25334_3 b/tests/bugs/modalg_5/bug25334_3
new file mode 100644
index 0000000000..bf8a152d16
--- /dev/null
+++ b/tests/bugs/modalg_5/bug25334_3
@@ -0,0 +1,35 @@
+puts "========"
+puts "OCC25334"
+puts "========"
+puts ""
+##########################################################################################################
+# BRepOffsetAPI_MakeOffset algofithm crashes on some customer's shape when option of open result is used
+##########################################################################################################
+
+restore [locate_data_file bug25334_faceProlongationCrash1.brep] a
+
+smallview
+
+explode a e
+wire ww a_3
+
+donly ww
+
+openoffset res ww 1 10
+renamevar res_1 result
+
+fit
+
+set length 354.958
+
+set nb_v_good 2
+set nb_e_good 1
+set nb_w_good 1
+set nb_f_good 0
+set nb_sh_good 0
+set nb_sol_good 0
+set nb_compsol_good 0
+set nb_compound_good  0
+set nb_shape_good 4
+
+set only_screen_axo 1
diff --git a/tests/bugs/modalg_5/bug25334_4 b/tests/bugs/modalg_5/bug25334_4
new file mode 100644
index 0000000000..5430c645d4
--- /dev/null
+++ b/tests/bugs/modalg_5/bug25334_4
@@ -0,0 +1,35 @@
+puts "========"
+puts "OCC25334"
+puts "========"
+puts ""
+##########################################################################################################
+# BRepOffsetAPI_MakeOffset algofithm crashes on some customer's shape when option of open result is used
+##########################################################################################################
+
+restore [locate_data_file bug25334_faceProlongationCrash1.brep] a
+
+smallview
+
+explode a e
+wire ww a_3
+
+donly ww
+
+openoffset res ww 1 -10
+renamevar res_1 result
+
+fit
+
+set length 386.077
+
+set nb_v_good 2
+set nb_e_good 1
+set nb_w_good 1
+set nb_f_good 0
+set nb_sh_good 0
+set nb_sol_good 0
+set nb_compsol_good 0
+set nb_compound_good  0
+set nb_shape_good 4
+
+set only_screen_axo 1
diff --git a/tests/bugs/modalg_5/bug25334_5 b/tests/bugs/modalg_5/bug25334_5
new file mode 100644
index 0000000000..78c1301c64
--- /dev/null
+++ b/tests/bugs/modalg_5/bug25334_5
@@ -0,0 +1,35 @@
+puts "========"
+puts "OCC25334"
+puts "========"
+puts ""
+##########################################################################################################
+# BRepOffsetAPI_MakeOffset algofithm crashes on some customer's shape when option of open result is used
+##########################################################################################################
+
+restore [locate_data_file bug25334_faceProlongationCrash1.brep] a
+
+smallview
+
+explode a e
+wire ww a_1 a_2
+
+donly ww
+
+openoffset res ww 1 10
+renamevar res_1 result
+
+fit
+
+set length 840.157
+
+set nb_v_good 5
+set nb_e_good 4
+set nb_w_good 1
+set nb_f_good 0
+set nb_sh_good 0
+set nb_sol_good 0
+set nb_compsol_good 0
+set nb_compound_good  0
+set nb_shape_good 10
+
+set only_screen_axo 1
diff --git a/tests/bugs/modalg_5/bug25334_6 b/tests/bugs/modalg_5/bug25334_6
new file mode 100644
index 0000000000..81784f948c
--- /dev/null
+++ b/tests/bugs/modalg_5/bug25334_6
@@ -0,0 +1,35 @@
+puts "========"
+puts "OCC25334"
+puts "========"
+puts ""
+##########################################################################################################
+# BRepOffsetAPI_MakeOffset algofithm crashes on some customer's shape when option of open result is used
+##########################################################################################################
+
+restore [locate_data_file bug25334_faceProlongationCrash1.brep] a
+
+smallview
+
+explode a e
+wire ww a_1 a_2
+
+donly ww
+
+openoffset res ww 1 -10
+renamevar res_1 result
+
+fit
+
+set length 782.224
+
+set nb_v_good 4
+set nb_e_good 3
+set nb_w_good 1
+set nb_f_good 0
+set nb_sh_good 0
+set nb_sol_good 0
+set nb_compsol_good 0
+set nb_compound_good  0
+set nb_shape_good 8
+
+set only_screen_axo 1
diff --git a/tests/bugs/modalg_5/bug25334_7 b/tests/bugs/modalg_5/bug25334_7
new file mode 100644
index 0000000000..052bdb7d3c
--- /dev/null
+++ b/tests/bugs/modalg_5/bug25334_7
@@ -0,0 +1,35 @@
+puts "========"
+puts "OCC25334"
+puts "========"
+puts ""
+##########################################################################################################
+# BRepOffsetAPI_MakeOffset algofithm crashes on some customer's shape when option of open result is used
+##########################################################################################################
+
+restore [locate_data_file bug25334_faceProlongationCrash1.brep] a
+
+smallview
+
+explode a e
+wire ww a_2 a_3
+
+donly ww
+
+openoffset res ww 1 10
+renamevar res_1 result
+
+fit
+
+set length 559.65
+
+set nb_v_good 5
+set nb_e_good 4
+set nb_w_good 1
+set nb_f_good 0
+set nb_sh_good 0
+set nb_sol_good 0
+set nb_compsol_good 0
+set nb_compound_good  0
+set nb_shape_good 10
+
+set only_screen_axo 1
diff --git a/tests/bugs/modalg_5/bug25334_8 b/tests/bugs/modalg_5/bug25334_8
new file mode 100644
index 0000000000..3922c68ed4
--- /dev/null
+++ b/tests/bugs/modalg_5/bug25334_8
@@ -0,0 +1,35 @@
+puts "========"
+puts "OCC25334"
+puts "========"
+puts ""
+##########################################################################################################
+# BRepOffsetAPI_MakeOffset algofithm crashes on some customer's shape when option of open result is used
+##########################################################################################################
+
+restore [locate_data_file bug25334_faceProlongationCrash1.brep] a
+
+smallview
+
+explode a e
+wire ww a_2 a_3
+
+donly ww
+
+openoffset res ww 1 -10
+renamevar res_1 result
+
+fit
+
+set length 533.593
+
+set nb_v_good 4
+set nb_e_good 3
+set nb_w_good 1
+set nb_f_good 0
+set nb_sh_good 0
+set nb_sol_good 0
+set nb_compsol_good 0
+set nb_compound_good  0
+set nb_shape_good 8
+
+set only_screen_axo 1
diff --git a/tests/bugs/modalg_5/bug25334_9 b/tests/bugs/modalg_5/bug25334_9
new file mode 100644
index 0000000000..ad993a8087
--- /dev/null
+++ b/tests/bugs/modalg_5/bug25334_9
@@ -0,0 +1,35 @@
+puts "========"
+puts "OCC25334"
+puts "========"
+puts ""
+##########################################################################################################
+# BRepOffsetAPI_MakeOffset algofithm crashes on some customer's shape when option of open result is used
+##########################################################################################################
+
+restore [locate_data_file bug25334_faceProlongationCrash1.brep] a
+
+smallview
+
+explode a e
+wire ww a_3 a_4
+
+donly ww
+
+openoffset res ww 1 10
+renamevar res_1 result
+
+fit
+
+set length 558.479
+
+set nb_v_good 4
+set nb_e_good 3
+set nb_w_good 1
+set nb_f_good 0
+set nb_sh_good 0
+set nb_sol_good 0
+set nb_compsol_good 0
+set nb_compound_good  0
+set nb_shape_good 8
+
+set only_screen_axo 1