0026396: Taper API result differs run-to-run for identical inputs
authorisn <isn@opencascade.com>
Thu, 8 Oct 2015 07:32:41 +0000 (10:32 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 8 Oct 2015 07:35:08 +0000 (10:35 +0300)
- all data maps where shape used as a key have been replaced with indexed data maps. Now index used for iteration through this map instead of shape-key.
- new test have been added. This test allows to test stability of DraftAngle-algo.
- alignment corrections...

Removing warnings

12 files changed:
src/Draft/Draft_DataMapIteratorOfDataMapOfEdgeEdgeInfo.hxx [deleted file]
src/Draft/Draft_DataMapIteratorOfDataMapOfFaceFaceInfo.hxx [deleted file]
src/Draft/Draft_DataMapIteratorOfDataMapOfVertexVertexInfo.hxx [deleted file]
src/Draft/Draft_IndexedDataMapOfEdgeEdgeInfo.hxx [moved from src/Draft/Draft_DataMapOfEdgeEdgeInfo.hxx with 69% similarity]
src/Draft/Draft_IndexedDataMapOfFaceFaceInfo.hxx [moved from src/Draft/Draft_DataMapOfFaceFaceInfo.hxx with 69% similarity]
src/Draft/Draft_IndexedDataMapOfVertexVertexInfo.hxx [moved from src/Draft/Draft_DataMapOfVertexVertexInfo.hxx with 68% similarity]
src/Draft/Draft_Modification.cxx
src/Draft/Draft_Modification.hxx
src/Draft/Draft_Modification_1.cxx
src/Draft/FILES
src/QABugs/QABugs_19.cxx
tests/bugs/modalg_6/bug26396 [new file with mode: 0644]

diff --git a/src/Draft/Draft_DataMapIteratorOfDataMapOfEdgeEdgeInfo.hxx b/src/Draft/Draft_DataMapIteratorOfDataMapOfEdgeEdgeInfo.hxx
deleted file mode 100644 (file)
index 149670b..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-#ifndef Draft_DataMapIteratorOfDataMapOfEdgeEdgeInfo_HeaderFile
-#define Draft_DataMapIteratorOfDataMapOfEdgeEdgeInfo_HeaderFile
-
-#include <Draft_DataMapOfEdgeEdgeInfo.hxx>
-
-#endif
diff --git a/src/Draft/Draft_DataMapIteratorOfDataMapOfFaceFaceInfo.hxx b/src/Draft/Draft_DataMapIteratorOfDataMapOfFaceFaceInfo.hxx
deleted file mode 100644 (file)
index e71ca73..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-#ifndef Draft_DataMapIteratorOfDataMapOfFaceFaceInfo_HeaderFile
-#define Draft_DataMapIteratorOfDataMapOfFaceFaceInfo_HeaderFile
-
-#include <Draft_DataMapOfFaceFaceInfo.hxx>
-
-#endif
diff --git a/src/Draft/Draft_DataMapIteratorOfDataMapOfVertexVertexInfo.hxx b/src/Draft/Draft_DataMapIteratorOfDataMapOfVertexVertexInfo.hxx
deleted file mode 100644 (file)
index 26b301a..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-#ifndef Draft_DataMapIteratorOfDataMapOfVertexVertexInfo_HeaderFile
-#define Draft_DataMapIteratorOfDataMapOfVertexVertexInfo_HeaderFile
-
-#include <Draft_DataMapOfVertexVertexInfo.hxx>
-
-#endif
similarity index 69%
rename from src/Draft/Draft_DataMapOfEdgeEdgeInfo.hxx
rename to src/Draft/Draft_IndexedDataMapOfEdgeEdgeInfo.hxx
index e807944..27efe88 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-#ifndef Draft_DataMapOfEdgeEdgeInfo_HeaderFile
-#define Draft_DataMapOfEdgeEdgeInfo_HeaderFile
+#ifndef Draft_IndexedDataMapOfEdgeEdgeInfo_HeaderFile
+#define Draft_IndexedDataMapOfEdgeEdgeInfo_HeaderFile
 
 #include <TopoDS_Edge.hxx>
 #include <Draft_EdgeInfo.hxx>
 #include <TopTools_ShapeMapHasher.hxx>
-#include <NCollection_DataMap.hxx>
+#include <NCollection_IndexedDataMap.hxx>
 
-typedef NCollection_DataMap<TopoDS_Edge,Draft_EdgeInfo,TopTools_ShapeMapHasher> Draft_DataMapOfEdgeEdgeInfo;
-typedef NCollection_DataMap<TopoDS_Edge,Draft_EdgeInfo,TopTools_ShapeMapHasher>::Iterator Draft_DataMapIteratorOfDataMapOfEdgeEdgeInfo;
+typedef NCollection_IndexedDataMap<TopoDS_Edge,Draft_EdgeInfo,TopTools_ShapeMapHasher> Draft_IndexedDataMapOfEdgeEdgeInfo;
 
 
 #endif
similarity index 69%
rename from src/Draft/Draft_DataMapOfFaceFaceInfo.hxx
rename to src/Draft/Draft_IndexedDataMapOfFaceFaceInfo.hxx
index b0c0d70..d94e8c3 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-#ifndef Draft_DataMapOfFaceFaceInfo_HeaderFile
-#define Draft_DataMapOfFaceFaceInfo_HeaderFile
+#ifndef Draft_IndexedDataMapOfFaceFaceInfo_HeaderFile
+#define Draft_IndexedDataMapOfFaceFaceInfo_HeaderFile
 
 #include <TopoDS_Face.hxx>
 #include <Draft_FaceInfo.hxx>
 #include <TopTools_ShapeMapHasher.hxx>
-#include <NCollection_DataMap.hxx>
+#include <NCollection_IndexedDataMap.hxx>
 
-typedef NCollection_DataMap<TopoDS_Face,Draft_FaceInfo,TopTools_ShapeMapHasher> Draft_DataMapOfFaceFaceInfo;
-typedef NCollection_DataMap<TopoDS_Face,Draft_FaceInfo,TopTools_ShapeMapHasher>::Iterator Draft_DataMapIteratorOfDataMapOfFaceFaceInfo;
+typedef NCollection_IndexedDataMap<TopoDS_Face,Draft_FaceInfo,TopTools_ShapeMapHasher> Draft_IndexedDataMapOfFaceFaceInfo;
 
 
 #endif
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-#ifndef Draft_DataMapOfVertexVertexInfo_HeaderFile
-#define Draft_DataMapOfVertexVertexInfo_HeaderFile
+#ifndef Draft_IndexedDataMapOfVertexVertexInfo_HeaderFile
+#define Draft_IndexedDataMapOfVertexVertexInfo_HeaderFile
 
 #include <TopoDS_Vertex.hxx>
 #include <Draft_VertexInfo.hxx>
 #include <TopTools_ShapeMapHasher.hxx>
-#include <NCollection_DataMap.hxx>
+#include <NCollection_IndexedDataMap.hxx>
 
-typedef NCollection_DataMap<TopoDS_Vertex,Draft_VertexInfo,TopTools_ShapeMapHasher> Draft_DataMapOfVertexVertexInfo;
-typedef NCollection_DataMap<TopoDS_Vertex,Draft_VertexInfo,TopTools_ShapeMapHasher>::Iterator Draft_DataMapIteratorOfDataMapOfVertexVertexInfo;
+typedef NCollection_IndexedDataMap<TopoDS_Vertex,Draft_VertexInfo,TopTools_ShapeMapHasher> Draft_IndexedDataMapOfVertexVertexInfo;
 
 
 #endif
index 0065bb7..5d79aa0 100644 (file)
@@ -18,8 +18,6 @@
 #include <BRep_Builder.hxx>
 #include <BRep_Tool.hxx>
 #include <BRepTools.hxx>
-#include <Draft_DataMapIteratorOfDataMapOfEdgeEdgeInfo.hxx>
-#include <Draft_DataMapIteratorOfDataMapOfFaceFaceInfo.hxx>
 #include <Draft_EdgeInfo.hxx>
 #include <Draft_FaceInfo.hxx>
 #include <Draft_Modification.hxx>
@@ -129,44 +127,60 @@ Standard_Boolean Draft_Modification::Add(const TopoDS_Face& F,
 
 void Draft_Modification::Remove(const TopoDS_Face& F)
 {
-  if (!myFMap.IsBound(F) || myComp) {
+  if (!myFMap.Contains(F) || myComp) {
     Standard_NoSuchObject::Raise();
   }
 
   conneF.Clear();
   TopTools_ListIteratorOfListOfShape ltod;
 
-  curFace = myFMap(F).RootFace();
-  Draft_DataMapIteratorOfDataMapOfFaceFaceInfo itf(myFMap);
-  while (itf.More()) {
-    const TopoDS_Face& theF = itf.Key();
-    if (myFMap(theF).RootFace().IsSame(curFace)) {
+  curFace = myFMap.FindFromKey(F).RootFace();
+  for (Standard_Integer i = 1; i <= myFMap.Extent(); i++)
+  {
+    const TopoDS_Face& theF = myFMap.FindKey(i);
+    if (myFMap.FindFromKey(theF).RootFace().IsSame(curFace)) {
       conneF.Append(theF);
       if (theF.IsSame(badShape)) {
        badShape.Nullify();
       }
     }
-    itf.Next();
   }
 
   ltod.Initialize(conneF);
+  Standard_Integer IndToReplace = 0;
   while (ltod.More()) {
-    myFMap.UnBind(TopoDS::Face(ltod.Value()));
+    IndToReplace = myFMap.FindIndex(TopoDS::Face(ltod.Value()));
+    if (IndToReplace)
+    {
+      Standard_Integer LInd = myFMap.Extent();
+      TopoDS_Face LF = myFMap.FindKey(LInd);
+      Draft_FaceInfo LFInfo = myFMap.FindFromIndex(LInd);
+      myFMap.RemoveLast();
+      if (IndToReplace != LInd)
+        myFMap.Substitute(IndToReplace, LF, LFInfo);
+    }
     ltod.Next();
   }
 
   conneF.Clear();
-  Draft_DataMapIteratorOfDataMapOfEdgeEdgeInfo ite(myEMap);
-  while (ite.More()) {
-    const TopoDS_Edge& theE = ite.Key();
-    if (myEMap(theE).RootFace().IsSame(curFace)) {
-      conneF.Append(theE);
-    }
-    ite.Next();
+  for (Standard_Integer i = 1; i <= myEMap.Extent(); i++)
+  {
+    const TopoDS_Edge& theE = myEMap.FindKey(i);
+    if (myEMap.FindFromKey(theE).RootFace().IsSame(curFace))
+       conneF.Append(theE);
   }
   ltod.Initialize(conneF);
   while (ltod.More()) {
-    myEMap.UnBind(TopoDS::Edge(ltod.Value()));
+    IndToReplace = myFMap.FindIndex(TopoDS::Face(ltod.Value()));
+    if (IndToReplace)
+    {
+      Standard_Integer LInd = myEMap.Extent();
+      TopoDS_Edge LF = myEMap.FindKey(LInd);
+      Draft_EdgeInfo LFInfo = myEMap.FindFromIndex(LInd);
+      myEMap.RemoveLast();
+      if (IndToReplace != LInd)
+        myEMap.Substitute(IndToReplace, LF, LFInfo);
+    }
     ltod.Next();
   }
 }
@@ -212,22 +226,21 @@ const TopoDS_Shape& Draft_Modification::ProblematicShape() const
 
 const TopTools_ListOfShape & Draft_Modification::ConnectedFaces(const TopoDS_Face& F)
 {
-  if (!myFMap.IsBound(F)) {
+  if (!myFMap.Contains(F)) {
     Standard_NoSuchObject::Raise();
   }
   if (!IsDone()) {
     StdFail_NotDone::Raise();
   }
   conneF.Clear();
-  curFace = myFMap(F).RootFace();
+  curFace = myFMap.FindFromKey(F).RootFace();
 
-  Draft_DataMapIteratorOfDataMapOfFaceFaceInfo itf(myFMap);
-  while (itf.More()) {
-    const TopoDS_Face& theF = itf.Key();
-    if (myFMap(theF).RootFace().IsSame(curFace)) {
+  for (Standard_Integer i = 1; i <= myFMap.Extent(); i++)
+  {
+    const TopoDS_Face& theF = myFMap.FindKey(i);
+    if (myFMap.FindFromKey(theF).RootFace().IsSame(curFace)) {
       conneF.Append(theF);
     }
-    itf.Next();
   }
 
   return conneF;
@@ -248,13 +261,12 @@ const TopTools_ListOfShape & Draft_Modification::ModifiedFaces()
   }
   conneF.Clear();
 
-  Draft_DataMapIteratorOfDataMapOfFaceFaceInfo itf(myFMap);
-  while (itf.More()) {
-    const TopoDS_Face& theF = itf.Key();
-    if (!myFMap(theF).RootFace().IsNull()) {
+  for (Standard_Integer i = 1; i <= myFMap.Extent(); i++)
+  {
+    const TopoDS_Face& theF = myFMap.FindKey(i);
+    if (!myFMap.FindFromKey(theF).RootFace().IsNull()) {
       conneF.Append(theF);
     }
-    itf.Next();
   }
 
   return conneF;
@@ -277,7 +289,7 @@ Standard_Boolean Draft_Modification::NewSurface(const TopoDS_Face& F,
 {
   if (!IsDone()) {Standard_DomainError::Raise();}
 
-  if (!myFMap.IsBound(F) || !myFMap(F).NewGeometry()) {
+  if (!myFMap.Contains(F) || !myFMap.FindFromKey(F).NewGeometry()) {
     return Standard_False;
   }
 
@@ -289,7 +301,7 @@ Standard_Boolean Draft_Modification::NewSurface(const TopoDS_Face& F,
 
   L.Identity();
 
-  S = myFMap(F).Geometry();
+  S = myFMap.FindFromKey(F).Geometry();
 
   return Standard_True;
 }
@@ -307,17 +319,17 @@ Standard_Boolean Draft_Modification::NewCurve(const TopoDS_Edge& E,
 {
   if (!IsDone()) {Standard_DomainError::Raise();}
 
-  if (!myEMap.IsBound(E)) 
+  if (!myEMap.Contains(E)) 
     return Standard_False;
   
-  const Draft_EdgeInfo& Einf= myEMap(E);
-  if (!myEMap(E).NewGeometry())
+  const Draft_EdgeInfo& Einf= myEMap.FindFromKey(E);
+  if (!myEMap.FindFromKey(E).NewGeometry())
     return Standard_False;
   
   Tol = Einf.Tolerance();
   Tol = Max(Tol, BRep_Tool::Tolerance(E));
   L.Identity();
-  C = myEMap(E).Geometry();
+  C = myEMap.FindFromKey(E).Geometry();
 
   return Standard_True;
 
@@ -335,12 +347,12 @@ Standard_Boolean Draft_Modification::NewPoint(const TopoDS_Vertex& V,
 {
   if (!IsDone()) {Standard_DomainError::Raise();};
 
-  if (!myVMap.IsBound(V)) {
+  if (!myVMap.Contains(V)) {
     return Standard_False;
   }
 
   Tol = BRep_Tool::Tolerance(V);
-  P = myVMap(V).Geometry();
+  P = myVMap.FindFromKey(V).Geometry();
   return Standard_True;
 }
 
@@ -360,16 +372,16 @@ Standard_Boolean Draft_Modification::NewCurve2d(const TopoDS_Edge& E,
   
   if (!IsDone()) {Standard_DomainError::Raise();};
 
-  if (!myEMap.IsBound(E)) {
+  if (!myEMap.Contains(E)) {
     return Standard_False;
   }
   
   Standard_Real Fp,Lp;
   BRep_Tool::Range(NewE,Fp,Lp);
   
-  Handle(Geom_Surface) SB = myFMap(F).Geometry();
+  Handle(Geom_Surface) SB = myFMap.FindFromKey(F).Geometry();
 
-  const Draft_EdgeInfo& Einf = myEMap(E);
+  const Draft_EdgeInfo& Einf = myEMap.FindFromKey(E);
   if ( Einf.FirstFace().IsSame(F) && !Einf.FirstPC().IsNull()) {
     C = Einf.FirstPC();
   }
@@ -378,7 +390,7 @@ Standard_Boolean Draft_Modification::NewCurve2d(const TopoDS_Edge& E,
   }
   else {
     
-    if (!myEMap(E).NewGeometry()) {
+    if (!myEMap.FindFromKey(E).NewGeometry()) {
       Standard_Real Fpi,Lpi;
       BRep_Tool::Range(E,Fpi,Lpi);
       if (Fpi <= Fp && Fp <= Lpi && Fpi <= Lp && Lp <= Lpi) {
@@ -390,7 +402,7 @@ Standard_Boolean Draft_Modification::NewCurve2d(const TopoDS_Edge& E,
     
     //  if (!BRep_Tool::IsClosed(E,F)) {
     BRep_Tool::Range(NewE,Fp,Lp);
-    Handle(Geom_TrimmedCurve) TC = new Geom_TrimmedCurve(myEMap(E).Geometry(),
+    Handle(Geom_TrimmedCurve) TC = new Geom_TrimmedCurve(myEMap.FindFromKey(E).Geometry(),
                                                         Fp,Lp);
     Fp = TC->FirstParameter();
     Lp = TC->LastParameter();
@@ -464,12 +476,12 @@ Standard_Boolean Draft_Modification::NewParameter(const TopoDS_Vertex& V,
 
   if (!IsDone()) {Standard_DomainError::Raise();};
 
-  if (!myVMap.IsBound(V)) {
+  if (!myVMap.Contains(V)) {
     return Standard_False;
   }
 
-  P = myVMap(V).Parameter(E);
-  Handle(Geom_Curve) GC = myEMap(E).Geometry();
+  P = myVMap.ChangeFromKey(V).Parameter(E);
+  Handle(Geom_Curve) GC = myEMap.FindFromKey(E).Geometry();
   Handle(Standard_Type) typc = GC->DynamicType();
   if (typc == STANDARD_TYPE(Geom_TrimmedCurve)) {
     GC = Handle(Geom_TrimmedCurve)::DownCast(GC);
@@ -479,8 +491,8 @@ Standard_Boolean Draft_Modification::NewParameter(const TopoDS_Vertex& V,
   if (GC->IsClosed()) {
     TopoDS_Vertex FV = TopExp::FirstVertex(E);
     Standard_Real paramf;
-    if (myVMap.IsBound(FV)) {
-      paramf = myVMap(FV).Parameter(E);
+    if (myVMap.Contains(FV)) {
+      paramf = myVMap.ChangeFromKey(FV).Parameter(E);
     }
     else {
       paramf = BRep_Tool::Parameter(FV,E);
index 9f003d6..c96ae43 100644 (file)
@@ -20,9 +20,9 @@
 #include <Standard.hxx>
 #include <Standard_Type.hxx>
 
-#include <Draft_DataMapOfFaceFaceInfo.hxx>
-#include <Draft_DataMapOfEdgeEdgeInfo.hxx>
-#include <Draft_DataMapOfVertexVertexInfo.hxx>
+#include <Draft_IndexedDataMapOfFaceFaceInfo.hxx>
+#include <Draft_IndexedDataMapOfEdgeEdgeInfo.hxx>
+#include <Draft_IndexedDataMapOfVertexVertexInfo.hxx>
 #include <Standard_Boolean.hxx>
 #include <TopoDS_Shape.hxx>
 #include <Draft_ErrorStatus.hxx>
@@ -184,9 +184,9 @@ private:
   
   Standard_EXPORT Handle(Geom_Surface) NewSurface (const Handle(Geom_Surface)& S, const TopAbs_Orientation OriS, const gp_Dir& Direction, const Standard_Real Angle, const gp_Pln& NeutralPlane);
 
-  Draft_DataMapOfFaceFaceInfo myFMap;
-  Draft_DataMapOfEdgeEdgeInfo myEMap;
-  Draft_DataMapOfVertexVertexInfo myVMap;
+  Draft_IndexedDataMapOfFaceFaceInfo myFMap;
+  Draft_IndexedDataMapOfEdgeEdgeInfo myEMap;
+  Draft_IndexedDataMapOfVertexVertexInfo myVMap;
   Standard_Boolean myComp;
   TopoDS_Shape myShape;
   TopoDS_Shape badShape;
index 2f49afb..e021596 100644 (file)
@@ -14,7 +14,6 @@
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-
 #include <Adaptor3d_CurveOnSurface.hxx>
 #include <Adaptor3d_HCurveOnSurface.hxx>
 #include <Adaptor3d_SurfaceOfLinearExtrusion.hxx>
@@ -25,9 +24,6 @@
 #include <BRepExtrema_ExtPC.hxx>
 #include <BRepLib_MakeFace.hxx>
 #include <BRepTools.hxx>
-#include <Draft_DataMapIteratorOfDataMapOfEdgeEdgeInfo.hxx>
-#include <Draft_DataMapIteratorOfDataMapOfFaceFaceInfo.hxx>
-#include <Draft_DataMapIteratorOfDataMapOfVertexVertexInfo.hxx>
 #include <Draft_EdgeInfo.hxx>
 #include <Draft_FaceInfo.hxx>
 #include <Draft_Modification.hxx>
 #include <TopTools_MapIteratorOfMapOfShape.hxx>
 #include <TopTools_MapOfShape.hxx>
 
-static Standard_Boolean Choose(const Draft_DataMapOfFaceFaceInfo&,
-                              Draft_DataMapOfEdgeEdgeInfo&,
-                              const TopoDS_Vertex&,
-                              Draft_VertexInfo&,
-                              GeomAdaptor_Curve&,
-                              GeomAdaptor_Surface&);
+static Standard_Boolean Choose(const Draft_IndexedDataMapOfFaceFaceInfo&,
+  Draft_IndexedDataMapOfEdgeEdgeInfo&,
+  const TopoDS_Vertex&,
+  Draft_VertexInfo&,
+  GeomAdaptor_Curve&,
+  GeomAdaptor_Surface&);
 
 static Standard_Real Parameter(const Handle(Geom_Curve)&,
-                              const gp_Pnt&,
-                              Standard_Integer&);
+  const gp_Pnt&,
+  Standard_Integer&);
 
 static Standard_Real SmartParameter(Draft_EdgeInfo&,
-                                   const Standard_Real EdgeTol,
-                                   const gp_Pnt&,
-                                   const Standard_Integer,
-                                   const Handle(Geom_Surface)&,
-                                   const Handle(Geom_Surface)&);
+  const Standard_Real EdgeTol,
+  const gp_Pnt&,
+  const Standard_Integer,
+  const Handle(Geom_Surface)&,
+  const Handle(Geom_Surface)&);
 
 static TopAbs_Orientation Orientation(const TopoDS_Shape&,
-                                     const TopoDS_Face&);
+  const TopoDS_Face&);
 
 static Standard_Boolean FindRotation(const gp_Pln&,
-                                    const TopAbs_Orientation,
-                                    const gp_Dir&,
-                                    const Standard_Real,
-                                    const gp_Pln&,
-                                    gp_Ax1&,
-                                    Standard_Real&);
+  const TopAbs_Orientation,
+  const gp_Dir&,
+  const Standard_Real,
+  const gp_Pln&,
+  gp_Ax1&,
+  Standard_Real&);
 
 
 //=======================================================================
@@ -141,13 +137,13 @@ static Standard_Boolean FindRotation(const gp_Pln&,
 //=======================================================================
 
 Standard_Boolean Draft_Modification::InternalAdd(const TopoDS_Face& F,
-                                                const gp_Dir& Direction,
-                                                const Standard_Real Angle,
-                                                const gp_Pln& NeutralPlane,
-                                                const Standard_Boolean Flag)
+  const gp_Dir& Direction,
+  const Standard_Real Angle,
+  const gp_Pln& NeutralPlane,
+  const Standard_Boolean Flag)
 {
 
-  if (myFMap.IsBound(F)) {
+  if (myFMap.Contains(F)) {
     return (badShape.IsNull());
   }
 
@@ -167,47 +163,47 @@ Standard_Boolean Draft_Modification::InternalAdd(const TopoDS_Face& F,
   if (postponed) {
     Handle(Standard_Type) typS = S->DynamicType();
     if (typS == STANDARD_TYPE(Geom_CylindricalSurface) ||
-       typS == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) {
+        typS == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) {
       gp_Circ Cir;
       if (typS == STANDARD_TYPE(Geom_CylindricalSurface)) {
-       gp_Cylinder cyl = 
-         Handle(Geom_CylindricalSurface)::DownCast(S)->Cylinder();
-       gp_Ax1 axcyl = cyl.Axis();
-       Cir = ElSLib::CylinderVIso( cyl.Position(), cyl.Radius(), 0.);
-       gp_Vec VV(cyl.Location(),NeutralPlane.Location());
-       Cir.Translate(VV.Dot(axcyl.Direction())*axcyl.Direction());
+        gp_Cylinder cyl = 
+          Handle(Geom_CylindricalSurface)::DownCast(S)->Cylinder();
+        gp_Ax1 axcyl = cyl.Axis();
+        Cir = ElSLib::CylinderVIso( cyl.Position(), cyl.Radius(), 0.);
+        gp_Vec VV(cyl.Location(),NeutralPlane.Location());
+        Cir.Translate(VV.Dot(axcyl.Direction())*axcyl.Direction());
       }
       else {
-       Handle(Geom_Curve) Cbas = 
-         Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(S)->BasisCurve();
-       gp_Dir theDirextr = 
-         Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(S)->Direction();
-
-       if (Cbas->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
-         Cbas = Handle(Geom_TrimmedCurve)::DownCast(Cbas)->BasisCurve();
-       }
-       if (Cbas->IsKind(STANDARD_TYPE(Geom_Circle))) {
-         Cir = Handle(Geom_Circle)::DownCast(Cbas)->Circ();
-         gp_Dir dircir = Cir.Axis().Direction();
-         if (!Direction.IsParallel(dircir,Precision::Angular())) {
-           badShape = F;
-           errStat = Draft_FaceRecomputation;
-           return Standard_False;
-         }
-       }
-       else {
-         badShape = F;
-         errStat = Draft_FaceRecomputation;
-         return Standard_False;
-       }
-
-       gp_Ax3 Axis = NeutralPlane.Position();
-       Standard_Real L =
-         gp_Vec(Cir.Location(),Axis.Location()).
-           Dot(Axis.Direction());
-       Standard_Real Cos = theDirextr.Dot(Axis.Direction());
-       gp_Vec VV = ( L / Cos) * theDirextr;
-       Cir.Translate(VV);
+        Handle(Geom_Curve) Cbas = 
+          Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(S)->BasisCurve();
+        gp_Dir theDirextr = 
+          Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(S)->Direction();
+
+        if (Cbas->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
+          Cbas = Handle(Geom_TrimmedCurve)::DownCast(Cbas)->BasisCurve();
+        }
+        if (Cbas->IsKind(STANDARD_TYPE(Geom_Circle))) {
+          Cir = Handle(Geom_Circle)::DownCast(Cbas)->Circ();
+          gp_Dir dircir = Cir.Axis().Direction();
+          if (!Direction.IsParallel(dircir,Precision::Angular())) {
+            badShape = F;
+            errStat = Draft_FaceRecomputation;
+            return Standard_False;
+          }
+        }
+        else {
+          badShape = F;
+          errStat = Draft_FaceRecomputation;
+          return Standard_False;
+        }
+
+        gp_Ax3 Axis = NeutralPlane.Position();
+        Standard_Real L =
+          gp_Vec(Cir.Location(),Axis.Location()).
+          Dot(Axis.Direction());
+        Standard_Real Cos = theDirextr.Dot(Axis.Direction());
+        gp_Vec VV = ( L / Cos) * theDirextr;
+        Cir.Translate(VV);
       }
 
       theCircle = new Geom_Circle(Cir);
@@ -229,45 +225,45 @@ Standard_Boolean Draft_Modification::InternalAdd(const TopoDS_Face& F,
     // To avoid some problems with infinite restrictions
     const Handle(Standard_Type)& typs = NewS->DynamicType();
     if (typs == STANDARD_TYPE(Geom_CylindricalSurface) ||
-       typs == STANDARD_TYPE(Geom_ConicalSurface)) {
+        typs == STANDARD_TYPE(Geom_ConicalSurface)) {
       Standard_Real umin,umax,vmin,vmax;
       BRepTools::UVBounds(F,umin,umax,vmin,vmax);
       if (!Precision::IsNegativeInfinite(vmin) &&
-         !Precision::IsPositiveInfinite(vmax)) {
-       Standard_Real deltav = 10.*(vmax-vmin);
-       if(typs == STANDARD_TYPE(Geom_CylindricalSurface)) {
-         vmin = vmin - deltav;
-         vmax = vmax + deltav;
-       }
-       else {
-         gp_Cone Co = Handle(Geom_ConicalSurface)::DownCast(NewS)->Cone();
-         Standard_Real Vapex = - Co.RefRadius()/Sin(Co.SemiAngle());
-         if (vmin < Vapex) { // vmax should not exceed Vapex
-           if (vmax + deltav > Vapex) {
-             vmax = Vapex;
-             vmin = vmin - 10.*(vmax - vmin);
-             // JAG debug to avoid apex
-             vmax = vmax-Precision::Confusion();
-           }
-           else {
-             vmin = vmin - deltav;
-             vmax = vmax + deltav;
-           }
-         }
-         else { // Vapex <= vmin < vmax
-           if (vmin - deltav < Vapex) {
-             vmin = Vapex;
-             vmax = vmax + 10.*(vmax - vmin);
-             // JAG debug to avoid apex
-             vmin = vmin+Precision::Confusion();
-           }
-           else {
-             vmin = vmin - deltav;
-             vmax = vmax + deltav;
-           }
-         }
-       }
-       NewS = new Geom_RectangularTrimmedSurface(NewS,0.,2.*M_PI,vmin,vmax);
+          !Precision::IsPositiveInfinite(vmax)) {
+        Standard_Real deltav = 10.*(vmax-vmin);
+        if(typs == STANDARD_TYPE(Geom_CylindricalSurface)) {
+          vmin = vmin - deltav;
+          vmax = vmax + deltav;
+        }
+        else {
+          gp_Cone Co = Handle(Geom_ConicalSurface)::DownCast(NewS)->Cone();
+          Standard_Real Vapex = - Co.RefRadius()/Sin(Co.SemiAngle());
+          if (vmin < Vapex) { // vmax should not exceed Vapex
+            if (vmax + deltav > Vapex) {
+              vmax = Vapex;
+              vmin = vmin - 10.*(vmax - vmin);
+              // JAG debug to avoid apex
+              vmax = vmax-Precision::Confusion();
+            }
+            else {
+              vmin = vmin - deltav;
+              vmax = vmax + deltav;
+            }
+          }
+          else { // Vapex <= vmin < vmax
+            if (vmin - deltav < Vapex) {
+              vmin = Vapex;
+              vmax = vmax + 10.*(vmax - vmin);
+              // JAG debug to avoid apex
+              vmin = vmin+Precision::Confusion();
+            }
+            else {
+              vmin = vmin - deltav;
+              vmax = vmax + deltav;
+            }
+          }
+        }
+        NewS = new Geom_RectangularTrimmedSurface(NewS,0.,2.*M_PI,vmin,vmax);
       }
     }
   }
@@ -275,9 +271,9 @@ Standard_Boolean Draft_Modification::InternalAdd(const TopoDS_Face& F,
   if (postponed || S != NewS) {
     Draft_FaceInfo FI(NewS,Standard_True);
     FI.RootFace(curFace);
-    myFMap.Bind(F,FI);
+    myFMap.Add(F,FI);
     if (postponed) {
-      myFMap(F).ChangeCurve() = theCircle;
+      myFMap.ChangeFromKey(F).ChangeCurve() = theCircle;
     }
   }    
 
@@ -285,121 +281,142 @@ Standard_Boolean Draft_Modification::InternalAdd(const TopoDS_Face& F,
   TopTools_MapOfShape MapOfE;
   while (expl.More() && badShape.IsNull()) {
     const TopoDS_Edge& edg = TopoDS::Edge(expl.Current());
-    if (!myEMap.IsBound(edg)) {
+    if (!myEMap.Contains(edg)) {
       Standard_Boolean addedg  = Standard_False;
       Standard_Boolean addface = Standard_False;
       TopoDS_Face OtherF;
-      //       if (BRep_Tool::IsClosed(edg,F)) {
+      //if (BRep_Tool::IsClosed(edg,F)) {
       if (BRepTools::IsReallyClosed(edg,F)) {
-       addedg = Standard_True;
-       addface = Standard_False;
+        addedg = Standard_True;
+        addface = Standard_False;
       }
       else {
-       // Find the other face containing the edge.
-       TopTools_ListIteratorOfListOfShape it;
-       it.Initialize(myEFMap.FindFromKey(edg));
-       Standard_Integer nbother = 0;
-       while (it.More()) {
-         if (!it.Value().IsSame(F)) {
-           if (OtherF.IsNull()) {
-             OtherF = TopoDS::Face(it.Value());
-           }
-           nbother++;
-         }
-         it.Next();
-       }         
-       if (nbother >=2) {
-         badShape = edg;
-         errStat = Draft_EdgeRecomputation;
-       }
-       else if (! OtherF.IsNull() && 
-                BRep_Tool::Continuity(edg,F,OtherF) >= GeomAbs_G1) {
-         addface= Standard_True;
-         addedg = Standard_True;
-       }
-       else if (nbother == 0) {
-         //        badShape = F;
-       }
+        // Find the other face containing the edge.
+        TopTools_ListIteratorOfListOfShape it;
+        it.Initialize(myEFMap.FindFromKey(edg));
+        Standard_Integer nbother = 0;
+        while (it.More()) {
+          if (!it.Value().IsSame(F)) {
+            if (OtherF.IsNull()) {
+              OtherF = TopoDS::Face(it.Value());
+            }
+            nbother++;
+          }
+          it.Next();
+        }        
+        if (nbother >=2) {
+          badShape = edg;
+          errStat = Draft_EdgeRecomputation;
+        }
+        else if (! OtherF.IsNull() && 
+                 BRep_Tool::Continuity(edg,F,OtherF) >= GeomAbs_G1) {
+          addface= Standard_True;
+          addedg = Standard_True;
+        }
+        else if (nbother == 0) {
+          //       badShape = F;
+        }
       }
       if (addedg) {
-       if (postponed) {
-         myFMap(F).Add(OtherF);
-       }
-       Standard_Real f,l;
-       TopLoc_Location L;
-       Handle(Geom_Curve) C = BRep_Tool::Curve(edg,L,f,l);
-       C = Handle(Geom_Curve)::DownCast(C->Transformed(L));
-       if (C->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve)) {
-         C = Handle(Geom_TrimmedCurve)::DownCast(C)->BasisCurve();
-       }
+        if (postponed) {
+          myFMap.ChangeFromKey(F).Add(OtherF);
+        }
+        Standard_Real f,l;
+        TopLoc_Location L;
+        Handle(Geom_Curve) C = BRep_Tool::Curve(edg,L,f,l);
+        C = Handle(Geom_Curve)::DownCast(C->Transformed(L));
+        if (C->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve)) {
+          C = Handle(Geom_TrimmedCurve)::DownCast(C)->BasisCurve();
+        }
         Handle(Geom_Curve) NewC;
-       Draft_EdgeInfo EInf(Standard_True);     
+        Draft_EdgeInfo EInf(Standard_True);    
         if(postponed) {
-         EInf.Add(F);
-         EInf.Add(OtherF);
-
-         // find fixed point 
-         Handle(Geom_Line) aLocalGeom = Handle(Geom_Line)::DownCast(C);
-         if (aLocalGeom.IsNull()) {
-           badShape = edg;
-           errStat = Draft_EdgeRecomputation;
-         }
-         else {
-           gp_Lin lin = aLocalGeom->Lin();
-           IntAna_IntConicQuad ilipl(lin,NeutralPlane,Precision::Angular());
-           if (ilipl.IsDone() && ilipl.NbPoints() != 0){
-             EInf.Tangent(ilipl.Point(1));
-           }
-           else {
-             badShape = edg;
-             errStat = Draft_EdgeRecomputation;
-           }
-         }
-       }
+          EInf.Add(F);
+          EInf.Add(OtherF);
+
+          // find fixed point 
+          Handle(Geom_Line) aLocalGeom = Handle(Geom_Line)::DownCast(C);
+          if (aLocalGeom.IsNull()) {
+            badShape = edg;
+            errStat = Draft_EdgeRecomputation;
+          }
+          else {
+            gp_Lin lin = aLocalGeom->Lin();
+            IntAna_IntConicQuad ilipl(lin,NeutralPlane,Precision::Angular());
+            if (ilipl.IsDone() && ilipl.NbPoints() != 0){
+              EInf.Tangent(ilipl.Point(1));
+            }
+            else {
+              badShape = edg;
+              errStat = Draft_EdgeRecomputation;
+            }
+          }
+        }
         else {
-         NewC = NewCurve(C,S,oris,Direction,Angle,NeutralPlane, Flag);
-         if (NewC.IsNull()) {
-           badShape = edg;
-           errStat = Draft_EdgeRecomputation;
-         }
-       }
-
-       Handle(Geom_TrimmedCurve) T = Handle(Geom_TrimmedCurve)::DownCast(NewC);
-       if (!T.IsNull()) NewC = T->BasisCurve();
-       EInf.ChangeGeometry() = NewC;
-
-       EInf.RootFace(curFace);
-       myEMap.Bind(edg,EInf);
-       MapOfE.Add(edg);
-       if (addface) {
-         Standard_Boolean Fl = Flag;
-         Handle(Geom_Surface) alocalSurface = BRep_Tool::Surface(OtherF,Lo);
-         if (alocalSurface->DynamicType() == 
-             STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
-           alocalSurface = Handle(Geom_RectangularTrimmedSurface)::
-             DownCast(alocalSurface)->BasisSurface();
-         }
-         Handle(Standard_Type) typS = alocalSurface->DynamicType();
-         if (typS == STANDARD_TYPE(Geom_CylindricalSurface) || 
-             typS == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) {
-           if ( myFMap.IsBound(F)) {
-             if ( Flag == Standard_False && !postponed) {
-               myFMap.UnBind(F);
-               TopTools_MapIteratorOfMapOfShape itm(MapOfE);
-               for ( ; itm.More(); itm.Next())
-                 myEMap.UnBind(TopoDS::Edge(itm.Key()));
-             }
-           }
-         } 
-         InternalAdd(OtherF,Direction,Angle,NeutralPlane, Fl);
-       }
+          NewC = NewCurve(C,S,oris,Direction,Angle,NeutralPlane, Flag);
+          if (NewC.IsNull()) {
+            badShape = edg;
+            errStat = Draft_EdgeRecomputation;
+          }
+        }
+
+        Handle(Geom_TrimmedCurve) T = Handle(Geom_TrimmedCurve)::DownCast(NewC);
+        if (!T.IsNull()) NewC = T->BasisCurve();
+        EInf.ChangeGeometry() = NewC;
+
+        EInf.RootFace(curFace);
+        myEMap.Add(edg,EInf);
+        MapOfE.Add(edg);
+        if (addface) {
+          Standard_Boolean Fl = Flag;
+          Handle(Geom_Surface) alocalSurface = BRep_Tool::Surface(OtherF,Lo);
+          if (alocalSurface->DynamicType() == 
+              STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
+            alocalSurface = Handle(Geom_RectangularTrimmedSurface)::
+              DownCast(alocalSurface)->BasisSurface();
+          }
+          Handle(Standard_Type) typS = alocalSurface->DynamicType();
+          if (typS == STANDARD_TYPE(Geom_CylindricalSurface) || 
+              typS == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) {
+            if ( myFMap.Contains(F)) {
+              if ( Flag == Standard_False && !postponed) {
+                Standard_Integer IndToReplace = myFMap.FindIndex(F);
+                if (IndToReplace) {
+                  Standard_Integer LInd = myFMap.Extent();
+                  TopoDS_Face LF = myFMap.FindKey(LInd);
+                  Draft_FaceInfo LFInfo = myFMap.FindFromIndex(LInd);
+                  myFMap.RemoveLast();
+
+                  if (IndToReplace != LInd)
+                    myFMap.Substitute(IndToReplace, LF, LFInfo);
+                }
+                TopTools_MapIteratorOfMapOfShape itm(MapOfE);
+                for ( ; itm.More(); itm.Next())
+                {
+                  Standard_Integer IndToReplace = myEMap.FindIndex(TopoDS::Edge(itm.Key()));
+                  if ( IndToReplace )
+                  {
+                    Standard_Integer LInd = myEMap.Extent();
+                    TopoDS_Edge LE = myEMap.FindKey(LInd);
+                    Draft_EdgeInfo LEInfo = myEMap.FindFromIndex(LInd);
+                    myEMap.RemoveLast();
+
+                    if (IndToReplace != LInd)
+                      myEMap.Substitute(IndToReplace, LE, LEInfo);
+                  }
+                }
+              }
+            }
+          } 
+          InternalAdd(OtherF,Direction,Angle,NeutralPlane, Fl);
+        }
       }
     }
     expl.Next();
   }
   return (badShape.IsNull());
 }
-    
+
 
 //=======================================================================
 //function : Propagate
@@ -411,8 +428,6 @@ Standard_Boolean Draft_Modification::Propagate ()
 
   if (!badShape.IsNull()) return Standard_False;
 
-  Draft_DataMapIteratorOfDataMapOfFaceFaceInfo itf(myFMap);
-
   // Set all edges and vertices of modified faces
   TopoDS_Face F;
   TopoDS_Edge E;
@@ -420,36 +435,36 @@ Standard_Boolean Draft_Modification::Propagate ()
   TopExp_Explorer editer;
   TopExp_Explorer vtiter;
 
-  while (itf.More()) {
-    const TopoDS_Face& Fc = itf.Key();
+  for (Standard_Integer i = 1; i <= myFMap.Extent(); i++)
+  {
+    const TopoDS_Face& Fc = myFMap.FindKey(i);
 
     // Exploration of the edges of the face
     editer.Init(Fc,TopAbs_EDGE);
     while (editer.More()) {
       E = TopoDS::Edge(editer.Current());
 
-      if (!myEMap.IsBound(E)) {
-       Draft_EdgeInfo EInf(Standard_True);     
-       myEMap.Bind(E,EInf);
+      if (!myEMap.Contains(E)) {
+        Draft_EdgeInfo EInf(Standard_True);    
+        myEMap.Add(E,EInf);
       }
-      myEMap(E).Add(Fc);
+      myEMap.ChangeFromKey(E).Add(Fc);
 
       // Exploration of the vertices of the edge
       vtiter.Init(E,TopAbs_VERTEX);
       while (vtiter.More()) {
-       V = TopoDS::Vertex(vtiter.Current());
-       if (!myVMap.IsBound(V)) {
-         Draft_VertexInfo VInf;
-         myVMap.Bind(V,VInf);
-       }
-
-       myVMap(V).Add(E);
-       myVMap(V).ChangeParameter(E) = BRep_Tool::Parameter(V, E);
-       vtiter.Next();
+        V = TopoDS::Vertex(vtiter.Current());
+        if (!myVMap.Contains(V)) {
+          Draft_VertexInfo VInf;
+          myVMap.Add(V,VInf);
+        }
+
+        myVMap.ChangeFromKey(V).Add(E);
+        myVMap.ChangeFromKey(V).ChangeParameter(E) = BRep_Tool::Parameter(V, E);
+        vtiter.Next();
       }
       editer.Next();
     }
-    itf.Next();
   }
 
 
@@ -458,10 +473,9 @@ Standard_Boolean Draft_Modification::Propagate ()
 
   // Set edges containing modified vertices.
 
-  Draft_DataMapIteratorOfDataMapOfVertexVertexInfo itv(myVMap);
-
-  while (itv.More()) {
-    const TopoDS_Vertex& Vt = itv.Key();
+  for (Standard_Integer i = 1; i <= myVMap.Extent(); i++)
+  {
+    const TopoDS_Vertex& Vt = myVMap.FindKey(i);
 
     // Exploration of the ancestors of the vertex
     anc.Init(myShape,TopAbs_EDGE);
@@ -471,197 +485,195 @@ Standard_Boolean Draft_Modification::Propagate ()
       vtiter.Init(E,TopAbs_VERTEX);
       found = Standard_False;
       while (vtiter.More()) {
-       if (Vt.IsSame(TopoDS::Vertex(vtiter.Current()))) {
-         found = Standard_True;
-         break;
-       }
-       vtiter.Next();
+        if (Vt.IsSame(TopoDS::Vertex(vtiter.Current()))) {
+          found = Standard_True;
+          break;
+        }
+        vtiter.Next();
       }
       if (found) {
-       if (!myEMap.IsBound(E)) {
-         Draft_EdgeInfo EInf(Standard_False);
-         myEMap.Bind(E,EInf);
-       }
-       myVMap(Vt).Add(E);
-       myVMap(Vt).ChangeParameter(E) = BRep_Tool::Parameter(Vt, E);
+        if (!myEMap.Contains(E)) {
+          Draft_EdgeInfo EInf(Standard_False);
+          myEMap.Add(E,EInf);
+        }
+        myVMap.ChangeFromKey(Vt).Add(E);
+        myVMap.ChangeFromKey(Vt).ChangeParameter(E) = BRep_Tool::Parameter(Vt, E);
       }
       anc.Next();
     }
-    itv.Next();
   }
 
 
   // Set faces containing modified edges
-
-  Draft_DataMapIteratorOfDataMapOfEdgeEdgeInfo ite(myEMap);
-
-  while (ite.More()) {
-    const TopoDS_Edge& Ed = ite.Key();
+  for (Standard_Integer i = 1; i <= myEMap.Extent(); i++)
+  {
+    const TopoDS_Edge& Ed = myEMap.FindKey(i);
     TopTools_ListIteratorOfListOfShape it;
     for (it.Initialize(myEFMap.FindFromKey(Ed)); it.More(); it.Next()) {
       F = TopoDS::Face(it.Value());
-      if (!myFMap.IsBound(F)) {
-       TopLoc_Location L;
-       Handle(Geom_Surface) S = BRep_Tool::Surface(F,L);
-       Handle(Geom_Surface) NewS = 
-         Handle(Geom_Surface)::DownCast(S->Transformed(L.Transformation()));
-       
-       const Handle(Standard_Type)& typs = S->DynamicType();
-       if (typs == STANDARD_TYPE(Geom_CylindricalSurface) ||
-           typs == STANDARD_TYPE(Geom_ConicalSurface)) {
-         Standard_Real umin,umax,vmin,vmax;
-         BRepTools::UVBounds(F,umin,umax,vmin,vmax);
-         if (!Precision::IsNegativeInfinite(vmin) &&
-               !Precision::IsPositiveInfinite(vmax)) {
-           Standard_Real deltav = 10.*(vmax-vmin);
-           vmin = vmin - deltav;
-           vmax = vmax + deltav;
-           NewS = 
-             new Geom_RectangularTrimmedSurface(NewS,0.,2.*M_PI,vmin,vmax);
-         }
-       }
-       
-       Draft_FaceInfo FInf(NewS,Standard_False);
-       myFMap.Bind(F,FInf);
+      if (!myFMap.Contains(F)) {
+        TopLoc_Location L;
+        Handle(Geom_Surface) S = BRep_Tool::Surface(F,L);
+        Handle(Geom_Surface) NewS = 
+          Handle(Geom_Surface)::DownCast(S->Transformed(L.Transformation()));
+
+        const Handle(Standard_Type)& typs = S->DynamicType();
+        if (typs == STANDARD_TYPE(Geom_CylindricalSurface) ||
+            typs == STANDARD_TYPE(Geom_ConicalSurface)) {
+          Standard_Real umin,umax,vmin,vmax;
+          BRepTools::UVBounds(F,umin,umax,vmin,vmax);
+          if (!Precision::IsNegativeInfinite(vmin) &&
+              !Precision::IsPositiveInfinite(vmax)) {
+            Standard_Real deltav = 10.*(vmax-vmin);
+            vmin = vmin - deltav;
+            vmax = vmax + deltav;
+            NewS = new Geom_RectangularTrimmedSurface(NewS,0.,2.*M_PI,vmin,vmax);
+          }
+        }
+
+        Draft_FaceInfo FInf(NewS,Standard_False);
+        myFMap.Add(F,FInf);
       }
-      myEMap(Ed).Add(F);
+      myEMap.ChangeFromKey(Ed).Add(F);
     }
-    ite.Next();
   }
 
   //  Try to add faces for free borders...
   // JAG 09.11.95
-  ite.Initialize(myEMap);
-  for (; ite.More(); ite.Next()) {
-    Draft_EdgeInfo& Einf = myEMap(ite.Key());
-    if (Einf.NewGeometry() && Einf.Geometry().IsNull() && 
-       Einf.SecondFace().IsNull()) {
-      
+  for (Standard_Integer i = 1; i <= myEMap.Extent(); i++)
+  {
+    Draft_EdgeInfo& Einf = myEMap.ChangeFromIndex(i);
+    if (Einf.NewGeometry() && 
+        Einf.Geometry().IsNull() &&    
+        Einf.SecondFace().IsNull()) {
+
       TopLoc_Location Loc;
       Handle(Geom_Surface) S1 = BRep_Tool::Surface(Einf.FirstFace(),Loc);
       S1 = Handle(Geom_Surface)::
         DownCast(S1->Transformed(Loc.Transformation()));
       Handle(Geom_Surface) S2;
-      
+
       Standard_Real f,l;
-      Handle(Geom_Curve) C = BRep_Tool::Curve(ite.Key(),Loc,f,l);
+      const TopoDS_Edge& EK = myEMap.FindKey(i);
+      Handle(Geom_Curve) C = BRep_Tool::Curve(EK,Loc,f,l);
       C = Handle(Geom_Curve)::DownCast(C->Transformed(Loc.Transformation()));
       if (C->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve)) {
-       C = Handle(Geom_TrimmedCurve)::DownCast(C)->BasisCurve();
+        C = Handle(Geom_TrimmedCurve)::DownCast(C)->BasisCurve();
       }
       if (!S1->IsKind(STANDARD_TYPE(Geom_Plane))) {
-       if (C->IsKind(STANDARD_TYPE(Geom_Conic))) {
-         gp_Ax3 thePl(Handle(Geom_Conic)::DownCast(C)->Position());
-         S2 = new Geom_Plane(thePl);
-       }
-       else if (C->DynamicType() == STANDARD_TYPE(Geom_Line)) {
-         gp_Ax1 axis;
-         if (S1->DynamicType()== STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
-           axis = Handle(Geom_ElementarySurface)::DownCast
-             (Handle(Geom_RectangularTrimmedSurface)::DownCast(S1)->
-              BasisSurface())->Axis();
-         }
-         else {
-           axis = Handle(Geom_ElementarySurface)::DownCast(S1)->Axis();
-         }
-         gp_Vec they(axis.Location(), C->Value(0.));
-         gp_Dir axz(axis.Direction().Crossed(they));
-         S2=new Geom_Plane(gp_Ax3(axis.Location(),axz,axis.Direction()));
-
-       }
-       else {
-         badShape = TopoDS::Edge(ite.Key());
-         errStat = Draft_EdgeRecomputation;
-         break; // leave from for
-       }
+        if (C->IsKind(STANDARD_TYPE(Geom_Conic))) {
+          gp_Ax3 thePl(Handle(Geom_Conic)::DownCast(C)->Position());
+          S2 = new Geom_Plane(thePl);
+        }
+        else if (C->DynamicType() == STANDARD_TYPE(Geom_Line)) {
+          gp_Ax1 axis;
+          if (S1->DynamicType()== STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
+            axis = Handle(Geom_ElementarySurface)::DownCast
+              (Handle(Geom_RectangularTrimmedSurface)::DownCast(S1)->
+              BasisSurface())->Axis();
+          }
+          else {
+            axis = Handle(Geom_ElementarySurface)::DownCast(S1)->Axis();
+          }
+          gp_Vec they(axis.Location(), C->Value(0.));
+          gp_Dir axz(axis.Direction().Crossed(they));
+          S2=new Geom_Plane(gp_Ax3(axis.Location(),axz,axis.Direction()));
+
+        }
+        else {
+          badShape = EK;
+          errStat = Draft_EdgeRecomputation;
+          break; // leave from for
+        }
       }
       else { // on the plane
-       Draft_DataMapIteratorOfDataMapOfVertexVertexInfo anewitv(myVMap);
-       while (anewitv.More()) {
-         Draft_VertexInfo& Vinf = myVMap(anewitv.Key());
-         for (Vinf.InitEdgeIterator();Vinf.MoreEdge();Vinf.NextEdge()) {
-           if (Vinf.Edge().IsSame(ite.Key())) {
-             break;
-           }
-         }
-         if (Vinf.MoreEdge()) {
-           for (Vinf.InitEdgeIterator();Vinf.MoreEdge();Vinf.NextEdge()) {
-             const TopoDS_Edge& edg = Vinf.Edge();
-             if (!edg.IsSame(ite.Key())) {
-               if (!myEMap(edg).FirstFace().IsSame(Einf.FirstFace()) &&
-                   (myEMap(edg).SecondFace().IsNull() || 
-                    !myEMap(edg).SecondFace().IsSame(Einf.FirstFace()))) {
-                 break;
-               }
-             }
-           }
-           if (Vinf.MoreEdge()) {
-             Handle(Geom_Curve) C2 = BRep_Tool::Curve(Vinf.Edge(), Loc,f,l);
-             Handle(GeomAdaptor_HCurve) HCur;
-             gp_Vec Direc;
-             C2 = Handle(Geom_Curve)::DownCast
-               (C2->Transformed(Loc.Transformation()));
-             if (C2->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve)) {
-               C2 = Handle(Geom_TrimmedCurve)::DownCast(C2)->BasisCurve();
-             }
-             if (C->DynamicType() == STANDARD_TYPE(Geom_Line)) {
-               Direc = Handle(Geom_Line)::DownCast(C)->Lin().Direction();
-               HCur = new GeomAdaptor_HCurve(C2);
-
-             }
-             else if (C2->DynamicType() == STANDARD_TYPE(Geom_Line)) {
-               Direc = Handle(Geom_Line)::DownCast(C2)->Lin().Direction();
-               HCur = new GeomAdaptor_HCurve(C);
-             }
-             else {
-               badShape = TopoDS::Edge(ite.Key());
-               errStat = Draft_EdgeRecomputation;
-               break; // leave from while
-             }
-             Adaptor3d_SurfaceOfLinearExtrusion SLE(HCur,Direc);
-             switch(SLE.GetType()){
-
-             case GeomAbs_Plane :
-               {
-                 S2 = new Geom_Plane(SLE.Plane());
-               }
-               break;
-             case GeomAbs_Cylinder :
-               {
-                 S2 =   new Geom_CylindricalSurface(SLE.Cylinder());
-               }
-               break;
-             default :
-               {
-                 S2 = new Geom_SurfaceOfLinearExtrusion(HCur->ChangeCurve().
-                                                        Curve(),
-                                                        Direc);
-               }
-               break;
-             }
-             
-           }
-           else {
-             badShape = TopoDS::Edge(ite.Key());
-             errStat = Draft_EdgeRecomputation;
-             break; // leave from while
-           }
-           break;
-         }
-         anewitv.Next();
-       }
+        for (Standard_Integer j = 1; j <= myVMap.Extent(); j++)
+        {
+          Draft_VertexInfo& Vinf = myVMap.ChangeFromIndex(j);
+          for (Vinf.InitEdgeIterator();Vinf.MoreEdge();Vinf.NextEdge()) {
+            if (Vinf.Edge().IsSame(EK)) {
+              break;
+            }
+          }
+          if (Vinf.MoreEdge()) {
+            for (Vinf.InitEdgeIterator();Vinf.MoreEdge();Vinf.NextEdge()) {
+              const TopoDS_Edge& edg = Vinf.Edge();
+              if (!edg.IsSame(EK)) {
+                const Draft_EdgeInfo& EI = myEMap.FindFromKey(edg);
+                if (!EI.FirstFace().IsSame(Einf.FirstFace()) &&
+                  (EI.SecondFace().IsNull() || 
+                  !EI.SecondFace().IsSame(Einf.FirstFace()))) {
+                    break;
+                }
+              }
+            }
+            if (Vinf.MoreEdge()) {
+              Handle(Geom_Curve) C2 = BRep_Tool::Curve(Vinf.Edge(), Loc,f,l);
+              Handle(GeomAdaptor_HCurve) HCur;
+              gp_Vec Direc;
+              C2 = Handle(Geom_Curve)::DownCast
+                (C2->Transformed(Loc.Transformation()));
+              if (C2->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve)) {
+                C2 = Handle(Geom_TrimmedCurve)::DownCast(C2)->BasisCurve();
+              }
+              if (C->DynamicType() == STANDARD_TYPE(Geom_Line)) {
+                Direc = Handle(Geom_Line)::DownCast(C)->Lin().Direction();
+                HCur = new GeomAdaptor_HCurve(C2);
+
+              }
+              else if (C2->DynamicType() == STANDARD_TYPE(Geom_Line)) {
+                Direc = Handle(Geom_Line)::DownCast(C2)->Lin().Direction();
+                HCur = new GeomAdaptor_HCurve(C);
+              }
+              else {
+                badShape = EK;
+                errStat = Draft_EdgeRecomputation;
+                break; // leave from while
+              }
+              Adaptor3d_SurfaceOfLinearExtrusion SLE(HCur,Direc);
+              switch(SLE.GetType()){
+
+              case GeomAbs_Plane :
+                {
+                  S2 = new Geom_Plane(SLE.Plane());
+                }
+                break;
+              case GeomAbs_Cylinder :
+                {
+                  S2 =   new Geom_CylindricalSurface(SLE.Cylinder());
+                }
+                break;
+              default :
+                {
+                  S2 = new Geom_SurfaceOfLinearExtrusion(HCur->ChangeCurve().
+                    Curve(),
+                    Direc);
+                }
+                break;
+              }
+
+            }
+            else {
+              badShape = EK;
+              errStat = Draft_EdgeRecomputation;
+              break; // leave from while
+            }
+            break;
+          }
+          //j++;
+        }
       }
 
       if (badShape.IsNull()) {
-       BRep_Builder B;
-       TopoDS_Face TheNewFace;
-       B.MakeFace(TheNewFace,S2,Precision::Confusion());
-       Einf.Add(TheNewFace);
-       Draft_FaceInfo FI(S2,Standard_False);
-       myFMap.Bind(TheNewFace,FI);
+        BRep_Builder B;
+        TopoDS_Face TheNewFace;
+        B.MakeFace(TheNewFace,S2,Precision::Confusion());
+        Einf.Add(TheNewFace);
+        Draft_FaceInfo FI(S2,Standard_False);
+        myFMap.Add(TheNewFace,FI);
       }
       else {
-       break; // leave from for
+        break; // leave from for
       }
       // Fin JAG 09.11.95
     }
@@ -689,837 +701,835 @@ void Draft_Modification::Perform ()
 
     // Calculate eventual faces
 
-    Draft_DataMapIteratorOfDataMapOfFaceFaceInfo itf(myFMap);
-    while (itf.More()) {
-      Draft_FaceInfo& Finf = myFMap(itf.Key());
+    for (Standard_Integer i = 1; i <= myFMap.Extent(); i++) 
+    {
+      const TopoDS_Face& FK = myFMap.FindKey(i);
+      Draft_FaceInfo& Finf = myFMap.ChangeFromIndex(i);
       if (Finf.NewGeometry() && Finf.Geometry().IsNull()) {
-       const TopoDS_Face& F1 = Finf.FirstFace();
-       const TopoDS_Face& F2 = Finf.SecondFace();
-
-       if (F1.IsNull() || F2.IsNull()) {
-         errStat = Draft_FaceRecomputation;
-         badShape = TopoDS::Face(itf.Key());
-         return;
-       }
-       Handle(Geom_Surface) S1 = myFMap(F1).Geometry();
-       Handle(Geom_Surface) S2 = myFMap(F2).Geometry();
-       if (S1.IsNull() || S2.IsNull()) {
-         errStat = Draft_FaceRecomputation;
-         badShape = TopoDS::Face(itf.Key());
-         return;
-       }
-       if (S1->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
-         S1 = Handle(Geom_RectangularTrimmedSurface)::
-           DownCast(S1)->BasisSurface();
-       }
-       if (S2->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
-         S2 = Handle(Geom_RectangularTrimmedSurface)::
-           DownCast(S2)->BasisSurface();
-       }
-       Handle(Geom_Plane) P1 = Handle(Geom_Plane)::DownCast(S1);
-       Handle(Geom_Plane) P2 = Handle(Geom_Plane)::DownCast(S2);
-       if (P1.IsNull() || P2.IsNull()) {
-         errStat = Draft_FaceRecomputation;
-         badShape = TopoDS::Face(itf.Key());
-         return;
-       }
-       gp_Pln pp1 = P1->Pln();
-       gp_Pln pp2 = P2->Pln();
-       IntAna_QuadQuadGeo i2p(pp1,pp2,
-                              Precision::Angular(),Precision::Confusion());
-       if (!i2p.IsDone() || i2p.TypeInter() != IntAna_Line) {
-         errStat = Draft_FaceRecomputation;
-         badShape = TopoDS::Face(itf.Key());
-         return;
-       }
-
-       gp_Dir extrdir = i2p.Line(1).Direction();
-
-       // Preserve the same direction as the base face
-       Handle(Geom_Surface) RefSurf = 
-         BRep_Tool::Surface(TopoDS::Face(itf.Key()));
-       if (RefSurf->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
-         RefSurf = 
-           Handle(Geom_RectangularTrimmedSurface)::DownCast(RefSurf)
-             ->BasisSurface();
-       }
-       gp_Dir DirRef;
-
-       if ( RefSurf->DynamicType() == STANDARD_TYPE(Geom_CylindricalSurface)) {
-         gp_Ax3 AxeRef = 
-           Handle(Geom_CylindricalSurface)::DownCast(RefSurf)
-             ->Cylinder().Position();
-         DirRef = AxeRef.Direction();
-       }
-       else if (RefSurf->DynamicType() == 
-                STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) {
-         DirRef = 
-           Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(RefSurf)
-             ->Direction();
-       }
-       
-       if (extrdir.Dot(DirRef) < 0.) extrdir.Reverse();
-
-       // it is possible to accelerate speed by storing the info during
-       // InternalAdd --> modification of FaceInfo to preserve the circle
-
-       Handle(Geom_Circle) CCir = 
-         Handle(Geom_Circle)::DownCast(Finf.Curve());
-       Handle(Geom_Surface) NewS = 
-         new Geom_SurfaceOfLinearExtrusion(CCir, extrdir);    
-
-       Standard_Real umin, umax, vmin, vmax;
-       BRepTools::UVBounds(TopoDS::Face(itf.Key()),umin,umax,vmin,vmax);
-       if (!Precision::IsNegativeInfinite(vmin) &&
-           !Precision::IsPositiveInfinite(vmax)) {
-         Standard_Real deltav = 2.*(vmax-vmin);
-         vmin = vmin - deltav;
-         vmax = vmax + deltav;
-       }
-
-       // very temporary
-       else {
-         vmax = 300;
-         vmin = -300;
-       }
-
-       NewS = new Geom_RectangularTrimmedSurface(NewS,0.,1.9*M_PI,vmin,vmax);
-       Finf.ChangeGeometry() = NewS;
+        const TopoDS_Face& F1 = Finf.FirstFace();
+        const TopoDS_Face& F2 = Finf.SecondFace();
+
+        if (F1.IsNull() || F2.IsNull()) {
+          errStat = Draft_FaceRecomputation;
+          badShape = FK;
+          return;
+        }
+        Handle(Geom_Surface) S1 = myFMap.FindFromKey(F1).Geometry();
+        Handle(Geom_Surface) S2 = myFMap.FindFromKey(F2).Geometry();
+        if (S1.IsNull() || S2.IsNull()) {
+          errStat = Draft_FaceRecomputation;
+          badShape = FK;
+          return;
+        }
+        if (S1->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
+          S1 = Handle(Geom_RectangularTrimmedSurface)::
+            DownCast(S1)->BasisSurface();
+        }
+        if (S2->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
+          S2 = Handle(Geom_RectangularTrimmedSurface)::
+            DownCast(S2)->BasisSurface();
+        }
+        Handle(Geom_Plane) P1 = Handle(Geom_Plane)::DownCast(S1);
+        Handle(Geom_Plane) P2 = Handle(Geom_Plane)::DownCast(S2);
+        if (P1.IsNull() || P2.IsNull()) {
+          errStat = Draft_FaceRecomputation;
+          badShape = FK;
+          return;
+        }
+        gp_Pln pp1 = P1->Pln();
+        gp_Pln pp2 = P2->Pln();
+        IntAna_QuadQuadGeo i2p(pp1,pp2,
+          Precision::Angular(),Precision::Confusion());
+        if (!i2p.IsDone() || i2p.TypeInter() != IntAna_Line) {
+          errStat = Draft_FaceRecomputation;
+          badShape = FK;
+          return;
+        }
+
+        gp_Dir extrdir = i2p.Line(1).Direction();
+
+        // Preserve the same direction as the base face
+        Handle(Geom_Surface) RefSurf = 
+          BRep_Tool::Surface(FK);
+        if (RefSurf->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
+          RefSurf = 
+            Handle(Geom_RectangularTrimmedSurface)::DownCast(RefSurf)
+            ->BasisSurface();
+        }
+        gp_Dir DirRef;
+
+        if ( RefSurf->DynamicType() == STANDARD_TYPE(Geom_CylindricalSurface)) {
+          gp_Ax3 AxeRef = 
+            Handle(Geom_CylindricalSurface)::DownCast(RefSurf)
+            ->Cylinder().Position();
+          DirRef = AxeRef.Direction();
+        }
+        else if (RefSurf->DynamicType() == 
+                 STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) {
+          DirRef = 
+            Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(RefSurf)->Direction();
+        }
+
+        if (extrdir.Dot(DirRef) < 0.) extrdir.Reverse();
+
+        // it is possible to accelerate speed by storing the info during
+        // InternalAdd --> modification of FaceInfo to preserve the circle
+
+        Handle(Geom_Circle) CCir = 
+          Handle(Geom_Circle)::DownCast(Finf.Curve());
+        Handle(Geom_Surface) NewS = 
+          new Geom_SurfaceOfLinearExtrusion(CCir, extrdir);    
+
+        Standard_Real umin, umax, vmin, vmax;
+        BRepTools::UVBounds(FK,umin,umax,vmin,vmax);
+        if (!Precision::IsNegativeInfinite(vmin) &&
+            !Precision::IsPositiveInfinite(vmax)) {
+          Standard_Real deltav = 2.*(vmax-vmin);
+          vmin = vmin - deltav;
+          vmax = vmax + deltav;
+        }
+
+        // very temporary
+        else {
+          vmax = 300;
+          vmin = -300;
+        }
+
+        NewS = new Geom_RectangularTrimmedSurface(NewS,0.,1.9*M_PI,vmin,vmax);
+        Finf.ChangeGeometry() = NewS;
       }
-      itf.Next();
     }
-    
+
     // Calculate new edges.
 
     Handle(Geom_Surface) S1,S2;
     Handle(Geom_Curve) C, newC;
     Standard_Real f,l;
     TopLoc_Location L;
-    Draft_DataMapIteratorOfDataMapOfEdgeEdgeInfo ite(myEMap);
 
-    while (ite.More()) {
-      Draft_EdgeInfo& Einf = myEMap(ite.Key());
+    for (Standard_Integer ii = 1; ii <= myEMap.Extent(); ii++) 
+    {
+      Draft_EdgeInfo& Einf = myEMap.ChangeFromIndex(ii); 
 
-      const TopoDS_Edge& theEdge = TopoDS::Edge(ite.Key());
+      const TopoDS_Edge& theEdge = TopoDS::Edge(myEMap.FindKey(ii));
 
       C = BRep_Tool::Curve(theEdge,L,f,l);
       C = Handle(Geom_Curve)::DownCast(C->Transformed(L.Transformation()));
 
       if (Einf.NewGeometry() && Einf.Geometry().IsNull()) {
-       gp_Pnt ptfixe;
-       if (!Einf.IsTangent(ptfixe)) {
-         const TopoDS_Face& FirstFace = Einf.FirstFace();
-         const TopoDS_Face& SecondFace = Einf.SecondFace();
-
-         S1 = myFMap(FirstFace).Geometry();
-         S2 = myFMap(SecondFace).Geometry();
-
-         Standard_Integer detrompeur = 0;
-
-         // Return FirstVertex and the tangent at this point.
-         TopoDS_Vertex FV = TopExp::FirstVertex(theEdge);
-         TopoDS_Vertex LV = TopExp::LastVertex(theEdge);
-         Standard_Real pmin = 0.;
-         Standard_Real prmfv = BRep_Tool::Parameter(FV,ite.Key());
-         Standard_Real prmlv = BRep_Tool::Parameter(LV,ite.Key());
-         gp_Pnt pfv, plv;
-         gp_Vec d1fv,d1lv, newd1;
-         C->D1(prmfv,pfv,d1fv);
-         C->D1(prmlv,plv,d1lv);
-
-         Standard_Real TolF1 = BRep_Tool::Tolerance (FirstFace);
-         Standard_Real TolF2 = BRep_Tool::Tolerance (SecondFace);
-
-         //Pass the tolerance of the face to project
-         GeomAPI_ProjectPointOnSurf proj1 (pfv, S1, TolF1);
-         GeomAPI_ProjectPointOnSurf proj2 (plv, S1, TolF1);
-         GeomAPI_ProjectPointOnSurf proj3 (pfv, S2, TolF2);
-         GeomAPI_ProjectPointOnSurf proj4 (plv, S2, TolF2);
-
-         if (proj1.IsDone () && proj2.IsDone ()) {
-           if(proj1.LowerDistance()<= Precision::Confusion() &&
-              proj2.LowerDistance()<= Precision::Confusion())  {
-             detrompeur = 1;
-           }
-         }
-
-         if (proj3.IsDone () && proj4.IsDone ()) {
-           if(proj3.LowerDistance() <= Precision::Confusion() &&
-              proj4.LowerDistance() <= Precision::Confusion())  {
-             detrompeur = 2;
-           }
-         }
-         
-         gp_Dir TheDirExtr;
-         gp_Ax3 Axis;
-         Handle(Geom_Curve) TheNewCurve;
-         Standard_Boolean KPart = Standard_False;
-
-         if ( S1->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
-           S1 = Handle(Geom_RectangularTrimmedSurface)::
-             DownCast(S1)->BasisSurface();
-         }
-         if ( S2->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
-           S2 = Handle(Geom_RectangularTrimmedSurface)::
-             DownCast(S2)->BasisSurface();
-         }
-
-         Standard_Boolean PC1 = Standard_True; // KPart on S1
-         if (S1->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion) &&
-             S2->DynamicType() == STANDARD_TYPE(Geom_Plane) ) {
-           KPart = Standard_True;
-           Axis = Handle(Geom_Plane)::DownCast(S2)->Position();
-           TheNewCurve = Handle(Geom_SurfaceOfLinearExtrusion)::
-             DownCast(S1)->BasisCurve();
-           TheDirExtr = Handle(Geom_SurfaceOfLinearExtrusion)::
-             DownCast(S1)->Direction();
-         }
-         else if (S2->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion) &&
-                  S1->DynamicType() == STANDARD_TYPE(Geom_Plane) ) {
-           KPart = Standard_True;
-           PC1 = Standard_False;
-           Axis = Handle(Geom_Plane)::DownCast(S1)->Position();
-           TheNewCurve = Handle(Geom_SurfaceOfLinearExtrusion)::
-             DownCast(S2)->BasisCurve();
-           TheDirExtr = Handle(Geom_SurfaceOfLinearExtrusion)::
-             DownCast(S2)->Direction();
-         }
-         Handle(Geom_Circle) aCirc ;
-         if ( KPart) {  // very temporary on circles !!!
-           aCirc = Handle(Geom_Circle)::DownCast(TheNewCurve);
-           if (aCirc.IsNull())
-             KPart = Standard_False;
-           else
-             {
-               gp_Dir AxofCirc = aCirc->Position().Direction();
-               if (AxofCirc.IsParallel(Axis.Direction(),Precision::Angular()))
-                 KPart = Standard_True;
-               else
-                 KPart = Standard_False;
-             }
-         }
-
-         Standard_Integer imin;
-         GeomInt_IntSS i2s;
-         if ( KPart) {
-           // direct calculation of NewC
-           Standard_Real aLocalReal =
-             gp_Vec(aCirc->Circ().Location(),Axis.Location()).
-               Dot(Axis.Direction());
-           Standard_Real Cos = TheDirExtr.Dot(Axis.Direction());
-           gp_Vec VV = ( aLocalReal / Cos) * TheDirExtr;
-           newC = Handle(Geom_Curve)::DownCast(TheNewCurve->Translated(VV));
-           // it is possible to calculate PCurve
-           Handle(Geom2d_Line) L2d 
-             = new Geom2d_Line(gp_Pnt2d(0.,aLocalReal/Cos),
-                               gp::DX2d());
-
-           if ( PC1) 
-             Einf.ChangeFirstPC() = L2d;
-           else
-             Einf.ChangeSecondPC() = L2d;
-         }
-         else {
-           S1 = myFMap(Einf.FirstFace()).Geometry();
-           S2 = myFMap(Einf.SecondFace()).Geometry();
-
-
-           // PCurves are not calculated immediately for 2 reasons:
-           // 1 - If ProjLib should make an Approx, it is stupid to approximate the 
-           //     entire intersection curve.
-           // 2 - Additionally, if YaRev, there is a risk to not be SameRange.
-           i2s.Perform(S1,S2,Precision::Confusion(),
-                       Standard_True,Standard_False,Standard_False);
-           
-           if (!i2s.IsDone() || i2s.NbLines() <= 0) {
-             errStat = Draft_EdgeRecomputation;
-             badShape = TopoDS::Edge(ite.Key());
-             return;
-           }
-           
-           Standard_Real Dist2, Dist2Min = 0., Glob2Min = RealLast();
-           GeomAdaptor_Curve TheCurve;
-           
-           Standard_Integer i,j; //,jmin;
-           
-           if (i2s.Line(1)->DynamicType() != STANDARD_TYPE(Geom_BSplineCurve))
-             {
-               imin = 0;
-               for (i=1; i<= i2s.NbLines(); i++) {
-                 TheCurve.Load(i2s.Line(i));
-                 Extrema_ExtPC myExtPC(pfv,TheCurve);
-                 
-                 Standard_Real locpmin = 0.;
-                 if (myExtPC.IsDone()) {
-                   if(myExtPC.NbExt() >= 1) {
-                     Dist2Min = myExtPC.SquareDistance(1);
-                     locpmin = myExtPC.Point(1).Parameter();
-                   }
-            if(myExtPC.NbExt() == 2 && Dist2Min > Precision::SquareConfusion()) {
-                     //to avoid incorrectly choosing the image 
-                     //of the first vertex of the initial edge
-                     Standard_Real d1_2 = myExtPC.SquareDistance(1);
-                     Standard_Real d2_2 = myExtPC.SquareDistance(2);
-                     if(d1_2 > 1.21*d2_2) {
-                       Dist2Min = myExtPC.SquareDistance(2);
-                       locpmin = myExtPC.Point(2).Parameter();
-                     }
-                     else if(d2_2 > 1.21*d1_2) {
-                       Dist2Min = myExtPC.SquareDistance(1);
-                       locpmin = myExtPC.Point(1).Parameter();
-                     }
-                     else {
-                       Standard_Real pfvpar = myExtPC.Point(1).Parameter();
-                       Standard_Real plvpar = myExtPC.Point(2).Parameter();
-                       newC = i2s.Line(i);
-                       
-                       gp_Pnt pfvprim, plvprim;
-                       
-                       newC->D0(pfvpar,pfvprim);
-                       newC->D0(plvpar,plvprim);
-                       
-                       Handle(Geom_Surface) theSurf;
-                       if(detrompeur == 1) {
-                         if(S1->DynamicType() == 
-                            STANDARD_TYPE(Geom_RectangularTrimmedSurface))  
-                           S1 = Handle(Geom_RectangularTrimmedSurface)::
-                             DownCast(S1)->BasisSurface();
-                         theSurf = S1;
-                         
-                       }
-                       else if(detrompeur == 2) {
-                         if(S2->DynamicType() == 
-                            STANDARD_TYPE(Geom_RectangularTrimmedSurface)) 
-                           S2 = Handle(Geom_RectangularTrimmedSurface)::
-                             DownCast(S2)->BasisSurface();
-                         theSurf = S2;             
-                       }
-                       if(detrompeur != 0 && detrompeur != 4) {
-                         Standard_Real ul = 0., vl = 0., uf = 0., vf = 0.;
-                         Standard_Real ufprim = 0., ulprim = 0., vfprim = 0., vlprim = 0.;
-                         
-                         if(theSurf->DynamicType() == STANDARD_TYPE(Geom_Plane)) {     
-                           gp_Pln pl = Handle(Geom_Plane)::DownCast(S2)->Pln();
-                           ElSLib::Parameters(pl, plv, ul, vl);
-                           ElSLib::Parameters(pl, pfv, uf, vf);
-                           ElSLib::Parameters(pl, plvprim, ulprim, vlprim);
-                           ElSLib::Parameters(pl, pfvprim, ufprim, vfprim);
-                         }
-                         else if(theSurf->DynamicType() == 
-                                 STANDARD_TYPE(Geom_CylindricalSurface)) {
-                           gp_Cylinder cy = Handle(Geom_CylindricalSurface)
-                             ::DownCast(S2)->Cylinder();
-                           ElSLib::Parameters(cy, plv, ul, vl);
-                           ElSLib::Parameters(cy, pfv, uf, vf);
-                           ElSLib::Parameters(cy, plvprim, ulprim, vlprim);
-                           ElSLib::Parameters(cy, pfvprim, ufprim, vfprim);
-                         }
-                         else detrompeur = 4;
-                         
-                         if(detrompeur == 1 || detrompeur == 2) {
-                           gp_Vec2d v1((ul-ufprim), (vl-vfprim));
-                           gp_Vec2d norm((vf-vfprim), (ufprim-uf)); 
-                           gp_Vec2d v2((ulprim-ufprim), (vlprim-vfprim));
-                           if( (v1.Dot(norm))*(v2.Dot(norm)) < 0) {
-                             Dist2Min = myExtPC.SquareDistance(2);
-                             locpmin = myExtPC.Point(2).Parameter();
-                           }
-                         }
-                       }
-                     }
-                   }
-                   if (myExtPC.NbExt() == 1 || myExtPC.NbExt() > 2 || detrompeur ==4) {
-                     Dist2Min = myExtPC.SquareDistance(1);
-                     locpmin = myExtPC.Point(1).Parameter();
-                     for (j=2; j<=myExtPC.NbExt(); j++) {
-                       Dist2 = myExtPC.SquareDistance(j);
-                       if (Dist2 < Dist2Min) {
-                         Dist2Min = Dist2;
-                         locpmin = myExtPC.Point(j).Parameter();
-                       }
-                     }
-                   }
-                   else if(myExtPC.NbExt() < 1){
-                     Standard_Real dist1_2,dist2_2;
-                     gp_Pnt p1b,p2b;
-                     myExtPC.TrimmedSquareDistances(dist1_2,dist2_2,p1b,p2b);
-                     if (dist1_2 < dist2_2) {
-                       Dist2Min = dist1_2;
-                       locpmin = TheCurve.FirstParameter();
-                     }
-                     else {
-                       Dist2Min = dist2_2;
-                       locpmin = TheCurve.LastParameter();
-                     }
-                   }
-                   
-                   if (Dist2Min  < Glob2Min) {
-                     Glob2Min = Dist2Min;
-                     imin = i;
-                     pmin = locpmin;
-                   }
-                 }
-               }
-               if (imin == 0) {
-                 errStat = Draft_EdgeRecomputation;
-                 badShape = TopoDS::Edge(ite.Key());
-                 return;
-               }
-               
-               newC = i2s.Line(imin);
-               
-               newC->D1(pmin,pfv,newd1);
-               Standard_Boolean YaRev = d1fv.Dot(newd1) <0.; 
-               
-               if (YaRev)
-                 newC->Reverse();
-               
-               if (i2s.HasLineOnS1(imin)) {
-                 Einf.ChangeFirstPC() = i2s.LineOnS1(imin);
-                 if ( YaRev) 
-                   Einf.ChangeFirstPC()->Reverse();
-               }
-               
-               if (i2s.HasLineOnS2(imin)) {
-                 Einf.ChangeSecondPC() = i2s.LineOnS2(imin);
-                 if ( YaRev) 
-                   Einf.ChangeSecondPC()->Reverse();
-               }
-             } // if (i2s.Line(1)->DynamicType() != STANDARD_TYPE(Geom_BSplineCurve))
-           else // i2s.Line(1) is BSplineCurve
-             {
-               //Find the first curve to glue
-               TColGeom_SequenceOfCurve Candidates;
-               if (S1->DynamicType() == STANDARD_TYPE(Geom_CylindricalSurface) ||
-                   S1->DynamicType() == STANDARD_TYPE(Geom_ConicalSurface)) 
-                 {
-                   for (i = 1; i <= i2s.NbLines(); i++)
-                     {
-                       Handle( Geom_Curve ) aCurve = i2s.Line(i);
-                       gp_Pnt Pnt = aCurve->Value( aCurve->FirstParameter() );
-                       GeomAPI_ProjectPointOnSurf projector( Pnt, S1, Precision::Confusion() );
-                       Standard_Real U, V;
-                       projector.LowerDistanceParameters( U, V );
-                       if (Abs(U) <= Precision::Confusion() || Abs(U-2.*M_PI) <= Precision::Confusion())
-                         Candidates.Append( aCurve );
-                       else
-                         {
-                           Pnt = aCurve->Value( aCurve->LastParameter() );
-                           projector.Init( Pnt, S1, Precision::Confusion() );
-                           projector.LowerDistanceParameters( U, V );
-                           if (Abs(U) <= Precision::Confusion() || Abs(U-2.*M_PI) <= Precision::Confusion())
-                             {
-                               aCurve->Reverse();
-                               Candidates.Append( aCurve );
-                             }
-                         }
-                     }
-
-                   if(Candidates.Length() == 0) 
-                     {
-//                     errStat = Draft_EdgeRecomputation;
-//                     badShape = TopoDS::Edge(ite.Key());
-//                     return;
-                       for (i = 1; i <= i2s.NbLines(); i++)
-                         Candidates.Append( i2s.Line(i) );
-                     }
-                 }
-               else 
-                 {
-                   for (i = 1; i <= i2s.NbLines(); i++)
-                     Candidates.Append( i2s.Line(i) );
-                 }
-               
-               Handle( Geom_Curve ) FirstCurve;
-               if (Candidates.Length() > 1)
-                 {
-                   Dist2Min = RealLast();
-                   for (i = 1; i <= Candidates.Length(); i++)
-                     {
-                       Handle( Geom_Curve ) aCurve = Candidates(i);
-                       gp_Pnt Pnt = aCurve->Value( aCurve->FirstParameter() );
-                       Dist2 = Pnt.SquareDistance( pfv );
-                       if (Dist2 < Dist2Min)
-                         {
-                           Dist2Min = Dist2;
-                           FirstCurve = aCurve;
-                         }
-                     }
-                 }
-               else
-                 FirstCurve = Candidates(1);
-
-               //Glueing
-               TColGeom_SequenceOfCurve Curves;
-               for (i = 1; i <= i2s.NbLines(); i++)
-                 if (FirstCurve != i2s.Line(i))
-                   Curves.Append( i2s.Line(i) );
-
-               TColGeom_SequenceOfCurve ToGlue;
-               gp_Pnt EndPoint = FirstCurve->Value( FirstCurve->LastParameter() );
-               Standard_Boolean added = Standard_True;
-               while (added)
-                 {
-                   added = Standard_False;
-                   for (i = 1; i <= Curves.Length(); i++)
-                     {
-                       Handle( Geom_Curve ) aCurve = Curves(i);
-                       gp_Pnt pfirst, plast;
-                       pfirst = aCurve->Value( aCurve->FirstParameter() );
-                       plast = aCurve->Value( aCurve->LastParameter() );
-                       if (pfirst.Distance( EndPoint ) <= Precision::Confusion())
-                         {
-                           ToGlue.Append( aCurve );
-                           EndPoint = plast;
-                           Curves.Remove(i);
-                           added = Standard_True;
-                           break;
-                         }
-                       if (plast.Distance( EndPoint ) <= Precision::Confusion())
-                         {
-                           aCurve->Reverse();
-                           ToGlue.Append( aCurve );
-                           EndPoint = pfirst;
-                           Curves.Remove(i);
-                           added = Standard_True;
-                           break;
-                         }
-                     }
-                 }
-
-               if (FirstCurve.IsNull()) {
-                 errStat = Draft_EdgeRecomputation;
-                 badShape = TopoDS::Edge(ite.Key());
-                 return;
-               }
-               
-               GeomConvert_CompCurveToBSplineCurve Concat( Handle(Geom_BSplineCurve)::DownCast(FirstCurve) );
-               for (i = 1; i <= ToGlue.Length(); i++)
-                 Concat.Add( Handle(Geom_BSplineCurve)::DownCast(ToGlue(i)), Precision::Confusion(), Standard_True );
-
-               newC = Concat.BSplineCurve();
-               
-               TheCurve.Load( newC );
-               Extrema_ExtPC myExtPC( pfv, TheCurve );
-               Dist2Min = RealLast();
-               for (i = 1; i <= myExtPC.NbExt(); i++)
-                 {
-                    if (myExtPC.IsMin(i))
-                    {
-                      Dist2 = myExtPC.SquareDistance(i);
-                      if (Dist2 < Dist2Min)
-                      {
+        gp_Pnt ptfixe;
+        if (!Einf.IsTangent(ptfixe)) {
+          const TopoDS_Face& FirstFace = Einf.FirstFace();
+          const TopoDS_Face& SecondFace = Einf.SecondFace();
+
+          S1 = myFMap.FindFromKey(FirstFace).Geometry();
+          S2 = myFMap.FindFromKey(SecondFace).Geometry();
+
+          Standard_Integer detrompeur = 0;
+
+          // Return FirstVertex and the tangent at this point.
+          TopoDS_Vertex FV = TopExp::FirstVertex(theEdge);
+          TopoDS_Vertex LV = TopExp::LastVertex(theEdge);
+          Standard_Real pmin = 0.;
+          Standard_Real prmfv = BRep_Tool::Parameter(FV, theEdge);
+          Standard_Real prmlv = BRep_Tool::Parameter(LV, theEdge);
+          gp_Pnt pfv, plv;
+          gp_Vec d1fv,d1lv, newd1;
+          C->D1(prmfv,pfv,d1fv);
+          C->D1(prmlv,plv,d1lv);
+
+          Standard_Real TolF1 = BRep_Tool::Tolerance (FirstFace);
+          Standard_Real TolF2 = BRep_Tool::Tolerance (SecondFace);
+
+          //Pass the tolerance of the face to project
+          GeomAPI_ProjectPointOnSurf proj1 (pfv, S1, TolF1);
+          GeomAPI_ProjectPointOnSurf proj2 (plv, S1, TolF1);
+          GeomAPI_ProjectPointOnSurf proj3 (pfv, S2, TolF2);
+          GeomAPI_ProjectPointOnSurf proj4 (plv, S2, TolF2);
+
+          if (proj1.IsDone () && proj2.IsDone ()) {
+            if(proj1.LowerDistance()<= Precision::Confusion() &&
+               proj2.LowerDistance()<= Precision::Confusion())  {
+               detrompeur = 1;
+            }
+          }
+
+          if (proj3.IsDone () && proj4.IsDone ()) {
+            if(proj3.LowerDistance() <= Precision::Confusion() &&
+               proj4.LowerDistance() <= Precision::Confusion())  {
+               detrompeur = 2;
+            }
+          }
+
+          gp_Dir TheDirExtr;
+          gp_Ax3 Axis;
+          Handle(Geom_Curve) TheNewCurve;
+          Standard_Boolean KPart = Standard_False;
+
+          if ( S1->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
+            S1 = Handle(Geom_RectangularTrimmedSurface)::
+              DownCast(S1)->BasisSurface();
+          }
+          if ( S2->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
+            S2 = Handle(Geom_RectangularTrimmedSurface)::
+              DownCast(S2)->BasisSurface();
+          }
+
+          Standard_Boolean PC1 = Standard_True; // KPart on S1
+          if (S1->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion) &&
+              S2->DynamicType() == STANDARD_TYPE(Geom_Plane) ) {
+            KPart = Standard_True;
+            Axis = Handle(Geom_Plane)::DownCast(S2)->Position();
+            TheNewCurve = Handle(Geom_SurfaceOfLinearExtrusion)::
+              DownCast(S1)->BasisCurve();
+            TheDirExtr = Handle(Geom_SurfaceOfLinearExtrusion)::
+              DownCast(S1)->Direction();
+          }
+          else if (S2->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion) &&
+                   S1->DynamicType() == STANDARD_TYPE(Geom_Plane) ) {
+            KPart = Standard_True;
+            PC1 = Standard_False;
+            Axis = Handle(Geom_Plane)::DownCast(S1)->Position();
+            TheNewCurve = Handle(Geom_SurfaceOfLinearExtrusion)::
+              DownCast(S2)->BasisCurve();
+            TheDirExtr = Handle(Geom_SurfaceOfLinearExtrusion)::
+              DownCast(S2)->Direction();
+          }
+          Handle(Geom_Circle) aCirc ;
+          if ( KPart) {  // very temporary on circles !!!
+            aCirc = Handle(Geom_Circle)::DownCast(TheNewCurve);
+            if (aCirc.IsNull())
+              KPart = Standard_False;
+            else
+            {
+              gp_Dir AxofCirc = aCirc->Position().Direction();
+              if (AxofCirc.IsParallel(Axis.Direction(),Precision::Angular()))
+                KPart = Standard_True;
+              else
+                KPart = Standard_False;
+            }
+          }
+
+          Standard_Integer imin;
+          GeomInt_IntSS i2s;
+          if ( KPart) {
+            // direct calculation of NewC
+            Standard_Real aLocalReal =
+              gp_Vec(aCirc->Circ().Location(),Axis.Location()).
+              Dot(Axis.Direction());
+            Standard_Real Cos = TheDirExtr.Dot(Axis.Direction());
+            gp_Vec VV = ( aLocalReal / Cos) * TheDirExtr;
+            newC = Handle(Geom_Curve)::DownCast(TheNewCurve->Translated(VV));
+            // it is possible to calculate PCurve
+            Handle(Geom2d_Line) L2d 
+              = new Geom2d_Line(gp_Pnt2d(0.,aLocalReal/Cos),
+              gp::DX2d());
+
+            if ( PC1) 
+              Einf.ChangeFirstPC() = L2d;
+            else
+              Einf.ChangeSecondPC() = L2d;
+          }
+          else {
+            S1 = myFMap.FindFromKey(Einf.FirstFace()).Geometry();
+            S2 = myFMap.FindFromKey(Einf.SecondFace()).Geometry();
+
+
+            // PCurves are not calculated immediately for 2 reasons:
+            // 1 - If ProjLib should make an Approx, it is stupid to approximate the 
+            //     entire intersection curve.
+            // 2 - Additionally, if YaRev, there is a risk to not be SameRange.
+            i2s.Perform(S1,S2,Precision::Confusion(),
+              Standard_True,Standard_False,Standard_False);
+
+            if (!i2s.IsDone() || i2s.NbLines() <= 0) {
+              errStat = Draft_EdgeRecomputation;
+              badShape = theEdge;
+              return;
+            }
+
+            Standard_Real Dist2, Dist2Min = 0., Glob2Min = RealLast();
+            GeomAdaptor_Curve TheCurve;
+
+            Standard_Integer i,j; //,jmin;
+
+            if (i2s.Line(1)->DynamicType() != STANDARD_TYPE(Geom_BSplineCurve))
+            {
+              imin = 0;
+              for (i=1; i<= i2s.NbLines(); i++) {
+                TheCurve.Load(i2s.Line(i));
+                Extrema_ExtPC myExtPC(pfv,TheCurve);
+
+                Standard_Real locpmin = 0.;
+                if (myExtPC.IsDone()) {
+                  if(myExtPC.NbExt() >= 1) {
+                    Dist2Min = myExtPC.SquareDistance(1);
+                    locpmin = myExtPC.Point(1).Parameter();
+                  }
+                  if(myExtPC.NbExt() == 2 && Dist2Min > Precision::SquareConfusion()) {
+                    //to avoid incorrectly choosing the image 
+                    //of the first vertex of the initial edge
+                    Standard_Real d1_2 = myExtPC.SquareDistance(1);
+                    Standard_Real d2_2 = myExtPC.SquareDistance(2);
+                    if(d1_2 > 1.21*d2_2) {
+                      Dist2Min = myExtPC.SquareDistance(2);
+                      locpmin = myExtPC.Point(2).Parameter();
+                    }
+                    else if(d2_2 > 1.21*d1_2) {
+                      Dist2Min = myExtPC.SquareDistance(1);
+                      locpmin = myExtPC.Point(1).Parameter();
+                    }
+                    else {
+                      Standard_Real pfvpar = myExtPC.Point(1).Parameter();
+                      Standard_Real plvpar = myExtPC.Point(2).Parameter();
+                      newC = i2s.Line(i);
+
+                      gp_Pnt pfvprim, plvprim;
+
+                      newC->D0(pfvpar,pfvprim);
+                      newC->D0(plvpar,plvprim);
+
+                      Handle(Geom_Surface) theSurf;
+                      if(detrompeur == 1) {
+                        if(S1->DynamicType() == 
+                           STANDARD_TYPE(Geom_RectangularTrimmedSurface))  
+                          S1 = Handle(Geom_RectangularTrimmedSurface)::
+                          DownCast(S1)->BasisSurface();
+                        theSurf = S1;
+
+                      }
+                      else if(detrompeur == 2) {
+                        if(S2->DynamicType() == 
+                           STANDARD_TYPE(Geom_RectangularTrimmedSurface)) 
+                          S2 = Handle(Geom_RectangularTrimmedSurface)::
+                          DownCast(S2)->BasisSurface();
+                        theSurf = S2;              
+                      }
+                      if(detrompeur != 0 && detrompeur != 4) {
+                        Standard_Real ul = 0., vl = 0., uf = 0., vf = 0.;
+                        Standard_Real ufprim = 0., ulprim = 0., vfprim = 0., vlprim = 0.;
+
+                        if(theSurf->DynamicType() == STANDARD_TYPE(Geom_Plane)) {      
+                          gp_Pln pl = Handle(Geom_Plane)::DownCast(S2)->Pln();
+                          ElSLib::Parameters(pl, plv, ul, vl);
+                          ElSLib::Parameters(pl, pfv, uf, vf);
+                          ElSLib::Parameters(pl, plvprim, ulprim, vlprim);
+                          ElSLib::Parameters(pl, pfvprim, ufprim, vfprim);
+                        }
+                        else if(theSurf->DynamicType() == 
+                                STANDARD_TYPE(Geom_CylindricalSurface)) {
+                          gp_Cylinder cy = Handle(Geom_CylindricalSurface)
+                            ::DownCast(S2)->Cylinder();
+                          ElSLib::Parameters(cy, plv, ul, vl);
+                          ElSLib::Parameters(cy, pfv, uf, vf);
+                          ElSLib::Parameters(cy, plvprim, ulprim, vlprim);
+                          ElSLib::Parameters(cy, pfvprim, ufprim, vfprim);
+                        }
+                        else detrompeur = 4;
+
+                        if(detrompeur == 1 || detrompeur == 2) {
+                          gp_Vec2d v1((ul-ufprim), (vl-vfprim));
+                          gp_Vec2d norm((vf-vfprim), (ufprim-uf)); 
+                          gp_Vec2d v2((ulprim-ufprim), (vlprim-vfprim));
+                          if( (v1.Dot(norm))*(v2.Dot(norm)) < 0) {
+                            Dist2Min = myExtPC.SquareDistance(2);
+                            locpmin = myExtPC.Point(2).Parameter();
+                          }
+                        }
+                      }
+                    }
+                  }
+                  if (myExtPC.NbExt() == 1 || myExtPC.NbExt() > 2 || detrompeur ==4) {
+                    Dist2Min = myExtPC.SquareDistance(1);
+                    locpmin = myExtPC.Point(1).Parameter();
+                    for (j=2; j<=myExtPC.NbExt(); j++) {
+                      Dist2 = myExtPC.SquareDistance(j);
+                      if (Dist2 < Dist2Min) {
                         Dist2Min = Dist2;
-                        pmin = myExtPC.Point(i).Parameter();
+                        locpmin = myExtPC.Point(j).Parameter();
                       }
                     }
-                 }
-               newC->D1(pmin,pfv,newd1);
-               Standard_Boolean YaRev = d1fv.Dot(newd1) < 0.; 
-               
-               if (YaRev)
-                 newC->Reverse();
-               /*
-               if (i2s.HasLineOnS1(imin)) {
-                 Einf.ChangeFirstPC() = i2s.LineOnS1(imin);
-                 if ( YaRev) 
-                   Einf.ChangeFirstPC()->Reverse();
-               }
-               
-               if (i2s.HasLineOnS2(imin)) {
-                 Einf.ChangeSecondPC() = i2s.LineOnS2(imin);
-                 if ( YaRev) 
-                   Einf.ChangeSecondPC()->Reverse();
-               }
-               */
-             } // else: i2s.NbLines() > 2 && S1 is Cylinder or Cone
-           
-           Einf.Tolerance(Max(Einf.Tolerance(), i2s.TolReached3d()));
-         }  // End step KPart
-       }
-       else { // case of tangency
-         const TopoDS_Face& F1 = Einf.FirstFace();
-         const TopoDS_Face& F2 = Einf.SecondFace();
-
-         Handle(Geom_Surface) aLocalS1 = myFMap(F1).Geometry();
-         Handle(Geom_Surface) aLocalS2 = myFMap(F2).Geometry();
-         if (aLocalS1.IsNull() || aLocalS2.IsNull()) {
-           errStat = Draft_EdgeRecomputation;
-           badShape = TopoDS::Edge(ite.Key());
-           return;
-         }
-         if (aLocalS1->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
-           aLocalS1 = Handle(Geom_RectangularTrimmedSurface)::
-           DownCast(aLocalS1)->BasisSurface();
-         }
-         if (aLocalS2->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
-           aLocalS2 = Handle(Geom_RectangularTrimmedSurface)::
-           DownCast(aLocalS2)->BasisSurface();
-         }
-
-         gp_Dir dirextr;
-         //Standard_Boolean dirfound = Standard_False;
-         if (aLocalS1->DynamicType() == STANDARD_TYPE(Geom_CylindricalSurface)) {
-           gp_Cylinder cyl = 
-             Handle(Geom_CylindricalSurface)::DownCast(aLocalS1)->Cylinder();
-           dirextr = cyl.Axis().Direction();
-           //dirfound = Standard_True;
-           // see direction...
-
-         }
-         else if (aLocalS1->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) {
-           dirextr = Handle(Geom_SurfaceOfLinearExtrusion)::
-             DownCast(aLocalS1)->Direction();
-           //dirfound = Standard_True;
-           // see direction...
-
-           // Here it is possible to calculate PCurve.
-           Handle(Geom_SurfaceOfLinearExtrusion) SEL = 
-             Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(aLocalS1);
-           Handle(Geom_Circle) GCir = 
-             Handle(Geom_Circle)::DownCast(SEL->BasisCurve());
-           if ( !GCir.IsNull()) {
-             Standard_Real U = ElCLib::Parameter(GCir->Circ(),ptfixe);
-             Handle(Geom2d_Line) PC1 = 
-               new Geom2d_Line(gp_Pnt2d(U,0.),gp::DY2d());
-             Einf.ChangeFirstPC() = PC1;
-           }
-         }
-
-         else if (aLocalS2->DynamicType() == STANDARD_TYPE(Geom_CylindricalSurface)) {
-           gp_Cylinder cyl = 
-             Handle(Geom_CylindricalSurface)::DownCast(aLocalS2)->Cylinder();
-           dirextr = cyl.Axis().Direction();
-           // dirfound = Standard_True;
-           // see direction...
-
-         }
-         else if (aLocalS2->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) {
-           dirextr = Handle(Geom_SurfaceOfLinearExtrusion)::
-             DownCast(aLocalS2)->Direction();
-           // dirfound = Standard_True;
-           // see direction...
-
-           // Here it is possible to calculate PCurve.
-           Handle(Geom_SurfaceOfLinearExtrusion) SEL = 
-             Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(aLocalS2);
-           Handle(Geom_Circle) GCir = 
-             Handle(Geom_Circle)::DownCast(SEL->BasisCurve());
-           if ( !GCir.IsNull()) {
-             Standard_Real U = ElCLib::Parameter(GCir->Circ(),ptfixe);
-             Handle(Geom2d_Line) PC2 = 
-               new Geom2d_Line(gp_Pnt2d(U,0.),gp::DY2d());
-             Einf.ChangeSecondPC() = PC2;
-           }
-         }
-         newC = new Geom_Line(ptfixe,dirextr);
-
-         gp_Pnt pfv;
-         gp_Vec d1fv,newd1;
-         C->D1(0.,pfv,d1fv);
-         newC->D1(0.,pfv,newd1);
-         Standard_Boolean YaRev = d1fv.Dot(newd1) <0.; 
-         if (YaRev) {
-           newC->Reverse();
-           if(!Einf.FirstPC().IsNull()) {
-             Einf.ChangeFirstPC()->Reverse();
-           }
-           if(!Einf.SecondPC().IsNull()) {
-             Einf.ChangeSecondPC()->Reverse();
-           }
-         }
-       }
-
-       Handle(Geom_TrimmedCurve) T = Handle(Geom_TrimmedCurve)::DownCast(newC);
-       if (!T.IsNull()) newC = T->BasisCurve();
-       Einf.ChangeGeometry() = newC;
+                  }
+                  else if(myExtPC.NbExt() < 1){
+                    Standard_Real dist1_2,dist2_2;
+                    gp_Pnt p1b,p2b;
+                    myExtPC.TrimmedSquareDistances(dist1_2,dist2_2,p1b,p2b);
+                    if (dist1_2 < dist2_2) {
+                      Dist2Min = dist1_2;
+                      locpmin = TheCurve.FirstParameter();
+                    }
+                    else {
+                      Dist2Min = dist2_2;
+                      locpmin = TheCurve.LastParameter();
+                    }
+                  }
+
+                  if (Dist2Min  < Glob2Min) {
+                    Glob2Min = Dist2Min;
+                    imin = i;
+                    pmin = locpmin;
+                  }
+                }
+              }
+              if (imin == 0) {
+                errStat = Draft_EdgeRecomputation;
+                badShape = theEdge;
+                return;
+              }
+
+              newC = i2s.Line(imin);
+
+              newC->D1(pmin,pfv,newd1);
+              Standard_Boolean YaRev = d1fv.Dot(newd1) <0.; 
+
+              if (YaRev)
+                newC->Reverse();
+
+              if (i2s.HasLineOnS1(imin)) {
+                Einf.ChangeFirstPC() = i2s.LineOnS1(imin);
+                if ( YaRev) 
+                  Einf.ChangeFirstPC()->Reverse();
+              }
+
+              if (i2s.HasLineOnS2(imin)) {
+                Einf.ChangeSecondPC() = i2s.LineOnS2(imin);
+                if ( YaRev) 
+                  Einf.ChangeSecondPC()->Reverse();
+              }
+            } // if (i2s.Line(1)->DynamicType() != STANDARD_TYPE(Geom_BSplineCurve))
+            else // i2s.Line(1) is BSplineCurve
+            {
+              //Find the first curve to glue
+              TColGeom_SequenceOfCurve Candidates;
+              if (S1->DynamicType() == STANDARD_TYPE(Geom_CylindricalSurface) ||
+                  S1->DynamicType() == STANDARD_TYPE(Geom_ConicalSurface)) 
+              {
+                for (i = 1; i <= i2s.NbLines(); i++)
+                {
+                  Handle( Geom_Curve ) aCurve = i2s.Line(i);
+                  gp_Pnt Pnt = aCurve->Value( aCurve->FirstParameter() );
+                  GeomAPI_ProjectPointOnSurf projector( Pnt, S1, Precision::Confusion() );
+                  Standard_Real U, V;
+                  projector.LowerDistanceParameters( U, V );
+                  if (Abs(U) <= Precision::Confusion() || Abs(U-2.*M_PI) <= Precision::Confusion())
+                    Candidates.Append( aCurve );
+                  else
+                  {
+                    Pnt = aCurve->Value( aCurve->LastParameter() );
+                    projector.Init( Pnt, S1, Precision::Confusion() );
+                    projector.LowerDistanceParameters( U, V );
+                    if (Abs(U) <= Precision::Confusion() || Abs(U-2.*M_PI) <= Precision::Confusion())
+                    {
+                      aCurve->Reverse();
+                      Candidates.Append( aCurve );
+                    }
+                  }
+                }
+
+                if(Candidates.Length() == 0) 
+                {
+                  //errStat = Draft_EdgeRecomputation;
+                  //badShape = TopoDS::Edge(ite.Key());
+                  //return;
+                  for (i = 1; i <= i2s.NbLines(); i++)
+                    Candidates.Append( i2s.Line(i) );
+                }
+              }
+              else 
+              {
+                for (i = 1; i <= i2s.NbLines(); i++)
+                  Candidates.Append( i2s.Line(i) );
+              }
+
+              Handle( Geom_Curve ) FirstCurve;
+              if (Candidates.Length() > 1)
+              {
+                Dist2Min = RealLast();
+                for (i = 1; i <= Candidates.Length(); i++)
+                {
+                  Handle( Geom_Curve ) aCurve = Candidates(i);
+                  gp_Pnt Pnt = aCurve->Value( aCurve->FirstParameter() );
+                  Dist2 = Pnt.SquareDistance( pfv );
+                  if (Dist2 < Dist2Min)
+                  {
+                    Dist2Min = Dist2;
+                    FirstCurve = aCurve;
+                  }
+                }
+              }
+              else
+                FirstCurve = Candidates(1);
+
+              //Glueing
+              TColGeom_SequenceOfCurve Curves;
+              for (i = 1; i <= i2s.NbLines(); i++)
+                if (FirstCurve != i2s.Line(i))
+                  Curves.Append( i2s.Line(i) );
+
+              TColGeom_SequenceOfCurve ToGlue;
+              gp_Pnt EndPoint = FirstCurve->Value( FirstCurve->LastParameter() );
+              Standard_Boolean added = Standard_True;
+              while (added)
+              {
+                added = Standard_False;
+                for (i = 1; i <= Curves.Length(); i++)
+                {
+                  Handle( Geom_Curve ) aCurve = Curves(i);
+                  gp_Pnt pfirst, plast;
+                  pfirst = aCurve->Value( aCurve->FirstParameter() );
+                  plast = aCurve->Value( aCurve->LastParameter() );
+                  if (pfirst.Distance( EndPoint ) <= Precision::Confusion())
+                  {
+                    ToGlue.Append( aCurve );
+                    EndPoint = plast;
+                    Curves.Remove(i);
+                    added = Standard_True;
+                    break;
+                  }
+                  if (plast.Distance( EndPoint ) <= Precision::Confusion())
+                  {
+                    aCurve->Reverse();
+                    ToGlue.Append( aCurve );
+                    EndPoint = pfirst;
+                    Curves.Remove(i);
+                    added = Standard_True;
+                    break;
+                  }
+                }
+              }
+
+              if (FirstCurve.IsNull()) {
+                errStat = Draft_EdgeRecomputation;
+                badShape = theEdge;
+                return;
+              }
+
+              GeomConvert_CompCurveToBSplineCurve Concat( Handle(Geom_BSplineCurve)::DownCast(FirstCurve) );
+              for (i = 1; i <= ToGlue.Length(); i++)
+                Concat.Add( Handle(Geom_BSplineCurve)::DownCast(ToGlue(i)), Precision::Confusion(), Standard_True );
+
+              newC = Concat.BSplineCurve();
+
+              TheCurve.Load( newC );
+              Extrema_ExtPC myExtPC( pfv, TheCurve );
+              Dist2Min = RealLast();
+              for (i = 1; i <= myExtPC.NbExt(); i++)
+              {
+                if (myExtPC.IsMin(i))
+                {
+                  Dist2 = myExtPC.SquareDistance(i);
+                  if (Dist2 < Dist2Min)
+                  {
+                    Dist2Min = Dist2;
+                    pmin = myExtPC.Point(i).Parameter();
+                  }
+                }
+              }
+              newC->D1(pmin,pfv,newd1);
+              Standard_Boolean YaRev = d1fv.Dot(newd1) < 0.; 
+
+              if (YaRev)
+                newC->Reverse();
+              /*
+              if (i2s.HasLineOnS1(imin)) {
+              Einf.ChangeFirstPC() = i2s.LineOnS1(imin);
+              if ( YaRev) 
+              Einf.ChangeFirstPC()->Reverse();
+              }
+
+              if (i2s.HasLineOnS2(imin)) {
+              Einf.ChangeSecondPC() = i2s.LineOnS2(imin);
+              if ( YaRev) 
+              Einf.ChangeSecondPC()->Reverse();
+              }
+              */
+            } // else: i2s.NbLines() > 2 && S1 is Cylinder or Cone
+
+            Einf.Tolerance(Max(Einf.Tolerance(), i2s.TolReached3d()));
+          }  // End step KPart
+        }
+        else { // case of tangency
+          const TopoDS_Face& F1 = Einf.FirstFace();
+          const TopoDS_Face& F2 = Einf.SecondFace();
+
+          Handle(Geom_Surface) aLocalS1 = myFMap.FindFromKey(F1).Geometry();
+          Handle(Geom_Surface) aLocalS2 = myFMap.FindFromKey(F2).Geometry();
+          if (aLocalS1.IsNull() || aLocalS2.IsNull()) {
+            errStat = Draft_EdgeRecomputation;
+            badShape = theEdge;
+            return;
+          }
+          if (aLocalS1->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
+            aLocalS1 = Handle(Geom_RectangularTrimmedSurface)::
+              DownCast(aLocalS1)->BasisSurface();
+          }
+          if (aLocalS2->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
+            aLocalS2 = Handle(Geom_RectangularTrimmedSurface)::
+              DownCast(aLocalS2)->BasisSurface();
+          }
+
+          gp_Dir dirextr;
+          //Standard_Boolean dirfound = Standard_False;
+          if (aLocalS1->DynamicType() == STANDARD_TYPE(Geom_CylindricalSurface)) {
+            gp_Cylinder cyl = 
+              Handle(Geom_CylindricalSurface)::DownCast(aLocalS1)->Cylinder();
+            dirextr = cyl.Axis().Direction();
+            //dirfound = Standard_True;
+            // see direction...
+
+          }
+          else if (aLocalS1->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) {
+            dirextr = Handle(Geom_SurfaceOfLinearExtrusion)::
+              DownCast(aLocalS1)->Direction();
+            //dirfound = Standard_True;
+            // see direction...
+
+            // Here it is possible to calculate PCurve.
+            Handle(Geom_SurfaceOfLinearExtrusion) SEL = 
+              Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(aLocalS1);
+            Handle(Geom_Circle) GCir = 
+              Handle(Geom_Circle)::DownCast(SEL->BasisCurve());
+            if ( !GCir.IsNull()) {
+              Standard_Real U = ElCLib::Parameter(GCir->Circ(),ptfixe);
+              Handle(Geom2d_Line) PC1 = 
+                new Geom2d_Line(gp_Pnt2d(U,0.),gp::DY2d());
+              Einf.ChangeFirstPC() = PC1;
+            }
+          }
+
+          else if (aLocalS2->DynamicType() == STANDARD_TYPE(Geom_CylindricalSurface)) {
+            gp_Cylinder cyl = 
+              Handle(Geom_CylindricalSurface)::DownCast(aLocalS2)->Cylinder();
+            dirextr = cyl.Axis().Direction();
+            // dirfound = Standard_True;
+            // see direction...
+
+          }
+          else if (aLocalS2->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) {
+            dirextr = Handle(Geom_SurfaceOfLinearExtrusion)::
+              DownCast(aLocalS2)->Direction();
+            // dirfound = Standard_True;
+            // see direction...
+
+            // Here it is possible to calculate PCurve.
+            Handle(Geom_SurfaceOfLinearExtrusion) SEL = 
+              Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(aLocalS2);
+            Handle(Geom_Circle) GCir = 
+              Handle(Geom_Circle)::DownCast(SEL->BasisCurve());
+            if ( !GCir.IsNull()) {
+              Standard_Real U = ElCLib::Parameter(GCir->Circ(),ptfixe);
+              Handle(Geom2d_Line) PC2 = 
+                new Geom2d_Line(gp_Pnt2d(U,0.),gp::DY2d());
+              Einf.ChangeSecondPC() = PC2;
+            }
+          }
+          newC = new Geom_Line(ptfixe,dirextr);
+
+          gp_Pnt pfv;
+          gp_Vec d1fv,newd1;
+          C->D1(0.,pfv,d1fv);
+          newC->D1(0.,pfv,newd1);
+          Standard_Boolean YaRev = d1fv.Dot(newd1) <0.; 
+          if (YaRev) {
+            newC->Reverse();
+            if(!Einf.FirstPC().IsNull()) {
+              Einf.ChangeFirstPC()->Reverse();
+            }
+            if(!Einf.SecondPC().IsNull()) {
+              Einf.ChangeSecondPC()->Reverse();
+            }
+          }
+        }
+
+        Handle(Geom_TrimmedCurve) T = Handle(Geom_TrimmedCurve)::DownCast(newC);
+        if (!T.IsNull()) newC = T->BasisCurve();
+        Einf.ChangeGeometry() = newC;
       }
       else if (!Einf.NewGeometry()){
-       // set existing curve 3D
-       Handle(Geom_TrimmedCurve) T = Handle(Geom_TrimmedCurve)::DownCast(C);
-       if (!T.IsNull()) C = T->BasisCurve();
-       Einf.ChangeGeometry() = C;
+        // set existing curve 3D
+        Handle(Geom_TrimmedCurve) T = Handle(Geom_TrimmedCurve)::DownCast(C);
+        if (!T.IsNull()) C = T->BasisCurve();
+        Einf.ChangeGeometry() = C;
       }
-      ite.Next();
     }
 
     // Calculate new vertices.
 
-    Draft_DataMapIteratorOfDataMapOfVertexVertexInfo itv(myVMap);
-
     Handle(GeomAdaptor_HCurve)   HAC = new GeomAdaptor_HCurve;
     Handle(GeomAdaptor_HSurface) HAS = new GeomAdaptor_HSurface;
-    
-    while (itv.More()) {
+
+    for (Standard_Integer ii = 1; ii <= myVMap.Extent(); ii++)
+    {
       GeomAdaptor_Curve    AC;
       GeomAdaptor_Surface  AS;
 
-      Draft_VertexInfo& Vinf = myVMap(itv.Key());
-      if (!Choose(myFMap,myEMap,itv.Key(),Vinf,AC,AS)) {
-
-// no concerted edge => alignment of two consecutive edges.
-       gp_Pnt pvt;
-       Vinf.ChangeGeometry() = pvt;
-       Vinf.InitEdgeIterator();
-       if (Vinf.MoreEdge()) {
-         const TopoDS_Edge& Edg1 = Vinf.Edge();
-         //const Draft_EdgeInfo& Einf1 = myEMap(Edg1);
-         Draft_EdgeInfo& Einf1 = myEMap(Edg1);
-         gp_Pnt vtori = BRep_Tool::Pnt(itv.Key());
-         //Einf1.Geometry()->D0(Vinf.Parameter(Edg1), pvt);
-         GeomAPI_ProjectPointOnCurve Projector( vtori, Einf1.Geometry() ); //patch
-         pvt = Projector.NearestPoint();
+      const TopoDS_Vertex& TVV = myVMap.FindKey(ii);
+      Draft_VertexInfo& Vinf = myVMap.ChangeFromIndex(ii);
+      if (!Choose(myFMap,myEMap,TVV,Vinf,AC,AS)) {
+
+        // no concerted edge => alignment of two consecutive edges.
+        gp_Pnt pvt;
+        Vinf.ChangeGeometry() = pvt;
+        Vinf.InitEdgeIterator();
+        if (Vinf.MoreEdge()) {
+          const TopoDS_Edge& Edg1 = Vinf.Edge();
+          //const Draft_EdgeInfo& Einf1 = myEMap(Edg1);
+          Draft_EdgeInfo& Einf1 = myEMap.ChangeFromKey(Edg1);
+          gp_Pnt vtori = BRep_Tool::Pnt(TVV);
+          //Einf1.Geometry()->D0(Vinf.Parameter(Edg1), pvt);
+          GeomAPI_ProjectPointOnCurve Projector( vtori, Einf1.Geometry() ); //patch
+          pvt = Projector.NearestPoint();
 
 #ifdef OCCT_DEBUG
-         static Standard_Integer VertexRecomp = 1;
-         if (VertexRecomp!=0) {
-           cout << "pori :" << vtori.X() << " " << vtori.Y() << " " << vtori.Z() << endl;
-           cout << "  Edg 1 :" << Vinf.Parameter(Edg1) << endl;
-           cout << "pvt :" << pvt.X() << " " << pvt.Y() << " " << pvt.Z() << endl;
-         }
+          static Standard_Integer VertexRecomp = 1;
+          if (VertexRecomp!=0) {
+            cout << "pori :" << vtori.X() << " " << vtori.Y() << " " << vtori.Z() << endl;
+            cout << "  Edg 1 :" << Vinf.Parameter(Edg1) << endl;
+            cout << "pvt :" << pvt.X() << " " << pvt.Y() << " " << pvt.Z() << endl;
+          }
 #endif
 
-         Standard_Real dion=pvt.SquareDistance(vtori);
-         Vinf.NextEdge();
-         if (Vinf.MoreEdge()) {
-           const TopoDS_Edge& Edg2 = Vinf.Edge();
-           //const Draft_EdgeInfo& Einf2 = myEMap(Edg2);
-           Draft_EdgeInfo& Einf2 = myEMap(Edg2);
-//         Standard_Real f;
-           gp_Pnt opvt;
-           Einf2.Geometry()->D0(Vinf.Parameter(Edg2), opvt);
+          Standard_Real dion=pvt.SquareDistance(vtori);
+          Vinf.NextEdge();
+          if (Vinf.MoreEdge()) {
+            const TopoDS_Edge& Edg2 = Vinf.Edge();
+            //const Draft_EdgeInfo& Einf2 = myEMap(Edg2);
+            Draft_EdgeInfo& Einf2 = myEMap.ChangeFromKey(Edg2);
+            //     Standard_Real f;
+            gp_Pnt opvt;
+            Einf2.Geometry()->D0(Vinf.Parameter(Edg2), opvt);
 
 #ifdef OCCT_DEBUG
-         if (VertexRecomp!=0) {
-           cout << "  Edg 2 :" << Vinf.Parameter(Vinf.Edge()) << endl;
-           cout << "opvt " << opvt.X() << " " << opvt.Y() << " " << opvt.Z() << endl;
-         }
+            if (VertexRecomp!=0) {
+              cout << "  Edg 2 :" << Vinf.Parameter(Vinf.Edge()) << endl;
+              cout << "opvt " << opvt.X() << " " << opvt.Y() << " " << opvt.Z() << endl;
+            }
 #endif
 
-           if (opvt.SquareDistance(vtori) < dion) {
-             pvt = opvt;
-           }
-           //Vinf.ChangeParameter(Edg2) = Parameter(Einf2.Geometry(), pvt);
-           Standard_Integer done;
-           Standard_Real param = Parameter(Einf2.Geometry(), pvt, done);
-           if (done != 0)
-             {
-               S1 = myFMap(Einf2.FirstFace()).Geometry();
-               S2 = myFMap(Einf2.SecondFace()).Geometry();
-               Vinf.ChangeParameter(Edg2) = SmartParameter( Einf2, BRep_Tool::Tolerance(Edg2), pvt, done, S1, S2 );
-             }
-           else
-             Vinf.ChangeParameter(Edg2) = param;
-         }
-
-         Vinf.ChangeGeometry() = pvt;
-         //Vinf.ChangeParameter(Edg1) = Parameter(Einf1.Geometry(), pvt);
-         Standard_Integer done;
-         Standard_Real param = Parameter(Einf1.Geometry(), pvt, done);
-         if (done != 0)
-           {
-             S1 = myFMap(Einf1.FirstFace()).Geometry();
-             S2 = myFMap(Einf1.SecondFace()).Geometry();
-             Vinf.ChangeParameter(Edg1) = SmartParameter( Einf1, BRep_Tool::Tolerance(Edg1), pvt, done, S1, S2 );
-           }
-         else
-           Vinf.ChangeParameter(Edg1) = param;
-         itv.Next();
-         continue;
-       }
-
-
-       errStat = Draft_VertexRecomputation;
-       badShape = TopoDS::Vertex(itv.Key());
-       return;
+            if (opvt.SquareDistance(vtori) < dion) {
+              pvt = opvt;
+            }
+            //Vinf.ChangeParameter(Edg2) = Parameter(Einf2.Geometry(), pvt);
+            Standard_Integer done;
+            Standard_Real param = Parameter(Einf2.Geometry(), pvt, done);
+            if (done != 0)
+            {
+              S1 = myFMap.FindFromKey(Einf2.FirstFace()).Geometry();
+              S2 = myFMap.FindFromKey(Einf2.SecondFace()).Geometry();
+              Vinf.ChangeParameter(Edg2) = SmartParameter( Einf2, BRep_Tool::Tolerance(Edg2), pvt, done, S1, S2 );
+            }
+            else
+              Vinf.ChangeParameter(Edg2) = param;
+          }
+
+          Vinf.ChangeGeometry() = pvt;
+          //Vinf.ChangeParameter(Edg1) = Parameter(Einf1.Geometry(), pvt);
+          Standard_Integer done;
+          Standard_Real param = Parameter(Einf1.Geometry(), pvt, done);
+          if (done != 0)
+          {
+            S1 = myFMap.FindFromKey(Einf1.FirstFace()).Geometry();
+            S2 = myFMap.FindFromKey(Einf1.SecondFace()).Geometry();
+            Vinf.ChangeParameter(Edg1) = SmartParameter( Einf1, BRep_Tool::Tolerance(Edg1), pvt, done, S1, S2 );
+          }
+          else
+            Vinf.ChangeParameter(Edg1) = param;
+          continue;
+        }
+
+
+        errStat = Draft_VertexRecomputation;
+        badShape = TVV;
+        return;
       }
 
       IntCurveSurface_HInter myintcs;
       HAC->Set(AC);
       HAS->Set(AS);
+
       myintcs.Perform(HAC,HAS);
 
+
       if (!myintcs.IsDone()) {
-       errStat = Draft_VertexRecomputation;
-       badShape = TopoDS::Vertex(itv.Key());
-       return;
+        errStat = Draft_VertexRecomputation;
+        badShape = TVV;
+        return;
       }
 
-      gp_Pnt vtori = BRep_Tool::Pnt(itv.Key());
+      gp_Pnt vtori = BRep_Tool::Pnt(TVV);
       gp_Pnt pvt;
 
       Standard_Integer nbsol = myintcs.NbPoints();
       if (nbsol <= 0)
-       {
-         Extrema_ExtCS extr( AC, AS, Precision::PConfusion(), Precision::PConfusion() );
-
-         if(!extr.IsDone() || extr.NbExt() == 0) {
-           errStat = Draft_VertexRecomputation;
-           badShape = TopoDS::Vertex(itv.Key());
-           return;
-         }
-           
-
-         Standard_Real disref = RealLast();
-         Standard_Integer iref = 0;
-         Extrema_POnCurv Pc;
-         Extrema_POnSurf Ps;
-         for (Standard_Integer i = 1; i <= extr.NbExt(); i++)
-           {
-             extr.Points( i, Pc, Ps );
-             Standard_Real distemp = Pc.Value().SquareDistance(vtori);
-             if ( distemp < disref)
-               {
-                 disref = distemp;
-                 iref = i;
-               }
-           } 
-         extr.Points( iref, Pc, Ps );
-         pvt = Pc.Value();
-       }
+      {
+        Extrema_ExtCS extr( AC, AS, Precision::PConfusion(), Precision::PConfusion() );
+
+        if(!extr.IsDone() || extr.NbExt() == 0) {
+          errStat = Draft_VertexRecomputation;
+          badShape = TVV;
+          return;
+        }
+
+
+        Standard_Real disref = RealLast();
+        Standard_Integer iref = 0;
+        Extrema_POnCurv Pc;
+        Extrema_POnSurf Ps;
+        for (Standard_Integer i = 1; i <= extr.NbExt(); i++)
+        {
+          extr.Points( i, Pc, Ps );
+          Standard_Real distemp = Pc.Value().SquareDistance(vtori);
+          if ( distemp < disref)
+          {
+            disref = distemp;
+            iref = i;
+          }
+        } 
+        extr.Points( iref, Pc, Ps );
+        pvt = Pc.Value();
+      }
       else
-       {
-         Standard_Real disref = RealLast();
-         Standard_Integer iref = 0;
-         for (Standard_Integer i = 1; i <= nbsol; i++)
-           {
-             Standard_Real distemp = myintcs.Point(i).Pnt().SquareDistance(vtori);
-             if ( distemp < disref)
-               {
-                 disref = distemp;
-                 iref = i;
-               }
-           } 
-         pvt = myintcs.Point(iref).Pnt();
-       }
-         
+      {
+        Standard_Real disref = RealLast();
+        Standard_Integer iref = 0;
+        for (Standard_Integer i = 1; i <= nbsol; i++)
+        {
+          Standard_Real distemp = myintcs.Point(i).Pnt().SquareDistance(vtori);
+          if ( distemp < disref)
+          {
+            disref = distemp;
+            iref = i;
+          }
+        } 
+        pvt = myintcs.Point(iref).Pnt();
+      }
+
       Vinf.ChangeGeometry() = pvt;
 
       for (Vinf.InitEdgeIterator();Vinf.MoreEdge(); Vinf.NextEdge()) {
-       const TopoDS_Edge& Edg = Vinf.Edge();
-       //const Draft_EdgeInfo& Einf = myEMap(Edg);
-       Draft_EdgeInfo& Einf = myEMap(Edg);
-       //Vinf.ChangeParameter(Edg) = Parameter(Einf.Geometry(),pvt);
-       Standard_Integer done;
-       Standard_Real param = Parameter(Einf.Geometry(), pvt, done);
-       if (done != 0)
-         {
-           S1 = myFMap(Einf.FirstFace()).Geometry();
-           S2 = myFMap(Einf.SecondFace()).Geometry();
-           Vinf.ChangeParameter(Edg) = SmartParameter( Einf, BRep_Tool::Tolerance(Edg), pvt, done, S1, S2 );
-         }
-       else
-         Vinf.ChangeParameter(Edg) = param;
+        const TopoDS_Edge& Edg = Vinf.Edge();
+        //const Draft_EdgeInfo& Einf = myEMap(Edg);
+        Draft_EdgeInfo& Einf = myEMap.ChangeFromKey(Edg);
+        //Vinf.ChangeParameter(Edg) = Parameter(Einf.Geometry(),pvt);
+        Standard_Integer done;
+        Standard_Real param = Parameter(Einf.Geometry(), pvt, done);
+        if (done != 0)
+        {
+          S1 = myFMap.FindFromKey(Einf.FirstFace()).Geometry();
+          S2 = myFMap.FindFromKey(Einf.SecondFace()).Geometry();
+          Vinf.ChangeParameter(Edg) = SmartParameter( Einf, BRep_Tool::Tolerance(Edg), pvt, done, S1, S2 );
+        }
+        else
+          Vinf.ChangeParameter(Edg) = param;
       }
-      itv.Next();
     }
   }
 
   // small loop of validation/protection
 
-  for (Draft_DataMapIteratorOfDataMapOfEdgeEdgeInfo ite(myEMap);
-       ite.More(); ite.Next()) {
-    const TopoDS_Edge& edg = TopoDS::Edge(ite.Key());
+  for (Standard_Integer i = 1; i <= myEMap.Extent(); i++) 
+  {
+    const TopoDS_Edge& edg = TopoDS::Edge(myEMap.FindKey(i));
 
     TopoDS_Vertex Vf,Vl;
     TopExp::Vertices(edg,Vf,Vl);
@@ -1535,37 +1545,37 @@ void Draft_Modification::Perform ()
       pl = BRep_Tool::Parameter(Vl,edg);
     }
     if (pl <= pf) {
-//      const Handle(Geom_Curve) gc=ite.Value().Geometry();
-//      if (!gc.IsNull()) {
-//     pl = gc->LastParameter();
-//     pf = gc->FirstParameter();
-//      }
-      Handle( Geom_Curve ) theCurve = myEMap(edg).Geometry();
+      //      const Handle(Geom_Curve) gc=ite.Value().Geometry();
+      //      if (!gc.IsNull()) {
+      //       pl = gc->LastParameter();
+      //       pf = gc->FirstParameter();
+      //      }
+      Handle( Geom_Curve ) theCurve = myEMap.FindFromKey(edg).Geometry();
       if (theCurve->IsClosed())
-       {
-         // pf >= pl
-         Standard_Real FirstPar = theCurve->FirstParameter(), LastPar = theCurve->LastParameter();
-         Standard_Real pconf = Precision::PConfusion();
-         if (Abs( pf - LastPar ) <= pconf)
-           pf = FirstPar;
-         else if (Abs( pl - FirstPar ) <= pconf)
-           pl = LastPar;
-
-         if(pl <= pf) {
-           pl += (LastPar-FirstPar);
-         }
-
-       }
+      {
+        // pf >= pl
+        Standard_Real FirstPar = theCurve->FirstParameter(), LastPar = theCurve->LastParameter();
+        Standard_Real pconf = Precision::PConfusion();
+        if (Abs( pf - LastPar ) <= pconf)
+          pf = FirstPar;
+        else if (Abs( pl - FirstPar ) <= pconf)
+          pl = LastPar;
+
+        if(pl <= pf) {
+          pl += (LastPar-FirstPar);
+        }
+
+      }
       if (pl <= pf) {
-       errStat = Draft_EdgeRecomputation;
-       badShape = TopoDS::Edge(ite.Key());
-       return;
+        errStat = Draft_EdgeRecomputation;
+        badShape = edg;
+        return;
       }
     }
-    if (myVMap.IsBound( Vf ))
-      myVMap(Vf).ChangeParameter(edg) = pf;
-    if (myVMap.IsBound( Vl ))
-      myVMap(Vl).ChangeParameter(edg) = pl;
+    if (myVMap.Contains( Vf ))
+      myVMap.ChangeFromKey(Vf).ChangeParameter(edg) = pf;
+    if (myVMap.Contains( Vl ))
+      myVMap.ChangeFromKey(Vl).ChangeParameter(edg) = pl;
   }
 }
 
@@ -1578,10 +1588,10 @@ void Draft_Modification::Perform ()
 
 Handle(Geom_Surface) Draft_Modification::NewSurface
   (const Handle(Geom_Surface)& S,
-   const TopAbs_Orientation Oris,
-   const gp_Dir& Direction,
-   const Standard_Real Angle,
-   const gp_Pln& NeutralPlane) 
+  const TopAbs_Orientation Oris,
+  const gp_Dir& Direction,
+  const Standard_Real Angle,
+  const gp_Pln& NeutralPlane) 
 {
   Handle(Geom_Surface) NewS;
 
@@ -1593,10 +1603,10 @@ Handle(Geom_Surface) Draft_Modification::NewSurface
     Standard_Real Theta;
     if (FindRotation(Pl,Oris,Direction,Angle,NeutralPlane,Axe,Theta)) {
       if ( Abs(Theta) > Precision::Angular()) {
-       NewS = Handle(Geom_Surface)::DownCast(S->Rotated(Axe,Theta));
+        NewS = Handle(Geom_Surface)::DownCast(S->Rotated(Axe,Theta));
       }
       else {
-       NewS = S;
+        NewS = S;
       }
     }
   }
@@ -1604,7 +1614,7 @@ Handle(Geom_Surface) Draft_Modification::NewSurface
     Standard_Real testdir = Direction.Dot(NeutralPlane.Axis().Direction());
     if (Abs(testdir) <= 1.-Precision::Angular()) {     
 #ifdef OCCT_DEBUG
-    cout << "NewSurfaceCyl:Draft_Direction_and_Neutral_Perpendicular" << endl;
+      cout << "NewSurfaceCyl:Draft_Direction_and_Neutral_Perpendicular" << endl;
 #endif
       return NewS;     
     }    
@@ -1612,7 +1622,7 @@ Handle(Geom_Surface) Draft_Modification::NewSurface
     testdir = Direction.Dot(Cy.Axis().Direction());
     if (Abs(testdir) <= 1.-Precision::Angular()) {
 #ifdef OCCT_DEBUG
-    cout << "NewSurfaceCyl:Draft_Direction_and_Cylinder_Perpendicular" << endl;
+      cout << "NewSurfaceCyl:Draft_Direction_and_Cylinder_Perpendicular" << endl;
 #endif
       return NewS;
     }
@@ -1632,30 +1642,30 @@ Handle(Geom_Surface) Draft_Modification::NewSurface
 
       if (!isIntDone || i2s.TypeInter() != IntAna_Circle) {
 #ifdef OCCT_DEBUG
-    cout << "NewSurfaceCyl:Draft_Intersection_Neutral_Cylinder_NotDone" << endl;
+        cout << "NewSurfaceCyl:Draft_Intersection_Neutral_Cylinder_NotDone" << endl;
 #endif
-       return NewS;
+        return NewS;
       } 
       gp_Ax3 axcone = Cy.Position();
       // Pb : Where is the material???
       Standard_Real alpha = Angle;
       Standard_Boolean direct(axcone.Direct());
       if ((direct && Oris == TopAbs_REVERSED) ||
-         (!direct && Oris == TopAbs_FORWARD)) {
-       alpha = -alpha;
+         (!direct && Oris == TopAbs_FORWARD)) {
+        alpha = -alpha;
       }
-      
+
       gp_Pnt Center = i2s.Circle(1).Location();
       if (testdir <0.) {
-       alpha = -alpha;
+        alpha = -alpha;
       }
       Standard_Real Z = ElCLib::LineParameter(Cy.Axis(),Center);
       Standard_Real Rad = Cy.Radius()+Z*Tan(alpha);
       if (Rad < 0.) {
-       Rad = -Rad;
+        Rad = -Rad;
       }
       else {
-       alpha = -alpha;
+        alpha = -alpha;
       }
       gp_Cone co(axcone,alpha,Rad);
       NewS = new Geom_ConicalSurface(co);
@@ -1665,21 +1675,21 @@ Handle(Geom_Surface) Draft_Modification::NewSurface
     }
   }
   else if (TypeS == STANDARD_TYPE(Geom_ConicalSurface)) {
-    
+
     Standard_Real testdir = Direction.Dot(NeutralPlane.Axis().Direction());
     if (Abs(testdir) <= 1.-Precision::Angular()) {     
 #ifdef OCCT_DEBUG
-    cout << "NewSurfaceCone:Draft_Direction_and_Neutral_Perpendicular" << endl;
+      cout << "NewSurfaceCone:Draft_Direction_and_Neutral_Perpendicular" << endl;
 #endif
       return NewS;     
     }  
-    
+
     gp_Cone Co1 = Handle(Geom_ConicalSurface)::DownCast(S)->Cone();
-    
+
     testdir = Direction.Dot(Co1.Axis().Direction());
     if (Abs(testdir) <= 1.-Precision::Angular()) {
 #ifdef OCCT_DEBUG
-    cout << "NewSurfaceCone:Draft_Direction_and_Cone_Perpendicular" << endl;
+      cout << "NewSurfaceCone:Draft_Direction_and_Cone_Perpendicular" << endl;
 #endif
       return NewS;
     }
@@ -1689,7 +1699,7 @@ Handle(Geom_Surface) Draft_Modification::NewSurface
     i2s.Perform(NeutralPlane,Co1,Precision::Angular(),Precision::Confusion());
     if (!i2s.IsDone() || i2s.TypeInter() != IntAna_Circle) {
 #ifdef OCCT_DEBUG
-    cout << "NewSurfaceCone:Draft_Intersection_Neutral_Conical_NotDone" << endl;
+      cout << "NewSurfaceCone:Draft_Intersection_Neutral_Conical_NotDone" << endl;
 #endif
       return NewS;
     }
@@ -1698,7 +1708,7 @@ Handle(Geom_Surface) Draft_Modification::NewSurface
     Standard_Real alpha = Angle;
     Standard_Boolean direct(axcone.Direct());
     if ((direct && Oris == TopAbs_REVERSED) ||
-       (!direct && Oris == TopAbs_FORWARD)) {
+       (!direct && Oris == TopAbs_FORWARD)) {
       alpha = -alpha;
     }
 
@@ -1725,7 +1735,7 @@ Handle(Geom_Surface) Draft_Modification::NewSurface
     }
     else {
       NewS = new
-       Geom_CylindricalSurface(gp_Cylinder(axcone,i2s.Circle(1).Radius()));
+        Geom_CylindricalSurface(gp_Cylinder(axcone,i2s.Circle(1).Radius()));
     }
   }
   else {
@@ -1744,12 +1754,12 @@ Handle(Geom_Surface) Draft_Modification::NewSurface
 
 Handle(Geom_Curve) Draft_Modification::NewCurve
   (const Handle(Geom_Curve)& C,
-   const Handle(Geom_Surface)& S,
-   const TopAbs_Orientation Oris,
-   const gp_Dir& Direction,
-   const Standard_Real Angle,
-   const gp_Pln& NeutralPlane,
-   const Standard_Boolean )
+  const Handle(Geom_Surface)& S,
+  const TopAbs_Orientation Oris,
+  const gp_Dir& Direction,
+  const Standard_Real Angle,
+  const gp_Pln& NeutralPlane,
+  const Standard_Boolean )
 
 {
   Handle(Geom_Curve) NewC;
@@ -1762,10 +1772,10 @@ Handle(Geom_Curve) Draft_Modification::NewCurve
     Standard_Real Theta;
     if (FindRotation(Pl,Oris,Direction,Angle,NeutralPlane,Axe,Theta)) {
       if ( Abs(Theta) > Precision::Angular()) {
-       NewC = Handle(Geom_Curve)::DownCast(C->Rotated(Axe,Theta));
+        NewC = Handle(Geom_Curve)::DownCast(C->Rotated(Axe,Theta));
       }
       else {
-       NewC = C;
+        NewC = C;
       }
     }
     return NewC;
@@ -1778,10 +1788,10 @@ Handle(Geom_Curve) Draft_Modification::NewCurve
 
 
   gp_Lin lin = Handle(Geom_Line)::DownCast(C)->Lin();
-//  Standard_Real testdir = Direction.Dot(lin.Direction());
-//  if (Abs(testdir) <= 1.-Precision::Angular()) {
-//    return NewC;
-//  }
+  //  Standard_Real testdir = Direction.Dot(lin.Direction());
+  //  if (Abs(testdir) <= 1.-Precision::Angular()) {
+  //    return NewC;
+  //  }
   gp_Dir Norm;
   if (TypeS == STANDARD_TYPE(Geom_CylindricalSurface)) {
     Standard_Real U,V;
@@ -1824,12 +1834,12 @@ Handle(Geom_Curve) Draft_Modification::NewCurve
 //purpose  : 
 //=======================================================================
 
-static Standard_Boolean Choose(const Draft_DataMapOfFaceFaceInfo& theFMap,
-                              Draft_DataMapOfEdgeEdgeInfo& theEMap,
-                              const TopoDS_Vertex& Vtx,
-                              Draft_VertexInfo& Vinf,
-                              GeomAdaptor_Curve& AC,
-                              GeomAdaptor_Surface& AS)
+static Standard_Boolean Choose(const Draft_IndexedDataMapOfFaceFaceInfo& theFMap,
+  Draft_IndexedDataMapOfEdgeEdgeInfo& theEMap,
+  const TopoDS_Vertex& Vtx,
+  Draft_VertexInfo& Vinf,
+  GeomAdaptor_Curve& AC,
+  GeomAdaptor_Surface& AS)
 {
   gp_Vec tgref; 
   Vinf.InitEdgeIterator();
@@ -1837,15 +1847,15 @@ static Standard_Boolean Choose(const Draft_DataMapOfFaceFaceInfo& theFMap,
   // Find a regular edge with null SecondFace
   while (Vinf.MoreEdge()) {
     const TopoDS_Edge& E1 = Vinf.Edge();
-    const Draft_EdgeInfo& Einf1 = theEMap(E1);
+    const Draft_EdgeInfo& Einf1 = theEMap.FindFromKey(E1);
     if (Einf1.SecondFace().IsNull()) {
       break;
     }
     else {
       GeomAbs_Shape te = BRep_Tool::Continuity(E1,Einf1.FirstFace(),
-                                                 Einf1.SecondFace());
+        Einf1.SecondFace());
       if (te >= GeomAbs_G1) {
-       break;
+        break;
       }
     }
     Vinf.NextEdge();
@@ -1856,7 +1866,7 @@ static Standard_Boolean Choose(const Draft_DataMapOfFaceFaceInfo& theFMap,
 
   const TopoDS_Edge& Eref = Vinf.Edge();
   //const Draft_EdgeInfo& Einf = theEMap(Eref);
-  Draft_EdgeInfo& Einf = theEMap(Eref);
+  Draft_EdgeInfo& Einf = theEMap.ChangeFromKey(Eref);
 
   AC.Load(Einf.Geometry());
 
@@ -1869,11 +1879,11 @@ static Standard_Boolean Choose(const Draft_DataMapOfFaceFaceInfo& theFMap,
   Standard_Integer done;
   Standard_Real param = Parameter( C, BRep_Tool::Pnt(Vtx), done );
   if (done != 0)
-    {
-      Handle( Geom_Surface ) S1 = theFMap(Einf.FirstFace()).Geometry();
-      Handle( Geom_Surface ) S2 = theFMap(Einf.SecondFace()).Geometry();
-      prm = SmartParameter( Einf, BRep_Tool::Tolerance(Eref), BRep_Tool::Pnt(Vtx), done, S1, S2 );
-    }
+  {
+    Handle( Geom_Surface ) S1 = theFMap.FindFromKey(Einf.FirstFace()).Geometry();
+    Handle( Geom_Surface ) S2 = theFMap.FindFromKey(Einf.SecondFace()).Geometry();
+    prm = SmartParameter( Einf, BRep_Tool::Tolerance(Eref), BRep_Tool::Pnt(Vtx), done, S1, S2 );
+  }
   else
     prm = param;
   C->D1(prm,ptbid,tgref);
@@ -1885,28 +1895,28 @@ static Standard_Boolean Choose(const Draft_DataMapOfFaceFaceInfo& theFMap,
     const TopoDS_Edge& Edg = Vinf.Edge();
     if (!Edg.IsSame(Eref)) {
       //const Draft_EdgeInfo& Einfo = theEMap(Edg);
-      Draft_EdgeInfo& Einfo = theEMap(Edg);
+      Draft_EdgeInfo& Einfo = theEMap.ChangeFromKey(Edg);
       if (!Einfo.SecondFace().IsNull() &&
-         BRep_Tool::Continuity(Edg,Einfo.FirstFace(),Einfo.SecondFace()) 
-         <= GeomAbs_C0) {
-       C = BRep_Tool::Curve(Edg,Loc,f,l);
-       C = Handle(Geom_Curve)::DownCast(C->Transformed(Loc.Transformation()));
-       //prm = Parameter(C,BRep_Tool::Pnt(Vtx));
-       Standard_Integer anewdone;
-       Standard_Real anewparam = Parameter( C, BRep_Tool::Pnt(Vtx), anewdone );
-       if (anewdone != 0)
-         {
-           Handle( Geom_Surface ) S1 = theFMap(Einfo.FirstFace()).Geometry();
-           Handle( Geom_Surface ) S2 = theFMap(Einfo.SecondFace()).Geometry();
-           prm = SmartParameter( Einfo, BRep_Tool::Tolerance(Edg), BRep_Tool::Pnt(Vtx), anewdone, S1, S2 );
-         }
-       else
-         prm = anewparam;
-       gp_Vec tg;
-       C->D1(prm,ptbid,tg);
-       if (tg.CrossMagnitude(tgref) > Precision::Confusion()) {
-         break;
-       }
+          BRep_Tool::Continuity(Edg,Einfo.FirstFace(),Einfo.SecondFace()) 
+          <= GeomAbs_C0) {
+        C = BRep_Tool::Curve(Edg,Loc,f,l);
+        C = Handle(Geom_Curve)::DownCast(C->Transformed(Loc.Transformation()));
+        //prm = Parameter(C,BRep_Tool::Pnt(Vtx));
+        Standard_Integer anewdone;
+        Standard_Real anewparam = Parameter( C, BRep_Tool::Pnt(Vtx), anewdone );
+        if (anewdone != 0)
+        {
+          Handle( Geom_Surface ) S1 = theFMap.FindFromKey(Einfo.FirstFace()).Geometry();
+          Handle( Geom_Surface ) S2 = theFMap.FindFromKey(Einfo.SecondFace()).Geometry();
+          prm = SmartParameter( Einfo, BRep_Tool::Tolerance(Edg), BRep_Tool::Pnt(Vtx), anewdone, S1, S2 );
+        }
+        else
+          prm = anewparam;
+        gp_Vec tg;
+        C->D1(prm,ptbid,tg);
+        if (tg.CrossMagnitude(tgref) > Precision::Confusion()) {
+          break;
+        }
       }
     }
     Vinf.NextEdge();
@@ -1915,23 +1925,23 @@ static Standard_Boolean Choose(const Draft_DataMapOfFaceFaceInfo& theFMap,
     return Standard_False;
   }
 
-  const Draft_EdgeInfo& Einf2 = theEMap(Vinf.Edge());
+  const Draft_EdgeInfo& Einf2 = theEMap.FindFromKey(Vinf.Edge());
   if (!Einf.SecondFace().IsNull()) {
 
     if (Einf2.FirstFace().IsSame(Einf.FirstFace()) ||
-       Einf2.FirstFace().IsSame(Einf.SecondFace())) {
-      AS.Load(theFMap(Einf2.SecondFace()).Geometry());
+        Einf2.FirstFace().IsSame(Einf.SecondFace())) {
+      AS.Load(theFMap.FindFromKey(Einf2.SecondFace()).Geometry());
     }
     else {
-      AS.Load(theFMap(Einf2.FirstFace()).Geometry());
+      AS.Load(theFMap.FindFromKey(Einf2.FirstFace()).Geometry());
     }
   }
   else {
     if (Einf2.FirstFace().IsSame(Einf.FirstFace())) {
-      AS.Load(theFMap(Einf2.SecondFace()).Geometry());
+      AS.Load(theFMap.FindFromKey(Einf2.SecondFace()).Geometry());
     }
     else {
-      AS.Load(theFMap(Einf2.FirstFace()).Geometry());
+      AS.Load(theFMap.FindFromKey(Einf2.FirstFace()).Geometry());
     }
   }
   return Standard_True;
@@ -1944,8 +1954,8 @@ static Standard_Boolean Choose(const Draft_DataMapOfFaceFaceInfo& theFMap,
 //=======================================================================
 
 static Standard_Real Parameter(const Handle(Geom_Curve)& C,
-                              const gp_Pnt& P,
-                              Standard_Integer& done)
+  const gp_Pnt& P,
+  Standard_Integer& done)
 {
   done = 0;
   Handle(Geom_Curve) cbase = C;
@@ -1999,11 +2009,11 @@ static Standard_Real Parameter(const Handle(Geom_Curve)& C,
       gp_Pnt p1b,p2b;
       myExtPC.TrimmedSquareDistances(dist1_2,dist2_2,p1b,p2b);
       if (dist1_2 < dist2_2) {
-       done = -1;
+        done = -1;
         param = TheCurve.FirstParameter();
       }
       else {
-       done = 1;
+        done = 1;
         param = TheCurve.LastParameter();
       }
     }
@@ -2012,7 +2022,7 @@ static Standard_Real Parameter(const Handle(Geom_Curve)& C,
       Standard_Real Per  = cbase->Period();
       Standard_Real Tolp = Precision::Parametric(Precision::Confusion());  
       if (Abs(Per-param) <= Tolp) {
-       param = 0.;
+        param = 0.;
       }
     }
   }
@@ -2025,11 +2035,11 @@ static Standard_Real Parameter(const Handle(Geom_Curve)& C,
 //=======================================================================
 
 static Standard_Real SmartParameter(Draft_EdgeInfo& Einf,
-                                   const Standard_Real EdgeTol,
-                                   const gp_Pnt& Pnt,
-                                   const Standard_Integer sign,
-                                   const Handle(Geom_Surface)& S1,
-                                   const Handle(Geom_Surface)& S2)
+  const Standard_Real EdgeTol,
+  const gp_Pnt& Pnt,
+  const Standard_Integer sign,
+  const Handle(Geom_Surface)& S1,
+  const Handle(Geom_Surface)& S2)
 {
   Handle( Geom2d_Curve ) NewC2d;
   Standard_Real Tol = Precision::Confusion();
@@ -2039,57 +2049,57 @@ static Standard_Real SmartParameter(Draft_EdgeInfo& Einf,
   Handle( Geom2d_Curve ) pcu2 = Einf.SecondPC();
 
   if (pcu1.IsNull())
-    {
-      Handle( Geom_Curve ) theCurve = Einf.Geometry();
-      pcu1 = GeomProjLib::Curve2d( theCurve, theCurve->FirstParameter(), theCurve->LastParameter(), S1, Etol );
-      Einf.ChangeFirstPC() = pcu1;
-    }
+  {
+    Handle( Geom_Curve ) theCurve = Einf.Geometry();
+    pcu1 = GeomProjLib::Curve2d( theCurve, theCurve->FirstParameter(), theCurve->LastParameter(), S1, Etol );
+    Einf.ChangeFirstPC() = pcu1;
+  }
   if (pcu2.IsNull())
-    {
-      Handle( Geom_Curve ) theCurve = Einf.Geometry();
-      pcu2 = GeomProjLib::Curve2d( theCurve, theCurve->FirstParameter(), theCurve->LastParameter(), S2, Etol );
-      Einf.ChangeSecondPC() = pcu2;
-    }
+  {
+    Handle( Geom_Curve ) theCurve = Einf.Geometry();
+    pcu2 = GeomProjLib::Curve2d( theCurve, theCurve->FirstParameter(), theCurve->LastParameter(), S2, Etol );
+    Einf.ChangeSecondPC() = pcu2;
+  }
 
   GeomAPI_ProjectPointOnSurf Projector( Pnt, S1 );
   Standard_Real U, V;
   Projector.LowerDistanceParameters( U, V );
-  
+
   NewC2d = Einf.FirstPC();
   if (NewC2d->DynamicType() == STANDARD_TYPE(Geom2d_TrimmedCurve))
     NewC2d = (Handle(Geom2d_TrimmedCurve)::DownCast(NewC2d))->BasisCurve();
-  
+
   gp_Pnt2d P2d( U, V );
   Geom2dAPI_ProjectPointOnCurve Projector2d( P2d, NewC2d );
   if (Projector2d.NbPoints() == 0 || Projector2d.LowerDistance() > Tol)
+  {
+    Handle( Geom2d_BSplineCurve ) BCurve;
+    if (NewC2d->DynamicType() != STANDARD_TYPE(Geom2d_BSplineCurve))
+      BCurve = Geom2dConvert::CurveToBSplineCurve( NewC2d );
+    else
+      BCurve = Handle( Geom2d_BSplineCurve )::DownCast( NewC2d );
+    if (sign == -1)
     {
-      Handle( Geom2d_BSplineCurve ) BCurve;
-      if (NewC2d->DynamicType() != STANDARD_TYPE(Geom2d_BSplineCurve))
-       BCurve = Geom2dConvert::CurveToBSplineCurve( NewC2d );
-      else
-       BCurve = Handle( Geom2d_BSplineCurve )::DownCast( NewC2d );
-      if (sign == -1)
-       {
-         TColgp_Array1OfPnt2d PntArray( 1, 2 );
-         PntArray(1) = P2d;
-         PntArray(2) = BCurve->Pole(1);
-         Handle( Geom2d_BezierCurve ) Patch = new Geom2d_BezierCurve( PntArray );
-         Geom2dConvert_CompCurveToBSplineCurve Concat( BCurve, Convert_QuasiAngular );
-         Concat.Add( Patch, Tol, Standard_False );
-         BCurve = Concat.BSplineCurve();
-       }
-      else
-       {
-         TColgp_Array1OfPnt2d PntArray( 1, 2 );
-         PntArray(1) = BCurve->Pole( BCurve->NbPoles() );
-         PntArray(2) = P2d;
-         Handle( Geom2d_BezierCurve ) Patch = new Geom2d_BezierCurve( PntArray );
-         Geom2dConvert_CompCurveToBSplineCurve Concat( BCurve, Convert_QuasiAngular );
-         Concat.Add( Patch, Tol, Standard_True );
-         BCurve = Concat.BSplineCurve();
-       }
-      NewC2d = BCurve;
+      TColgp_Array1OfPnt2d PntArray( 1, 2 );
+      PntArray(1) = P2d;
+      PntArray(2) = BCurve->Pole(1);
+      Handle( Geom2d_BezierCurve ) Patch = new Geom2d_BezierCurve( PntArray );
+      Geom2dConvert_CompCurveToBSplineCurve Concat( BCurve, Convert_QuasiAngular );
+      Concat.Add( Patch, Tol, Standard_False );
+      BCurve = Concat.BSplineCurve();
     }
+    else
+    {
+      TColgp_Array1OfPnt2d PntArray( 1, 2 );
+      PntArray(1) = BCurve->Pole( BCurve->NbPoles() );
+      PntArray(2) = P2d;
+      Handle( Geom2d_BezierCurve ) Patch = new Geom2d_BezierCurve( PntArray );
+      Geom2dConvert_CompCurveToBSplineCurve Concat( BCurve, Convert_QuasiAngular );
+      Concat.Add( Patch, Tol, Standard_True );
+      BCurve = Concat.BSplineCurve();
+    }
+    NewC2d = BCurve;
+  }
   Einf.ChangeFirstPC() = NewC2d;
   Handle( Geom2dAdaptor_HCurve ) hcur = new Geom2dAdaptor_HCurve( NewC2d );
   Handle( GeomAdaptor_HSurface ) hsur = new GeomAdaptor_HSurface( S1 );
@@ -2103,8 +2113,8 @@ static Standard_Real SmartParameter(Draft_EdgeInfo& Einf,
   ProjCurve.Bounds(1, Udeb, Ufin);
   Standard_Integer MaxSeg = 20 + HProjector->NbIntervals(GeomAbs_C3);
   Approx_CurveOnSurface appr( HProjector, hsur2, Udeb, Ufin, Tol,
-                             GeomAbs_C1, 10, MaxSeg, 
-                             Standard_False, Standard_False );
+    GeomAbs_C1, 10, MaxSeg, 
+    Standard_False, Standard_False );
   Einf.ChangeSecondPC() = appr.Curve2d();
   Einf.ChangeGeometry() = appr.Curve3d();
   Einf.SetNewGeometry( Standard_True );
@@ -2122,14 +2132,14 @@ static Standard_Real SmartParameter(Draft_EdgeInfo& Einf,
 //=======================================================================
 
 static TopAbs_Orientation Orientation(const TopoDS_Shape& S,
-                                     const TopoDS_Face& F)
+  const TopoDS_Face& F)
 {
-//
-// change porting NT
-//
+  //
+  // change porting NT
+  //
   TopExp_Explorer expl ;
   expl.Init(S,
-           TopAbs_FACE) ;
+    TopAbs_FACE) ;
   while (expl.More()) {
     if (TopoDS::Face(expl.Current()).IsSame(F)) {
       return expl.Current().Orientation();
@@ -2146,16 +2156,16 @@ static TopAbs_Orientation Orientation(const TopoDS_Shape& S,
 //=======================================================================
 
 static Standard_Boolean FindRotation(const gp_Pln& Pl,
-                                    const TopAbs_Orientation Oris,
-                                    const gp_Dir& Direction,
-                                    const Standard_Real Angle,
-                                    const gp_Pln& NeutralPlane,
-                                    gp_Ax1& Axe,
-                                    Standard_Real& theta)
+  const TopAbs_Orientation Oris,
+  const gp_Dir& Direction,
+  const Standard_Real Angle,
+  const gp_Pln& NeutralPlane,
+  gp_Ax1& Axe,
+  Standard_Real& theta)
 {                                   
   IntAna_QuadQuadGeo i2pl(Pl,NeutralPlane,
-                         Precision::Angular(),Precision::Confusion());
-  
+    Precision::Angular(),Precision::Confusion());
+
   if (i2pl.IsDone() && i2pl.TypeInter() == IntAna_Line) {
     gp_Lin li = i2pl.Line(1);
     // Try to turn around this line
@@ -2167,26 +2177,26 @@ static Standard_Boolean FindRotation(const gp_Pln& Pl,
       Standard_Real c = Direction.Dot(Pl.Axis().Direction());
       Standard_Boolean direct(Pl.Position().Direct());
       if ((direct && Oris == TopAbs_REVERSED) ||
-         (!direct && Oris == TopAbs_FORWARD)) {
-       b = -b;
-       c = -c;
+        (!direct && Oris == TopAbs_FORWARD)) {
+          b = -b;
+          c = -c;
       }
       Standard_Real denom = Sqrt(1-a*a);
       Standard_Real Sina = Sin(Angle);
       if (denom>Abs(Sina)) {
-       Standard_Real phi = ATan2(b/denom,c/denom);
-       Standard_Real theta0 = ACos(Sina/denom); 
-       theta = theta0 - phi;
-       if (Cos(theta) <0.) {
-         theta = -theta0 -phi;
-       }
-       //  modified by NIZHNY-EAP Tue Nov 16 15:51:38 1999 ___BEGIN___
-       while (Abs(theta)>M_PI) {
-         theta = theta + M_PI*(theta<0 ? 1 : -1);
-       }
-       //  modified by NIZHNY-EAP Tue Nov 16 15:53:32 1999 ___END___
-       Axe = li.Position();
-       return Standard_True;
+        Standard_Real phi = ATan2(b/denom,c/denom);
+        Standard_Real theta0 = ACos(Sina/denom); 
+        theta = theta0 - phi;
+        if (Cos(theta) <0.) {
+          theta = -theta0 -phi;
+        }
+        //  modified by NIZHNY-EAP Tue Nov 16 15:51:38 1999 ___BEGIN___
+        while (Abs(theta)>M_PI) {
+          theta = theta + M_PI*(theta<0 ? 1 : -1);
+        }
+        //  modified by NIZHNY-EAP Tue Nov 16 15:53:32 1999 ___END___
+        Axe = li.Position();
+        return Standard_True;
       }
     }
   }
index accd161..3722bfd 100755 (executable)
@@ -1,11 +1,8 @@
 Draft.cxx
 Draft.hxx
-Draft_DataMapIteratorOfDataMapOfEdgeEdgeInfo.hxx
-Draft_DataMapIteratorOfDataMapOfFaceFaceInfo.hxx
-Draft_DataMapIteratorOfDataMapOfVertexVertexInfo.hxx
-Draft_DataMapOfEdgeEdgeInfo.hxx
-Draft_DataMapOfFaceFaceInfo.hxx
-Draft_DataMapOfVertexVertexInfo.hxx
+Draft_IndexedDataMapOfEdgeEdgeInfo.hxx
+Draft_IndexedDataMapOfFaceFaceInfo.hxx
+Draft_IndexedDataMapOfVertexVertexInfo.hxx
 Draft_EdgeInfo.cxx
 Draft_EdgeInfo.hxx
 Draft_ErrorStatus.hxx
index cb83da8..f72eb66 100644 (file)
@@ -4485,6 +4485,97 @@ static Standard_Integer OCC24537(
   return 0;
 }
 
+
+#include <TopExp.hxx>
+#include <BRepOffsetAPI_DraftAngle.hxx>
+#include <vector>
+static TopoDS_Shape taper(const TopoDS_Shape &shape, const TopoDS_Face &face_a, const TopoDS_Face &face_b, Standard_Real angle)
+{
+  // Use maximum face-to-taper z-offset.
+  const gp_Pln neutral_plane(gp_Ax3(gp_Pnt(0.0, 0.0, 140.0), gp_Dir(0.0, 0.0, 1.0)));
+
+  // Draft angle needs to be in radians, and flipped to adhere to our own (arbitrary) draft
+  // angle definition.
+  const Standard_Real draft_angle = -(angle / 180.0) * M_PI;
+
+  // Add face to draft. The first argument indicates that all material added/removed during
+  // drafting is located below the neutral plane
+  BRepOffsetAPI_DraftAngle drafter(shape);
+  drafter.Add(face_a, gp_Dir(0.0, 0.0, -1.0), draft_angle, neutral_plane);
+  drafter.Add(face_b, gp_Dir(0.0, 0.0, -1.0), draft_angle, neutral_plane);
+  drafter.Build();
+
+  return drafter.Shape();
+}
+
+static void dumpShapeVertices(const TopoDS_Shape &shape, std::vector<Standard_Real>& coords)
+{
+  TopTools_IndexedMapOfShape shape_vertices;
+  TopExp::MapShapes(shape, TopAbs_VERTEX, shape_vertices);
+
+  for (Standard_Integer i = 1; i <= shape_vertices.Extent(); i++)
+  {
+    gp_Pnt p = BRep_Tool::Pnt(TopoDS::Vertex(shape_vertices(i)));
+    coords.push_back(p.X());
+    coords.push_back(p.Y());
+    coords.push_back(p.Z());
+  }
+}
+
+static void GetCoords(const Standard_CString& path_to_file, std::vector<Standard_Real>& coords)
+{
+  TopoDS_Shape shape;
+  BRep_Builder builder;
+  BRepTools::Read(shape, path_to_file, builder);
+  TopTools_IndexedMapOfShape shape_faces;
+  TopExp::MapShapes(shape, TopAbs_FACE, shape_faces);
+  TopoDS_Face face_a = TopoDS::Face(shape_faces(1));
+  TopoDS_Face face_b = TopoDS::Face(shape_faces(5));
+  dumpShapeVertices(taper(shape, face_a, face_b, 5.0), coords);
+}
+
+static Standard_Integer OCC26396 (Draw_Interpretor& theDI, Standard_Integer theArgc, const char** theArgv)
+{
+  if (theArgc < 2)
+  {
+    theDI << "Error: path to file is missing\n";
+    return 1;
+  }
+
+  const int maxInd = 50;
+
+  std::vector<Standard_Real> ref_coords;
+  ref_coords.reserve(100);
+  Standard_Boolean Stat = Standard_True;
+
+  GetCoords(theArgv[1], ref_coords);
+
+  std::vector<Standard_Real> coords;
+  coords.reserve(100);
+  for (int i = 1; i < maxInd; i++)
+  {
+    GetCoords(theArgv[1], coords);
+    if (coords.size() != ref_coords.size())
+    {
+      Stat = Standard_False;
+      break;
+    }
+    for (size_t j = 0; j < coords.size(); j++)
+      if (Abs(ref_coords[j] - coords[j]) > RealEpsilon())
+      {
+        Stat = Standard_False;
+        break;
+      }
+    coords.clear();
+  }
+  if (!Stat)
+    theDI << "Error: unstable results";
+  else
+    theDI << "test OK";
+
+  return 0;
+}
+
 //=======================================================================
 //function : OCC26750 
 //purpose  : 
@@ -4609,6 +4700,7 @@ void QABugs::Commands_19(Draw_Interpretor& theCommands) {
                    __FILE__, OCC26462, group);
 
   theCommands.Add ("OCC26313", "OCC26313 result shape", __FILE__, OCC26313, group);
+  theCommands.Add ("OCC26396", "OCC26396 shape_file_path", __FILE__, OCC26396, group);
   theCommands.Add ("OCC26525", "OCC26525 result edge face ", __FILE__, OCC26525, group);
 
   theCommands.Add ("OCC24537", "OCC24537 [file]", __FILE__, OCC24537, group);
diff --git a/tests/bugs/modalg_6/bug26396 b/tests/bugs/modalg_6/bug26396
new file mode 100644 (file)
index 0000000..3604baa
--- /dev/null
@@ -0,0 +1,8 @@
+puts "================"
+puts "OCC26396"
+puts "================"
+puts ""
+
+pload QAcommands
+
+OCC26396 [locate_data_file bug26396_shape.brep]