diff --git a/Common/Context.h b/Common/Context.h
index 2a65486c34851754b4c1f82efe094a59876ebb8f..0374e518fb3f8c2b6fdae3306ec491dc7473ed35 100644
--- a/Common/Context.h
+++ b/Common/Context.h
@@ -175,7 +175,7 @@ public :
     int format, nb_smoothing, algo2d, algo3d, algo_recombine;
     int order, second_order_linear, second_order_incomplete;
     int min_circ_points;
-    int bgmesh_type, constrained_bgmesh, lc_from_curvature;
+    int bgmesh_view_num, constrained_bgmesh, lc_from_curvature;
     double normals, tangents, explode;
     int color_carousel;
     int use_cut_plane, cut_plane_draw_intersect, cut_plane_only_volume;
diff --git a/Common/Options.cpp b/Common/Options.cpp
index 8db80e2915a4fe3cf61f8b9c07cd7a9021532fec..534112f0cc9b9c8318e7edaafcdb070a6c4e3d85 100644
--- a/Common/Options.cpp
+++ b/Common/Options.cpp
@@ -1,4 +1,4 @@
-// $Id: Options.cpp,v 1.333 2007-01-26 17:51:55 geuzaine Exp $
+// $Id: Options.cpp,v 1.334 2007-01-28 13:56:19 geuzaine Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -144,7 +144,7 @@ void Init_Options(int num)
   CTX.post.force_num = 0;
   CTX.threads_lock = 0; // very primitive locking
   CTX.mesh.changed = 0;
-  CTX.mesh.bgmesh_type = WITHPOINTS;
+  CTX.mesh.bgmesh_view_num = -1;
   CTX.post.combine_time = 0; // try to combine_time views at startup
   CTX.post.plugin_draw_function = NULL;
 #if defined(HAVE_FLTK)
diff --git a/Common/Views.cpp b/Common/Views.cpp
index dc70942c00eb6b8696c855f00fdc1405a539f4db..2aae9d5448c8b1f4a70c8824d1e9a414eed7e17e 100644
--- a/Common/Views.cpp
+++ b/Common/Views.cpp
@@ -1,4 +1,4 @@
-// $Id: Views.cpp,v 1.192 2006-11-27 22:22:08 geuzaine Exp $
+// $Id: Views.cpp,v 1.193 2007-01-28 13:56:19 geuzaine Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -86,8 +86,10 @@ Post_View *BeginView(int allocate)
   else {
     v->Num = CTX.post.force_num;
     List_Replace(CTX.post.list, &v, fcmpPostViewNum);
+    // invalidate the background mesh
+    if(v->Num == CTX.mesh.bgmesh_view_num) CTX.mesh.bgmesh_view_num = -1;
   }
-
+  
   int i = List_ISearch(CTX.post.list, &v, fcmpPostViewNum);
   List_Read(CTX.post.list, i, &v);
 
diff --git a/Geo/Makefile b/Geo/Makefile
index daf028ef6b301750041c15418008acf88d7f07fa..9a52238902e4d15d7b2e12b4aa1c0ee51fbc13f1 100644
--- a/Geo/Makefile
+++ b/Geo/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.124 2007-01-22 16:31:43 geuzaine Exp $
+# $Id: Makefile,v 1.125 2007-01-28 13:56:19 geuzaine Exp $
 #
 # Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 #
@@ -178,7 +178,7 @@ GModelIO_Geo.o: GModelIO_Geo.cpp GModel.h GVertex.h GEntity.h Range.h \
   ../Common/SmoothNormals.h Geo.h ../DataStr/Tree.h ../DataStr/avl.h \
   ../Parser/OpenFile.h ../DataStr/Tools.h ../DataStr/List.h \
   ../DataStr/Tree.h ../Common/Message.h gmshVertex.h gmshFace.h \
-  gmshEdge.h gmshRegion.h
+  gmshEdge.h gmshRegion.h ../Parser/Parser.h
 GModelIO_Mesh.o: GModelIO_Mesh.cpp ../Common/Message.h \
   ../Common/GmshDefines.h GModel.h GVertex.h GEntity.h Range.h SPoint3.h \
   SBoundingBox3d.h MVertex.h GPoint.h SPoint2.h GEdge.h SVector3.h \
