diff --git a/Geo/GModelFactory.cpp b/Geo/GModelFactory.cpp
index 76915970b710b5db241712e6ef74eb638e2b936a..088a2b87f6fd2369080e207e18ffa07eb63b9f29 100644
--- a/Geo/GModelFactory.cpp
+++ b/Geo/GModelFactory.cpp
@@ -725,7 +725,7 @@ GEntity *OCCFactory::addSphere(GModel *gm, double xc, double yc, double zc, doub
   gm->destroy();
   gm->_occ_internals->buildLists();
   gm->_occ_internals->buildGModel(gm);
-  return getOCCRegionByNativePtr(gm, TopoDS::Solid(shape));
+  return gm->_occ_internals->getOCCRegionByNativePtr(gm, TopoDS::Solid(shape));
 }
 
 GRegion* OCCFactory::addVolume (GModel *gm, std::vector<std::vector<GFace *> > faces)
@@ -763,7 +763,7 @@ GEntity *OCCFactory::addCylinder(GModel *gm, std::vector<double> p1,
   gm->destroy();
   gm->_occ_internals->buildLists();
   gm->_occ_internals->buildGModel(gm);
-  return getOCCRegionByNativePtr(gm, TopoDS::Solid(shape));
+  return gm->_occ_internals->getOCCRegionByNativePtr(gm, TopoDS::Solid(shape));
 }
 
 GEntity *OCCFactory::addTorus(GModel *gm, std::vector<double> p1,
@@ -795,7 +795,7 @@ GEntity *OCCFactory::addTorus(GModel *gm, std::vector<double> p1,
   gm->destroy();
   gm->_occ_internals->buildLists();
   gm->_occ_internals->buildGModel(gm);
-  return getOCCRegionByNativePtr(gm, TopoDS::Solid(shape));
+  return gm->_occ_internals->getOCCRegionByNativePtr(gm, TopoDS::Solid(shape));
 }
 
 GEntity *OCCFactory::addCone(GModel *gm,  std::vector<double> p1,
@@ -828,7 +828,7 @@ GEntity *OCCFactory::addCone(GModel *gm,  std::vector<double> p1,
   gm->destroy();
   gm->_occ_internals->buildLists();
   gm->_occ_internals->buildGModel(gm);
-  return getOCCRegionByNativePtr(gm,TopoDS::Solid(shape));
+  return gm->_occ_internals->getOCCRegionByNativePtr(gm,TopoDS::Solid(shape));
 }
 
 GEntity *OCCFactory::addBlock(GModel *gm, std::vector<double> p1,
@@ -850,7 +850,7 @@ GEntity *OCCFactory::addBlock(GModel *gm, std::vector<double> p1,
   gm->destroy();
   gm->_occ_internals->buildLists();
   gm->_occ_internals->buildGModel(gm);
-  return getOCCRegionByNativePtr(gm, TopoDS::Solid(shape));
+  return gm->_occ_internals->getOCCRegionByNativePtr(gm, TopoDS::Solid(shape));
 }
 
 GModel *OCCFactory::computeBooleanUnion(GModel* obj, GModel* tool,
diff --git a/Geo/GModelIO_OCC.cpp b/Geo/GModelIO_OCC.cpp
index a49e06b69a627d42c998716c850494e7b9e39ce5..7bd203de97f9fc445c4329f395b15b5a03437838 100644
--- a/Geo/GModelIO_OCC.cpp
+++ b/Geo/GModelIO_OCC.cpp
@@ -99,7 +99,7 @@ void OCC_Internals::addShapeToLists(TopoDS_Shape _shape)
       }
     }
   }
-  
+
   // Free Shells
   for(exp1.Init(exp0.Current(), TopAbs_SHELL, TopAbs_SOLID); exp1.More(); exp1.Next()){
     TopoDS_Shape shell = exp1.Current();
@@ -110,7 +110,7 @@ void OCC_Internals::addShapeToLists(TopoDS_Shape _shape)
         TopoDS_Face face = TopoDS::Face(exp2.Current());
         if(fmap.FindIndex(face) < 1){
           fmap.Add(face);
-                  
+
           for(exp3.Init(exp2.Current(), TopAbs_WIRE); exp3.More(); exp3.Next()){
             TopoDS_Wire wire = TopoDS::Wire(exp3.Current());
             if(wmap.FindIndex(wire) < 1){
@@ -134,18 +134,18 @@ void OCC_Internals::addShapeToLists(TopoDS_Shape _shape)
       }
     }
   }
-    
+
   // Free Faces
   for(exp2.Init(_shape, TopAbs_FACE, TopAbs_SHELL); exp2.More(); exp2.Next()){
     TopoDS_Face face = TopoDS::Face(exp2.Current());
     if(fmap.FindIndex(face) < 1){
       fmap.Add(face);
-          
+
       for(exp3.Init(exp2.Current(), TopAbs_WIRE); exp3.More(); exp3.Next()){
         TopoDS_Wire wire = TopoDS::Wire(exp3.Current());
         if(wmap.FindIndex(wire) < 1){
           wmap.Add(wire);
-          
+
           for(exp4.Init(exp3.Current(), TopAbs_EDGE); exp4.More(); exp4.Next()){
             TopoDS_Edge edge = TopoDS::Edge(exp4.Current());
             if(emap.FindIndex(edge) < 1){
@@ -168,7 +168,7 @@ void OCC_Internals::addShapeToLists(TopoDS_Shape _shape)
     TopoDS_Wire wire = TopoDS::Wire(exp3.Current());
     if(wmap.FindIndex(wire) < 1){
       wmap.Add(wire);
-      
+
       for(exp4.Init(exp3.Current(), TopAbs_EDGE); exp4.More(); exp4.Next()){
         TopoDS_Edge edge = TopoDS::Edge(exp4.Current());
         if(emap.FindIndex(edge) < 1){
@@ -203,12 +203,12 @@ void OCC_Internals::addShapeToLists(TopoDS_Shape _shape)
     TopoDS_Vertex vertex = TopoDS::Vertex(exp5.Current());
     if(vmap.FindIndex(vertex) < 1)
       vmap.Add(vertex);
-  }    
-  
+  }
+
 }
 
 void OCC_Internals::healGeometry(double tolerance, bool fixdegenerated,
-                                 bool fixsmalledges, bool fixspotstripfaces, 
+                                 bool fixsmalledges, bool fixspotstripfaces,
                                  bool sewfaces, bool makesolids, bool connect)
 {
   if(!fixdegenerated && !fixsmalledges && !fixspotstripfaces &&
@@ -223,7 +223,7 @@ void OCC_Internals::healGeometry(double tolerance, bool fixdegenerated,
   int nrw = wmap.Extent(), nre = emap.Extent(), nrv = vmap.Extent();
   for (exp0.Init(shape, TopAbs_COMPOUND); exp0.More(); exp0.Next()) nrc++;
   for (exp0.Init(shape, TopAbs_COMPSOLID); exp0.More(); exp0.Next()) nrcs++;
- 
+
   double surfacecont = 0;
   for (exp0.Init(shape, TopAbs_FACE); exp0.More(); exp0.Next()){
     TopoDS_Face face = TopoDS::Face(exp0.Current());
@@ -251,7 +251,7 @@ void OCC_Internals::healGeometry(double tolerance, bool fixdegenerated,
       Handle(ShapeFix_Face) sff;
       Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape;
       rebuild->Apply(shape);
-      
+
       for (exp0.Init (shape, TopAbs_FACE); exp0.More(); exp0.Next()){
         TopoDS_Face face = TopoDS::Face(exp0.Current());
 
@@ -259,7 +259,7 @@ void OCC_Internals::healGeometry(double tolerance, bool fixdegenerated,
         sff->FixAddNaturalBoundMode() = Standard_True;
         sff->FixSmallAreaWireMode() = Standard_True;
         sff->Perform();
-        
+
         if(sff->Status(ShapeExtend_DONE1) ||
            sff->Status(ShapeExtend_DONE2) ||
            sff->Status(ShapeExtend_DONE3) ||
@@ -278,13 +278,13 @@ void OCC_Internals::healGeometry(double tolerance, bool fixdegenerated,
             else if(sff->Status(ShapeExtend_DONE5))
               Msg::Info("  (natural bounds added)");
             TopoDS_Face newface = sff->Face();
-            
+
             rebuild->Replace(face, newface, Standard_False);
           }
       }
       shape = rebuild->Apply(shape);
     }
-    
+
     {
       Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape;
       rebuild->Apply(shape);
@@ -296,29 +296,29 @@ void OCC_Internals::healGeometry(double tolerance, bool fixdegenerated,
       shape = rebuild->Apply(shape);
     }
   }
-  
+
   if (fixsmalledges){
     Msg::Info("- fixing small edges");
-    
+
     Handle(ShapeFix_Wire) sfw;
     Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape;
     rebuild->Apply(shape);
-    
+
     for (exp0.Init (shape, TopAbs_FACE); exp0.More(); exp0.Next()){
       TopoDS_Face face = TopoDS::Face(exp0.Current());
-      
+
       for (exp1.Init (face, TopAbs_WIRE); exp1.More(); exp1.Next()){
         TopoDS_Wire oldwire = TopoDS::Wire(exp1.Current());
         sfw = new ShapeFix_Wire (oldwire, face ,tolerance);
         sfw->ModifyTopologyMode() = Standard_True;
-        
+
         sfw->ClosedWireMode() = Standard_True;
-        
+
         bool replace = false;
         replace = sfw->FixReorder() || replace;
         replace = sfw->FixConnected() || replace;
-        
-        if (sfw->FixSmall(Standard_False, tolerance) && 
+
+        if (sfw->FixSmall(Standard_False, tolerance) &&
             ! (sfw->StatusSmall(ShapeExtend_FAIL1) ||
                sfw->StatusSmall(ShapeExtend_FAIL2) ||
                sfw->StatusSmall(ShapeExtend_FAIL3))){
@@ -336,7 +336,7 @@ void OCC_Internals::healGeometry(double tolerance, bool fixdegenerated,
         else if (sfw->StatusSmall(ShapeExtend_FAIL3))
           Msg::Warning("Failed to fix small edge in wire, CheckConnected has failed",
                        wmap.FindIndex(oldwire));
-        
+
         replace = sfw->FixEdgeCurves() || replace;
         replace = sfw->FixDegenerated() || replace;
         replace = sfw->FixSelfIntersection() || replace;
@@ -347,18 +347,18 @@ void OCC_Internals::healGeometry(double tolerance, bool fixdegenerated,
         }
       }
     }
-    
+
     shape = rebuild->Apply(shape);
-    
+
     {
       buildLists();
       Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape;
       rebuild->Apply(shape);
-      
+
       for (exp1.Init (shape, TopAbs_EDGE); exp1.More(); exp1.Next()){
         TopoDS_Edge edge = TopoDS::Edge(exp1.Current());
-        if (vmap.FindIndex(TopExp::FirstVertex (edge)) ==
-            vmap.FindIndex(TopExp::LastVertex (edge))){
+        if (vmap.FindIndex(TopExp::FirstVertex(edge)) ==
+            vmap.FindIndex(TopExp::LastVertex(edge))){
           GProp_GProps system;
           BRepGProp::LinearProperties(edge, system);
           if (system.Mass() < tolerance){
@@ -371,7 +371,7 @@ void OCC_Internals::healGeometry(double tolerance, bool fixdegenerated,
       }
       shape = rebuild->Apply(shape);
     }
-    
+
     {
       Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape;
       rebuild->Apply(shape);
@@ -382,38 +382,38 @@ void OCC_Internals::healGeometry(double tolerance, bool fixdegenerated,
       }
       shape = rebuild->Apply(shape);
     }
-    
+
     Handle(ShapeFix_Wireframe) sfwf = new ShapeFix_Wireframe;
     sfwf->SetPrecision(tolerance);
     sfwf->Load (shape);
     sfwf->ModeDropSmallEdges() = Standard_True;
-    
+
     if (sfwf->FixWireGaps()){
       Msg::Info("- fixing wire gaps");
-      if (sfwf->StatusWireGaps(ShapeExtend_OK)) 
+      if (sfwf->StatusWireGaps(ShapeExtend_OK))
         Msg::Info("  no gaps found");
       if (sfwf->StatusWireGaps(ShapeExtend_DONE1))
         Msg::Info("  some 2D gaps fixed");
-      if (sfwf->StatusWireGaps(ShapeExtend_DONE2)) 
+      if (sfwf->StatusWireGaps(ShapeExtend_DONE2))
         Msg::Info("  some 3D gaps fixed");
-      if (sfwf->StatusWireGaps(ShapeExtend_FAIL1)) 
+      if (sfwf->StatusWireGaps(ShapeExtend_FAIL1))
         Msg::Info("  failed to fix some 2D gaps");
       if (sfwf->StatusWireGaps(ShapeExtend_FAIL2))
         Msg::Info("  failed to fix some 3D gaps");
     }
-    
+
     sfwf->SetPrecision(tolerance);
-    
+
     if (sfwf->FixSmallEdges()){
       Msg::Info("- fixing wire frames");
-      if (sfwf->StatusSmallEdges(ShapeExtend_OK)) 
+      if (sfwf->StatusSmallEdges(ShapeExtend_OK))
         Msg::Info("  no small edges found");
       if (sfwf->StatusSmallEdges(ShapeExtend_DONE1))
         Msg::Info("  some small edges fixed");
-      if (sfwf->StatusSmallEdges(ShapeExtend_FAIL1)) 
+      if (sfwf->StatusSmallEdges(ShapeExtend_FAIL1))
         Msg::Info("  failed to fix some small edges");
     }
-    
+
     shape = sfwf->Shape();
   }
 
@@ -423,28 +423,28 @@ void OCC_Internals::healGeometry(double tolerance, bool fixdegenerated,
     sffsm -> Init (shape);
     sffsm -> SetPrecision (tolerance);
     sffsm -> Perform();
-    
+
     shape = sffsm -> FixShape();
   }
 
   if (sewfaces){
     Msg::Info("- sewing faces");
-    
+
     BRepOffsetAPI_Sewing sewedObj(tolerance);
-    
+
     for (exp0.Init (shape, TopAbs_FACE); exp0.More(); exp0.Next()){
       TopoDS_Face face = TopoDS::Face (exp0.Current());
       sewedObj.Add (face);
     }
-    
+
     sewedObj.Perform();
-    
+
     if (!sewedObj.SewedShape().IsNull())
       shape = sewedObj.SewedShape();
     else
       Msg::Info("  not possible");
   }
-  
+
   {
     Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape;
     rebuild->Apply(shape);
@@ -455,17 +455,17 @@ void OCC_Internals::healGeometry(double tolerance, bool fixdegenerated,
     }
     shape = rebuild->Apply(shape);
   }
-  
+
   if (makesolids){
     Msg::Info("- making solids");
-    
+
     BRepBuilderAPI_MakeSolid ms;
     int count = 0;
     for (exp0.Init(shape, TopAbs_SHELL); exp0.More(); exp0.Next()){
       count++;
       ms.Add (TopoDS::Shell(exp0.Current()));
     }
-    
+
     if (!count){
       Msg::Info("  not possible (no shells)");
     }
@@ -478,7 +478,7 @@ void OCC_Internals::healGeometry(double tolerance, bool fixdegenerated,
         sfs->SetMaxTolerance(tolerance);
         sfs->Perform();
         shape = sfs->Shape();
-        
+
         for (exp0.Init(shape, TopAbs_SOLID); exp0.More(); exp0.Next()){
           TopoDS_Solid solid = TopoDS::Solid(exp0.Current());
           TopoDS_Solid newsolid = solid;
@@ -519,7 +519,7 @@ void OCC_Internals::healGeometry(double tolerance, bool fixdegenerated,
     shape = connect;
 #endif
   }
-  
+
   double newsurfacecont = 0;
   for (exp0.Init (shape, TopAbs_FACE); exp0.More(); exp0.Next()){
     TopoDS_Face face = TopoDS::Face(exp0.Current());
@@ -534,7 +534,7 @@ void OCC_Internals::healGeometry(double tolerance, bool fixdegenerated,
   int nnrw = wmap.Extent(), nnre = emap.Extent(), nnrv = vmap.Extent();
   for (exp0.Init(shape, TopAbs_COMPOUND); exp0.More(); exp0.Next()) nnrc++;
   for (exp0.Init(shape, TopAbs_COMPSOLID); exp0.More(); exp0.Next()) nnrcs++;
-  
+
   Msg::Info("-----------------------------------");
   Msg::Info("Compounds          : %d (%d)", nnrc, nrc);
   Msg::Info("Composite solids   : %d (%d)", nnrcs, nrcs);
@@ -553,7 +553,7 @@ void OCC_Internals::loadBREP(const char *fn)
   BRep_Builder aBuilder;
   BRepTools::Read(shape, (char*)fn, aBuilder);
   BRepTools::Clean(shape);
-  healGeometry(CTX::instance()->geom.tolerance, 
+  healGeometry(CTX::instance()->geom.tolerance,
                CTX::instance()->geom.occFixDegenerated,
                CTX::instance()->geom.occFixSmallEdges,
                CTX::instance()->geom.occFixSmallFaces,
@@ -582,10 +582,10 @@ void OCC_Internals::loadSTEP(const char *fn)
   STEPControl_Reader reader;
   reader.ReadFile((char*)fn);
   reader.NbRootsForTransfer();
-  reader.TransferRoots(); 
-  shape = reader.OneShape();  
+  reader.TransferRoots();
+  shape = reader.OneShape();
   BRepTools::Clean(shape);
-  healGeometry(CTX::instance()->geom.tolerance, 
+  healGeometry(CTX::instance()->geom.tolerance,
                CTX::instance()->geom.occFixDegenerated,
                CTX::instance()->geom.occFixSmallEdges,
                CTX::instance()->geom.occFixSmallFaces,
@@ -600,7 +600,7 @@ void OCC_Internals::writeSTEP(const char *fn)
 {
   STEPControl_Writer writer;
   IFSelect_ReturnStatus status = writer.Transfer(shape, STEPControl_ManifoldSolidBrep);
-  if (status == IFSelect_RetDone) 
+  if (status == IFSelect_RetDone)
     status = writer.Write((char*)fn);
 }
 
@@ -609,10 +609,10 @@ void OCC_Internals::loadIGES(const char *fn)
   IGESControl_Reader reader;
   reader.ReadFile((char*)fn);
   reader.NbRootsForTransfer();
-  reader.TransferRoots(); 
-  shape = reader.OneShape();  
+  reader.TransferRoots();
+  shape = reader.OneShape();
   BRepTools::Clean(shape);
-  healGeometry(CTX::instance()->geom.tolerance, 
+  healGeometry(CTX::instance()->geom.tolerance,
                CTX::instance()->geom.occFixDegenerated,
                CTX::instance()->geom.occFixSmallEdges,
                CTX::instance()->geom.occFixSmallFaces,
@@ -630,6 +630,34 @@ void OCC_Internals::loadShape(const TopoDS_Shape *s)
   buildLists();
 }
 
+GVertex *OCC_Internals::getOCCVertexByNativePtr(GModel *model, TopoDS_Vertex toFind)
+{
+  if(gvNumCache.IsBound(toFind))
+    return model->getVertexByTag(gvNumCache.Find(toFind));
+  return 0;
+}
+
+GEdge *OCC_Internals::getOCCEdgeByNativePtr(GModel *model, TopoDS_Edge toFind)
+{
+  if(geNumCache.IsBound(toFind))
+    return model->getEdgeByTag(geNumCache.Find(toFind));
+  return 0;
+}
+
+GFace *OCC_Internals::getOCCFaceByNativePtr(GModel *model, TopoDS_Face toFind)
+{
+  if(gfNumCache.IsBound(toFind))
+    return model->getFaceByTag(gfNumCache.Find(toFind));
+  return 0;
+}
+
+GRegion *OCC_Internals::getOCCRegionByNativePtr(GModel *model, TopoDS_Solid toFind)
+{
+  if(grNumCache.IsBound(toFind))
+    return model->getRegionByTag(grNumCache.Find(toFind));
+  return 0;
+}
+
 GVertex *OCC_Internals::addVertexToModel(GModel *model, TopoDS_Vertex vertex)
 {
   GVertex *gv = getOCCVertexByNativePtr(model, vertex);
@@ -637,7 +665,7 @@ GVertex *OCC_Internals::addVertexToModel(GModel *model, TopoDS_Vertex vertex)
   addShapeToLists(vertex);
   buildShapeFromLists(vertex);
   buildGModel(model);
-  return getOCCVertexByNativePtr (model,vertex);
+  return getOCCVertexByNativePtr(model, vertex);
 }
 
 GEdge *OCC_Internals::addEdgeToModel(GModel *model, TopoDS_Edge edge)
@@ -647,65 +675,70 @@ GEdge *OCC_Internals::addEdgeToModel(GModel *model, TopoDS_Edge edge)
   addShapeToLists(edge);
   buildShapeFromLists(edge);
   buildGModel(model);
-  return getOCCEdgeByNativePtr(model,edge);
+  return getOCCEdgeByNativePtr(model, edge);
 }
 
 GFace* OCC_Internals::addFaceToModel(GModel *model, TopoDS_Face face)
 {
-  GFace *gf = getOCCFaceByNativePtr(model,face);
+  GFace *gf = getOCCFaceByNativePtr(model, face);
   if (gf) return gf;
   addShapeToLists(face);
   buildShapeFromLists(face);
   buildGModel(model);
-  return getOCCFaceByNativePtr(model,face);
+  return getOCCFaceByNativePtr(model, face);
 }
 
 GRegion* OCC_Internals::addRegionToModel(GModel *model, TopoDS_Solid region)
 {
-  GRegion *gr  = getOCCRegionByNativePtr(model,region);
+  GRegion *gr  = getOCCRegionByNativePtr(model, region);
   if (gr) return gr;
   addShapeToLists(region);
   buildShapeFromLists(region);
   buildGModel(model);
-  return getOCCRegionByNativePtr(model,region);
+  return getOCCRegionByNativePtr(model, region);
 }
 
 void OCC_Internals::buildGModel(GModel *model)
 {
   // building geom vertices
-  int nvertices = vmap.Extent();
-  for(int i = 1; i <= nvertices; i++){
-    int num = model->getMaxElementaryNumber(0) + 1;
-    if (!getOCCVertexByNativePtr(model, TopoDS::Vertex(vmap(i))))
-      model->add(new OCCVertex(model, num, TopoDS::Vertex(vmap(i))));
+  int numv = model->getMaxElementaryNumber(0) + 1;
+  for(int i = 1; i <= vmap.Extent(); i++){
+    TopoDS_Vertex vertex = TopoDS::Vertex(vmap(i));
+    if (!getOCCVertexByNativePtr(model, vertex)){
+      model->add(new OCCVertex(model, numv, vertex));
+      numv++;
+    }
   }
 
   // building geom edges
-  int nedges = emap.Extent();
-  for(int i = 1; i <= nedges; i++){
-    int i1 = vmap.FindIndex(TopExp::FirstVertex(TopoDS::Edge(emap(i)))); 
+  int nume = model->getMaxElementaryNumber(1) + 1;
+  for(int i = 1; i <= emap.Extent(); i++){
+    int i1 = vmap.FindIndex(TopExp::FirstVertex(TopoDS::Edge(emap(i))));
     int i2 = vmap.FindIndex(TopExp::LastVertex(TopoDS::Edge(emap(i))));
-    int num = model->getMaxElementaryNumber(1) + 1;
     if (!getOCCEdgeByNativePtr(model, TopoDS::Edge(emap(i)))){
       GVertex *v1 = getOCCVertexByNativePtr(model, TopoDS::Vertex(vmap(i1)));
       GVertex *v2 = getOCCVertexByNativePtr(model, TopoDS::Vertex(vmap(i2)));
-      model->add(new OCCEdge(model, TopoDS::Edge(emap(i)), num, v1, v2));
+      model->add(new OCCEdge(model, TopoDS::Edge(emap(i)), nume, v1, v2));
+      nume++;
     }
   }
 
   // building geom faces
-  int nfaces = fmap.Extent();
-  for(int i = 1; i <= nfaces; i++){
-    int num = model->getMaxElementaryNumber(2) + 1;
-    if (!getOCCFaceByNativePtr(model, TopoDS::Face(fmap(i))))
-      model->add(new OCCFace(model, TopoDS::Face(fmap(i)), num));
+  int numf = model->getMaxElementaryNumber(2) + 1;
+  for(int i = 1; i <= fmap.Extent(); i++){
+    if (!getOCCFaceByNativePtr(model, TopoDS::Face(fmap(i)))){
+      model->add(new OCCFace(model, TopoDS::Face(fmap(i)), numf));
+      numf++;
+    }
   }
+
   // building geom regions
-  int nvolumes = somap.Extent();
-  for(int i = 1; i <= nvolumes; i++){
-    int num = model->getMaxElementaryNumber(3) + 1;
-    if (!getOCCRegionByNativePtr(model, TopoDS::Solid(somap(i))))
-      model->add(new OCCRegion(model, TopoDS::Solid(somap(i)), num));
+  int numr = model->getMaxElementaryNumber(3) + 1;
+  for(int i = 1; i <= somap.Extent(); i++){
+    if (!getOCCRegionByNativePtr(model, TopoDS::Solid(somap(i)))){
+      model->add(new OCCRegion(model, TopoDS::Solid(somap(i)), numr));
+      numr++;
+    }
   }
 }
 
@@ -718,7 +751,7 @@ void addSimpleShapes(TopoDS_Shape theShape, TopTools_ListOfShape &theList)
   }
 
   TopTools_MapOfShape mapShape;
-  TopoDS_Iterator It (theShape, Standard_True, Standard_True);
+  TopoDS_Iterator It(theShape, Standard_True, Standard_True);
 
   for (; It.More(); It.Next()) {
     TopoDS_Shape aShape_i = It.Value();
@@ -726,7 +759,7 @@ void addSimpleShapes(TopoDS_Shape theShape, TopTools_ListOfShape &theList)
       if (aShape_i.ShapeType() == TopAbs_COMPOUND ||
           aShape_i.ShapeType() == TopAbs_COMPSOLID) {
         addSimpleShapes(aShape_i, theList);
-      } 
+      }
       else {
         theList.Append(aShape_i);
       }
@@ -742,7 +775,7 @@ void OCC_Internals::applyBooleanOperator(TopoDS_Shape tool, const BooleanOperato
     switch(op){
     case OCC_Internals::Intersection :
       {
-        TopoDS_Shape theNewShape;       
+        TopoDS_Shape theNewShape;
         BRep_Builder B;
         TopoDS_Compound C;
         B.MakeCompound(C);
@@ -751,7 +784,7 @@ void OCC_Internals::applyBooleanOperator(TopoDS_Shape tool, const BooleanOperato
         addSimpleShapes(tool, listShape2);
         Standard_Boolean isCompound =
           (listShape1.Extent() > 1 || listShape2.Extent() > 1);
-        
+
         TopTools_ListIteratorOfListOfShape itSub1 (listShape1);
         for (; itSub1.More(); itSub1.Next()) {
           TopoDS_Shape aValue1 = itSub1.Value();
@@ -781,33 +814,33 @@ void OCC_Internals::applyBooleanOperator(TopoDS_Shape tool, const BooleanOperato
         if (isCompound) {
           TopTools_ListOfShape listShapeC;
           addSimpleShapes(C, listShapeC);
-          TopTools_ListIteratorOfListOfShape itSubC (listShapeC);
+          TopTools_ListIteratorOfListOfShape itSubC(listShapeC);
           bool isOnlySolids = true;
           for (; itSubC.More(); itSubC.Next()) {
             TopoDS_Shape aValueC = itSubC.Value();
             if (aValueC.ShapeType() != TopAbs_SOLID) isOnlySolids = false;
           }
-	  //          if (isOnlySolids)
-	  //            theNewShape = GlueFaces(C, Precision::Confusion());
-	  //          else
-            theNewShape = C;
+	  // if (isOnlySolids)
+	  //   theNewShape = GlueFaces(C, Precision::Confusion());
+	  // else
+               theNewShape = C;
         }
         shape = theNewShape;
       }
       break;
     case OCC_Internals::Cut :
       {
-        TopoDS_Shape theNewShape;       
+        TopoDS_Shape theNewShape;
         BRep_Builder B;
         TopoDS_Compound C;
         B.MakeCompound(C);
-        
+
         TopTools_ListOfShape listShapes, listTools;
         addSimpleShapes(shape, listShapes);
         addSimpleShapes(tool, listTools);
-        
+
         Standard_Boolean isCompound = (listShapes.Extent() > 1);
-        
+
         TopTools_ListIteratorOfListOfShape itSub1 (listShapes);
         for (; itSub1.More(); itSub1.Next()) {
           TopoDS_Shape aCut = itSub1.Value();
@@ -836,7 +869,7 @@ void OCC_Internals::applyBooleanOperator(TopoDS_Shape tool, const BooleanOperato
           else
             theNewShape = aCut;
         }
-        
+
         if (isCompound) {
           TopTools_ListOfShape listShapeC;
           addSimpleShapes(C, listShapeC);
@@ -846,13 +879,13 @@ void OCC_Internals::applyBooleanOperator(TopoDS_Shape tool, const BooleanOperato
             TopoDS_Shape aValueC = itSubC.Value();
             if (aValueC.ShapeType() != TopAbs_SOLID) isOnlySolids = false;
           }
-	  //          if (isOnlySolids)
-	  //            theNewShape = GlueFaces(C, Precision::Confusion());
-	  //          else
-	  theNewShape = C;
+	  // if (isOnlySolids)
+	  //   theNewShape = GlueFaces(C, Precision::Confusion());
+	  // else
+	       theNewShape = C;
         }
         shape = theNewShape;
-      }      
+      }
       break;
     case OCC_Internals::Fuse :
       {
@@ -873,7 +906,7 @@ void OCC_Internals::applyBooleanOperator(TopoDS_Shape tool, const BooleanOperato
         TopTools_ListOfShape listShapes, listTools;
         addSimpleShapes(shape, listShapes);
         addSimpleShapes(tool, listTools);
-        
+
         Standard_Boolean isCompound = (listShapes.Extent() > 1);
         TopTools_ListIteratorOfListOfShape itSub1 (listShapes);
         for (; itSub1.More(); itSub1.Next()) {
@@ -903,7 +936,7 @@ void OCC_Internals::applyBooleanOperator(TopoDS_Shape tool, const BooleanOperato
           else
             theNewShape = BO.Shape();
           }
-        }       
+        }
         if (isCompound)
           theNewShape = C;
         shape = theNewShape;
@@ -915,7 +948,7 @@ void OCC_Internals::applyBooleanOperator(TopoDS_Shape tool, const BooleanOperato
     }
   }
 }
-  
+
 void OCC_Internals::fillet(std::vector<TopoDS_Edge> &edgesToFillet,
                            double Radius)
 {
diff --git a/Geo/GModelIO_OCC.h b/Geo/GModelIO_OCC.h
index 5ca1844bc730f902214f415ecdf2e040a3340dce..27f6f1636a3e2d858bdce0fc45b65b70a65113be 100644
--- a/Geo/GModelIO_OCC.h
+++ b/Geo/GModelIO_OCC.h
@@ -16,33 +16,40 @@
 class OCC_Internals {
  protected :
   TopoDS_Shape shape;
+  // all TopoDS_Shapes in the OCC model
   TopTools_IndexedMapOfShape fmap, emap, vmap, somap, shmap, wmap;
+  // cache mapping TopoDS_Shapes to their corresponding GEntity tags
+  TopTools_DataMapOfShapeInteger gvNumCache, geNumCache, gfNumCache, grNumCache;
  public:
-  enum BooleanOperator { Intersection, Cut, Section, Fuse }; 
-  OCC_Internals()
-  {
-    somap.Clear();
-    shmap.Clear();
-    fmap.Clear();
-    wmap.Clear();
-    emap.Clear();
-    vmap.Clear();
-  }
+  enum BooleanOperator { Intersection, Cut, Section, Fuse };
+  OCC_Internals(){}
   TopoDS_Shape getShape () { return shape; }
   void buildLists();
   void buildShapeFromLists(TopoDS_Shape _shape);
   void addShapeToLists(TopoDS_Shape shape);
   void healGeometry(double tolerance, bool fixdegenerated,
                     bool fixsmalledges, bool fixspotstripfaces,
-                    bool sewfaces, bool makesolids=false, 
+                    bool sewfaces, bool makesolids=false,
                     bool connect=false);
-  void loadBREP(const char *);  
-  void writeBREP(const char *);  
+  void loadBREP(const char *);
+  void writeBREP(const char *);
   void loadSTEP(const char *);
-  void writeSTEP(const char *);  
+  void writeSTEP(const char *);
   void loadIGES(const char *);
   void loadShape(const TopoDS_Shape *);
   void buildGModel(GModel *gm);
+  void bind(TopoDS_Vertex vertex, int num){ gvNumCache.Bind(vertex, num); }
+  void bind(TopoDS_Edge edge, int num){ geNumCache.Bind(edge, num); }
+  void bind(TopoDS_Face face, int num){ gfNumCache.Bind(face, num); }
+  void bind(TopoDS_Solid solid, int num){ grNumCache.Bind(solid, num); }
+  void unbind(TopoDS_Vertex vertex){ gvNumCache.UnBind(vertex); }
+  void unbind(TopoDS_Edge edge){ geNumCache.UnBind(edge); }
+  void unbind(TopoDS_Face face){ gfNumCache.UnBind(face); }
+  void unbind(TopoDS_Solid solid){ grNumCache.UnBind(solid); }
+  GVertex *getOCCVertexByNativePtr(GModel *model, TopoDS_Vertex toFind);
+  GEdge *getOCCEdgeByNativePtr(GModel *model, TopoDS_Edge toFind);
+  GFace *getOCCFaceByNativePtr(GModel *model, TopoDS_Face toFind);
+  GRegion *getOCCRegionByNativePtr(GModel *model, TopoDS_Solid toFind);
   GVertex *addVertexToModel(GModel *model, TopoDS_Vertex v);
   GEdge *addEdgeToModel(GModel *model, TopoDS_Edge e);
   GFace *addFaceToModel(GModel *model, TopoDS_Face f);
diff --git a/Geo/OCCEdge.cpp b/Geo/OCCEdge.cpp
index 0fbc440d6e838ce92ac8866b4fa468ecd1d95c20..43759e3e8237a02532c31183c4c0ac16cc8f0657 100644
--- a/Geo/OCCEdge.cpp
+++ b/Geo/OCCEdge.cpp
@@ -12,6 +12,7 @@
 #include "Context.h"
 
 #if defined(HAVE_OCC)
+#include "GModelIO_OCC.h"
 #include <Geom2dLProp_CLProps2d.hxx>
 #include <Geom_BezierCurve.hxx>
 #include <Geom_OffsetCurve.hxx>
@@ -24,34 +25,23 @@
 #include <Geom_Conic.hxx>
 #include <BOPTools_Tools.hxx>
 
-GEdge *getOCCEdgeByNativePtr(GModel *model, TopoDS_Edge toFind)
-{
-  GModel::eiter it = model->firstEdge();
-  for (; it != model->lastEdge(); it++){
-    OCCEdge *ed = dynamic_cast<OCCEdge*>(*it);
-    if (ed){
-      if (toFind.IsSame(ed->getTopoDS_Edge())){
-	return *it;
-      }
-      if (toFind.IsSame(ed->getTopoDS_EdgeOld())){
-	return *it;
-      }
-    }
-  }
-  return 0;
-}
-
-OCCEdge::OCCEdge(GModel *model, TopoDS_Edge edge, int num, GVertex *v1, GVertex *v2)
-  : GEdge(model, num, v1, v2), c(edge), trimmed(0)
+OCCEdge::OCCEdge(GModel *m, TopoDS_Edge edge, int num, GVertex *v1, GVertex *v2)
+  : GEdge(m, num, v1, v2), c(edge), trimmed(0)
 {
   curve = BRep_Tool::Curve(c, s0, s1);
   // build the reverse curve
   c_rev = c;
   c_rev.Reverse();
+  model()->getOCCInternals()->bind(c, num);
+}
+
+OCCEdge::~OCCEdge()
+{
+  model()->getOCCInternals()->unbind(c);
 }
 
 Range<double> OCCEdge::parBounds(int i) const
-{ 
+{
   return Range<double>(s0, s1);
 }
 
@@ -84,7 +74,7 @@ SPoint2 OCCEdge::reparamOnFace(const GFace *face, double epar, int dir) const
     else{
       c2d = BRep_Tool::CurveOnSurface(c_rev, *s, t0, t1);
     }
-  
+
     if(c2d.IsNull()){
       Msg::Fatal("Reparam on face failed: curve %d is not on surface %d",
 		 tag(), face->tag());
@@ -116,12 +106,12 @@ GPoint OCCEdge::closestPoint(const SPoint3 &qp, double &param) const
 {
   gp_Pnt pnt(qp.x(), qp.y(), qp.z());
   GeomAPI_ProjectPointOnCurve proj(pnt, curve, s0, s1);
-  
+
   if(!proj.NbPoints()){
     Msg::Error("OCC Project Point on Curve FAIL");
     return GPoint(0, 0);
   }
-  
+
   param = proj.LowerDistanceParameter();
 
   if(param < s0 || param > s1){
@@ -167,7 +157,7 @@ GPoint OCCEdge::point(double par) const
 }
 
 SVector3 OCCEdge::firstDer(double par) const
-{  
+{
   BRepAdaptor_Curve brepc(c);
   BRepLProp_CLProps prop(brepc, 1, 1e-5);
   prop.SetParameter(par);
@@ -230,9 +220,9 @@ int OCCEdge::minimumMeshSegments() const
   int np;
   if(geomType() == Line)
     np = GEdge::minimumMeshSegments();
-  else 
+  else
     np = CTX::instance()->mesh.minCurvPoints - 1;
-  
+
   // if the edge is closed, ensure that at least 3 points are
   // generated in the 1D mesh (4 segments, one of which is
   // degenerated)
@@ -249,7 +239,7 @@ int OCCEdge::minimumDrawSegments() const
     return CTX::instance()->geom.numSubEdges * GEdge::minimumDrawSegments();
 }
 
-double OCCEdge::curvature(double par) const 
+double OCCEdge::curvature(double par) const
 {
   const double eps = 1.e-15;
 
@@ -265,7 +255,7 @@ double OCCEdge::curvature(double par) const
   else{
     BRepAdaptor_Curve brepc(c);
     BRepLProp_CLProps prop(brepc, 2, eps);
-    prop.SetParameter(par); 
+    prop.SetParameter(par);
     if(!prop.IsTangentDefined())
       Crv = eps;
     else
@@ -288,9 +278,9 @@ void OCCEdge::writeGEO(FILE *fp)
     // GEO supports only circle arcs < Pi
     if(s1 - s0 < M_PI){
       fprintf(fp, "p%d = newp;\n", tag());
-      fprintf(fp, "Point(p%d + 1) = {%.16g, %.16g, %.16g};\n", 
+      fprintf(fp, "Point(p%d + 1) = {%.16g, %.16g, %.16g};\n",
               tag(), center.X(), center.Y(), center.Z());
-      fprintf(fp, "Circle(%d) = {%d, p%d + 1, %d};\n", 
+      fprintf(fp, "Circle(%d) = {%d, p%d + 1, %d};\n",
               tag(), getBeginVertex()->tag(), tag(), getEndVertex()->tag());
     }
     else
@@ -311,7 +301,7 @@ void OCCEdge::replaceEndingPointsInternals(GVertex *g0, GVertex *g1)
 
   //  printf("%p %p --- %p %p replacing %d %d by %d %d in occedge %d\n",
   //	 v0,v1,g0,g1,v0->tag(),v1->tag(),g0->tag(),g1->tag(),tag());
-  
+
   Standard_Boolean bIsDE = BRep_Tool::Degenerated(c);
 
   TopoDS_Edge aEx = c;
@@ -340,7 +330,7 @@ void OCCEdge::replaceEndingPointsInternals(GVertex *g0, GVertex *g1)
     _replacement=E;
   }
   else {
-    BOPTools_Tools::MakeSplitEdge(aEx, aVR1, t1, aVR2, t2, _replacement); 
+    BOPTools_Tools::MakeSplitEdge(aEx, aVR1, t1, aVR2, t2, _replacement);
   }
   TopoDS_Edge temp = c;
   c = _replacement;
diff --git a/Geo/OCCEdge.h b/Geo/OCCEdge.h
index 5a09a8a7d30f7f8859114953f746692cfac5d274..99efe6eefd6c2c2fa9ede0e938bdf689f8aa3283 100644
--- a/Geo/OCCEdge.h
+++ b/Geo/OCCEdge.h
@@ -27,7 +27,7 @@ class OCCEdge : public GEdge {
   mutable GFace *trimmed;
  public:
   OCCEdge(GModel *model, TopoDS_Edge _e, int num, GVertex *v1, GVertex *v2);
-  virtual ~OCCEdge() {}
+  virtual ~OCCEdge();
   virtual Range<double> parBounds(int i) const;
   virtual GeomType geomType() const;
   virtual bool degenerate(int) const { return BRep_Tool::Degenerated(c); }
@@ -49,8 +49,6 @@ class OCCEdge : public GEdge {
   void replaceEndingPointsInternals(GVertex *, GVertex *);
 };
 
-GEdge *getOCCEdgeByNativePtr(GModel *model, TopoDS_Edge toFind);
-
 #endif
 
 #endif
diff --git a/Geo/OCCFace.cpp b/Geo/OCCFace.cpp
index fc590117002a5f70cea44d609f789b252b504958..a6dc23b0f542fe84cd28c9ec84d8b31279377ec8 100644
--- a/Geo/OCCFace.cpp
+++ b/Geo/OCCFace.cpp
@@ -14,6 +14,7 @@
 #include "Context.h"
 
 #if defined(HAVE_OCC)
+#include "GModelIO_OCC.h"
 #include <Standard_Version.hxx>
 #include <Geom_CylindricalSurface.hxx>
 #include <Geom_ConicalSurface.hxx>
@@ -33,6 +34,13 @@ OCCFace::OCCFace(GModel *m, TopoDS_Face _s, int num)
   : GFace(m, num), s(_s)
 {
   setup();
+  model()->getOCCInternals()->bind(s, num);
+}
+
+OCCFace::~OCCFace()
+{
+  model()->getOCCInternals()->unbind(s);
+  model()->getOCCInternals()->unbind(_replaced);
 }
 
 void OCCFace::setup()
@@ -47,7 +55,7 @@ void OCCFace::setup()
     std::list<GEdge*> l_wire;
     for(exp3.Init(wire, TopAbs_EDGE); exp3.More(); exp3.Next()){
       TopoDS_Edge edge = TopoDS::Edge(exp3.Current());
-      GEdge *e = getOCCEdgeByNativePtr(model(), edge);
+      GEdge *e = model()->getOCCInternals()->getOCCEdgeByNativePtr(model(), edge);
       if(!e){
 	Msg::Error("Unknown edge in face %d", tag());
       }
@@ -409,19 +417,6 @@ bool OCCFace::buildSTLTriangulation(bool force)
   return true;
 }
 
-GFace *getOCCFaceByNativePtr(GModel *model, TopoDS_Face toFind)
-{
-  GModel::fiter it =model->firstFace();
-  for (; it !=model->lastFace(); ++it){
-    OCCFace *gf = dynamic_cast<OCCFace*>(*it);
-    if (gf){
-      if(toFind.IsSame(gf->getTopoDS_Face())) return *it;
-      if(toFind.IsSame(gf->getTopoDS_FaceOld())) return *it;
-    }
-  }
-  return 0;
-}
-
 void OCCFace::replaceEdgesInternal(std::list<GEdge*> &new_edges)
 {
 #if defined(OCC_VERSION_HEX) && OCC_VERSION_HEX >= 0x060503
@@ -520,6 +515,7 @@ void OCCFace::replaceEdgesInternal(std::list<GEdge*> &new_edges)
   s = newFace;
 
   setup();
+  model()->getOCCInternals()->bind(_replaced, tag());
 }
 
 bool OCCFace::isSphere (double &radius, SPoint3 &center) const
diff --git a/Geo/OCCFace.h b/Geo/OCCFace.h
index f80acb28743977294630784fe50b4437f357f1ef..0628159b1978cb01c21650384a803183c6d0f198 100644
--- a/Geo/OCCFace.h
+++ b/Geo/OCCFace.h
@@ -30,16 +30,16 @@ class OCCFace : public GFace {
   SPoint3 _center;
  public:
   OCCFace(GModel *m, TopoDS_Face s, int num);
-  virtual ~OCCFace(){}
-  Range<double> parBounds(int i) const; 
-  virtual GPoint point(double par1, double par2) const; 
-  virtual GPoint closestPoint(const SPoint3 & queryPoint, 
-                              const double initialGuess[2]) const; 
-  virtual bool containsPoint(const SPoint3 &pt) const;  
-  virtual SVector3 normal(const SPoint2 &param) const; 
+  virtual ~OCCFace();
+  Range<double> parBounds(int i) const;
+  virtual GPoint point(double par1, double par2) const;
+  virtual GPoint closestPoint(const SPoint3 & queryPoint,
+                              const double initialGuess[2]) const;
+  virtual bool containsPoint(const SPoint3 &pt) const;
+  virtual SVector3 normal(const SPoint2 &param) const;
   virtual Pair<SVector3,SVector3> firstDer(const SPoint2 &param) const;
   virtual void secondDer(const SPoint2 &, SVector3 *, SVector3 *, SVector3 *) const;
-  virtual GEntity::GeomType geomType() const; 
+  virtual GEntity::GeomType geomType() const;
   ModelType getNativeType() const { return OpenCascadeModel; }
   void *getNativePtr() const { return (void*)&s; }
   virtual SPoint2 parFromPoint(const SPoint3 &, bool onSurface=true) const;
@@ -47,14 +47,12 @@ class OCCFace : public GFace {
   virtual double curvatures(const SPoint2 &param, SVector3 *dirMax, SVector3 *dirMin,
                             double *curvMax, double *curvMin) const;
   surface_params getSurfaceParams() const;
-  TopoDS_Face getTopoDS_Face () {return s;}
-  TopoDS_Face getTopoDS_FaceOld () {return _replaced;}
+  TopoDS_Face getTopoDS_Face () { return s; }
+  TopoDS_Face getTopoDS_FaceOld () { return _replaced; }
   // tells if it's a sphere, and if it is, returns parameters
   virtual bool isSphere (double &radius, SPoint3 &center) const;
 };
 
-GFace *getOCCFaceByNativePtr(GModel *model, TopoDS_Face toFind);
-
 #endif
 
 #endif
diff --git a/Geo/OCCIncludes.h b/Geo/OCCIncludes.h
index 4619d9a4cdfb901630fc0935215be86e51cb7692..51928a340cada14297e8f3aa68d0c8dac94661c0 100644
--- a/Geo/OCCIncludes.h
+++ b/Geo/OCCIncludes.h
@@ -54,6 +54,7 @@ using std::iostream;
 #include <BRepTools_WireExplorer.hxx>
 #include <BRepTools.hxx>
 #include <TopTools_IndexedMapOfShape.hxx>
+#include <TopTools_DataMapOfShapeInteger.hxx>
 #include <TopExp.hxx>
 #include <BRepBuilderAPI_MakeVertex.hxx>
 #include <BRepBuilderAPI_MakeShell.hxx>
diff --git a/Geo/OCCRegion.cpp b/Geo/OCCRegion.cpp
index e341df9d35f479ad1f80d8a6a1d9e6600035d1ac..65deb4942f08e78a9dc0ab0f9666bead2cd04090 100644
--- a/Geo/OCCRegion.cpp
+++ b/Geo/OCCRegion.cpp
@@ -12,11 +12,18 @@
 #include "OCCRegion.h"
 
 #if defined(HAVE_OCC)
+#include "GModelIO_OCC.h"
 
 OCCRegion::OCCRegion(GModel *m, TopoDS_Solid _s, int num)
   : GRegion(m, num), s(_s)
 {
   setup();
+  model()->getOCCInternals()->bind(s, num);
+}
+
+OCCRegion::~OCCRegion()
+{
+  model()->getOCCInternals()->unbind(s);
 }
 
 void OCCRegion::setup()
@@ -28,7 +35,7 @@ void OCCRegion::setup()
     Msg::Debug("OCC Region %d - New Shell",tag());
     for(exp3.Init(shell, TopAbs_FACE); exp3.More(); exp3.Next()){
       TopoDS_Face face = TopoDS::Face(exp3.Current());
-      GFace *f = getOCCFaceByNativePtr(model(),face);
+      GFace *f = model()->getOCCInternals()->getOCCFaceByNativePtr(model(),face);
       if(f){
         l_faces.push_back(f);
         f->addRegion(this);
@@ -110,18 +117,4 @@ void OCCRegion::replaceFacesInternal(std::list<GFace*> &new_faces)
   setup();
 }
 
-GRegion *getOCCRegionByNativePtr(GModel *model, TopoDS_Solid toFind)
-{
-  GModel::riter it =model->firstRegion();
-  for (; it !=model->lastRegion(); it++){
-    OCCRegion *occr = dynamic_cast<OCCRegion*>(*it);
-    if (occr){
-      if (toFind.IsSame(occr->getTopoDS_Shape())){
-	return *it;
-      }
-    }
-  }
-  return 0;
-}
-
 #endif
diff --git a/Geo/OCCRegion.h b/Geo/OCCRegion.h
index 85ef9b8d5ab63700152e0f0129282117d8927f9d..14dfe84e5007c6ef354714163112837a85475ad9 100644
--- a/Geo/OCCRegion.h
+++ b/Geo/OCCRegion.h
@@ -18,15 +18,13 @@ class OCCRegion : public GRegion {
   void setup();
  public:
   OCCRegion(GModel *m, TopoDS_Solid s, int num);
-  virtual ~OCCRegion() {}
+  virtual ~OCCRegion();
   virtual GeomType geomType() const;
   ModelType getNativeType() const { return OpenCascadeModel; }
   void * getNativePtr() const { return (void*)&s; }
   TopoDS_Solid getTopoDS_Shape() {return s;}
 };
 
-GRegion *getOCCRegionByNativePtr(GModel *model, TopoDS_Solid toFind);
-
 #endif
 
 #endif
diff --git a/Geo/OCCVertex.cpp b/Geo/OCCVertex.cpp
index cac9d8e916de4e456f1eb4b284b03a00cea18bfb..706d7998a760fadb01660b0e9b3e1bf7343f6385 100644
--- a/Geo/OCCVertex.cpp
+++ b/Geo/OCCVertex.cpp
@@ -13,7 +13,9 @@
 
 #if defined(HAVE_OCC)
 
-OCCVertex::OCCVertex(GModel *m, int num, TopoDS_Vertex _v) 
+#include "GModelIO_OCC.h"
+
+OCCVertex::OCCVertex(GModel *m, int num, TopoDS_Vertex _v)
   : GVertex(m, num), v(_v)
 {
   max_curvature = -1;
@@ -21,6 +23,12 @@ OCCVertex::OCCVertex(GModel *m, int num, TopoDS_Vertex _v)
   _x = pnt.X();
   _y = pnt.Y();
   _z = pnt.Z();
+  model()->getOCCInternals()->bind(v, num);
+}
+
+OCCVertex::~OCCVertex()
+{
+  model()->getOCCInternals()->unbind(v);
 }
 
 void OCCVertex::setPosition(GPoint &p)
@@ -35,7 +43,7 @@ void OCCVertex::setPosition(GPoint &p)
   }
 }
 
-double max_surf_curvature(const GVertex *gv, double x, double y, double z, 
+double max_surf_curvature(const GVertex *gv, double x, double y, double z,
                           const GEdge *_myGEdge)
 {
   std::list<GFace *> faces = _myGEdge->faces();
@@ -46,14 +54,14 @@ double max_surf_curvature(const GVertex *gv, double x, double y, double z,
     double cc = (*it)->curvatureDiv(par);
     if(cc > 0) curv = std::max(curv, cc);
     ++it;
-  }  
+  }
   return curv;
 }
 
 double OCCVertex::max_curvature_of_surfaces() const
-{  
+{
   if(max_curvature < 0){
-    for(std::list<GEdge*>::const_iterator it = l_edges.begin(); 
+    for(std::list<GEdge*>::const_iterator it = l_edges.begin();
         it != l_edges.end(); ++it){
       max_curvature = std::max(max_surf_curvature(this, x(), y(), z(), *it),
                                max_curvature);
@@ -82,7 +90,7 @@ SPoint2 OCCVertex::reparamOnFace(const GFace *gf, int dir) const
       }
     }
     ++it;
-  }  
+  }
   it = l_edges.begin();
   while(it != l_edges.end()){
     std::list<GEdge*> l = gf->edges();
@@ -111,18 +119,4 @@ SPoint2 OCCVertex::reparamOnFace(const GFace *gf, int dir) const
   return GVertex::reparamOnFace(gf, dir);
 }
 
-GVertex *getOCCVertexByNativePtr(GModel *model, TopoDS_Vertex toFind)
-{
-  GModel::viter it =model->firstVertex();
-  for (; it != model->lastVertex(); it++){
-    OCCVertex *occv = dynamic_cast<OCCVertex*>(*it);
-    if (occv){
-      if (toFind.IsSame(occv->getShape())){
-	return *it;
-      }
-    }
-  }
-  return 0;
-}
-
 #endif
diff --git a/Geo/OCCVertex.h b/Geo/OCCVertex.h
index 90c5f611d724a023a0539e74981c5aa4e8dc8835..af48efdb3f713b3f2f5a93255cdf8f4c70376a70 100644
--- a/Geo/OCCVertex.h
+++ b/Geo/OCCVertex.h
@@ -21,7 +21,7 @@ class OCCVertex : public GVertex {
   double max_curvature_of_surfaces() const;
  public:
   OCCVertex(GModel *m, int num, TopoDS_Vertex _v);
-  virtual ~OCCVertex() {}
+  virtual ~OCCVertex();
   virtual GPoint point() const { return GPoint(x(), y(), z()); }
   virtual double x() const { return _x; }
   virtual double y() const { return _y; }
@@ -33,8 +33,6 @@ class OCCVertex : public GVertex {
   TopoDS_Vertex getShape() { return v; }
 };
 
-GVertex *getOCCVertexByNativePtr(GModel *model, TopoDS_Vertex toFind);
-
 #endif
 
 #endif
diff --git a/Graphics/drawGeom.cpp b/Graphics/drawGeom.cpp
index 3ba0674a932ce41e113d8ee7881b2c323a173332..07b43513d18003fd4c1d7e677a3c9a1afa2fde2e 100644
--- a/Graphics/drawGeom.cpp
+++ b/Graphics/drawGeom.cpp
@@ -339,7 +339,7 @@ class drawGFace {
     if(CTX::instance()->geom.surfaces) {
       bool selected = false;
       if (f->getSelection() || (f->getCompound() && f->getCompound()->getSelection()))
-          selected = true;
+        selected = true;
       if(CTX::instance()->geom.surfaceType > 0 && f->va_geom_triangles){
         _drawVertexArray(f->va_geom_triangles, CTX::instance()->geom.light,
                          f->getSelection(), CTX::instance()->color.geom.selection);