diff --git a/Mesh/BackgroundMesh.cpp b/Mesh/BackgroundMesh.cpp
index e4a0e685e1b422610173f2ea14d63b1e305f197d..78415f621d13dde1ee96994124b9d30d4274e480 100644
--- a/Mesh/BackgroundMesh.cpp
+++ b/Mesh/BackgroundMesh.cpp
@@ -1,4 +1,4 @@
-// $Id: BackgroundMesh.cpp,v 1.13 2007-01-18 13:18:42 geuzaine Exp $
+// $Id: BackgroundMesh.cpp,v 1.14 2007-01-28 13:56:19 geuzaine Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -33,7 +33,6 @@
 extern Context_T CTX;
 
 static OctreePost *BGM_OCTREE = NULL;
-static double BGM_MAX = 0.;
 
 const double MAX_LC = 1.e22;
 
@@ -42,50 +41,20 @@ int BGMWithView(Post_View * ErrView)
   Msg(INFO, "Applying '%s' as background mesh", ErrView->Name);
   if(BGM_OCTREE) delete BGM_OCTREE;
   BGM_OCTREE = new OctreePost(ErrView);
-  BGM_MAX = ErrView->Max;
-  CTX.mesh.bgmesh_type = ONFILE;
+  CTX.mesh.bgmesh_view_num = ErrView->Num; // view numbers are unique
   return 1 ;
 }
 
 int BGMExists()
 {
-  return BGM_OCTREE != 0;
-}
+  if(!BGM_OCTREE || CTX.mesh.bgmesh_view_num < 0) return 0;
 
-double BGMXYZ(double X, double Y, double Z)
-{
-  if(!BGM_OCTREE){
-    Msg(GERROR, "Missing background mesh");
-    CTX.mesh.bgmesh_type = WITHPOINTS;
-    return 1.;
+  for(int i = 0; i < List_Nbr(CTX.post.list); i++){
+    Post_View *v = *(Post_View**)List_Pointer_Fast(CTX.post.list, i);
+    if(v->Num == CTX.mesh.bgmesh_view_num) return 1;
   }
-
-  double l = 0.;
-  double fact[9] = {0.001, 0.0025, 0.005, 0.0075, 0.01, 0.025, 0.05, 0.075, 0.1};
-
-  if(!BGM_OCTREE->searchScalar(X, Y, Z, &l, 0)){
-    // try really hard to find an element around the point
-    for(int i = 0; i < 9; i++){
-      double eps = CTX.lc * fact[i];
-      if(BGM_OCTREE->searchScalar(X + eps, Y, Z, &l, 0)) break;
-      if(BGM_OCTREE->searchScalar(X - eps, Y, Z, &l, 0)) break;
-      if(BGM_OCTREE->searchScalar(X, Y + eps, Z, &l, 0)) break;
-      if(BGM_OCTREE->searchScalar(X, Y - eps, Z, &l, 0)) break;
-      if(BGM_OCTREE->searchScalar(X, Y, Z + eps, &l, 0)) break;
-      if(BGM_OCTREE->searchScalar(X, Y, Z - eps, &l, 0)) break;
-      if(BGM_OCTREE->searchScalar(X + eps, Y - eps, Z - eps, &l, 0)) break;
-      if(BGM_OCTREE->searchScalar(X + eps, Y + eps, Z - eps, &l, 0)) break;
-      if(BGM_OCTREE->searchScalar(X - eps, Y - eps, Z - eps, &l, 0)) break;
-      if(BGM_OCTREE->searchScalar(X - eps, Y + eps, Z - eps, &l, 0)) break;
-      if(BGM_OCTREE->searchScalar(X + eps, Y - eps, Z + eps, &l, 0)) break;
-      if(BGM_OCTREE->searchScalar(X + eps, Y + eps, Z + eps, &l, 0)) break;
-      if(BGM_OCTREE->searchScalar(X - eps, Y - eps, Z + eps, &l, 0)) break;
-      if(BGM_OCTREE->searchScalar(X - eps, Y + eps, Z + eps, &l, 0)) break;
-    }
-  }
-  if(l <= 0) return MAX_LC;
-
-  return l;
+  CTX.mesh.bgmesh_view_num = -1;
+  return 0;
 }
 
 // computes the characteristic length of the mesh at a vertex in order
@@ -158,15 +127,37 @@ double LC_MVertex_CURV(GEntity *ge, double U, double V)
   else return MAX_LC;
 }
 
-// compute the mesh size at a given vertex due to prescribed sizes at
-// mesh vertices
-
+// compute the mesh size at a given point in space using a background
+// mesh on file
 double LC_MVertex_BGM(GEntity *ge, double X, double Y, double Z)
 {
-  if(BGMExists())
-    return BGMXYZ(X,Y,Z);
-  else
-    return MAX_LC;
+  if(!BGMExists()) return MAX_LC;
+
+  double l = 0.;
+  double fact[9] = {0.001, 0.0025, 0.005, 0.0075, 0.01, 0.025, 0.05, 0.075, 0.1};
+
+  if(!BGM_OCTREE->searchScalar(X, Y, Z, &l, 0)){
+    // try really hard to find an element around the point
+    for(int i = 0; i < 9; i++){
+      double eps = CTX.lc * fact[i];
+      if(BGM_OCTREE->searchScalar(X + eps, Y, Z, &l, 0)) break;
+      if(BGM_OCTREE->searchScalar(X - eps, Y, Z, &l, 0)) break;
+      if(BGM_OCTREE->searchScalar(X, Y + eps, Z, &l, 0)) break;
+      if(BGM_OCTREE->searchScalar(X, Y - eps, Z, &l, 0)) break;
+      if(BGM_OCTREE->searchScalar(X, Y, Z + eps, &l, 0)) break;
+      if(BGM_OCTREE->searchScalar(X, Y, Z - eps, &l, 0)) break;
+      if(BGM_OCTREE->searchScalar(X + eps, Y - eps, Z - eps, &l, 0)) break;
+      if(BGM_OCTREE->searchScalar(X + eps, Y + eps, Z - eps, &l, 0)) break;
+      if(BGM_OCTREE->searchScalar(X - eps, Y - eps, Z - eps, &l, 0)) break;
+      if(BGM_OCTREE->searchScalar(X - eps, Y + eps, Z - eps, &l, 0)) break;
+      if(BGM_OCTREE->searchScalar(X + eps, Y - eps, Z + eps, &l, 0)) break;
+      if(BGM_OCTREE->searchScalar(X + eps, Y + eps, Z + eps, &l, 0)) break;
+      if(BGM_OCTREE->searchScalar(X - eps, Y - eps, Z + eps, &l, 0)) break;
+      if(BGM_OCTREE->searchScalar(X - eps, Y + eps, Z + eps, &l, 0)) break;
+    }
+  }
+  if(l <= 0) return MAX_LC;
+  return l;
 }
 
 // compute the mesh size at a given vertex due to prescribed sizes at
@@ -197,20 +188,20 @@ double LC_MVertex_PNTS(GEntity *ge, double U, double V)
 
 double BGM_MeshSize(GEntity *ge, double U, double V, double X, double Y, double Z)
 {
-  // unconstrained background mesh
-  if(CTX.mesh.bgmesh_type == ONFILE && !CTX.mesh.constrained_bgmesh){
-    return CTX.mesh.lc_factor * BGMXYZ(X, Y, Z);
-  }
-
   double l2 = MAX_LC;
   double l3 = CTX.lc / 10.;
   double l4 = LC_MVertex_BGM(ge, X, Y, Z);
+
+  if(l4 < MAX_LC && !CTX.mesh.constrained_bgmesh)
+    return l4 * CTX.mesh.lc_factor;
+
   if(ge->dim() < 2) l2 = LC_MVertex_PNTS(ge, U, V);
+
   double l = std::min(std::min(l2, l4), l3);
 
   l *= CTX.mesh.lc_factor ;
-  double l1 = MAX_LC;
 
+  double l1 = MAX_LC;
   if(CTX.mesh.lc_from_curvature && ge->dim() < 3)
     l1 = std::max(l3/100, LC_MVertex_CURV(ge, U, V));
 
diff --git a/Mesh/BackgroundMesh.h b/Mesh/BackgroundMesh.h
index 7be7861bff0901dbf96ac6332021f86d2a3834f3..c69edbeda9cc39b91d5d44c867f330730eadcad4 100644
--- a/Mesh/BackgroundMesh.h
+++ b/Mesh/BackgroundMesh.h
@@ -20,9 +20,6 @@
 // 
 // Please report all bugs and problems to <gmsh@geuz.org>.
 
-#define ONFILE      2
-#define WITHPOINTS  3
-
 class GEntity;
 double BGM_MeshSize(GEntity *ge, double U, double V, double X, double Y, double Z);
 int BGMExists();