diff --git a/Box/Box.cpp b/Box/Box.cpp
index 4de38d58fde2a219049620e8eb0a976aac026bdf..667d09eba06a607b092f4dfacbbf1aa6b1681830 100644
--- a/Box/Box.cpp
+++ b/Box/Box.cpp
@@ -1,4 +1,4 @@
-// $Id: Box.cpp,v 1.35 2007-04-21 19:39:59 geuzaine Exp $
+// $Id: Box.cpp,v 1.36 2007-08-21 19:05:38 geuzaine Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -39,7 +39,6 @@
 
 Context_T CTX;
 Mesh *THEM = 0;
-GModel *GMODEL = 0;
 
 // Print some help/info messages
 
@@ -79,7 +78,7 @@ int GMSHBOX(int argc, char *argv[])
 {
   ParUtil::Instance()->init(argc, argv);
 
-  GMODEL = new GModel;
+  GModel::list.push_back(new GModel);
   THEM = new Mesh;
 
   InitSymbols();
diff --git a/Common/CommandLine.cpp b/Common/CommandLine.cpp
index 05830de95a31ccf4fa79ea4ce728fc7833c85305..5ce79b517c0840b015ecb56056e2bc22cb262d02 100644
--- a/Common/CommandLine.cpp
+++ b/Common/CommandLine.cpp
@@ -1,4 +1,4 @@
-// $Id: CommandLine.cpp,v 1.101 2007-05-24 17:34:03 geuzaine Exp $
+// $Id: CommandLine.cpp,v 1.102 2007-08-21 19:05:38 geuzaine Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -43,7 +43,6 @@
 #endif
 
 extern Context_T CTX;
-extern GModel *GMODEL;
 
 char gmsh_progname[]  = "Gmsh, a 3D mesh generator with pre- and post-processing facilities" ;
 char gmsh_copyright[] = "Copyright (C) 1997-2007 Christophe Geuzaine and Jean-Francois Remacle";
@@ -296,7 +295,7 @@ void Get_Options(int argc, char *argv[])
             WriteView(v, filename, 1, (j == numviews_old) ? 0 : 1);
 	  }
 	  // convert mesh to latest binary format
-	  if(GMODEL->getMeshStatus() > 0){
+	  if(GModel::current()->getMeshStatus() > 0){
 	    CTX.mesh.msh_file_version = 2.0;
 	    CTX.mesh.msh_binary = 1;
 	    CreateOutputFile(filename, FORMAT_MSH);
diff --git a/Common/Makefile b/Common/Makefile
index 068a73e6a830423b66f1464ef2bebbd59e8f936b..2cecec6f1a9d3f0dc42accdd657655f98f891a85 100644
--- a/Common/Makefile
+++ b/Common/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.133 2007-07-09 13:54:36 geuzaine Exp $
+# $Id: Makefile,v 1.134 2007-08-21 19:05:38 geuzaine Exp $
 #
 # Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 #
@@ -72,11 +72,11 @@ OctreeInternals.o: OctreeInternals.cpp Message.h OctreeInternals.h
 Options.o: Options.cpp Gmsh.h Message.h ../DataStr/Malloc.h \
   ../DataStr/List.h ../DataStr/Tree.h ../DataStr/avl.h ../DataStr/Tools.h \
   ../DataStr/List.h ../DataStr/Tree.h GmshUI.h GmshDefines.h \
-  ../Graphics/Draw.h ../Post/Views.h ../Post/ColorTable.h \
-  ../Common/VertexArray.h ../Common/SmoothData.h ../Numeric/Numeric.h \
-  ../Post/AdaptiveViews.h ../Common/GmshMatrix.h ../Mesh/Generator.h \
-  Context.h Options.h ../Mesh/BackgroundMesh.h ../Plugin/PluginManager.h \
-  ../Plugin/Plugin.h ../Common/Options.h ../Common/Message.h \
+  ../Graphics/Draw.h ../Mesh/Generator.h Context.h Options.h \
+  ../Mesh/BackgroundMesh.h ../Plugin/PluginManager.h ../Plugin/Plugin.h \
+  ../Common/Options.h ../Common/Message.h ../Post/Views.h \
+  ../Post/ColorTable.h ../Common/VertexArray.h ../Common/SmoothData.h \
+  ../Numeric/Numeric.h ../Post/AdaptiveViews.h ../Common/GmshMatrix.h \
   ../Fltk/Solvers.h ../Fltk/GUI.h ../Fltk/Opengl_Window.h \
   ../Fltk/Colorbar_Window.h ../Common/GmshUI.h ../Fltk/Popup_Button.h \
   ../Fltk/SpherePosition_Widget.h
diff --git a/Common/Visibility.cpp b/Common/Visibility.cpp
index fa29cf5644debb50fd22086f36d20bfa26b26e85..bae999db4f69894a37a5e48d249c8b22f6e8d570 100644
--- a/Common/Visibility.cpp
+++ b/Common/Visibility.cpp
@@ -1,4 +1,4 @@
-// $Id: Visibility.cpp,v 1.26 2006-12-12 18:16:41 geuzaine Exp $
+// $Id: Visibility.cpp,v 1.27 2007-08-21 19:05:39 geuzaine Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -23,8 +23,6 @@
 #include "GModel.h"
 #include "Parser.h" // for Symbol_T
 
-extern GModel *GMODEL;
-
 VisibilityManager *VisibilityManager::manager = 0;
 
 class VisLessThan{
@@ -64,10 +62,12 @@ void VisibilityManager::update(int type)
   // get old labels from parser
   if(Tree_Nbr(Symbol_T)) Tree_Action(Symbol_T, setLabels);
 
+  GModel *m = GModel::current();
+
   // add new labels for physicals
   if(type == 1){
-    GModel::piter it = GMODEL->firstPhysicalName();
-    while(it != GMODEL->lastPhysicalName()){
+    GModel::piter it = m->firstPhysicalName();
+    while(it != m->lastPhysicalName()){
       setLabel(it->first, it->second);
       ++it;
     }
@@ -78,18 +78,18 @@ void VisibilityManager::update(int type)
   _entities.clear();
   
   if(type == 0){ // elementary entities
-    for(GModel::viter it = GMODEL->firstVertex(); it != GMODEL->lastVertex(); it++)
+    for(GModel::viter it = m->firstVertex(); it != m->lastVertex(); it++)
       _entities.push_back(new VisElementary(*it));
-    for(GModel::eiter it = GMODEL->firstEdge(); it != GMODEL->lastEdge(); it++)
+    for(GModel::eiter it = m->firstEdge(); it != m->lastEdge(); it++)
       _entities.push_back(new VisElementary(*it));
-    for(GModel::fiter it = GMODEL->firstFace(); it != GMODEL->lastFace(); it++)
+    for(GModel::fiter it = m->firstFace(); it != m->lastFace(); it++)
       _entities.push_back(new VisElementary(*it));
-    for(GModel::riter it = GMODEL->firstRegion(); it != GMODEL->lastRegion(); it++)
+    for(GModel::riter it = m->firstRegion(); it != m->lastRegion(); it++)
       _entities.push_back(new VisElementary(*it));
   }
   else if(type == 1){ // physical entities
     std::map<int, std::vector<GEntity*> > groups[4];
-    GMODEL->getPhysicalGroups(groups);
+    m->getPhysicalGroups(groups);
     for(int i = 0; i < 4; i++){
       std::map<int, std::vector<GEntity*> >::const_iterator it = groups[i].begin();
       for(; it != groups[i].end(); ++it)
@@ -97,7 +97,7 @@ void VisibilityManager::update(int type)
     }
   }
   else if(type == 2){ // partitions
-    std::set<int> part = GMODEL->getMeshPartitions();
+    std::set<int> part = m->getMeshPartitions();
     for(std::set<int>::const_iterator it = part.begin(); it != part.end(); ++it)
       _entities.push_back(new VisPartition(*it));
   }
@@ -106,15 +106,17 @@ void VisibilityManager::update(int type)
 
 void VisibilityManager::setAllInvisible(int type)
 {
+  GModel *m = GModel::current();
+
   if(type == 0 || type == 1){
     // elementary or physical mode: set all entities in the model invisible
-    for(GModel::viter it = GMODEL->firstVertex(); it != GMODEL->lastVertex(); it++)
+    for(GModel::viter it = m->firstVertex(); it != m->lastVertex(); it++)
       (*it)->setVisibility(false);
-    for(GModel::eiter it = GMODEL->firstEdge(); it != GMODEL->lastEdge(); it++)
+    for(GModel::eiter it = m->firstEdge(); it != m->lastEdge(); it++)
       (*it)->setVisibility(false);
-    for(GModel::fiter it = GMODEL->firstFace(); it != GMODEL->lastFace(); it++)
+    for(GModel::fiter it = m->firstFace(); it != m->lastFace(); it++)
       (*it)->setVisibility(false);
-    for(GModel::riter it = GMODEL->firstRegion(); it != GMODEL->lastRegion(); it++)
+    for(GModel::riter it = m->firstRegion(); it != m->lastRegion(); it++)
       (*it)->setVisibility(false);
   }
 
@@ -137,16 +139,18 @@ std::string VisibilityManager::getStringForGEO()
 {
   std::vector<int> state[4][2];
 
-  for(GModel::viter it = GMODEL->firstVertex(); it != GMODEL->lastVertex(); it++)
+  GModel *m = GModel::current();
+
+  for(GModel::viter it = m->firstVertex(); it != m->lastVertex(); it++)
     (*it)->getVisibility() ?
       state[0][1].push_back((*it)->tag()) : state[0][0].push_back((*it)->tag());
-  for(GModel::eiter it = GMODEL->firstEdge(); it != GMODEL->lastEdge(); it++)
+  for(GModel::eiter it = m->firstEdge(); it != m->lastEdge(); it++)
     (*it)->getVisibility() ? 
       state[1][1].push_back((*it)->tag()) : state[1][0].push_back((*it)->tag());
-  for(GModel::fiter it = GMODEL->firstFace(); it != GMODEL->lastFace(); it++)
+  for(GModel::fiter it = m->firstFace(); it != m->lastFace(); it++)
     (*it)->getVisibility() ? 
       state[2][1].push_back((*it)->tag()) : state[2][0].push_back((*it)->tag());
-  for(GModel::riter it = GMODEL->firstRegion(); it != GMODEL->lastRegion(); it++)
+  for(GModel::riter it = m->firstRegion(); it != m->lastRegion(); it++)
     (*it)->getVisibility() ? 
       state[3][1].push_back((*it)->tag()) : state[3][0].push_back((*it)->tag());
   
@@ -193,32 +197,34 @@ void VisibilityManager::setVisibilityByNumber(int type, int num, char val, bool
 {
   bool all = (num < 0) ? true : false;
 
+  GModel *m = GModel::current();
+
   switch(type){
   case 0: // nodes
-    for(GModel::viter it = GMODEL->firstVertex(); it != GMODEL->lastVertex(); it++)
+    for(GModel::viter it = m->firstVertex(); it != m->lastVertex(); it++)
       for(unsigned int i = 0; i < (*it)->mesh_vertices.size(); i++)
 	if(all || (*it)->mesh_vertices[i]->getNum() == num) 
 	  (*it)->mesh_vertices[i]->setVisibility(val);
-    for(GModel::eiter it = GMODEL->firstEdge(); it != GMODEL->lastEdge(); it++)
+    for(GModel::eiter it = m->firstEdge(); it != m->lastEdge(); it++)
       for(unsigned int i = 0; i < (*it)->mesh_vertices.size(); i++)
 	if(all || (*it)->mesh_vertices[i]->getNum() == num) 
 	  (*it)->mesh_vertices[i]->setVisibility(val);
-    for(GModel::fiter it = GMODEL->firstFace(); it != GMODEL->lastFace(); it++)
+    for(GModel::fiter it = m->firstFace(); it != m->lastFace(); it++)
       for(unsigned int i = 0; i < (*it)->mesh_vertices.size(); i++)
 	if(all || (*it)->mesh_vertices[i]->getNum() == num) 
 	  (*it)->mesh_vertices[i]->setVisibility(val);
-    for(GModel::riter it = GMODEL->firstRegion(); it != GMODEL->lastRegion(); it++)
+    for(GModel::riter it = m->firstRegion(); it != m->lastRegion(); it++)
       for(unsigned int i = 0; i < (*it)->mesh_vertices.size(); i++)
 	if(all || (*it)->mesh_vertices[i]->getNum() == num) 
 	  (*it)->mesh_vertices[i]->setVisibility(val);
     break;
   case 1: // elements
-    for(GModel::eiter it = GMODEL->firstEdge(); it != GMODEL->lastEdge(); it++){
+    for(GModel::eiter it = m->firstEdge(); it != m->lastEdge(); it++){
       for(unsigned int i = 0; i < (*it)->lines.size(); i++)
 	if(all || (*it)->lines[i]->getNum() == num) 
 	  (*it)->lines[i]->setVisibility(val);
     }
-    for(GModel::fiter it = GMODEL->firstFace(); it != GMODEL->lastFace(); it++){
+    for(GModel::fiter it = m->firstFace(); it != m->lastFace(); it++){
       for(unsigned int i = 0; i < (*it)->triangles.size(); i++)
 	if(all || (*it)->triangles[i]->getNum() == num) 
 	  (*it)->triangles[i]->setVisibility(val);
@@ -226,7 +232,7 @@ void VisibilityManager::setVisibilityByNumber(int type, int num, char val, bool
 	if(all || (*it)->quadrangles[i]->getNum() == num) 
 	  (*it)->quadrangles[i]->setVisibility(val);
     }
-    for(GModel::riter it = GMODEL->firstRegion(); it != GMODEL->lastRegion(); it++){
+    for(GModel::riter it = m->firstRegion(); it != m->lastRegion(); it++){
       for(unsigned int i = 0; i < (*it)->tetrahedra.size(); i++)
 	if(all || (*it)->tetrahedra[i]->getNum() == num) 
 	  (*it)->tetrahedra[i]->setVisibility(val);
@@ -242,38 +248,38 @@ void VisibilityManager::setVisibilityByNumber(int type, int num, char val, bool
     }
     break;
   case 2: // point
-    for(GModel::viter it = GMODEL->firstVertex(); it != GMODEL->lastVertex(); it++)
+    for(GModel::viter it = m->firstVertex(); it != m->lastVertex(); it++)
       if(all || (*it)->tag() == num) (*it)->setVisibility(val, recursive);
     break;
   case 3: // line
-    for(GModel::eiter it = GMODEL->firstEdge(); it != GMODEL->lastEdge(); it++)
+    for(GModel::eiter it = m->firstEdge(); it != m->lastEdge(); it++)
       if(all || (*it)->tag() == num) (*it)->setVisibility(val, recursive);
     break;
   case 4: // surface
-    for(GModel::fiter it = GMODEL->firstFace(); it != GMODEL->lastFace(); it++)
+    for(GModel::fiter it = m->firstFace(); it != m->lastFace(); it++)
       if(all || (*it)->tag() == num) (*it)->setVisibility(val, recursive);
     break;
   case 5: // volume
-    for(GModel::riter it = GMODEL->firstRegion(); it != GMODEL->lastRegion(); it++)
+    for(GModel::riter it = m->firstRegion(); it != m->lastRegion(); it++)
       if(all || (*it)->tag() == num) (*it)->setVisibility(val, recursive);
     break;
   case 6: // physical point
-    for(GModel::viter it = GMODEL->firstVertex(); it != GMODEL->lastVertex(); it++)
+    for(GModel::viter it = m->firstVertex(); it != m->lastVertex(); it++)
       for(unsigned int i = 0; i < (*it)->physicals.size(); i++)
 	if (all || std::abs((*it)->physicals[i]) == num) (*it)->setVisibility(val, recursive);
     break;
   case 7: // physical line
-    for(GModel::eiter it = GMODEL->firstEdge(); it != GMODEL->lastEdge(); it++)
+    for(GModel::eiter it = m->firstEdge(); it != m->lastEdge(); it++)
       for(unsigned int i = 0; i < (*it)->physicals.size(); i++)
 	if (all || std::abs((*it)->physicals[i]) == num) (*it)->setVisibility(val, recursive);
     break;
   case 8: // physical surface
-    for(GModel::fiter it = GMODEL->firstFace(); it != GMODEL->lastFace(); it++)
+    for(GModel::fiter it = m->firstFace(); it != m->lastFace(); it++)
       for(unsigned int i = 0; i < (*it)->physicals.size(); i++)
 	if (all || std::abs((*it)->physicals[i]) == num) (*it)->setVisibility(val, recursive);
     break;
   case 9: // physical volume
-    for(GModel::riter it = GMODEL->firstRegion(); it != GMODEL->lastRegion(); it++)
+    for(GModel::riter it = m->firstRegion(); it != m->lastRegion(); it++)
       for(unsigned int i = 0; i < (*it)->physicals.size(); i++)
 	if (all || std::abs((*it)->physicals[i]) == num) (*it)->setVisibility(val, recursive);
     break;
@@ -294,13 +300,15 @@ void VisPhysical::setVisibility(char val, bool recursive)
 
 void VisPartition::setVisibility(char val, bool recursive)
 {
+  GModel *m = GModel::current();
+
   _visible = val;
-  for(GModel::eiter it = GMODEL->firstEdge(); it != GMODEL->lastEdge(); it++){
+  for(GModel::eiter it = m->firstEdge(); it != m->lastEdge(); it++){
     for(unsigned int i = 0; i < (*it)->lines.size(); i++)
       if((*it)->lines[i]->getPartition() == _tag) 
 	(*it)->lines[i]->setVisibility(val);
   }
-  for(GModel::fiter it = GMODEL->firstFace(); it != GMODEL->lastFace(); it++){
+  for(GModel::fiter it = m->firstFace(); it != m->lastFace(); it++){
     for(unsigned int i = 0; i < (*it)->triangles.size(); i++)
       if((*it)->triangles[i]->getPartition() == _tag) 
 	(*it)->triangles[i]->setVisibility(val);
@@ -308,7 +316,7 @@ void VisPartition::setVisibility(char val, bool recursive)
       if((*it)->quadrangles[i]->getPartition() == _tag) 
 	(*it)->quadrangles[i]->setVisibility(val);
   }
-  for(GModel::riter it = GMODEL->firstRegion(); it != GMODEL->lastRegion(); it++){
+  for(GModel::riter it = m->firstRegion(); it != m->lastRegion(); it++){
     for(unsigned int i = 0; i < (*it)->tetrahedra.size(); i++)
       if((*it)->tetrahedra[i]->getPartition() == _tag) 
 	(*it)->tetrahedra[i]->setVisibility(val);
diff --git a/Fltk/Callbacks.cpp b/Fltk/Callbacks.cpp
index 211723cecd316f574000731431358212f9cf80d5..fd8fcee192897033596abed7f0cd542811b2191d 100644
--- a/Fltk/Callbacks.cpp
+++ b/Fltk/Callbacks.cpp
@@ -1,4 +1,4 @@
-// $Id: Callbacks.cpp,v 1.537 2007-08-17 15:43:07 geuzaine Exp $
+// $Id: Callbacks.cpp,v 1.538 2007-08-21 19:05:39 geuzaine Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -53,7 +53,6 @@
 
 extern Context_T CTX;
 extern GUI *WID;
-extern GModel *GMODEL;
 
 // Helper routines
 
@@ -2023,13 +2022,13 @@ void visibility_delete_cb(CALLBACK_ARGS)
     }
   }
   if(all){
-    GMODEL->deletePhysicalGroups();
+    GModel::current()->deletePhysicalGroups();
   }
   else{
     for(int i = 0; i < VisibilityManager::instance()->getNumEntities(); i++){
       if(WID->vis_browser->selected(i + 1)){
 	Vis *v = VisibilityManager::instance()->getEntity(i);
-	GMODEL->deletePhysicalGroup(v->getDim(), v->getTag());
+	GModel::current()->deletePhysicalGroup(v->getDim(), v->getTag());
       }
     }
   }
@@ -3807,7 +3806,7 @@ void mesh_delete_parts_cb(CALLBACK_ARGS)
 	for(unsigned int i = 0; i < ent.size(); i++)
 	  if(ent[i]->getSelection() == 1) ent[i]->setVisibility(0);
       }
-      GMODEL->removeInvisibleElements();
+      GModel::current()->removeInvisibleElements();
       ele.clear();
       ent.clear();
     }
@@ -3889,9 +3888,10 @@ void mesh_inspect_cb(CALLBACK_ARGS)
 void mesh_degree_cb(CALLBACK_ARGS)
 {
   if((long)data == 2)
-    SetOrderN(GMODEL, 2, CTX.mesh.second_order_linear, CTX.mesh.second_order_incomplete);
+    SetOrderN(GModel::current(), 2, CTX.mesh.second_order_linear, 
+	      CTX.mesh.second_order_incomplete);
   else
-    SetOrder1(GMODEL);
+    SetOrder1(GModel::current());
   CTX.mesh.changed = ENT_LINE | ENT_SURFACE | ENT_VOLUME;
   Draw();
   Msg(STATUS2N, " ");
diff --git a/Fltk/GUI_Projection.cpp b/Fltk/GUI_Projection.cpp
index 27b8a4ea43812aa33dd24ad797f1161deb20fc47..8fbc78d64ae506b71e53b32c0f3b758fb8522a9a 100644
--- a/Fltk/GUI_Projection.cpp
+++ b/Fltk/GUI_Projection.cpp
@@ -8,7 +8,6 @@
 #include "GUI_Extras.h"
 #include "FFace.h"
 
-extern GModel *GMODEL;
 extern Context_T CTX;
 
 #if defined(HAVE_FOURIER_MODEL)
@@ -23,23 +22,24 @@ extern Context_T CTX;
 
 static FProjectionFace *createProjectionFaceFromName(char *name)
 {
-  int tag = GMODEL->numFace() + 1;
+  GModel *m = GModel::current();
+  int tag = m->numFace() + 1;
   FProjectionFace *f = 0;
   if(!strcmp(name, "plane"))
-    f = new FProjectionFace(GMODEL, tag, new FM::PlaneProjectionSurface(tag));
+    f = new FProjectionFace(m, tag, new FM::PlaneProjectionSurface(tag));
   else if(!strcmp(name, "paraboloid"))
-    f = new FProjectionFace(GMODEL, tag, new FM::ParaboloidProjectionSurface(tag));
+    f = new FProjectionFace(m, tag, new FM::ParaboloidProjectionSurface(tag));
   else if(!strcmp(name, "cylinder"))
-    f = new FProjectionFace(GMODEL, tag, new FM::CylindricalProjectionSurface(tag));
+    f = new FProjectionFace(m, tag, new FM::CylindricalProjectionSurface(tag));
   else if(!strcmp(name, "revolvedParabola"))
-    f = new FProjectionFace(GMODEL, tag, new FM::RevolvedParabolaProjectionSurface(tag));
+    f = new FProjectionFace(m, tag, new FM::RevolvedParabolaProjectionSurface(tag));
   else if(!strcmp(name, "translatedParabola"))
-    f = new FProjectionFace(GMODEL, tag, new FM::TranslatedParabolaProjectionSurface(tag));
+    f = new FProjectionFace(m, tag, new FM::TranslatedParabolaProjectionSurface(tag));
   else
     Msg(GERROR, "Unknown projection face `%s'", name);
   if(f){
     f->setVisibility(false);
-    GMODEL->add(f);
+    m->add(f);
   }
   return f;
 }
@@ -130,7 +130,7 @@ projection::projection(FProjectionFace *f, int x, int y, int w, int h, int BB, i
   : face(f)
 {
   group = new Fl_Scroll(x, y, w, h);
-  SBoundingBox3d bounds = GMODEL->bounds();
+  SBoundingBox3d bounds = GModel::current()->bounds();
   FM::ProjectionSurface *ps = f->GetProjectionSurface();
   
   Fl_Toggle_Button *b = new Fl_Toggle_Button(x, y, BB, BH, "Set position");
@@ -233,7 +233,7 @@ projectionEditor::projectionEditor()
   Fl_Group *o = new Fl_Group(WB, WB, 2 * BB, 3 * BH);
   _select[0] = new Fl_Round_Button(2 * WB + BB / 2, WB, BB, BH, "Points");
   _select[1] = new Fl_Round_Button(2 * WB + BB / 2, WB + BH, BB, BH, "Elements");
-  if(GMODEL->numElements())
+  if(GModel::current()->numElements())
     _select[1]->value(1);
   else
     _select[0]->value(1);
@@ -731,7 +731,7 @@ void filter_cb(Fl_Widget *w, void *data)
   projectionEditor *e = (projectionEditor*)data;
   projection *p = e->getCurrentProjection();
   if(p){
-    SBoundingBox3d bbox = GMODEL->bounds();
+    SBoundingBox3d bbox = GModel::current()->bounds();
     double lc = norm(SVector3(bbox.max(), bbox.min()));
     double threshold = e->getThreshold() * lc;
     FM::ProjectionSurface *ps = p->face->GetProjectionSurface();
@@ -973,16 +973,18 @@ void delete_fourier(GFace *gf)
 {
   if(gf->getNativeType() != GEntity::FourierModel) return;
 
+  GModel *m = GModel::current();
+
   // don't actually delete the data so we can add `undo' later
   std::list<GVertex*> vertices = gf->vertices();
   for(std::list<GVertex*>::iterator it = vertices.begin(); it != vertices.end(); it++)
-    GMODEL->remove(*it);
+    m->remove(*it);
 
   std::list<GEdge*> edges = gf->edges();
   for(std::list<GEdge*>::iterator it = edges.begin(); it != edges.end(); it++)
-    GMODEL->remove(*it);
+    m->remove(*it);
 
-  GMODEL->remove(gf);
+  m->remove(gf);
 }
 
 void action_cb(Fl_Widget *w, void *data)
@@ -990,15 +992,17 @@ void action_cb(Fl_Widget *w, void *data)
   std::string what((char*)data);
   std::vector<GFace*> faces;
 
+  GModel *m = GModel::current();
+
   if(what == "delete_last" || what == "save_last"){
     int id = -1;
-    for(GModel::fiter it = GMODEL->firstFace(); it != GMODEL->lastFace(); it++)
+    for(GModel::fiter it = m->firstFace(); it != m->lastFace(); it++)
       if((*it)->getNativeType() == GEntity::FourierModel) 
 	id = std::max(id, (*it)->tag());
-    if(id > 0) faces.push_back(GMODEL->faceByTag(id));
+    if(id > 0) faces.push_back(m->faceByTag(id));
   }
   else if(what == "delete_all" || what == "save_all"){
-    for(GModel::fiter it = GMODEL->firstFace(); it != GMODEL->lastFace(); it++)
+    for(GModel::fiter it = m->firstFace(); it != m->lastFace(); it++)
       if((*it)->getNativeType() == GEntity::FourierModel)
 	faces.push_back(*it);
   }
diff --git a/Fltk/Main.cpp b/Fltk/Main.cpp
index 330c4b9ff3189c319cb75c0ad8cfbd3e30aab02d..b21983dbbb2355432ec0da74cb10a65206122d1a 100644
--- a/Fltk/Main.cpp
+++ b/Fltk/Main.cpp
@@ -1,4 +1,4 @@
-// $Id: Main.cpp,v 1.107 2007-04-21 19:40:00 geuzaine Exp $
+// $Id: Main.cpp,v 1.108 2007-08-21 19:05:39 geuzaine Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -41,11 +41,11 @@
 #include "GModel.h"
 #include "Field.h"
 #include "BackgroundMesh.h"
+#include "PView.h"
 
 Context_T CTX;
 Mesh *THEM = 0;
 GUI *WID = 0;
-GModel *GMODEL = 0;
 
 int main(int argc, char *argv[])
 {
@@ -70,7 +70,7 @@ int main(int argc, char *argv[])
   }
 
   // Create a new model
-  GMODEL = new GModel;
+  GModel::list.push_back(new GModel);
   THEM = new Mesh;
 
   // Initialize the symbol tree that will hold variable names
@@ -146,7 +146,7 @@ int main(int argc, char *argv[])
       else if(CTX.batch == -1)
         CreateOutputFile(CTX.output_filename, FORMAT_GEO);
       else if(CTX.batch == -2)
-	GMODEL->checkMeshCoherence();
+	GModel::current()->checkMeshCoherence();
       exit(0);
     }
   }
diff --git a/Fltk/Makefile b/Fltk/Makefile
index 8a53ed139dc6dd47bdf943d349b2edac5a413d64..8a2518fbd3d6542c3d2c7fc26064c9d3151a3693 100644
--- a/Fltk/Makefile
+++ b/Fltk/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.140 2007-08-07 22:13:52 anand Exp $
+# $Id: Makefile,v 1.141 2007-08-21 19:05:39 geuzaine Exp $
 #
 # Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 #
@@ -74,23 +74,25 @@ Main.o: Main.cpp GUI.h Opengl_Window.h Colorbar_Window.h \
   ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h ../Geo/SPoint2.h \
   ../Geo/ExtrudeParams.h ../Common/SmoothData.h ../Numeric/Numeric.h \
   ../Mesh/Generator.h ../Parser/CreateFile.h ../Graphics/Draw.h \
-  ../Post/Views.h ../Post/ColorTable.h ../Common/VertexArray.h \
-  ../Post/AdaptiveViews.h ../Common/GmshMatrix.h ../Common/Context.h \
-  ../Common/Options.h ../Parser/Parser.h ../Parser/OpenFile.h \
-  ../Common/CommandLine.h Solvers.h ../Plugin/PluginManager.h \
-  ../Plugin/Plugin.h ../Geo/GModel.h ../Geo/GVertex.h ../Geo/GEntity.h \
-  ../Geo/Range.h ../Geo/SPoint3.h ../Geo/SBoundingBox3d.h \
-  ../Geo/MVertex.h ../Geo/SPoint3.h ../Geo/GPoint.h ../Geo/SPoint2.h \
-  ../Geo/GEdge.h ../Geo/GEntity.h ../Geo/GVertex.h ../Geo/SVector3.h \
-  ../Geo/SPoint3.h ../Geo/SPoint2.h ../Geo/MElement.h ../Geo/MVertex.h \
-  ../Geo/MEdge.h ../Geo/MVertex.h ../Geo/SVector3.h ../Common/Hash.h \
-  ../Geo/MFace.h ../Geo/MVertex.h ../Geo/SVector3.h \
-  ../Geo/ExtrudeParams.h ../Geo/GFace.h ../Geo/GPoint.h ../Geo/GEntity.h \
-  ../Geo/GEdgeLoop.h ../Geo/GEdge.h ../Geo/MElement.h ../Geo/SPoint2.h \
-  ../Geo/SVector3.h ../Geo/Pair.h ../Geo/ExtrudeParams.h ../Geo/GRegion.h \
-  ../Geo/GEntity.h ../Geo/MElement.h ../Geo/ExtrudeParams.h \
-  ../Geo/SBoundingBox3d.h ../Mesh/Field.h ../Post/OctreePost.h \
-  ../Common/Octree.h ../Common/OctreeInternals.h ../Mesh/BackgroundMesh.h
+  ../Common/Context.h ../Common/Options.h ../Parser/Parser.h \
+  ../Parser/OpenFile.h ../Common/CommandLine.h Solvers.h \
+  ../Plugin/PluginManager.h ../Plugin/Plugin.h ../Post/Views.h \
+  ../Post/ColorTable.h ../Common/VertexArray.h ../Post/AdaptiveViews.h \
+  ../Common/GmshMatrix.h ../Geo/GModel.h ../Geo/GVertex.h \
+  ../Geo/GEntity.h ../Geo/Range.h ../Geo/SPoint3.h \
+  ../Geo/SBoundingBox3d.h ../Geo/MVertex.h ../Geo/SPoint3.h \
+  ../Geo/GPoint.h ../Geo/SPoint2.h ../Geo/GEdge.h ../Geo/GEntity.h \
+  ../Geo/GVertex.h ../Geo/SVector3.h ../Geo/SPoint3.h ../Geo/SPoint2.h \
+  ../Geo/MElement.h ../Geo/MVertex.h ../Geo/MEdge.h ../Geo/MVertex.h \
+  ../Geo/SVector3.h ../Common/Hash.h ../Geo/MFace.h ../Geo/MVertex.h \
+  ../Geo/SVector3.h ../Geo/ExtrudeParams.h ../Geo/GFace.h ../Geo/GPoint.h \
+  ../Geo/GEntity.h ../Geo/GEdgeLoop.h ../Geo/GEdge.h ../Geo/MElement.h \
+  ../Geo/SPoint2.h ../Geo/SVector3.h ../Geo/Pair.h ../Geo/ExtrudeParams.h \
+  ../Geo/GRegion.h ../Geo/GEntity.h ../Geo/MElement.h \
+  ../Geo/ExtrudeParams.h ../Geo/SBoundingBox3d.h ../Mesh/Field.h \
+  ../Post/OctreePost.h ../Common/Octree.h ../Common/OctreeInternals.h \
+  ../Mesh/BackgroundMesh.h ../Post/PView.h ../Post/AdaptiveViews.h \
+  ../Post/PViewData.h ../Post/PViewOptions.h ../Post/ColorTable.h
 Message.o: Message.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
   ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h ../DataStr/Tree.h \
@@ -101,22 +103,20 @@ GUI.o: GUI.cpp ../Common/Gmsh.h ../Common/Message.h ../DataStr/Malloc.h \
   ../DataStr/List.h ../DataStr/Tree.h ../DataStr/avl.h ../DataStr/Tools.h \
   ../DataStr/List.h ../DataStr/Tree.h ../Common/GmshUI.h \
   ../Common/GmshDefines.h ../Numeric/Numeric.h ../Common/Context.h \
-  ../Common/Options.h ../Graphics/Draw.h ../Post/Views.h \
+  ../Common/Options.h ../Graphics/Draw.h GUI.h Opengl_Window.h \
+  Colorbar_Window.h ../Post/ColorTable.h Popup_Button.h \
+  SpherePosition_Widget.h Callbacks.h Win32Icon.h ../Parser/OpenFile.h \
+  ../Common/CommandLine.h ../Mesh/Generator.h Solvers.h \
+  ../Plugin/PluginManager.h ../Plugin/Plugin.h ../Post/Views.h \
   ../Post/ColorTable.h ../Common/VertexArray.h ../Common/SmoothData.h \
-  ../Post/AdaptiveViews.h ../Common/GmshMatrix.h GUI.h Opengl_Window.h \
-  Colorbar_Window.h Popup_Button.h SpherePosition_Widget.h Callbacks.h \
-  Win32Icon.h ../Parser/OpenFile.h ../Common/CommandLine.h \
-  ../Mesh/Generator.h Solvers.h ../Plugin/PluginManager.h \
-  ../Plugin/Plugin.h Shortcut_Window.h
+  ../Post/AdaptiveViews.h ../Common/GmshMatrix.h Shortcut_Window.h
 GUI_Extras.o: GUI_Extras.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
   ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h ../DataStr/Tree.h \
   ../Common/GmshUI.h ../Common/GmshDefines.h File_Picker.h \
   ../Parser/CreateFile.h ../Common/Options.h ../Common/Context.h \
-  ../Graphics/Draw.h ../Post/Views.h ../Post/ColorTable.h \
-  ../Common/VertexArray.h ../Common/SmoothData.h ../Numeric/Numeric.h \
-  ../Post/AdaptiveViews.h ../Common/GmshMatrix.h GUI.h Opengl_Window.h \
-  Colorbar_Window.h Popup_Button.h SpherePosition_Widget.h \
+  ../Graphics/Draw.h GUI.h Opengl_Window.h Colorbar_Window.h \
+  ../Post/ColorTable.h Popup_Button.h SpherePosition_Widget.h \
   Shortcut_Window.h
 GUI_Projection.o: GUI_Projection.cpp ../Geo/GModelIO_F.h ../Geo/GModel.h \
   ../Geo/GVertex.h ../Geo/GEntity.h ../Geo/Range.h ../Geo/SPoint3.h \
@@ -132,11 +132,10 @@ GUI_Projection.o: GUI_Projection.cpp ../Geo/GModelIO_F.h ../Geo/GModel.h \
   ../Geo/MElement.h ../Geo/SPoint2.h ../Geo/SVector3.h ../Geo/Pair.h \
   ../Geo/ExtrudeParams.h ../Geo/GRegion.h ../Geo/GEntity.h \
   ../Geo/MElement.h ../Geo/ExtrudeParams.h ../Geo/SBoundingBox3d.h \
-  ../Graphics/Draw.h ../Post/Views.h ../Post/ColorTable.h \
-  ../Common/VertexArray.h ../Post/AdaptiveViews.h ../Common/GmshMatrix.h \
-  ../Common/Options.h ../Graphics/SelectBuffer.h GUI_Projection.h \
-  ../Common/GmshUI.h ../Geo/FProjectionFace.h ../Geo/GModel.h \
-  ../Geo/Range.h GUI.h Opengl_Window.h Colorbar_Window.h Popup_Button.h \
+  ../Graphics/Draw.h ../Common/Options.h ../Parser/OpenFile.h \
+  ../Graphics/SelectBuffer.h GUI_Projection.h ../Common/GmshUI.h \
+  ../Geo/FProjectionFace.h ../Geo/GModel.h ../Geo/Range.h GUI.h \
+  Opengl_Window.h Colorbar_Window.h ../Post/ColorTable.h Popup_Button.h \
   SpherePosition_Widget.h Shortcut_Window.h GUI_Extras.h ../Geo/FFace.h \
   ../Geo/GFace.h ../Geo/GModel.h ../Geo/Range.h ../Geo/FEdge.h \
   ../Geo/GEdge.h ../Geo/GModel.h ../Geo/FVertex.h ../Geo/GModel.h \
@@ -162,9 +161,9 @@ Callbacks.o: Callbacks.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../Geo/GEdge.h ../Geo/MElement.h ../Geo/SPoint2.h ../Geo/SVector3.h \
   ../Geo/Pair.h ../Geo/ExtrudeParams.h ../Geo/GRegion.h ../Geo/GEntity.h \
   ../Geo/MElement.h ../Geo/ExtrudeParams.h ../Geo/SBoundingBox3d.h \
-  ../Graphics/Draw.h ../Post/Views.h ../Post/ColorTable.h \
-  ../Common/VertexArray.h ../Post/AdaptiveViews.h ../Common/GmshMatrix.h \
-  ../Graphics/SelectBuffer.h ../Parser/CreateFile.h ../Parser/OpenFile.h \
+  ../Graphics/Draw.h ../Graphics/SelectBuffer.h ../Post/Views.h \
+  ../Post/ColorTable.h ../Common/VertexArray.h ../Post/AdaptiveViews.h \
+  ../Common/GmshMatrix.h ../Parser/CreateFile.h ../Parser/OpenFile.h \
   ../Common/CommandLine.h ../Common/Options.h GUI.h Opengl_Window.h \
   Colorbar_Window.h Popup_Button.h SpherePosition_Widget.h GUI_Extras.h \
   Callbacks.h ../Plugin/Plugin.h ../Plugin/PluginManager.h \
@@ -175,9 +174,7 @@ Opengl.o: Opengl.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
   ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h ../DataStr/Tree.h \
   ../Common/GmshUI.h ../Numeric/Numeric.h ../Common/Context.h \
-  ../Graphics/Draw.h ../Post/Views.h ../Post/ColorTable.h \
-  ../Common/VertexArray.h ../Common/SmoothData.h ../Post/AdaptiveViews.h \
-  ../Common/GmshMatrix.h ../Graphics/SelectBuffer.h ../Geo/GVertex.h \
+  ../Graphics/Draw.h ../Graphics/SelectBuffer.h ../Geo/GVertex.h \
   ../Geo/GEntity.h ../Geo/Range.h ../Geo/SPoint3.h \
   ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h ../Common/GmshDefines.h \
   ../Geo/MVertex.h ../Geo/SPoint3.h ../Geo/GPoint.h ../Geo/SPoint2.h \
@@ -185,11 +182,12 @@ Opengl.o: Opengl.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../Geo/SPoint3.h ../Geo/SPoint3.h ../Geo/SPoint2.h ../Geo/MElement.h \
   ../Geo/MVertex.h ../Geo/MEdge.h ../Geo/MVertex.h ../Geo/SVector3.h \
   ../Common/Hash.h ../Geo/MFace.h ../Geo/MVertex.h ../Geo/SVector3.h \
-  ../Geo/ExtrudeParams.h ../Geo/GFace.h ../Geo/GPoint.h ../Geo/GEntity.h \
-  ../Geo/GEdgeLoop.h ../Geo/GEdge.h ../Geo/MElement.h ../Geo/SPoint2.h \
-  ../Geo/SVector3.h ../Geo/Pair.h ../Geo/ExtrudeParams.h ../Geo/GRegion.h \
-  ../Geo/GEntity.h ../Geo/MElement.h ../Geo/ExtrudeParams.h GUI.h \
-  Opengl_Window.h Colorbar_Window.h Popup_Button.h \
+  ../Geo/ExtrudeParams.h ../Common/SmoothData.h ../Geo/GFace.h \
+  ../Geo/GPoint.h ../Geo/GEntity.h ../Geo/GEdgeLoop.h ../Geo/GEdge.h \
+  ../Geo/MElement.h ../Geo/SPoint2.h ../Geo/SVector3.h ../Geo/Pair.h \
+  ../Geo/ExtrudeParams.h ../Geo/GRegion.h ../Geo/GEntity.h \
+  ../Geo/MElement.h ../Geo/ExtrudeParams.h GUI.h Opengl_Window.h \
+  Colorbar_Window.h ../Post/ColorTable.h Popup_Button.h \
   SpherePosition_Widget.h ../Graphics/gl2ps.h
 Opengl_Window.o: Opengl_Window.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
@@ -199,21 +197,19 @@ Opengl_Window.o: Opengl_Window.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../Geo/Range.h ../Geo/SPoint2.h ../Geo/SPoint3.h ../Geo/SVector3.h \
   ../Geo/SPoint3.h ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h \
   ../Geo/SPoint2.h ../Geo/ExtrudeParams.h ../Common/SmoothData.h \
-  ../Graphics/Draw.h ../Post/Views.h ../Post/ColorTable.h \
-  ../Common/VertexArray.h ../Post/AdaptiveViews.h ../Common/GmshMatrix.h \
-  ../Graphics/SelectBuffer.h ../Geo/GVertex.h ../Geo/GEntity.h \
-  ../Geo/Range.h ../Geo/SPoint3.h ../Geo/SBoundingBox3d.h \
-  ../Geo/MVertex.h ../Geo/SPoint3.h ../Geo/GPoint.h ../Geo/SPoint2.h \
-  ../Geo/GEdge.h ../Geo/GEntity.h ../Geo/GVertex.h ../Geo/SVector3.h \
-  ../Geo/SPoint3.h ../Geo/SPoint2.h ../Geo/MElement.h ../Geo/MVertex.h \
-  ../Geo/MEdge.h ../Geo/MVertex.h ../Geo/SVector3.h ../Common/Hash.h \
-  ../Geo/MFace.h ../Geo/MVertex.h ../Geo/SVector3.h \
-  ../Geo/ExtrudeParams.h ../Geo/GFace.h ../Geo/GPoint.h ../Geo/GEntity.h \
-  ../Geo/GEdgeLoop.h ../Geo/GEdge.h ../Geo/MElement.h ../Geo/SPoint2.h \
-  ../Geo/SVector3.h ../Geo/Pair.h ../Geo/ExtrudeParams.h ../Geo/GRegion.h \
-  ../Geo/GEntity.h ../Geo/MElement.h ../Geo/ExtrudeParams.h GUI.h \
-  Opengl_Window.h Colorbar_Window.h Popup_Button.h \
-  SpherePosition_Widget.h
+  ../Graphics/Draw.h ../Graphics/SelectBuffer.h ../Geo/GVertex.h \
+  ../Geo/GEntity.h ../Geo/Range.h ../Geo/SPoint3.h \
+  ../Geo/SBoundingBox3d.h ../Geo/MVertex.h ../Geo/SPoint3.h \
+  ../Geo/GPoint.h ../Geo/SPoint2.h ../Geo/GEdge.h ../Geo/GEntity.h \
+  ../Geo/GVertex.h ../Geo/SVector3.h ../Geo/SPoint3.h ../Geo/SPoint2.h \
+  ../Geo/MElement.h ../Geo/MVertex.h ../Geo/MEdge.h ../Geo/MVertex.h \
+  ../Geo/SVector3.h ../Common/Hash.h ../Geo/MFace.h ../Geo/MVertex.h \
+  ../Geo/SVector3.h ../Geo/ExtrudeParams.h ../Geo/GFace.h ../Geo/GPoint.h \
+  ../Geo/GEntity.h ../Geo/GEdgeLoop.h ../Geo/GEdge.h ../Geo/MElement.h \
+  ../Geo/SPoint2.h ../Geo/SVector3.h ../Geo/Pair.h ../Geo/ExtrudeParams.h \
+  ../Geo/GRegion.h ../Geo/GEntity.h ../Geo/MElement.h \
+  ../Geo/ExtrudeParams.h GUI.h Opengl_Window.h Colorbar_Window.h \
+  ../Post/ColorTable.h Popup_Button.h SpherePosition_Widget.h
 Colorbar_Window.o: Colorbar_Window.cpp ../Common/Gmsh.h \
   ../Common/Message.h ../DataStr/Malloc.h ../DataStr/List.h \
   ../DataStr/Tree.h ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h \
@@ -225,7 +221,4 @@ Solvers.o: Solvers.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h ../DataStr/Tree.h \
   Solvers.h GmshServer.h ../Parser/OpenFile.h ../Common/GmshUI.h GUI.h \
   Opengl_Window.h Colorbar_Window.h ../Post/ColorTable.h Popup_Button.h \
-  SpherePosition_Widget.h ../Graphics/Draw.h ../Post/Views.h \
-  ../Post/ColorTable.h ../Common/VertexArray.h ../Common/SmoothData.h \
-  ../Numeric/Numeric.h ../Post/AdaptiveViews.h ../Common/GmshMatrix.h \
-  ../Common/Context.h
+  SpherePosition_Widget.h ../Graphics/Draw.h ../Common/Context.h
diff --git a/Geo/GModel.cpp b/Geo/GModel.cpp
index 0bff15a530a0fbc7a8c4ff0aeb791f05e2b5ba0a..3ece4f48e29b225df118cb7c153d950ca9b9aa91 100644
--- a/Geo/GModel.cpp
+++ b/Geo/GModel.cpp
@@ -1,4 +1,4 @@
-// $Id: GModel.cpp,v 1.45 2007-08-06 21:22:58 geuzaine Exp $
+// $Id: GModel.cpp,v 1.46 2007-08-21 19:05:39 geuzaine Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -25,6 +25,18 @@
 #include "MRep.h"
 #include "BackgroundMesh.h"
 
+std::vector<GModel*> GModel::list;
+
+GModel *GModel::current()
+{ 
+  if(list.empty()){
+    Msg(GERROR, "No model available");
+    return 0;
+  }
+  // return last one for now
+  return list.back();
+}
+
 void GModel::destroy()
 {
   std::vector<GFace*> to_keep;
diff --git a/Geo/GModel.h b/Geo/GModel.h
index 863e31c46742ed45610fa270b44352fb259a5a44..b0ed6925a54f0c7b69466cf301b815a88cb04506 100644
--- a/Geo/GModel.h
+++ b/Geo/GModel.h
@@ -56,6 +56,11 @@ class GModel
   GModel(const std::string &name) : modelName(name), normals(0) {}
   ~GModel(){ deleteOCCInternals(); destroy(); }
   
+  // the static list of all loaded models
+  static std::vector<GModel*> list;
+  // returns the current model
+  static GModel *current();
+
   typedef std::set<GRegion*, GEntityLessThan>::iterator riter;
   typedef std::set<GFace*, GEntityLessThan>::iterator fiter;
   typedef std::set<GEdge*, GEntityLessThan>::iterator eiter;
diff --git a/Geo/GModelIO_F.cpp b/Geo/GModelIO_F.cpp
index b60bd3dbac0ea513a00f671aa9c8394380692a9c..5c5b75550fff12989c50f47555133b8490c8a7d8 100644
--- a/Geo/GModelIO_F.cpp
+++ b/Geo/GModelIO_F.cpp
@@ -15,8 +15,6 @@
 #include "FM_TopoFace.h"
 #include "FM_Reader.h"
 
-extern GModel *GMODEL;
-
 void makeGFace(FM::Patch* patch)
 {
   double LL[2], LR[2], UL[2], UR[2];
@@ -28,56 +26,58 @@ void makeGFace(FM::Patch* patch)
   int i1, i2;
   double xx,yy,zz;
   
-  int tagVertex = GMODEL->numVertex();
-  patch->F(LL[0],LL[1],xx,yy,zz);
-  FM::TopoVertex* vLL = new FM::TopoVertex(++tagVertex,xx,yy,zz);
-  GMODEL->add(new FVertex(GMODEL,vLL->GetTag(),vLL));
-  patch->F(LR[0],LR[1],xx,yy,zz);
-  FM::TopoVertex* vLR = new FM::TopoVertex(++tagVertex,xx,yy,zz);
-  GMODEL->add(new FVertex(GMODEL,vLR->GetTag(),vLR));
-  patch->F(UL[0],UL[1],xx,yy,zz);
-  FM::TopoVertex* vUL = new FM::TopoVertex(++tagVertex,xx,yy,zz);
-  GMODEL->add(new FVertex(GMODEL,vUL->GetTag(),vUL));
-  patch->F(UR[0],UR[1],xx,yy,zz);
-  FM::TopoVertex* vUR = new FM::TopoVertex(++tagVertex,xx,yy,zz);
-  GMODEL->add(new FVertex(GMODEL,vUR->GetTag(),vUR));
+  GModel *m = GModel::current();
+
+  int tagVertex = m->numVertex();
+  patch->F(LL[0], LL[1], xx, yy, zz);
+  FM::TopoVertex* vLL = new FM::TopoVertex(++tagVertex, xx, yy, zz);
+  m->add(new FVertex(m, vLL->GetTag(), vLL));
+  patch->F(LR[0], LR[1], xx, yy, zz);
+  FM::TopoVertex* vLR = new FM::TopoVertex(++tagVertex, xx, yy, zz);
+  m->add(new FVertex(m, vLR->GetTag(), vLR));
+  patch->F(UL[0], UL[1], xx, yy, zz);
+  FM::TopoVertex* vUL = new FM::TopoVertex(++tagVertex, xx, yy, zz);
+  m->add(new FVertex(m, vUL->GetTag(), vUL));
+  patch->F(UR[0], UR[1], xx, yy, zz);
+  FM::TopoVertex* vUR = new FM::TopoVertex(++tagVertex, xx, yy, zz);
+  m->add(new FVertex(m, vUR->GetTag(), vUR));
   
-  FM::Curve* curveB = new FM::FCurve(0,patch,LL,LR);
-  FM::Curve* curveR = new FM::FCurve(0,patch,LR,UR);
-  FM::Curve* curveT = new FM::FCurve(0,patch,UR,UL);
-  FM::Curve* curveL = new FM::FCurve(0,patch,UL,LL);
+  FM::Curve* curveB = new FM::FCurve(0, patch, LL, LR);
+  FM::Curve* curveR = new FM::FCurve(0, patch, LR, UR);
+  FM::Curve* curveT = new FM::FCurve(0, patch, UR, UL);
+  FM::Curve* curveL = new FM::FCurve(0, patch, UL, LL);
   
-  int tagEdge = GMODEL->numEdge();
-  FM::TopoEdge* eB = new FM::TopoEdge(++tagEdge,curveB,vLL,vLR);
+  int tagEdge = m->numEdge();
+  FM::TopoEdge* eB = new FM::TopoEdge(++tagEdge, curveB, vLL, vLR);
   i1 = eB->GetStartPoint()->GetTag();
   i2 = eB->GetEndPoint()->GetTag();
-  GMODEL->add(new FEdge(GMODEL,eB,eB->GetTag(),GMODEL->vertexByTag(i1),
-			GMODEL->vertexByTag(i2)));
-  FM::TopoEdge* eR = new FM::TopoEdge(++tagEdge,curveR,vLR,vUR); 
+  m->add(new FEdge(m, eB, eB->GetTag(), m->vertexByTag(i1),
+		   m->vertexByTag(i2)));
+  FM::TopoEdge* eR = new FM::TopoEdge(++tagEdge, curveR, vLR, vUR); 
   i1 = eR->GetStartPoint()->GetTag();
   i2 = eR->GetEndPoint()->GetTag();
-  GMODEL->add(new FEdge(GMODEL,eR,eR->GetTag(),GMODEL->vertexByTag(i1),
-			GMODEL->vertexByTag(i2))); 
-  FM::TopoEdge* eT = new FM::TopoEdge(++tagEdge,curveT,vUR,vUL);
+  m->add(new FEdge(m, eR, eR->GetTag(), m->vertexByTag(i1),
+		   m->vertexByTag(i2))); 
+  FM::TopoEdge* eT = new FM::TopoEdge(++tagEdge, curveT, vUR, vUL);
   i1 = eT->GetStartPoint()->GetTag();
   i2 = eT->GetEndPoint()->GetTag();
-  GMODEL->add(new FEdge(GMODEL,eT,eT->GetTag(),GMODEL->vertexByTag(i1),
-			GMODEL->vertexByTag(i2)));
-  FM::TopoEdge* eL = new FM::TopoEdge(++tagEdge,curveL,vUL,vLL); 
+  m->add(new FEdge(m, eT, eT->GetTag(), m->vertexByTag(i1),
+		   m->vertexByTag(i2)));
+  FM::TopoEdge* eL = new FM::TopoEdge(++tagEdge, curveL, vUL, vLL); 
   i1 = eL->GetStartPoint()->GetTag();
   i2 = eL->GetEndPoint()->GetTag();
-  GMODEL->add(new FEdge(GMODEL,eL,eL->GetTag(),GMODEL->vertexByTag(i1),
-			GMODEL->vertexByTag(i2)));
+  m->add(new FEdge(m, eL, eL->GetTag(), m->vertexByTag(i1),
+		   m->vertexByTag(i2)));
   
-  FM::TopoFace* face = new FM::TopoFace(GMODEL->numFace() + 1,patch);
+  FM::TopoFace* face = new FM::TopoFace(m->numFace() + 1, patch);
   face->AddEdge(eB); face->AddEdge(eR); 
   face->AddEdge(eT); face->AddEdge(eL);
   std::list<GEdge*> l_edges;
-  for (int j=0;j<face->GetNumEdges();j++) {
+  for (int j = 0; j < face->GetNumEdges(); j++) {
     int tag = face->GetEdge(j)->GetTag(); 
-    l_edges.push_back(GMODEL->edgeByTag(tag));
+    l_edges.push_back(m->edgeByTag(tag));
   }
-  GMODEL->add(new FFace(GMODEL,face,face->GetTag(),l_edges));
+  m->add(new FFace(m, face, face->GetTag(), l_edges));
 }
 
 int GModel::readF(const std::string &filename)
diff --git a/Geo/Geo.cpp b/Geo/Geo.cpp
index 929c196313c5ee405ab8cd4b754fc2a4e86a16ce..bea26778977a0739e9ecec362d3d878d805883bb 100644
--- a/Geo/Geo.cpp
+++ b/Geo/Geo.cpp
@@ -1,4 +1,4 @@
-// $Id: Geo.cpp,v 1.89 2007-07-25 15:48:32 geuzaine Exp $
+// $Id: Geo.cpp,v 1.90 2007-08-21 19:05:39 geuzaine Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -28,7 +28,6 @@
 
 extern Mesh *THEM;
 extern Context_T CTX;
-extern GModel *GMODEL;
 
 static List_T *ListOfTransformedPoints = NULL;
 
@@ -49,13 +48,13 @@ void Mesh::free_all()
 {
   MaxPointNum = MaxLineNum = MaxLineLoopNum = MaxSurfaceNum = 0;
   MaxSurfaceLoopNum = MaxVolumeNum = MaxPhysicalNum = 0;
-  Tree_Action(THEM->Points, Free_Vertex); Tree_Delete(THEM->Points);
-  Tree_Action(THEM->Curves, Free_Curve); Tree_Delete(THEM->Curves);
-  Tree_Action(THEM->EdgeLoops, Free_EdgeLoop); Tree_Delete(THEM->EdgeLoops);
-  Tree_Action(THEM->Surfaces, Free_Surface); Tree_Delete(THEM->Surfaces);
-  Tree_Action(THEM->SurfaceLoops, Free_SurfaceLoop); Tree_Delete(THEM->SurfaceLoops);
-  Tree_Action(THEM->Volumes, Free_Volume); Tree_Delete(THEM->Volumes);
-  List_Action(THEM->PhysicalGroups, Free_PhysicalGroup); List_Delete(THEM->PhysicalGroups);
+  Tree_Action(Points, Free_Vertex); Tree_Delete(Points);
+  Tree_Action(Curves, Free_Curve); Tree_Delete(Curves);
+  Tree_Action(EdgeLoops, Free_EdgeLoop); Tree_Delete(EdgeLoops);
+  Tree_Action(Surfaces, Free_Surface); Tree_Delete(Surfaces);
+  Tree_Action(SurfaceLoops, Free_SurfaceLoop); Tree_Delete(SurfaceLoops);
+  Tree_Action(Volumes, Free_Volume); Tree_Delete(Volumes);
+  List_Action(PhysicalGroups, Free_PhysicalGroup); List_Delete(PhysicalGroups);
 }
 
 // Comparison routines
@@ -3066,7 +3065,7 @@ void setVolumeSurfaces(Volume *v, List_T *loops)
 	  List_Add(v->SurfacesOrientations, &tmp);
 	}
 	else{
-	  GFace *gf = GMODEL->faceByTag(abs(is));
+	  GFace *gf = GModel::current()->faceByTag(abs(is));
 	  if(gf) {
 	    List_Add(v->SurfacesByTag, &is);
 	  }
diff --git a/Geo/GeoStringInterface.cpp b/Geo/GeoStringInterface.cpp
index a2a8f5a7451acdddc224f0bcf32e967c1db22f67..18c108b6bf80dd775b66ed51b4ad8427a7fdf9bc 100644
--- a/Geo/GeoStringInterface.cpp
+++ b/Geo/GeoStringInterface.cpp
@@ -1,4 +1,4 @@
-// $Id: GeoStringInterface.cpp,v 1.9 2007-08-17 15:43:07 geuzaine Exp $
+// $Id: GeoStringInterface.cpp,v 1.10 2007-08-21 19:05:39 geuzaine Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -29,7 +29,6 @@
 #include "GModel.h"
 
 extern Context_T CTX;
-extern GModel *GMODEL;
 
 #define BUFFSIZE 128000
 
@@ -97,9 +96,9 @@ void add_infile(char *text, char *fich, bool deleted_something)
   if(deleted_something){
     // we need to start from scratch since the command just parsed
     // could have deleted some entities
-    GMODEL->destroy();
+    GModel::current()->destroy();
   }
-  GMODEL->importTHEM();
+  GModel::current()->importTHEM();
   CTX.mesh.changed = ENT_ALL;
 
   FILE *file;
diff --git a/Geo/Makefile b/Geo/Makefile
index 96fa18deed16a9d73fda303794562ad925604154..e8c88f6b2373eacd7e0cf3c3e6acb5671a83b411 100644
--- a/Geo/Makefile
+++ b/Geo/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.156 2007-08-07 22:13:53 anand Exp $
+# $Id: Makefile,v 1.157 2007-08-21 19:05:39 geuzaine Exp $
 #
 # Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 #
@@ -221,7 +221,7 @@ GModelIO_F.o: GModelIO_F.cpp GModel.h GVertex.h GEntity.h Range.h \
   SPoint2.h GEdge.h SVector3.h MElement.h MEdge.h ../Common/Hash.h \
   MFace.h ../Numeric/Numeric.h ../Common/Context.h ../DataStr/List.h \
   ExtrudeParams.h ../Common/SmoothData.h GFace.h GEdgeLoop.h Pair.h \
-  GRegion.h ../Common/Message.h FFace.h FEdge.h FVertex.h GModelIO_F.h
+  GRegion.h ../Common/Message.h FVertex.h FEdge.h FFace.h GModelIO_F.h
 GModelIO_CGNS.o: GModelIO_CGNS.cpp GModel.h GVertex.h GEntity.h Range.h \
   SPoint3.h SBoundingBox3d.h ../Common/GmshDefines.h MVertex.h GPoint.h \
   SPoint2.h GEdge.h SVector3.h MElement.h MEdge.h ../Common/Hash.h \
diff --git a/Geo/findLinks.cpp b/Geo/findLinks.cpp
index 3698a484124e7d872f3dbe6cfaab5d23106156eb..65152dc2b1fcccd48d0f5fe780ebc9e3721d4413 100644
--- a/Geo/findLinks.cpp
+++ b/Geo/findLinks.cpp
@@ -1,4 +1,4 @@
-// $Id: findLinks.cpp,v 1.1 2007-02-15 08:26:46 geuzaine Exp $
+// $Id: findLinks.cpp,v 1.2 2007-08-21 19:05:39 geuzaine Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -22,8 +22,6 @@
 #include "Gmsh.h"
 #include "GModel.h"
 
-extern GModel *GMODEL;
-
 typedef struct{
   int n, a;
 }nxa;
@@ -47,7 +45,7 @@ static int complink(const void *a, const void *b)
 static void recurFindLinkedEdges(int ed, List_T *edges, Tree_T *points,
 				 Tree_T *links)
 {
-  GEdge *ge = GMODEL->edgeByTag(ed);
+  GEdge *ge = GModel::current()->edgeByTag(ed);
   if(!ge){
     Msg(GERROR, "Unknown curve %d", ed);
     return;
@@ -82,7 +80,8 @@ static void recurFindLinkedEdges(int ed, List_T *edges, Tree_T *points,
 
 static int createEdgeLinks(Tree_T *links)
 {
-  for(GModel::eiter it = GMODEL->firstEdge(); it != GMODEL->lastEdge(); it++) {
+  GModel *m = GModel::current();
+  for(GModel::eiter it = m->firstEdge(); it != m->lastEdge(); it++) {
     GEdge *ge = *it;;
     if(!ge->getBeginVertex() || !ge->getEndVertex()){
       Msg(GERROR, "Cannot link curves with no begin or end points");
@@ -121,7 +120,7 @@ static void orientAndSortEdges(List_T *edges, Tree_T *links)
   List_Read(temp, 0, &num);
   List_Add(edges, &num);
 
-  GEdge *ge0 = GMODEL->edgeByTag(abs(num));
+  GEdge *ge0 = GModel::current()->edgeByTag(abs(num));
   if(!ge0){
     Msg(GERROR, "Unknown curve %d", abs(num));
     return;
@@ -139,7 +138,7 @@ static void orientAndSortEdges(List_T *edges, Tree_T *links)
       nxa na;
       List_Read(lk.l, j, &na);
       if(ge0->tag() != na.a && List_Search(temp, &na.a, fcmp_absint)){
-	GEdge *ge1 = GMODEL->edgeByTag(abs(na.a));
+	GEdge *ge1 = GModel::current()->edgeByTag(abs(na.a));
 	if(!ge1){
 	  Msg(GERROR, "Unknown curve %d", abs(na.a));
 	  return;
@@ -174,7 +173,7 @@ int allEdgesLinked(int ed, List_T *edges)
   for(int i = 0; i < List_Nbr(edges); i++){
     int num;
     List_Read(edges, i, &num);
-    GEdge *ge = GMODEL->edgeByTag(abs(num));
+    GEdge *ge = GModel::current()->edgeByTag(abs(num));
     if(!ge){
       Msg(GERROR, "Unknown curve %d", abs(num));
       return 0;
@@ -218,7 +217,7 @@ int allEdgesLinked(int ed, List_T *edges)
 static void recurFindLinkedFaces(int fac, List_T *faces, Tree_T *edges, 
 				 Tree_T *links)
 {
-  GFace *gf = GMODEL->faceByTag(abs(fac));
+  GFace *gf = GModel::current()->faceByTag(abs(fac));
   if(!gf){
     Msg(GERROR, "Unknown surface %d", abs(fac));
     return;
@@ -251,7 +250,8 @@ static void recurFindLinkedFaces(int fac, List_T *faces, Tree_T *edges,
 
 static void createFaceLinks(Tree_T *links)
 {
-  for(GModel::fiter it = GMODEL->firstFace(); it != GMODEL->lastFace(); it++) {
+  GModel *m = GModel::current();
+  for(GModel::fiter it = m->firstFace(); it != m->lastFace(); it++) {
     GFace *gf = *it;
     if(gf->tag() > 0){
       nxa na;
@@ -285,7 +285,7 @@ int allFacesLinked(int fac, List_T *faces)
   for(int i = 0; i < List_Nbr(faces); i++){
     int num;
     List_Read(faces, i, &num);
-    GFace *gf = GMODEL->faceByTag(abs(num));
+    GFace *gf = GModel::current()->faceByTag(abs(num));
     if(!gf){
       Msg(GERROR, "Unknown surface %d", abs(num));
       return 0;
diff --git a/Graphics/Draw.cpp b/Graphics/Draw.cpp
index f6f564b9616c9dec32cdaae36a3bbb143ad2e39e..ebfa30950ce2eb348c4e0e4e026639955453d8a0 100644
--- a/Graphics/Draw.cpp
+++ b/Graphics/Draw.cpp
@@ -1,4 +1,4 @@
-// $Id: Draw.cpp,v 1.109 2006-11-27 22:22:14 geuzaine Exp $
+// $Id: Draw.cpp,v 1.110 2007-08-21 19:05:39 geuzaine Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -26,16 +26,17 @@
 #include "Context.h"
 #include "Numeric.h"
 #include "GModel.h"
+#include "Views.h"
 
 extern Context_T CTX;
-extern GModel *GMODEL;
 
 int NeedPolygonOffset()
 {
-  if(GMODEL->getMeshStatus() == 2 &&
+  GModel *m = GModel::current();
+  if(m->getMeshStatus() == 2 &&
      (CTX.mesh.surfaces_edges || CTX.geom.lines || CTX.geom.surfaces))
     return 1;
-  if(GMODEL->getMeshStatus() == 3 && 
+  if(m->getMeshStatus() == 3 && 
      (CTX.mesh.surfaces_edges || CTX.mesh.volumes_edges))
     return 1;
   for(int i = 0; i < List_Nbr(CTX.post.list); i++){
@@ -77,6 +78,7 @@ void Draw3d(void)
   Draw_Geom();
   Draw_Mesh();
   Draw_Post();
+  Draw_Post_New();
 }
 
 void Draw2d(void)
diff --git a/Graphics/Draw.h b/Graphics/Draw.h
index 011ce437eb54a007208a790ed443afdb2c9d8ca5..0518fff12c0108b1f02b2f7aa9d61d65200fc628 100644
--- a/Graphics/Draw.h
+++ b/Graphics/Draw.h
@@ -20,8 +20,10 @@
 // 
 // Please report all bugs and problems to <gmsh@geuz.org>.
 
+#include <vector>
 #include "List.h"
-#include "Views.h"
+
+class Post_View;
 
 #define GMSH_RENDER    1
 #define GMSH_SELECT    2
@@ -54,6 +56,7 @@ void Draw_String_Right(char *s);
 void Draw_Geom(void);
 void Draw_Mesh(void);
 void Draw_Post(void);
+void Draw_Post_New();
 void Draw_Graph2D(void);
 void Draw_Text2D(void);
 void Draw_Text2D3D(int dim, int timestep, int nb, List_T *td, List_T *tc);
diff --git a/Graphics/Entity.cpp b/Graphics/Entity.cpp
index d21e36ecfa06a6a685f8c20436022c978775ac7c..ffac8f692fe49e8bf63dc0adce007f248ada5b05 100644
--- a/Graphics/Entity.cpp
+++ b/Graphics/Entity.cpp
@@ -1,4 +1,4 @@
-// $Id: Entity.cpp,v 1.72 2007-06-22 12:08:16 remacle Exp $
+// $Id: Entity.cpp,v 1.73 2007-08-21 19:05:39 geuzaine Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -23,6 +23,7 @@
 #include "GmshUI.h"
 #include "Numeric.h"
 #include "Draw.h"
+#include "Views.h"
 #include "Context.h"
 #include "gl2ps.h"
 
diff --git a/Graphics/Geom.cpp b/Graphics/Geom.cpp
index d319321e6fe950df310463ae8ca4680bfab90ed2..22eb6c40827acf7484848aaf181da5a9d9b01374 100644
--- a/Graphics/Geom.cpp
+++ b/Graphics/Geom.cpp
@@ -1,4 +1,4 @@
-// $Id: Geom.cpp,v 1.137 2007-08-17 17:51:27 geuzaine Exp $
+// $Id: Geom.cpp,v 1.138 2007-08-21 19:05:39 geuzaine Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -28,7 +28,6 @@
 #include "SBoundingBox3d.h"
 
 extern Context_T CTX;
-extern GModel *GMODEL;
 
 class drawGVertex {
  public :
@@ -453,8 +452,7 @@ class drawGRegion {
     else
       glColor4ubv((GLubyte *) & CTX.color.geom.volume);
     
-    SBoundingBox3d bb = r->bounds();
-    SPoint3 p = bb.center();
+    SPoint3 p = r->bounds().center();
     const double size = 8.;
 
     if(CTX.geom.volumes)
@@ -489,23 +487,25 @@ void Draw_Geom()
     else
       glDisable((GLenum)(GL_CLIP_PLANE0 + i));
   
+  GModel *m = GModel::current();
+
   if(CTX.geom.points || CTX.geom.points_num)
-    std::for_each(GMODEL->firstVertex(), GMODEL->lastVertex(), drawGVertex());
+    std::for_each(m->firstVertex(), m->lastVertex(), drawGVertex());
 
   if(CTX.geom.lines || CTX.geom.lines_num || CTX.geom.tangents)
-    std::for_each(GMODEL->firstEdge(), GMODEL->lastEdge(), drawGEdge());
+    std::for_each(m->firstEdge(), m->lastEdge(), drawGEdge());
 
   if(CTX.geom.surfaces || CTX.geom.surfaces_num || CTX.geom.normals)
-    std::for_each(GMODEL->firstFace(), GMODEL->lastFace(), drawGFace());
+    std::for_each(m->firstFace(), m->lastFace(), drawGFace());
 
   if(CTX.geom.volumes || CTX.geom.volumes_num)
-    std::for_each(GMODEL->firstRegion(), GMODEL->lastRegion(), drawGRegion());
+    std::for_each(m->firstRegion(), m->lastRegion(), drawGRegion());
 
   for(int i = 0; i < 6; i++)
     glDisable((GLenum)(GL_CLIP_PLANE0 + i));
 
   bool geometryExists = 
-    GMODEL->numVertex() || GMODEL->numEdge() || GMODEL->numFace() || GMODEL->numRegion();
+    m->numVertex() || m->numEdge() || m->numFace() || m->numRegion();
 
   if(geometryExists && (CTX.draw_bbox || !CTX.mesh.draw)) {
     glColor4ubv((GLubyte *) & CTX.color.fg);
diff --git a/Graphics/Makefile b/Graphics/Makefile
index b65caf843cabe09055abf16229857d11828edf01..c83df1797bfa0dc4812cc6b0d5a8601e29d16114 100644
--- a/Graphics/Makefile
+++ b/Graphics/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.118 2007-07-09 13:54:36 geuzaine Exp $
+# $Id: Makefile,v 1.119 2007-08-21 19:05:39 geuzaine Exp $
 #
 # Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 #
@@ -29,7 +29,7 @@ CFLAGS  = ${OPTIM} ${FLAGS} ${INCLUDE}
 SRC = Draw.cpp \
       Mesh.cpp \
       Geom.cpp \
-      Post.cpp \
+      Post.cpp Post_New.cpp \
       PostElement.cpp \
       SelectBuffer.cpp \
       Iso.cpp \
@@ -70,9 +70,7 @@ depend:
 Draw.o: Draw.cpp ../Common/Gmsh.h ../Common/Message.h ../DataStr/Malloc.h \
   ../DataStr/List.h ../DataStr/Tree.h ../DataStr/avl.h ../DataStr/Tools.h \
   ../DataStr/List.h ../DataStr/Tree.h ../Common/GmshUI.h \
-  ../Common/GmshDefines.h Draw.h ../Post/Views.h ../Post/ColorTable.h \
-  ../Common/VertexArray.h ../Common/SmoothData.h ../Numeric/Numeric.h \
-  ../Post/AdaptiveViews.h ../Common/GmshMatrix.h ../Common/Context.h \
+  ../Common/GmshDefines.h Draw.h ../Common/Context.h ../Numeric/Numeric.h \
   ../Geo/GModel.h ../Geo/GVertex.h ../Geo/GEntity.h ../Geo/Range.h \
   ../Geo/SPoint3.h ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h \
   ../Geo/MVertex.h ../Geo/SPoint3.h ../Geo/GPoint.h ../Geo/SPoint2.h \
@@ -80,11 +78,13 @@ Draw.o: Draw.cpp ../Common/Gmsh.h ../Common/Message.h ../DataStr/Malloc.h \
   ../Geo/SPoint3.h ../Geo/SPoint3.h ../Geo/SPoint2.h ../Geo/MElement.h \
   ../Geo/MVertex.h ../Geo/MEdge.h ../Geo/MVertex.h ../Geo/SVector3.h \
   ../Common/Hash.h ../Geo/MFace.h ../Geo/MVertex.h ../Geo/SVector3.h \
-  ../Geo/ExtrudeParams.h ../Geo/GFace.h ../Geo/GPoint.h ../Geo/GEntity.h \
-  ../Geo/GEdgeLoop.h ../Geo/GEdge.h ../Geo/MElement.h ../Geo/SPoint2.h \
-  ../Geo/SVector3.h ../Geo/Pair.h ../Geo/ExtrudeParams.h ../Geo/GRegion.h \
-  ../Geo/GEntity.h ../Geo/MElement.h ../Geo/ExtrudeParams.h \
-  ../Geo/SBoundingBox3d.h
+  ../Geo/ExtrudeParams.h ../Common/SmoothData.h ../Geo/GFace.h \
+  ../Geo/GPoint.h ../Geo/GEntity.h ../Geo/GEdgeLoop.h ../Geo/GEdge.h \
+  ../Geo/MElement.h ../Geo/SPoint2.h ../Geo/SVector3.h ../Geo/Pair.h \
+  ../Geo/ExtrudeParams.h ../Geo/GRegion.h ../Geo/GEntity.h \
+  ../Geo/MElement.h ../Geo/ExtrudeParams.h ../Geo/SBoundingBox3d.h \
+  ../Post/Views.h ../Post/ColorTable.h ../Common/VertexArray.h \
+  ../Post/AdaptiveViews.h ../Common/GmshMatrix.h
 Mesh.o: Mesh.cpp ../Common/Gmsh.h ../Common/Message.h ../DataStr/Malloc.h \
   ../DataStr/List.h ../DataStr/Tree.h ../DataStr/avl.h ../DataStr/Tools.h \
   ../DataStr/List.h ../DataStr/Tree.h ../Common/GmshUI.h ../Geo/GModel.h \
@@ -100,69 +100,82 @@ Mesh.o: Mesh.cpp ../Common/Gmsh.h ../Common/Message.h ../DataStr/Malloc.h \
   ../Geo/GEdgeLoop.h ../Geo/GEdge.h ../Geo/MElement.h ../Geo/SPoint2.h \
   ../Geo/SVector3.h ../Geo/Pair.h ../Geo/ExtrudeParams.h ../Geo/GRegion.h \
   ../Geo/GEntity.h ../Geo/MElement.h ../Geo/ExtrudeParams.h \
-  ../Geo/SBoundingBox3d.h Draw.h ../Post/Views.h ../Post/ColorTable.h \
-  ../Common/VertexArray.h ../Post/AdaptiveViews.h ../Common/GmshMatrix.h \
-  ../Geo/MRep.h ../Geo/GEdge.h ../Geo/GFace.h ../Geo/GRegion.h \
-  ../Geo/MVertex.h ../Geo/MEdge.h ../Geo/MElement.h ../Common/OS.h \
-  gl2ps.h
+  ../Geo/SBoundingBox3d.h Draw.h ../Geo/MRep.h ../Geo/GEdge.h \
+  ../Geo/GFace.h ../Geo/GRegion.h ../Geo/MVertex.h ../Geo/MEdge.h \
+  ../Geo/MElement.h ../Common/VertexArray.h ../Common/OS.h gl2ps.h
 Geom.o: Geom.cpp ../Common/Gmsh.h ../Common/Message.h ../DataStr/Malloc.h \
   ../DataStr/List.h ../DataStr/Tree.h ../DataStr/avl.h ../DataStr/Tools.h \
   ../DataStr/List.h ../DataStr/Tree.h ../Common/GmshUI.h Draw.h \
-  ../Post/Views.h ../Post/ColorTable.h ../Common/VertexArray.h \
-  ../Common/SmoothData.h ../Numeric/Numeric.h ../Post/AdaptiveViews.h \
-  ../Common/GmshMatrix.h ../Common/Context.h gl2ps.h ../Geo/GModel.h \
-  ../Geo/GVertex.h ../Geo/GEntity.h ../Geo/Range.h ../Geo/SPoint3.h \
+  ../Common/Context.h gl2ps.h ../Geo/GModel.h ../Geo/GVertex.h \
+  ../Geo/GEntity.h ../Geo/Range.h ../Geo/SPoint3.h \
   ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h ../Common/GmshDefines.h \
   ../Geo/MVertex.h ../Geo/SPoint3.h ../Geo/GPoint.h ../Geo/SPoint2.h \
   ../Geo/GEdge.h ../Geo/GEntity.h ../Geo/GVertex.h ../Geo/SVector3.h \
   ../Geo/SPoint3.h ../Geo/SPoint3.h ../Geo/SPoint2.h ../Geo/MElement.h \
   ../Geo/MVertex.h ../Geo/MEdge.h ../Geo/MVertex.h ../Geo/SVector3.h \
   ../Common/Hash.h ../Geo/MFace.h ../Geo/MVertex.h ../Geo/SVector3.h \
-  ../Geo/ExtrudeParams.h ../Geo/GFace.h ../Geo/GPoint.h ../Geo/GEntity.h \
-  ../Geo/GEdgeLoop.h ../Geo/GEdge.h ../Geo/MElement.h ../Geo/SPoint2.h \
-  ../Geo/SVector3.h ../Geo/Pair.h ../Geo/ExtrudeParams.h ../Geo/GRegion.h \
-  ../Geo/GEntity.h ../Geo/MElement.h ../Geo/ExtrudeParams.h \
-  ../Geo/SBoundingBox3d.h
+  ../Numeric/Numeric.h ../Geo/ExtrudeParams.h ../Common/SmoothData.h \
+  ../Geo/GFace.h ../Geo/GPoint.h ../Geo/GEntity.h ../Geo/GEdgeLoop.h \
+  ../Geo/GEdge.h ../Geo/MElement.h ../Geo/SPoint2.h ../Geo/SVector3.h \
+  ../Geo/Pair.h ../Geo/ExtrudeParams.h ../Geo/GRegion.h ../Geo/GEntity.h \
+  ../Geo/MElement.h ../Geo/ExtrudeParams.h ../Geo/SBoundingBox3d.h
 Post.o: Post.cpp ../Common/Gmsh.h ../Common/Message.h ../DataStr/Malloc.h \
   ../DataStr/List.h ../DataStr/Tree.h ../DataStr/avl.h ../DataStr/Tools.h \
   ../DataStr/List.h ../DataStr/Tree.h ../Common/GmshUI.h \
   ../Numeric/Numeric.h Draw.h ../Post/Views.h ../Post/ColorTable.h \
   ../Common/VertexArray.h ../Common/SmoothData.h ../Post/AdaptiveViews.h \
   ../Common/GmshMatrix.h ../Common/Context.h gl2ps.h
+Post_New.o: Post_New.cpp ../Common/Gmsh.h ../Common/Message.h \
+  ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
+  ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h ../DataStr/Tree.h \
+  ../Common/GmshUI.h ../Numeric/Numeric.h Draw.h ../Post/PView.h \
+  ../Common/VertexArray.h ../Common/SmoothData.h ../Post/AdaptiveViews.h \
+  ../Common/GmshMatrix.h ../Post/PViewData.h ../Geo/GModel.h \
+  ../Geo/GVertex.h ../Geo/GEntity.h ../Geo/Range.h ../Geo/SPoint3.h \
+  ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h ../Common/GmshDefines.h \
+  ../Geo/MVertex.h ../Geo/SPoint3.h ../Geo/GPoint.h ../Geo/SPoint2.h \
+  ../Geo/GEdge.h ../Geo/GEntity.h ../Geo/GVertex.h ../Geo/SVector3.h \
+  ../Geo/SPoint3.h ../Geo/SPoint3.h ../Geo/SPoint2.h ../Geo/MElement.h \
+  ../Geo/MVertex.h ../Geo/MEdge.h ../Geo/MVertex.h ../Geo/SVector3.h \
+  ../Common/Hash.h ../Geo/MFace.h ../Geo/MVertex.h ../Geo/SVector3.h \
+  ../Common/Context.h ../Geo/ExtrudeParams.h ../Geo/GFace.h \
+  ../Geo/GPoint.h ../Geo/GEntity.h ../Geo/GEdgeLoop.h ../Geo/GEdge.h \
+  ../Geo/MElement.h ../Geo/SPoint2.h ../Geo/SVector3.h ../Geo/Pair.h \
+  ../Geo/ExtrudeParams.h ../Geo/GRegion.h ../Geo/GEntity.h \
+  ../Geo/MElement.h ../Geo/ExtrudeParams.h ../Geo/SBoundingBox3d.h \
+  ../Post/PViewOptions.h ../Post/ColorTable.h gl2ps.h
 PostElement.o: PostElement.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
   ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h ../DataStr/Tree.h \
-  ../Common/GmshUI.h Draw.h ../Post/Views.h ../Post/ColorTable.h \
+  ../Common/GmshUI.h Draw.h Iso.h ../Post/Views.h ../Post/ColorTable.h \
   ../Common/VertexArray.h ../Common/SmoothData.h ../Numeric/Numeric.h \
-  ../Post/AdaptiveViews.h ../Common/GmshMatrix.h Iso.h \
-  ../Common/Context.h
+  ../Post/AdaptiveViews.h ../Common/GmshMatrix.h ../Common/Context.h
 SelectBuffer.o: SelectBuffer.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
   ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h ../DataStr/Tree.h \
-  ../Common/GmshUI.h ../Common/GmshDefines.h Draw.h ../Post/Views.h \
-  ../Post/ColorTable.h ../Common/VertexArray.h ../Common/SmoothData.h \
-  ../Numeric/Numeric.h ../Post/AdaptiveViews.h ../Common/GmshMatrix.h \
-  ../Common/Context.h SelectBuffer.h ../Geo/GVertex.h ../Geo/GEntity.h \
-  ../Geo/Range.h ../Geo/SPoint3.h ../Geo/SBoundingBox3d.h \
-  ../Geo/SPoint3.h ../Geo/MVertex.h ../Geo/SPoint3.h ../Geo/GPoint.h \
-  ../Geo/SPoint2.h ../Geo/GEdge.h ../Geo/GEntity.h ../Geo/GVertex.h \
-  ../Geo/SVector3.h ../Geo/SPoint3.h ../Geo/SPoint3.h ../Geo/SPoint2.h \
-  ../Geo/MElement.h ../Geo/MVertex.h ../Geo/MEdge.h ../Geo/MVertex.h \
-  ../Geo/SVector3.h ../Common/Hash.h ../Geo/MFace.h ../Geo/MVertex.h \
-  ../Geo/SVector3.h ../Geo/ExtrudeParams.h ../Geo/GFace.h ../Geo/GPoint.h \
-  ../Geo/GEntity.h ../Geo/GEdgeLoop.h ../Geo/GEdge.h ../Geo/MElement.h \
-  ../Geo/SPoint2.h ../Geo/SVector3.h ../Geo/Pair.h ../Geo/ExtrudeParams.h \
-  ../Geo/GRegion.h ../Geo/GEntity.h ../Geo/MElement.h \
-  ../Geo/ExtrudeParams.h ../Geo/GModel.h ../Geo/GVertex.h ../Geo/GEdge.h \
-  ../Geo/GFace.h ../Geo/GRegion.h ../Geo/SBoundingBox3d.h ../Geo/MRep.h \
-  ../Geo/GEdge.h ../Geo/GFace.h ../Geo/GRegion.h ../Geo/MVertex.h \
-  ../Geo/MEdge.h ../Geo/MElement.h ../Common/OS.h
+  ../Common/GmshUI.h ../Common/GmshDefines.h Draw.h ../Common/Context.h \
+  SelectBuffer.h ../Geo/GVertex.h ../Geo/GEntity.h ../Geo/Range.h \
+  ../Geo/SPoint3.h ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h \
+  ../Geo/MVertex.h ../Geo/SPoint3.h ../Geo/GPoint.h ../Geo/SPoint2.h \
+  ../Geo/GEdge.h ../Geo/GEntity.h ../Geo/GVertex.h ../Geo/SVector3.h \
+  ../Geo/SPoint3.h ../Geo/SPoint3.h ../Geo/SPoint2.h ../Geo/MElement.h \
+  ../Geo/MVertex.h ../Geo/MEdge.h ../Geo/MVertex.h ../Geo/SVector3.h \
+  ../Common/Hash.h ../Geo/MFace.h ../Geo/MVertex.h ../Geo/SVector3.h \
+  ../Numeric/Numeric.h ../Geo/ExtrudeParams.h ../Common/SmoothData.h \
+  ../Geo/GFace.h ../Geo/GPoint.h ../Geo/GEntity.h ../Geo/GEdgeLoop.h \
+  ../Geo/GEdge.h ../Geo/MElement.h ../Geo/SPoint2.h ../Geo/SVector3.h \
+  ../Geo/Pair.h ../Geo/ExtrudeParams.h ../Geo/GRegion.h ../Geo/GEntity.h \
+  ../Geo/MElement.h ../Geo/ExtrudeParams.h ../Geo/GModel.h \
+  ../Geo/GVertex.h ../Geo/GEdge.h ../Geo/GFace.h ../Geo/GRegion.h \
+  ../Geo/SBoundingBox3d.h ../Geo/MRep.h ../Geo/GEdge.h ../Geo/GFace.h \
+  ../Geo/GRegion.h ../Geo/MVertex.h ../Geo/MEdge.h ../Geo/MElement.h \
+  ../Common/VertexArray.h ../Common/OS.h
 Iso.o: Iso.cpp ../Common/Gmsh.h ../Common/Message.h ../DataStr/Malloc.h \
   ../DataStr/List.h ../DataStr/Tree.h ../DataStr/avl.h ../DataStr/Tools.h \
   ../DataStr/List.h ../DataStr/Tree.h ../Common/GmshUI.h Draw.h \
-  ../Post/Views.h ../Post/ColorTable.h ../Common/VertexArray.h \
-  ../Common/SmoothData.h ../Numeric/Numeric.h ../Post/AdaptiveViews.h \
-  ../Common/GmshMatrix.h ../Common/Context.h
+  ../Common/Context.h ../Post/Views.h ../Post/ColorTable.h \
+  ../Common/VertexArray.h ../Common/SmoothData.h ../Numeric/Numeric.h \
+  ../Post/AdaptiveViews.h ../Common/GmshMatrix.h
 Entity.o: Entity.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
   ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h ../DataStr/Tree.h \
@@ -179,9 +192,9 @@ ReadImg.o: ReadImg.cpp ReadImg.h ../Common/Gmsh.h ../Common/Message.h \
 Scale.o: Scale.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
   ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h ../DataStr/Tree.h \
-  ../Common/GmshUI.h ../Numeric/Numeric.h Draw.h ../Post/Views.h \
-  ../Post/ColorTable.h ../Common/VertexArray.h ../Common/SmoothData.h \
-  ../Post/AdaptiveViews.h ../Common/GmshMatrix.h ../Common/Context.h \
+  ../Common/GmshUI.h ../Numeric/Numeric.h Draw.h ../Common/Context.h \
+  ../Post/Views.h ../Post/ColorTable.h ../Common/VertexArray.h \
+  ../Common/SmoothData.h ../Post/AdaptiveViews.h ../Common/GmshMatrix.h \
   gl2ps.h
 Graph2D.o: Graph2D.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
@@ -194,30 +207,20 @@ gl2ps.o: gl2ps.cpp gl2ps.h
 gl2gif.o: gl2gif.cpp gl2gif.h PixelBuffer.h ../Common/Gmsh.h \
   ../Common/Message.h ../DataStr/Malloc.h ../DataStr/List.h \
   ../DataStr/Tree.h ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h \
-  ../DataStr/Tree.h ../Common/GmshUI.h Draw.h ../Post/Views.h \
-  ../Post/ColorTable.h ../Common/VertexArray.h ../Common/SmoothData.h \
-  ../Numeric/Numeric.h ../Post/AdaptiveViews.h ../Common/GmshMatrix.h
+  ../DataStr/Tree.h ../Common/GmshUI.h Draw.h
 gl2jpeg.o: gl2jpeg.cpp gl2jpeg.h PixelBuffer.h ../Common/Gmsh.h \
   ../Common/Message.h ../DataStr/Malloc.h ../DataStr/List.h \
   ../DataStr/Tree.h ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h \
-  ../DataStr/Tree.h ../Common/GmshUI.h Draw.h ../Post/Views.h \
-  ../Post/ColorTable.h ../Common/VertexArray.h ../Common/SmoothData.h \
-  ../Numeric/Numeric.h ../Post/AdaptiveViews.h ../Common/GmshMatrix.h
+  ../DataStr/Tree.h ../Common/GmshUI.h Draw.h
 gl2png.o: gl2png.cpp gl2png.h PixelBuffer.h ../Common/Gmsh.h \
   ../Common/Message.h ../DataStr/Malloc.h ../DataStr/List.h \
   ../DataStr/Tree.h ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h \
-  ../DataStr/Tree.h ../Common/GmshUI.h Draw.h ../Post/Views.h \
-  ../Post/ColorTable.h ../Common/VertexArray.h ../Common/SmoothData.h \
-  ../Numeric/Numeric.h ../Post/AdaptiveViews.h ../Common/GmshMatrix.h
+  ../DataStr/Tree.h ../Common/GmshUI.h Draw.h
 gl2ppm.o: gl2ppm.cpp gl2ppm.h PixelBuffer.h ../Common/Gmsh.h \
   ../Common/Message.h ../DataStr/Malloc.h ../DataStr/List.h \
   ../DataStr/Tree.h ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h \
-  ../DataStr/Tree.h ../Common/GmshUI.h Draw.h ../Post/Views.h \
-  ../Post/ColorTable.h ../Common/VertexArray.h ../Common/SmoothData.h \
-  ../Numeric/Numeric.h ../Post/AdaptiveViews.h ../Common/GmshMatrix.h
+  ../DataStr/Tree.h ../Common/GmshUI.h Draw.h
 gl2yuv.o: gl2yuv.cpp gl2yuv.h PixelBuffer.h ../Common/Gmsh.h \
   ../Common/Message.h ../DataStr/Malloc.h ../DataStr/List.h \
   ../DataStr/Tree.h ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h \
-  ../DataStr/Tree.h ../Common/GmshUI.h Draw.h ../Post/Views.h \
-  ../Post/ColorTable.h ../Common/VertexArray.h ../Common/SmoothData.h \
-  ../Numeric/Numeric.h ../Post/AdaptiveViews.h ../Common/GmshMatrix.h
+  ../DataStr/Tree.h ../Common/GmshUI.h Draw.h
diff --git a/Graphics/Mesh.cpp b/Graphics/Mesh.cpp
index 513369450f99af6959979b2031475c7c2ffd177b..ca7dddd0b3527f850a0741585d1e6eb0fbe87d4e 100644
--- a/Graphics/Mesh.cpp
+++ b/Graphics/Mesh.cpp
@@ -1,4 +1,4 @@
-// $Id: Mesh.cpp,v 1.199 2007-07-26 13:10:48 geuzaine Exp $
+// $Id: Mesh.cpp,v 1.200 2007-08-21 19:05:39 geuzaine Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -28,7 +28,6 @@
 #include "OS.h"
 #include "gl2ps.h"
 
-extern GModel *GMODEL;
 extern Context_T CTX;
 
 // General helper routines
@@ -910,29 +909,30 @@ void Draw_Mesh()
   
   if(!CTX.threads_lock){
     CTX.threads_lock = 1; 
-    int status = GMODEL->getMeshStatus();
+    GModel *m = GModel::current();
+    int status = m->getMeshStatus();
     if(CTX.mesh.changed) {
       Msg(DEBUG, "Mesh has changed: reinitializing drawing data", CTX.mesh.changed);
       if(status >= 1 && CTX.mesh.changed & ENT_LINE)
-	std::for_each(GMODEL->firstEdge(), GMODEL->lastEdge(), initMeshGEdge());
+	std::for_each(m->firstEdge(), m->lastEdge(), initMeshGEdge());
       if(status >= 2 && CTX.mesh.changed & ENT_SURFACE){
-	if(GMODEL->normals) delete GMODEL->normals;
-	GMODEL->normals = new smooth_normals(CTX.mesh.angle_smooth_normals);
+	if(m->normals) delete m->normals;
+	m->normals = new smooth_normals(CTX.mesh.angle_smooth_normals);
 	if(CTX.mesh.smooth_normals)
-	  std::for_each(GMODEL->firstFace(), GMODEL->lastFace(), initSmoothNormalsGFace());
-	std::for_each(GMODEL->firstFace(), GMODEL->lastFace(), initMeshGFace());
+	  std::for_each(m->firstFace(), m->lastFace(), initSmoothNormalsGFace());
+	std::for_each(m->firstFace(), m->lastFace(), initMeshGFace());
       }
       if(status >= 3 && CTX.mesh.changed & ENT_VOLUME)
-	std::for_each(GMODEL->firstRegion(), GMODEL->lastRegion(), initMeshGRegion());
+	std::for_each(m->firstRegion(), m->lastRegion(), initMeshGRegion());
     }
     if(status >= 0)
-      std::for_each(GMODEL->firstVertex(), GMODEL->lastVertex(), drawMeshGVertex());
+      std::for_each(m->firstVertex(), m->lastVertex(), drawMeshGVertex());
     if(status >= 1)
-      std::for_each(GMODEL->firstEdge(), GMODEL->lastEdge(), drawMeshGEdge());
+      std::for_each(m->firstEdge(), m->lastEdge(), drawMeshGEdge());
     if(status >= 2)
-      std::for_each(GMODEL->firstFace(), GMODEL->lastFace(), drawMeshGFace());
+      std::for_each(m->firstFace(), m->lastFace(), drawMeshGFace());
     if(status >= 3)
-      std::for_each(GMODEL->firstRegion(), GMODEL->lastRegion(), drawMeshGRegion());
+      std::for_each(m->firstRegion(), m->lastRegion(), drawMeshGRegion());
     CTX.mesh.changed = 0;
     CTX.threads_lock = 0;
   }
diff --git a/Graphics/Post_New.cpp b/Graphics/Post_New.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7bd0fc9e8784f49944dabb67b8da27a6d4f70d2b
--- /dev/null
+++ b/Graphics/Post_New.cpp
@@ -0,0 +1,192 @@
+// $Id: Post_New.cpp,v 1.1 2007-08-21 19:05:39 geuzaine Exp $
+//
+// Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+// 
+// Please report all bugs and problems to <gmsh@geuz.org>.
+
+#include "Gmsh.h"
+#include "GmshUI.h"
+#include "Numeric.h"
+#include "Draw.h"
+#include "PView.h"
+#include "Context.h"
+#include "gl2ps.h"
+
+void addElementsInArrays(PView *p)
+{
+
+}
+
+void drawArrays(PView *p)
+{
+  /*
+  double x[20], y[20], z[20];
+
+  for(int i = 0; i < data->getNumElements(); i++){
+    int n = data->getNumNodes(i);
+    for(int j = 0; j < n; j++)
+      data->getNode(i, j, x[j], y[j], z[j]);
+    
+    if(n == 3){
+      glColor3d(1, 0, 0);
+      glBegin(GL_TRIANGLES);
+      glVertex3d(x[0], y[0], z[0]);
+      glVertex3d(x[1], y[1], z[1]);
+      glVertex3d(x[2], y[2], z[2]);
+      glEnd();
+    }
+
+  }
+  */
+
+}
+
+// We try to estimate how many primitives will end up in the vertex
+// arrays, since reallocating the arrays takes a HUGE amount of time
+// on Windows/Cygwin. A better way would be to slightly redesign the
+// drawing routines so we can have different pre-processing steps
+// (like the one we have for smooth normals right now), in order to
+// count how many primitives we will have.
+
+static int estimateNumTriangles(PView *p)
+{
+  PViewData *dat = p->getData();
+  int tris = dat->getNumTriangles();
+  int quads = dat->getNumQuadrangles();
+  int tets = dat->getNumTetrahedra();
+  int prisms = dat->getNumPrisms();
+  int pyrs = dat->getNumPyramids();
+  int hexas = dat->getNumHexahedra();
+
+  PViewOptions *opt = p->getOptions();  
+  int heuristic = 0;
+  if(opt->IntervalsType == PViewOptions::Iso)
+    heuristic = (tets + prisms + pyrs + hexas) / 10;
+  else if(opt->IntervalsType == PViewOptions::Continuous)
+    heuristic = (tris + 2 * quads + 6 * tets + 
+      8 * prisms + 6 * pyrs + 12 * hexas);
+  else if(opt->IntervalsType == PViewOptions::Discrete)
+    heuristic = (tris + 2 * quads + 6 * tets + 
+      8 * prisms + 6 * pyrs + 12 * hexas) * 2;
+
+  return heuristic + 10000;
+}
+
+static int estimateNumLines(PView *p)
+{
+  return 10000;
+}
+
+class initPView {
+ public :
+  void operator () (PView *p)
+  {
+    PViewData *data = p->getData();
+    PViewOptions *opt = p->getOptions();
+
+    if(!p->getChanged() || p->getDirty() || !opt->Visible) return;
+
+    if(p->va_lines) delete p->va_lines;
+    p->va_lines = new VertexArray(2, estimateNumLines(p));
+    if(p->va_triangles) delete p->va_triangles;
+    p->va_lines = new VertexArray(3, estimateNumTriangles(p));
+
+    addElementsInArrays(p);
+
+    p->setChanged(false);
+  }
+};
+
+class drawPView {
+ public :
+  void operator () (PView *p)
+  {
+    PViewData *data = p->getData();
+    PViewOptions *opt = p->getOptions();
+    
+    if(!opt->Visible) return;
+    
+    glPointSize(opt->PointSize);
+    gl2psPointSize(opt->PointSize * CTX.print.eps_point_size_factor);
+    
+    glLineWidth(opt->LineWidth);
+    gl2psLineWidth(opt->LineWidth * CTX.print.eps_line_width_factor);
+    
+    if(opt->LightTwoSide)
+      glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
+    else
+      glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
+    
+    for(int i = 0; i < 6; i++)
+      if(CTX.clip[i] & (1 << (2 + p->getIndex()))) 
+	glEnable((GLenum)(GL_CLIP_PLANE0 + i));
+      else
+	glDisable((GLenum)(GL_CLIP_PLANE0 + i));
+    
+    drawArrays(p);
+  }
+};
+
+class drawPViewBoundingBox {
+ public :
+  void operator () (PView *p)
+  {
+    PViewData *data = p->getData();
+    PViewOptions *opt = p->getOptions();
+
+    if(!opt->Visible || opt->Type != PViewOptions::Plot3D) return;
+
+    glColor4ubv((GLubyte *) & CTX.color.fg);
+    glLineWidth(CTX.line_width);
+    gl2psLineWidth(CTX.line_width * CTX.print.eps_line_width_factor);
+
+    SBoundingBox3d bb = data->getBoundingBox();
+    Draw_Box(bb.min().x(), bb.min().y(), bb.min().z(),
+	     bb.max().x(), bb.max().y(), bb.max().z());
+    glColor3d(1., 0., 0.);
+    for(int i = 0; i < 6; i++)
+      if(CTX.clip[i] & (1 << (2 + p->getIndex())))
+	Draw_PlaneInBoundingBox(bb.min().x(), bb.min().y(), bb.min().z(),
+				bb.max().x(), bb.max().y(), bb.max().z(),
+				CTX.clip_plane[i][0], CTX.clip_plane[i][1], 
+				CTX.clip_plane[i][2], CTX.clip_plane[i][3]);
+  }
+};
+
+void Draw_Post_New()
+{
+  // draw any plugin-specific stuff
+  if(CTX.post.plugin_draw_function)
+    (*CTX.post.plugin_draw_function)();
+
+  if(PView::list.empty()) return;
+
+  if(CTX.draw_bbox || !CTX.post.draw)
+    std::for_each(PView::list.begin(), PView::list.end(), drawPViewBoundingBox());
+
+  if(!CTX.post.draw) return;
+
+  if(!CTX.threads_lock){
+    CTX.threads_lock = 1; 
+    // recompute graphics data if we need to
+    std::for_each(PView::list.begin(), PView::list.end(), initPView());
+    std::for_each(PView::list.begin(), PView::list.end(), drawPView());
+    CTX.threads_lock = 0;
+  }
+
+}
diff --git a/Graphics/SelectBuffer.cpp b/Graphics/SelectBuffer.cpp
index a7b0a816c04030f614ff0a2daa97dbd8187f611c..23bd91bf84db0d6b29121d4467e37f5659a4737a 100644
--- a/Graphics/SelectBuffer.cpp
+++ b/Graphics/SelectBuffer.cpp
@@ -1,4 +1,4 @@
-// $Id: SelectBuffer.cpp,v 1.12 2007-02-04 15:59:18 geuzaine Exp $
+// $Id: SelectBuffer.cpp,v 1.13 2007-08-21 19:05:40 geuzaine Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -29,7 +29,6 @@
 #include "MRep.h"
 
 extern Context_T CTX;
-extern GModel *GMODEL;
 
 class hit{
 public:
@@ -63,9 +62,10 @@ bool ProcessSelectionBuffer(int entityType,
 
   // In our case the selection buffer size is equal to between 5 and 7
   // times the maximum number of possible hits
-  int eles = (meshSelection && CTX.pick_elements) ? 4 * GMODEL->numElements() : 0;
-  int size = 7 * (GMODEL->numVertex() + GMODEL->numEdge() + GMODEL->numFace() + 
-		  GMODEL->numRegion() + eles) + 1000 ;
+  GModel *m = GModel::current();
+  int eles = (meshSelection && CTX.pick_elements) ? 4 * m->numElements() : 0;
+  int size = 7 * (m->numVertex() + m->numEdge() + m->numFace() + 
+		  m->numRegion() + eles) + 1000 ;
 
   GLuint *selectionBuffer = new GLuint[size];
   glSelectBuffer(size, selectionBuffer);
@@ -153,7 +153,7 @@ bool ProcessSelectionBuffer(int entityType,
       switch (hits[i].type) {
       case 0:
 	{
-	  GVertex *v = GMODEL->vertexByTag(hits[i].ient);
+	  GVertex *v = m->vertexByTag(hits[i].ient);
 	  if(!v){
 	    Msg(GERROR, "Problem in point selection processing");
 	    return false;
@@ -164,7 +164,7 @@ bool ProcessSelectionBuffer(int entityType,
 	break;
       case 1:
 	{
-	  GEdge *e = GMODEL->edgeByTag(hits[i].ient);
+	  GEdge *e = m->edgeByTag(hits[i].ient);
 	  if(!e){
 	    Msg(GERROR, "Problem in line selection processing");
 	    return false;
@@ -179,7 +179,7 @@ bool ProcessSelectionBuffer(int entityType,
 	break;
       case 2:
 	{
-	  GFace *f = GMODEL->faceByTag(hits[i].ient);
+	  GFace *f = m->faceByTag(hits[i].ient);
 	  if(!f){
 	    Msg(GERROR, "Problem in surface selection processing");
 	    return false;
@@ -194,7 +194,7 @@ bool ProcessSelectionBuffer(int entityType,
 	break;
       case 3:
 	{
-	  GRegion *r = GMODEL->regionByTag(hits[i].ient);
+	  GRegion *r = m->regionByTag(hits[i].ient);
 	  if(!r){
 	    Msg(GERROR, "Problem in volume selection processing");
 	    return false;
@@ -224,20 +224,21 @@ void HighlightEntity(GEntity *e)
 
 void HighlightEntityNum(int v, int c, int s, int r)
 {
+  GModel *m = GModel::current();
   if(v) {
-    GVertex *pv = GMODEL->vertexByTag(v);
+    GVertex *pv = m->vertexByTag(v);
     if(pv) HighlightEntity(pv);
   }
   if(c) {
-    GEdge *pc = GMODEL->edgeByTag(c);
+    GEdge *pc = m->edgeByTag(c);
     if(pc) HighlightEntity(pc);
   }
   if(s) {
-    GFace *ps = GMODEL->faceByTag(s);
+    GFace *ps = m->faceByTag(s);
     if(ps) HighlightEntity(ps);
   }
   if(r) {
-    GRegion *pr = GMODEL->regionByTag(r);
+    GRegion *pr = m->regionByTag(r);
     if(pr) HighlightEntity(pr);
   }
 }
@@ -257,41 +258,44 @@ void ZeroHighlightEntity(GVertex *v, GEdge *c, GFace *s, GRegion *r)
 
 void ZeroHighlightEntityNum(int v, int c, int s, int r)
 {
+  GModel *m = GModel::current();
   if(v) {
-    GVertex *pv = GMODEL->vertexByTag(v);
+    GVertex *pv = m->vertexByTag(v);
     if(pv) ZeroHighlightEntity(pv);
   }
   if(c) {
-    GEdge *pc = GMODEL->edgeByTag(c);
+    GEdge *pc = m->edgeByTag(c);
     if(pc) ZeroHighlightEntity(pc);
   }
   if(s) {
-    GFace *ps = GMODEL->faceByTag(s);
+    GFace *ps = m->faceByTag(s);
     if(ps) ZeroHighlightEntity(ps);
   }
   if(r) {
-    GRegion *pr = GMODEL->regionByTag(r);
+    GRegion *pr = m->regionByTag(r);
     if(pr) ZeroHighlightEntity(pr);
   }
 }
 
 void ZeroHighlight()
 {
-  for(GModel::viter it = GMODEL->firstVertex(); it != GMODEL->lastVertex(); it++)
+  GModel *m = GModel::current();
+
+  for(GModel::viter it = m->firstVertex(); it != m->lastVertex(); it++)
     ZeroHighlightEntity(*it);
-  for(GModel::eiter it = GMODEL->firstEdge(); it != GMODEL->lastEdge(); it++)
+  for(GModel::eiter it = m->firstEdge(); it != m->lastEdge(); it++)
     ZeroHighlightEntity(*it);
-  for(GModel::fiter it = GMODEL->firstFace(); it != GMODEL->lastFace(); it++)
+  for(GModel::fiter it = m->firstFace(); it != m->lastFace(); it++)
     ZeroHighlightEntity(*it);
-  for(GModel::riter it = GMODEL->firstRegion(); it != GMODEL->lastRegion(); it++)
+  for(GModel::riter it = m->firstRegion(); it != m->lastRegion(); it++)
     ZeroHighlightEntity(*it);
 
-  for(GModel::eiter it = GMODEL->firstEdge(); it != GMODEL->lastEdge(); it++){
+  for(GModel::eiter it = m->firstEdge(); it != m->lastEdge(); it++){
     for(unsigned int i = 0; i < (*it)->lines.size(); i++)
       if((*it)->lines[i]->getVisibility() == 2)
 	(*it)->lines[i]->setVisibility(1);
   }
-  for(GModel::fiter it = GMODEL->firstFace(); it != GMODEL->lastFace(); it++){
+  for(GModel::fiter it = m->firstFace(); it != m->lastFace(); it++){
     for(unsigned int i = 0; i < (*it)->triangles.size(); i++)
       if((*it)->triangles[i]->getVisibility() == 2)
 	(*it)->triangles[i]->setVisibility(1);
@@ -299,7 +303,7 @@ void ZeroHighlight()
       if((*it)->quadrangles[i]->getVisibility() == 2) 
 	(*it)->quadrangles[i]->setVisibility(1);
   }
-  for(GModel::riter it = GMODEL->firstRegion(); it != GMODEL->lastRegion(); it++){
+  for(GModel::riter it = m->firstRegion(); it != m->lastRegion(); it++){
     for(unsigned int i = 0; i < (*it)->tetrahedra.size(); i++)
       if((*it)->tetrahedra[i]->getVisibility() == 2)
 	(*it)->tetrahedra[i]->setVisibility(1);
diff --git a/Mesh/Generator.cpp b/Mesh/Generator.cpp
index deaf6b72f45d26d992cdb877d95d0b815d2f959d..3dcf3e08c1d1de0c770b6f01abf82d2d4c62ceec 100644
--- a/Mesh/Generator.cpp
+++ b/Mesh/Generator.cpp
@@ -1,4 +1,4 @@
-// $Id: Generator.cpp,v 1.120 2007-07-11 16:55:11 geuzaine Exp $
+// $Id: Generator.cpp,v 1.121 2007-08-21 19:05:40 geuzaine Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -33,7 +33,6 @@
 #include "HighOrder.h"
 
 extern Context_T CTX;
-extern GModel *GMODEL;
 
 template<class T>
 static void GetQualityMeasure(std::vector<T*>& ele, 
@@ -67,26 +66,28 @@ void GetStatistics(double stat[50], double quality[3][100])
 {
   for(int i = 0; i < 50; i++) stat[i] = 0.;
 
-  stat[0] = GMODEL->numVertex();
-  stat[1] = GMODEL->numEdge();
-  stat[2] = GMODEL->numFace();
-  stat[3] = GMODEL->numRegion();
+  GModel *m = GModel::current();
+
+  stat[0] = m->numVertex();
+  stat[1] = m->numEdge();
+  stat[2] = m->numFace();
+  stat[3] = m->numRegion();
   
   std::map<int, std::vector<GEntity*> > physicals[4];
-  GMODEL->getPhysicalGroups(physicals);
+  m->getPhysicalGroups(physicals);
   stat[45] = physicals[0].size() + physicals[1].size() + 
     physicals[2].size() + physicals[3].size();
   
-  for(GModel::eiter it = GMODEL->firstEdge(); it != GMODEL->lastEdge(); ++it)
+  for(GModel::eiter it = m->firstEdge(); it != m->lastEdge(); ++it)
     stat[4] += (*it)->mesh_vertices.size();
   
-  for(GModel::fiter it = GMODEL->firstFace(); it != GMODEL->lastFace(); ++it){
+  for(GModel::fiter it = m->firstFace(); it != m->lastFace(); ++it){
     stat[5] += (*it)->mesh_vertices.size();
     stat[7] += (*it)->triangles.size();
     stat[8] += (*it)->quadrangles.size();
   }
   
-  for(GModel::riter it = GMODEL->firstRegion(); it != GMODEL->lastRegion(); ++it){
+  for(GModel::riter it = m->firstRegion(); it != m->lastRegion(); ++it){
     stat[6] += (*it)->mesh_vertices.size();
     stat[9] += (*it)->tetrahedra.size();
     stat[10] += (*it)->hexahedra.size();
@@ -105,7 +106,7 @@ void GetStatistics(double stat[50], double quality[3][100])
     double gamma=0., gammaMin=1., gammaMax=0.;
     double eta=0., etaMin=1., etaMax=0.;
     double rho=0., rhoMin=1., rhoMax=0.;
-    for(GModel::riter it = GMODEL->firstRegion(); it != GMODEL->lastRegion(); ++it){
+    for(GModel::riter it = m->firstRegion(); it != m->lastRegion(); ++it){
       GetQualityMeasure((*it)->tetrahedra, gamma, gammaMin, gammaMax,
 			eta, etaMin, etaMax, rho, rhoMin, rhoMax, quality);
       GetQualityMeasure((*it)->hexahedra, gamma, gammaMin, gammaMax,
@@ -181,15 +182,16 @@ void GetStatistics(double stat[50], double quality[3][100])
 
 bool TooManyElements(int dim)
 {
-  if(CTX.expert_mode || !GMODEL->numVertex()) return false;
+  GModel *m = GModel::current();
+  if(CTX.expert_mode || !m->numVertex()) return false;
 
   // try to detect obvious mistakes in characteristic lenghts (one of
   // the most common cause for erroneous bug reports on the mailing
   // list)
   double sumAllLc = 0.;
-  for(GModel::viter it = GMODEL->firstVertex(); it != GMODEL->lastVertex(); ++it)
+  for(GModel::viter it = m->firstVertex(); it != m->lastVertex(); ++it)
     sumAllLc += (*it)->prescribedMeshSizeAtVertex();
-  sumAllLc /= (double)GMODEL->numVertex();
+  sumAllLc /= (double)m->numVertex();
   if(!sumAllLc || pow(CTX.lc / sumAllLc, dim) > 1.e10) 
     return !GetBinaryAnswer("Your choice of characteristic lengths will likely produce\n"
 			    "a very large mesh. Do you really want to continue?\n\n"
@@ -205,7 +207,8 @@ void Mesh1D()
   Msg(STATUS1, "Meshing 1D...");
   double t1 = Cpu();
 
-  std::for_each(GMODEL->firstEdge(), GMODEL->lastEdge(), meshGEdge());
+  GModel *m = GModel::current();
+  std::for_each(m->firstEdge(), m->lastEdge(), meshGEdge());
 
   double t2 = Cpu();
   CTX.mesh_timer[0] = t2 - t1;
@@ -229,12 +232,13 @@ void Mesh2D()
   Msg(STATUS1, "Meshing 2D...");
   double t1 = Cpu();
 
-  std::for_each(GMODEL->firstFace(), GMODEL->lastFace(), meshGFace());  
+  GModel *m = GModel::current();
+  std::for_each(m->firstFace(), m->lastFace(), meshGFace());  
 
   // boundary layers are special: their definition (including vertices
   // and curve meshes) relies on the surface mesh--and it is global
   // since we use a smooth normal field
-  MeshBoundaryLayerFaces(GMODEL);
+  MeshBoundaryLayerFaces(m);
 
   double t2 = Cpu();
   CTX.mesh_timer[1] = t2 - t1;
@@ -256,16 +260,18 @@ void Mesh3D()
   Msg(STATUS1, "Meshing 3D...");
   double t1 = Cpu();
 
+  GModel *m = GModel::current();
+
   // mesh the extruded volumes first
-  std::for_each(GMODEL->firstRegion(), GMODEL->lastRegion(), meshGRegionExtruded());
+  std::for_each(m->firstRegion(), m->lastRegion(), meshGRegionExtruded());
 
   // then subdivide if necessary (unfortunately the subdivision is a
   // global operation, which can require changing the surface mesh!)
-  SubdivideExtrudedMesh(GMODEL);
+  SubdivideExtrudedMesh(m);
 
   // then mesh all the non-delaunay regions
   std::vector<GRegion*> delaunay;
-  std::for_each(GMODEL->firstRegion(), GMODEL->lastRegion(), meshGRegion(delaunay));
+  std::for_each(m->firstRegion(), m->lastRegion(), meshGRegion(delaunay));
 
   // and finally mesh the delaunay regions (again, this is global; but
   // we mesh each connected part separately for performance and mesh
@@ -286,7 +292,8 @@ void OptimizeMesh()
   Msg(STATUS1, "Optimizing 3D...");
   double t1 = Cpu();
 
-  std::for_each(GMODEL->firstRegion(), GMODEL->lastRegion(), optimizeMeshGRegion());
+  GModel *m = GModel::current();
+  std::for_each(m->firstRegion(), m->lastRegion(), optimizeMeshGRegion());
 
   double t2 = Cpu();
   Msg(INFO, "Mesh 3D optimization complete (%g s)", t2 - t1);
@@ -301,21 +308,23 @@ void GenerateMesh(int ask)
   }
   CTX.threads_lock = 1;
 
-  int old = GMODEL->getMeshStatus(false);
+  GModel *m = GModel::current();
+
+  int old = m->getMeshStatus(false);
 
   // Change any high order elements back into first order ones
-  SetOrder1(GMODEL);
+  SetOrder1(m);
 
   // 1D mesh
   if(ask == 1 || (ask > 1 && old < 1)) {
-    std::for_each(GMODEL->firstRegion(), GMODEL->lastRegion(), deMeshGRegion());
-    std::for_each(GMODEL->firstFace(), GMODEL->lastFace(), deMeshGFace());
+    std::for_each(m->firstRegion(), m->lastRegion(), deMeshGRegion());
+    std::for_each(m->firstFace(), m->lastFace(), deMeshGFace());
     Mesh1D();
   }
 
   // 2D mesh
   if(ask == 2 || (ask > 2 && old < 2)) {
-    std::for_each(GMODEL->firstRegion(), GMODEL->lastRegion(), deMeshGRegion());
+    std::for_each(m->firstRegion(), m->lastRegion(), deMeshGRegion());
     Mesh2D();
   }
 
@@ -325,19 +334,19 @@ void GenerateMesh(int ask)
   }
 
   // Orient the surface mesh so that it matches the geometry
-  if(GMODEL->getMeshStatus() >= 2)
-    std::for_each(GMODEL->firstFace(), GMODEL->lastFace(), orientMeshGFace());
+  if(m->getMeshStatus() >= 2)
+    std::for_each(m->firstFace(), m->lastFace(), orientMeshGFace());
   
   // Optimize quality
-  if(GMODEL->getMeshStatus() == 3 && CTX.mesh.optimize)
+  if(m->getMeshStatus() == 3 && CTX.mesh.optimize)
     OptimizeMesh();
   
   // Create high order elements
-  if(GMODEL->getMeshStatus() && CTX.mesh.order > 1) 
-    SetOrderN(GMODEL, CTX.mesh.order, CTX.mesh.second_order_linear, 
+  if(m->getMeshStatus() && CTX.mesh.order > 1) 
+    SetOrderN(m, CTX.mesh.order, CTX.mesh.second_order_linear, 
 	      CTX.mesh.second_order_incomplete);
 
-  Msg(INFO, "%d vertices %d elements", GMODEL->numVertices(), GMODEL->numElements());
+  Msg(INFO, "%d vertices %d elements", m->numVertices(), m->numElements());
 
   CTX.threads_lock = 0;
   CTX.mesh.changed = ENT_ALL;
diff --git a/Parser/CreateFile.cpp b/Parser/CreateFile.cpp
index a2dea94a6ef5aeeb476f0da0c009048da5b266ca..a903424ca4fa49ed7553c112697159fc66f90fa4 100644
--- a/Parser/CreateFile.cpp
+++ b/Parser/CreateFile.cpp
@@ -1,4 +1,4 @@
-// $Id: CreateFile.cpp,v 1.18 2007-08-17 15:43:07 geuzaine Exp $
+// $Id: CreateFile.cpp,v 1.19 2007-08-21 19:05:40 geuzaine Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -37,7 +37,6 @@
 #endif
 
 extern Context_T CTX;
-extern GModel *GMODEL;
 
 int GuessFileFormatFromFileName(char *name)
 {
@@ -150,51 +149,51 @@ void CreateOutputFile(char *filename, int format)
     break;
 
   case FORMAT_MSH:
-    GMODEL->writeMSH(name, CTX.mesh.msh_file_version, CTX.mesh.msh_binary, 
-		     CTX.mesh.save_all, CTX.mesh.scaling_factor);
+    GModel::current()->writeMSH(name, CTX.mesh.msh_file_version, CTX.mesh.msh_binary, 
+				CTX.mesh.save_all, CTX.mesh.scaling_factor);
     break;
 
   case FORMAT_STL:
-    GMODEL->writeSTL(name, CTX.mesh.stl_binary,
-		     CTX.mesh.save_all, CTX.mesh.scaling_factor);
+    GModel::current()->writeSTL(name, CTX.mesh.stl_binary,
+				CTX.mesh.save_all, CTX.mesh.scaling_factor);
     break;
 
   case FORMAT_VRML:
-    GMODEL->writeVRML(name, CTX.mesh.save_all, CTX.mesh.scaling_factor);
+    GModel::current()->writeVRML(name, CTX.mesh.save_all, CTX.mesh.scaling_factor);
     break;
 
   case FORMAT_UNV:
-    GMODEL->writeUNV(name, CTX.mesh.save_all, CTX.mesh.save_groups_of_nodes,
-		     CTX.mesh.scaling_factor);
+    GModel::current()->writeUNV(name, CTX.mesh.save_all, CTX.mesh.save_groups_of_nodes,
+				CTX.mesh.scaling_factor);
     break;
 
   case FORMAT_MESH:
-    GMODEL->writeMESH(name, CTX.mesh.save_all, CTX.mesh.scaling_factor);
+    GModel::current()->writeMESH(name, CTX.mesh.save_all, CTX.mesh.scaling_factor);
     break;
 
   case FORMAT_BDF:
-    GMODEL->writeBDF(name, CTX.mesh.bdf_field_format, 
+    GModel::current()->writeBDF(name, CTX.mesh.bdf_field_format, 
 		     CTX.mesh.save_all, CTX.mesh.scaling_factor);
     break;
 
   case FORMAT_P3D:
-    GMODEL->writeP3D(name, CTX.mesh.save_all, CTX.mesh.scaling_factor);
+    GModel::current()->writeP3D(name, CTX.mesh.save_all, CTX.mesh.scaling_factor);
     break;
 
   case FORMAT_CGNS:
-    GMODEL->writeCGNS(name, CTX.mesh.scaling_factor);
+    GModel::current()->writeCGNS(name, CTX.mesh.scaling_factor);
     break;
 
   case FORMAT_MED:
-    GMODEL->writeMED(name);
+    GModel::current()->writeMED(name);
     break;
 
   case FORMAT_POS:
-    GMODEL->writePOS(name, CTX.mesh.save_all, CTX.mesh.scaling_factor);
+    GModel::current()->writePOS(name, CTX.mesh.save_all, CTX.mesh.scaling_factor);
     break;
 
   case FORMAT_GEO:
-    GMODEL->writeGEO(name, CTX.print.geo_labels);
+    GModel::current()->writeGEO(name, CTX.print.geo_labels);
     break;
 
 #if defined(HAVE_FLTK)
diff --git a/Parser/Gmsh.tab.cpp b/Parser/Gmsh.tab.cpp
index 59551c318a2e843be7a32780b418137799aa5ace..0996bbbceaf334e72929de56c05a3d3a4b615b5e 100644
--- a/Parser/Gmsh.tab.cpp
+++ b/Parser/Gmsh.tab.cpp
@@ -131,7 +131,7 @@
 
 #line 1 "Gmsh.y"
 
-// $Id: Gmsh.tab.cpp,v 1.325 2007-07-25 15:48:32 geuzaine Exp $
+// $Id: Gmsh.tab.cpp,v 1.326 2007-08-21 19:05:40 geuzaine Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -182,7 +182,6 @@ Tree_T *Symbol_T = NULL;
 
 extern Context_T CTX;
 extern Mesh *THEM;
-extern GModel *GMODEL;
 
 static ExtrudeParams extr;
 
@@ -207,7 +206,7 @@ void skip_until(char *skip, char *until);
 int PrintListOfDouble(char *format, List_T *list, char *buffer);
 int CheckViewErrorFlags(Post_View *v);
 
-#line 79 "Gmsh.y"
+#line 78 "Gmsh.y"
 typedef union {
   char *c;
   int i;
@@ -531,15 +530,15 @@ static const short yyrhs[] = {   148,
 
 #if YYDEBUG != 0
 static const short yyrline[] = { 0,
-   145,   147,   152,   154,   157,   159,   160,   161,   162,   163,
-   164,   165,   166,   167,   168,   169,   170,   171,   172,   175,
-   180,   186,   192,   207,   220,   248,   256,   265,   273,   274,
-   275,   276,   277,   278,   281,   284,   288,   291,   295,   486,
-   500,   510,   516,   523,   531,   537,   543,   550,   558,   564,
-   570,   580,   585,   589,   598,   600,   601,   602,   603,   606,
-   608,   611,   646,   685,   739,   756,   774,   785,   802,   809,
-   823,   840,   866,   893,   907,   924,   938,   955,   975,   998,
-  1008,  1022,  1027,  1035,  1061,  1077,  1098,  1105,  1116,  1131,
+   144,   146,   151,   153,   156,   158,   159,   160,   161,   162,
+   163,   164,   165,   166,   167,   168,   169,   170,   171,   174,
+   179,   185,   191,   206,   219,   247,   255,   264,   272,   273,
+   274,   275,   276,   277,   280,   283,   287,   290,   294,   485,
+   499,   509,   515,   522,   530,   536,   542,   549,   557,   563,
+   569,   579,   584,   588,   597,   599,   600,   601,   602,   605,
+   607,   610,   645,   684,   738,   755,   773,   784,   801,   808,
+   822,   839,   865,   892,   906,   923,   937,   954,   974,   997,
+  1007,  1021,  1026,  1035,  1061,  1077,  1098,  1105,  1116,  1131,
   1146,  1153,  1165,  1199,  1235,  1257,  1275,  1293,  1311,  1337,
   1355,  1381,  1401,  1419,  1437,  1463,  1480,  1499,  1517,  1555,
   1559,  1563,  1568,  1590,  1612,  1628,  1648,  1665,  1682,  1702,
@@ -2867,90 +2866,90 @@ yyreduce:
   switch (yyn) {
 
 case 2:
-#line 147 "Gmsh.y"
+#line 146 "Gmsh.y"
 { yyerrok; return 1; ;
     break;}
 case 5:
-#line 158 "Gmsh.y"
+#line 157 "Gmsh.y"
 { return 1; ;
     break;}
 case 6:
-#line 159 "Gmsh.y"
+#line 158 "Gmsh.y"
 { return 1; ;
     break;}
 case 7:
-#line 160 "Gmsh.y"
+#line 159 "Gmsh.y"
 { return 1; ;
     break;}
 case 8:
-#line 161 "Gmsh.y"
+#line 160 "Gmsh.y"
 { return 1; ;
     break;}
 case 9:
-#line 162 "Gmsh.y"
+#line 161 "Gmsh.y"
 { List_Delete(yyvsp[0].l); return 1; ;
     break;}
 case 10:
-#line 163 "Gmsh.y"
+#line 162 "Gmsh.y"
 { List_Delete(yyvsp[0].l); return 1; ;
     break;}
 case 11:
-#line 164 "Gmsh.y"
+#line 163 "Gmsh.y"
 { return 1; ;
     break;}
 case 12:
-#line 165 "Gmsh.y"
+#line 164 "Gmsh.y"
 { return 1; ;
     break;}
 case 13:
-#line 166 "Gmsh.y"
+#line 165 "Gmsh.y"
 { return 1; ;
     break;}
 case 14:
-#line 167 "Gmsh.y"
+#line 166 "Gmsh.y"
 { List_Delete(yyvsp[0].l); return 1; ;
     break;}
 case 15:
-#line 168 "Gmsh.y"
+#line 167 "Gmsh.y"
 { return 1; ;
     break;}
 case 16:
-#line 169 "Gmsh.y"
+#line 168 "Gmsh.y"
 { return 1; ;
     break;}
 case 17:
-#line 170 "Gmsh.y"
+#line 169 "Gmsh.y"
 { return 1; ;
     break;}
 case 18:
-#line 171 "Gmsh.y"
+#line 170 "Gmsh.y"
 { return 1; ;
     break;}
 case 19:
-#line 172 "Gmsh.y"
+#line 171 "Gmsh.y"
 { return 1; ;
     break;}
 case 20:
-#line 177 "Gmsh.y"
+#line 176 "Gmsh.y"
 {
       yyval.c = "w";
     ;
     break;}
 case 21:
-#line 181 "Gmsh.y"
+#line 180 "Gmsh.y"
 {
       yyval.c = "a";
     ;
     break;}
 case 22:
-#line 188 "Gmsh.y"
+#line 187 "Gmsh.y"
 {
       Msg(DIRECT, yyvsp[-2].c);
       Free(yyvsp[-2].c);
     ;
     break;}
 case 23:
-#line 193 "Gmsh.y"
+#line 192 "Gmsh.y"
 {
       char tmpstring[1024];
       FixRelativePath(yyvsp[-1].c, tmpstring);
@@ -2967,7 +2966,7 @@ case 23:
     ;
     break;}
 case 24:
-#line 208 "Gmsh.y"
+#line 207 "Gmsh.y"
 {
       char tmpstring[1024];
       int i = PrintListOfDouble(yyvsp[-4].c, yyvsp[-2].l, tmpstring);
@@ -2982,7 +2981,7 @@ case 24:
     ;
     break;}
 case 25:
-#line 221 "Gmsh.y"
+#line 220 "Gmsh.y"
 {
       char tmpstring[1024];
       int i = PrintListOfDouble(yyvsp[-6].c, yyvsp[-4].l, tmpstring);
@@ -3008,7 +3007,7 @@ case 25:
     ;
     break;}
 case 26:
-#line 250 "Gmsh.y"
+#line 249 "Gmsh.y"
 { 
       if(!strcmp(yyvsp[-5].c, "View") && !CheckViewErrorFlags(View)){
 	EndView(View, 0, yyname, yyvsp[-4].c);
@@ -3017,7 +3016,7 @@ case 26:
     ;
     break;}
 case 27:
-#line 257 "Gmsh.y"
+#line 256 "Gmsh.y"
 {
       if(!strcmp(yyvsp[-7].c, "View") && !CheckViewErrorFlags(View)){
 	EndView(View, 0, yyname, yyvsp[-6].c);
@@ -3026,7 +3025,7 @@ case 27:
     ;
     break;}
 case 28:
-#line 267 "Gmsh.y"
+#line 266 "Gmsh.y"
 {
       View = BeginView(1); 
       for(int i = 0; i < VIEW_NB_ELEMENT_TYPES; i++){
@@ -3035,23 +3034,23 @@ case 28:
     ;
     break;}
 case 35:
-#line 283 "Gmsh.y"
+#line 282 "Gmsh.y"
 { ViewCoord[ViewCoordIdx] = yyvsp[0].d; ViewCoordIdx++; ;
     break;}
 case 36:
-#line 285 "Gmsh.y"
+#line 284 "Gmsh.y"
 { ViewCoord[ViewCoordIdx] = yyvsp[0].d; ViewCoordIdx++; ;
     break;}
 case 37:
-#line 290 "Gmsh.y"
+#line 289 "Gmsh.y"
 { if(ViewValueList) List_Add(ViewValueList, &yyvsp[0].d); ;
     break;}
 case 38:
-#line 292 "Gmsh.y"
+#line 291 "Gmsh.y"
 { if(ViewValueList) List_Add(ViewValueList, &yyvsp[0].d); ;
     break;}
 case 39:
-#line 297 "Gmsh.y"
+#line 296 "Gmsh.y"
 {
       if(!strcmp(yyvsp[0].c, "SP")){
 	ViewElementIdx = 0; ViewNumNodes = 1; ViewNumComp = 1;
@@ -3243,7 +3242,7 @@ case 39:
     ;
     break;}
 case 40:
-#line 487 "Gmsh.y"
+#line 486 "Gmsh.y"
 {
       if(ViewValueList){
 	if(ViewCoordIdx != 3 * ViewNumNodes){
@@ -3259,7 +3258,7 @@ case 40:
     ;
     break;}
 case 41:
-#line 501 "Gmsh.y"
+#line 500 "Gmsh.y"
 {
       if(ViewValueList){  
 	if((List_Nbr(ViewValueList) - ViewNumListTmp) % (ViewNumComp * ViewCoordIdx/3)) 
@@ -3269,21 +3268,21 @@ case 41:
     ;
     break;}
 case 42:
-#line 512 "Gmsh.y"
+#line 511 "Gmsh.y"
 { 
       for(int i = 0; i < (int)strlen(yyvsp[0].c)+1; i++) List_Add(View->T2C, &yyvsp[0].c[i]); 
       Free(yyvsp[0].c);
     ;
     break;}
 case 43:
-#line 517 "Gmsh.y"
+#line 516 "Gmsh.y"
 { 
       for(int i = 0; i < (int)strlen(yyvsp[0].c)+1; i++) List_Add(View->T2C, &yyvsp[0].c[i]); 
       Free(yyvsp[0].c);
     ;
     break;}
 case 44:
-#line 525 "Gmsh.y"
+#line 524 "Gmsh.y"
 { 
       List_Add(View->T2D, &yyvsp[-5].d); List_Add(View->T2D, &yyvsp[-3].d);
       List_Add(View->T2D, &yyvsp[-1].d); 
@@ -3292,27 +3291,27 @@ case 44:
     ;
     break;}
 case 45:
-#line 532 "Gmsh.y"
+#line 531 "Gmsh.y"
 {
       View->NbT2++;
     ;
     break;}
 case 46:
-#line 539 "Gmsh.y"
+#line 538 "Gmsh.y"
 { 
       for(int i = 0; i < (int)strlen(yyvsp[0].c)+1; i++) List_Add(View->T3C, &yyvsp[0].c[i]); 
       Free(yyvsp[0].c);
     ;
     break;}
 case 47:
-#line 544 "Gmsh.y"
+#line 543 "Gmsh.y"
 { 
       for(int i = 0; i < (int)strlen(yyvsp[0].c)+1; i++) List_Add(View->T3C, &yyvsp[0].c[i]); 
       Free(yyvsp[0].c);
     ;
     break;}
 case 48:
-#line 552 "Gmsh.y"
+#line 551 "Gmsh.y"
 { 
       List_Add(View->T3D, &yyvsp[-7].d); List_Add(View->T3D, &yyvsp[-5].d);
       List_Add(View->T3D, &yyvsp[-3].d); List_Add(View->T3D, &yyvsp[-1].d); 
@@ -3321,70 +3320,70 @@ case 48:
     ;
     break;}
 case 49:
-#line 559 "Gmsh.y"
+#line 558 "Gmsh.y"
 {
       View->NbT3++;
     ;
     break;}
 case 50:
-#line 567 "Gmsh.y"
+#line 566 "Gmsh.y"
 {
       View->adaptive = new Adaptive_Post_View(View, yyvsp[-5].l, yyvsp[-2].l);
     ;
     break;}
 case 51:
-#line 575 "Gmsh.y"
+#line 574 "Gmsh.y"
 {
       View->adaptive = new Adaptive_Post_View(View, yyvsp[-11].l, yyvsp[-8].l, yyvsp[-5].l, yyvsp[-2].l);
     ;
     break;}
 case 52:
-#line 582 "Gmsh.y"
+#line 581 "Gmsh.y"
 {
       ViewValueList = View->Time;
     ;
     break;}
 case 53:
-#line 586 "Gmsh.y"
+#line 585 "Gmsh.y"
 {
     ;
     break;}
 case 54:
-#line 591 "Gmsh.y"
+#line 590 "Gmsh.y"
 {
       (*View->Grains) [(int)yyvsp[-3].d] = yyvsp[-1].l;
     ;
     break;}
 case 55:
-#line 599 "Gmsh.y"
+#line 598 "Gmsh.y"
 { yyval.i = 0; ;
     break;}
 case 56:
-#line 600 "Gmsh.y"
+#line 599 "Gmsh.y"
 { yyval.i = 1; ;
     break;}
 case 57:
-#line 601 "Gmsh.y"
+#line 600 "Gmsh.y"
 { yyval.i = 2; ;
     break;}
 case 58:
-#line 602 "Gmsh.y"
+#line 601 "Gmsh.y"
 { yyval.i = 3; ;
     break;}
 case 59:
-#line 603 "Gmsh.y"
+#line 602 "Gmsh.y"
 { yyval.i = 4; ;
     break;}
 case 60:
-#line 607 "Gmsh.y"
+#line 606 "Gmsh.y"
 { yyval.i = 1; ;
     break;}
 case 61:
-#line 608 "Gmsh.y"
+#line 607 "Gmsh.y"
 { yyval.i = -1; ;
     break;}
 case 62:
-#line 616 "Gmsh.y"
+#line 615 "Gmsh.y"
 {
       Symbol TheSymbol;
       TheSymbol.Name = yyvsp[-3].c;
@@ -3417,7 +3416,7 @@ case 62:
     ;
     break;}
 case 63:
-#line 647 "Gmsh.y"
+#line 646 "Gmsh.y"
 {
       Symbol TheSymbol;
       TheSymbol.Name = yyvsp[-6].c;
@@ -3458,7 +3457,7 @@ case 63:
     ;
     break;}
 case 64:
-#line 686 "Gmsh.y"
+#line 685 "Gmsh.y"
 {
       if(List_Nbr(yyvsp[-5].l) != List_Nbr(yyvsp[-1].l)){
 	yymsg(GERROR, "Incompatible array dimensions in affectation");
@@ -3514,7 +3513,7 @@ case 64:
     ;
     break;}
 case 65:
-#line 740 "Gmsh.y"
+#line 739 "Gmsh.y"
 {
       Symbol TheSymbol;
       TheSymbol.Name = yyvsp[-5].c;
@@ -3533,7 +3532,7 @@ case 65:
     ;
     break;}
 case 66:
-#line 757 "Gmsh.y"
+#line 756 "Gmsh.y"
 {
       // appends to the list
       Symbol TheSymbol;
@@ -3553,7 +3552,7 @@ case 66:
     ;
     break;}
 case 67:
-#line 775 "Gmsh.y"
+#line 774 "Gmsh.y"
 {
       Symbol TheSymbol;
       TheSymbol.Name = yyvsp[-2].c;
@@ -3566,7 +3565,7 @@ case 67:
     ;
     break;}
 case 68:
-#line 786 "Gmsh.y"
+#line 785 "Gmsh.y"
 {
       Symbol TheSymbol;
       TheSymbol.Name = yyvsp[-5].c;
@@ -3584,13 +3583,13 @@ case 68:
     ;
     break;}
 case 69:
-#line 803 "Gmsh.y"
+#line 802 "Gmsh.y"
 { 
       Msg(WARNING, "Named string expressions not implemented yet");
     ;
     break;}
 case 70:
-#line 810 "Gmsh.y"
+#line 809 "Gmsh.y"
 { 
       char* (*pStrOpt)(int num, int action, char *value);
       StringXString *pStrCat;
@@ -3606,7 +3605,7 @@ case 70:
     ;
     break;}
 case 71:
-#line 824 "Gmsh.y"
+#line 823 "Gmsh.y"
 { 
       char* (*pStrOpt)(int num, int action, char *value);
       StringXString *pStrCat;
@@ -3622,7 +3621,7 @@ case 71:
     ;
     break;}
 case 72:
-#line 841 "Gmsh.y"
+#line 840 "Gmsh.y"
 {
       double (*pNumOpt)(int num, int action, double value);
       StringXNumber *pNumCat;
@@ -3650,7 +3649,7 @@ case 72:
     ;
     break;}
 case 73:
-#line 867 "Gmsh.y"
+#line 866 "Gmsh.y"
 {
       double (*pNumOpt)(int num, int action, double value);
       StringXNumber *pNumCat;
@@ -3679,7 +3678,7 @@ case 73:
     ;
     break;}
 case 74:
-#line 894 "Gmsh.y"
+#line 893 "Gmsh.y"
 {
       double (*pNumOpt)(int num, int action, double value);
       StringXNumber *pNumCat;
@@ -3695,7 +3694,7 @@ case 74:
     ;
     break;}
 case 75:
-#line 908 "Gmsh.y"
+#line 907 "Gmsh.y"
 {
       double (*pNumOpt)(int num, int action, double value);
       StringXNumber *pNumCat;
@@ -3711,7 +3710,7 @@ case 75:
     ;
     break;}
 case 76:
-#line 925 "Gmsh.y"
+#line 924 "Gmsh.y"
 {
       unsigned int (*pColOpt)(int num, int action, unsigned int value);
       StringXColor *pColCat;
@@ -3727,7 +3726,7 @@ case 76:
     ;
     break;}
 case 77:
-#line 939 "Gmsh.y"
+#line 938 "Gmsh.y"
 {
       unsigned int (*pColOpt)(int num, int action, unsigned int value);
       StringXColor *pColCat;
@@ -3743,7 +3742,7 @@ case 77:
     ;
     break;}
 case 78:
-#line 956 "Gmsh.y"
+#line 955 "Gmsh.y"
 {
       GmshColorTable *ct = Get_ColorTable(0);
       if(!ct)
@@ -3765,7 +3764,7 @@ case 78:
     ;
     break;}
 case 79:
-#line 976 "Gmsh.y"
+#line 975 "Gmsh.y"
 {
       GmshColorTable *ct = Get_ColorTable((int)yyvsp[-6].d);
       if(!ct)
@@ -3787,7 +3786,7 @@ case 79:
     ;
     break;}
 case 80:
-#line 999 "Gmsh.y"
+#line 998 "Gmsh.y"
 {
       try {
 	GMSH_PluginManager::instance()->setPluginOption(yyvsp[-6].c, yyvsp[-3].c, yyvsp[-1].d); 
@@ -3799,7 +3798,7 @@ case 80:
     ;
     break;}
 case 81:
-#line 1009 "Gmsh.y"
+#line 1008 "Gmsh.y"
 {
       try {
 	GMSH_PluginManager::instance()->setPluginOption(yyvsp[-6].c, yyvsp[-3].c, yyvsp[-1].c); 
@@ -3811,15 +3810,16 @@ case 81:
     ;
     break;}
 case 82:
-#line 1024 "Gmsh.y"
+#line 1023 "Gmsh.y"
 { 
       yyval.i = (int)yyvsp[0].d; 
     ;
     break;}
 case 83:
-#line 1028 "Gmsh.y"
+#line 1027 "Gmsh.y"
 { 
-      yyval.i = GMODEL->setPhysicalName(std::string(yyvsp[0].c), ++THEM->MaxPhysicalNum);
+      yyval.i = GModel::current()->setPhysicalName(std::string(yyvsp[0].c),
+					      ++THEM->MaxPhysicalNum);
       Free(yyvsp[0].c);
     ;
     break;}
@@ -3876,7 +3876,7 @@ case 86:
         if(v)
           att->addPoint(v->Pos.X, v->Pos.Y, v->Pos.Z);
         else{
-          GVertex *gv = GMODEL->vertexByTag((int)d);
+          GVertex *gv = GModel::current()->vertexByTag((int)d);
           if(gv) 
             att->addPoint(gv->x(), gv->y(), gv->z());
         }
@@ -3991,7 +3991,7 @@ case 93:
 	if(v)
 	  attractor->addPoint(v->Pos.X, v->Pos.Y, v->Pos.Z);
 	else{
-	  GVertex *gv = GMODEL->vertexByTag((int)d);
+	  GVertex *gv = GModel::current()->vertexByTag((int)d);
 	  if(gv) 
 	    attractor->addPoint(gv->x(), gv->y(), gv->z());
 	}
@@ -4028,7 +4028,7 @@ case 94:
 	  att->addCurve(c, (int)pars[3]);
 	}
 	else{
-	  GEdge *ge = GMODEL->edgeByTag((int)d);
+	  GEdge *ge = GModel::current()->edgeByTag((int)d);
 	  if(ge){
 	    att->addGEdge(ge, (int)pars[3]);
 	  }
@@ -4050,7 +4050,7 @@ case 95:
 	if(v)
 	  v->lc = yyvsp[-1].d;
 	else{
-	  GVertex *gv = GMODEL->vertexByTag((int)d);
+	  GVertex *gv = GModel::current()->vertexByTag((int)d);
 	  if(gv) 
 	    gv->setPrescribedMeshSizeAtVertex(yyvsp[-1].d);
 	}
@@ -4608,7 +4608,7 @@ case 129:
 	  List_Add(yyval.l, &TheShape);
 	}
 	else{
-	  GVertex *gv = GMODEL->vertexByTag(TheShape.Num);
+	  GVertex *gv = GModel::current()->vertexByTag(TheShape.Num);
 	  if(gv){
 	    TheShape.Type = MSH_POINT_FROM_GMODEL;
 	    List_Add(yyval.l, &TheShape);
@@ -4633,7 +4633,7 @@ case 130:
 	  List_Add(yyval.l, &TheShape);
 	}
 	else{
-	  GEdge *ge = GMODEL->edgeByTag(TheShape.Num);
+	  GEdge *ge = GModel::current()->edgeByTag(TheShape.Num);
 	  if(ge){
 	    TheShape.Type = MSH_SEGM_FROM_GMODEL;
 	    List_Add(yyval.l, &TheShape);
@@ -4658,7 +4658,7 @@ case 131:
 	  List_Add(yyval.l, &TheShape);
 	}
 	else{
-	  GFace *gf = GMODEL->faceByTag(TheShape.Num);
+	  GFace *gf = GModel::current()->faceByTag(TheShape.Num);
 	  if(gf){
 	    TheShape.Type = MSH_SURF_FROM_GMODEL;
 	    List_Add(yyval.l, &TheShape);
@@ -4683,7 +4683,7 @@ case 132:
 	  List_Add(yyval.l, &TheShape);
 	}
 	else{
-	  GRegion *gr = GMODEL->regionByTag(TheShape.Num);
+	  GRegion *gr = GModel::current()->regionByTag(TheShape.Num);
 	  if(gr){
 	    TheShape.Type = MSH_VOLUME_FROM_GMODEL;
 	    List_Add(yyval.l, &TheShape);
@@ -4758,13 +4758,13 @@ case 139:
 #line 1893 "Gmsh.y"
 {
       if(!strcmp(yyvsp[-1].c, "Meshes") || !strcmp(yyvsp[-1].c, "All")){
-	GMODEL->destroy();
+	GModel::current()->destroy();
 	THEM->destroy();
       }
       else if(!strcmp(yyvsp[-1].c, "Physicals")){
 	List_Action(THEM->PhysicalGroups, Free_PhysicalGroup);
 	List_Reset(THEM->PhysicalGroups);
-	GMODEL->deletePhysicalGroups();
+	GModel::current()->deletePhysicalGroups();
       }
       else{
 	yymsg(GERROR, "Unknown command 'Delete %s'", yyvsp[-1].c);
@@ -4860,7 +4860,7 @@ case 146:
 	// make sure we have the latest data from THEM in GModel
 	// (fixes bug where we would have no geometry in the picture if
 	// the print command is in the same file as the geometry)
-	GMODEL->importTHEM();
+	GModel::current()->importTHEM();
 	char tmpstring[1024];
 	FixRelativePath(yyvsp[-1].c, tmpstring);
 	CreateOutputFile(tmpstring, CTX.print.format);
@@ -4868,7 +4868,7 @@ case 146:
       }
       else if(!strcmp(yyvsp[-2].c, "Save")){
 #if defined(HAVE_FLTK)
-	GMODEL->importTHEM();
+	GModel::current()->importTHEM();
 	char tmpstring[1024];
 	FixRelativePath(yyvsp[-1].c, tmpstring);
 	CreateOutputFile(tmpstring, CTX.mesh.format);
diff --git a/Parser/Gmsh.y b/Parser/Gmsh.y
index 1b59a979f60388320066be101060d62c53b79e06..537e853f5abfb2a0910dfab51756ccd24c4878fa 100644
--- a/Parser/Gmsh.y
+++ b/Parser/Gmsh.y
@@ -1,5 +1,5 @@
 %{
-// $Id: Gmsh.y,v 1.280 2007-07-25 15:48:34 geuzaine Exp $
+// $Id: Gmsh.y,v 1.281 2007-08-21 19:05:42 geuzaine Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -50,7 +50,6 @@ Tree_T *Symbol_T = NULL;
 
 extern Context_T CTX;
 extern Mesh *THEM;
-extern GModel *GMODEL;
 
 static ExtrudeParams extr;
 
@@ -1026,7 +1025,8 @@ PhysicalId :
     }
   | StringExpr
     { 
-      $$ = GMODEL->setPhysicalName(std::string($1), ++THEM->MaxPhysicalNum);
+      $$ = GModel::current()->setPhysicalName(std::string($1),
+					      ++THEM->MaxPhysicalNum);
       Free($1);
     }
 ;
@@ -1084,7 +1084,7 @@ Shape :
         if(v)
           att->addPoint(v->Pos.X, v->Pos.Y, v->Pos.Z);
         else{
-          GVertex *gv = GMODEL->vertexByTag((int)d);
+          GVertex *gv = GModel::current()->vertexByTag((int)d);
           if(gv) 
             att->addPoint(gv->x(), gv->y(), gv->z());
         }
@@ -1186,7 +1186,7 @@ Shape :
 	if(v)
 	  attractor->addPoint(v->Pos.X, v->Pos.Y, v->Pos.Z);
 	else{
-	  GVertex *gv = GMODEL->vertexByTag((int)d);
+	  GVertex *gv = GModel::current()->vertexByTag((int)d);
 	  if(gv) 
 	    attractor->addPoint(gv->x(), gv->y(), gv->z());
 	}
@@ -1221,7 +1221,7 @@ Shape :
 	  att->addCurve(c, (int)pars[3]);
 	}
 	else{
-	  GEdge *ge = GMODEL->edgeByTag((int)d);
+	  GEdge *ge = GModel::current()->edgeByTag((int)d);
 	  if(ge){
 	    att->addGEdge(ge, (int)pars[3]);
 	  }
@@ -1241,7 +1241,7 @@ Shape :
 	if(v)
 	  v->lc = $5;
 	else{
-	  GVertex *gv = GMODEL->vertexByTag((int)d);
+	  GVertex *gv = GModel::current()->vertexByTag((int)d);
 	  if(gv) 
 	    gv->setPrescribedMeshSizeAtVertex($5);
 	}
@@ -1750,7 +1750,7 @@ ListOfShapes :
 	  List_Add($$, &TheShape);
 	}
 	else{
-	  GVertex *gv = GMODEL->vertexByTag(TheShape.Num);
+	  GVertex *gv = GModel::current()->vertexByTag(TheShape.Num);
 	  if(gv){
 	    TheShape.Type = MSH_POINT_FROM_GMODEL;
 	    List_Add($$, &TheShape);
@@ -1773,7 +1773,7 @@ ListOfShapes :
 	  List_Add($$, &TheShape);
 	}
 	else{
-	  GEdge *ge = GMODEL->edgeByTag(TheShape.Num);
+	  GEdge *ge = GModel::current()->edgeByTag(TheShape.Num);
 	  if(ge){
 	    TheShape.Type = MSH_SEGM_FROM_GMODEL;
 	    List_Add($$, &TheShape);
@@ -1796,7 +1796,7 @@ ListOfShapes :
 	  List_Add($$, &TheShape);
 	}
 	else{
-	  GFace *gf = GMODEL->faceByTag(TheShape.Num);
+	  GFace *gf = GModel::current()->faceByTag(TheShape.Num);
 	  if(gf){
 	    TheShape.Type = MSH_SURF_FROM_GMODEL;
 	    List_Add($$, &TheShape);
@@ -1819,7 +1819,7 @@ ListOfShapes :
 	  List_Add($$, &TheShape);
 	}
 	else{
-	  GRegion *gr = GMODEL->regionByTag(TheShape.Num);
+	  GRegion *gr = GModel::current()->regionByTag(TheShape.Num);
 	  if(gr){
 	    TheShape.Type = MSH_VOLUME_FROM_GMODEL;
 	    List_Add($$, &TheShape);
@@ -1892,13 +1892,13 @@ Delete :
   | tDelete tSTRING tEND
     {
       if(!strcmp($2, "Meshes") || !strcmp($2, "All")){
-	GMODEL->destroy();
+	GModel::current()->destroy();
 	THEM->destroy();
       }
       else if(!strcmp($2, "Physicals")){
 	List_Action(THEM->PhysicalGroups, Free_PhysicalGroup);
 	List_Reset(THEM->PhysicalGroups);
-	GMODEL->deletePhysicalGroups();
+	GModel::current()->deletePhysicalGroups();
       }
       else{
 	yymsg(GERROR, "Unknown command 'Delete %s'", $2);
@@ -1995,7 +1995,7 @@ Command :
 	// make sure we have the latest data from THEM in GModel
 	// (fixes bug where we would have no geometry in the picture if
 	// the print command is in the same file as the geometry)
-	GMODEL->importTHEM();
+	GModel::current()->importTHEM();
 	char tmpstring[1024];
 	FixRelativePath($2, tmpstring);
 	CreateOutputFile(tmpstring, CTX.print.format);
@@ -2003,7 +2003,7 @@ Command :
       }
       else if(!strcmp($1, "Save")){
 #if defined(HAVE_FLTK)
-	GMODEL->importTHEM();
+	GModel::current()->importTHEM();
 	char tmpstring[1024];
 	FixRelativePath($2, tmpstring);
 	CreateOutputFile(tmpstring, CTX.mesh.format);
diff --git a/Parser/Gmsh.yy.cpp b/Parser/Gmsh.yy.cpp
index 01bb9e532ac3cad90930b52502520e3367c65a68..121787d3e3c0e7e0beeb7650b2fe97753b79de94 100644
--- a/Parser/Gmsh.yy.cpp
+++ b/Parser/Gmsh.yy.cpp
@@ -2,7 +2,7 @@
 /* A lexical scanner generated by flex */
 
 /* Scanner skeleton version:
- * $Header: /cvsroot/gmsh/Parser/Gmsh.yy.cpp,v 1.324 2007-07-25 15:48:34 geuzaine Exp $
+ * $Header: /cvsroot/gmsh/Parser/Gmsh.yy.cpp,v 1.325 2007-08-21 19:05:43 geuzaine Exp $
  */
 
 #define FLEX_SCANNER
@@ -755,7 +755,7 @@ char *yytext;
 #line 1 "Gmsh.l"
 #define INITIAL 0
 #line 2 "Gmsh.l"
-// $Id: Gmsh.yy.cpp,v 1.324 2007-07-25 15:48:34 geuzaine Exp $
+// $Id: Gmsh.yy.cpp,v 1.325 2007-08-21 19:05:43 geuzaine Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
diff --git a/Parser/Makefile b/Parser/Makefile
index ef627661f285162329075bb69021696cc05f1943..43c92664858daa592c0f5a2a03b711c82fda511c 100644
--- a/Parser/Makefile
+++ b/Parser/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.122 2007-07-09 13:54:37 geuzaine Exp $
+# $Id: Makefile,v 1.123 2007-08-21 19:05:43 geuzaine Exp $
 #
 # Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 #
@@ -131,11 +131,13 @@ OpenFile.o: OpenFile.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../Geo/GEntity.h ../Geo/MElement.h ../Geo/ExtrudeParams.h \
   ../Geo/SBoundingBox3d.h Parser.h OpenFile.h ../Common/CommandLine.h \
   ../Post/Views.h ../Post/ColorTable.h ../Common/VertexArray.h \
-  ../Post/AdaptiveViews.h ../Common/GmshMatrix.h ../Graphics/ReadImg.h \
-  ../Common/OS.h ../Mesh/HighOrder.h ../Common/GmshUI.h \
-  ../Graphics/Draw.h ../Graphics/SelectBuffer.h ../Fltk/GUI.h \
-  ../Fltk/Opengl_Window.h ../Fltk/Colorbar_Window.h \
-  ../Fltk/Popup_Button.h ../Fltk/SpherePosition_Widget.h
+  ../Post/AdaptiveViews.h ../Common/GmshMatrix.h ../Post/PView.h \
+  ../Post/AdaptiveViews.h ../Post/PViewData.h ../Post/PViewOptions.h \
+  ../Post/ColorTable.h ../Graphics/ReadImg.h ../Common/OS.h \
+  ../Mesh/HighOrder.h ../Common/GmshUI.h ../Graphics/Draw.h \
+  ../Graphics/SelectBuffer.h ../Fltk/GUI.h ../Fltk/Opengl_Window.h \
+  ../Fltk/Colorbar_Window.h ../Fltk/Popup_Button.h \
+  ../Fltk/SpherePosition_Widget.h
 CreateFile.o: CreateFile.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
   ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h ../DataStr/Tree.h \
@@ -157,9 +159,7 @@ CreateFile.o: CreateFile.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../Geo/GEntity.h ../Geo/MElement.h ../Geo/ExtrudeParams.h \
   ../Geo/SBoundingBox3d.h ../Common/GmshUI.h ../Graphics/gl2ps.h \
   ../Graphics/gl2gif.h ../Graphics/PixelBuffer.h ../Graphics/Draw.h \
-  ../Post/Views.h ../Post/ColorTable.h ../Common/VertexArray.h \
-  ../Post/AdaptiveViews.h ../Common/GmshMatrix.h ../Graphics/gl2jpeg.h \
-  ../Graphics/PixelBuffer.h ../Graphics/gl2png.h \
+  ../Graphics/gl2jpeg.h ../Graphics/PixelBuffer.h ../Graphics/gl2png.h \
   ../Graphics/PixelBuffer.h ../Graphics/gl2ppm.h \
   ../Graphics/PixelBuffer.h ../Graphics/gl2yuv.h \
   ../Graphics/PixelBuffer.h
diff --git a/Parser/OpenFile.cpp b/Parser/OpenFile.cpp
index 5220d7795ee667155ba4f09d0f5b233227019cbc..5d1e4fd9a62767ca3a50d406db08c50aea2ee46f 100644
--- a/Parser/OpenFile.cpp
+++ b/Parser/OpenFile.cpp
@@ -1,4 +1,4 @@
-// $Id: OpenFile.cpp,v 1.150 2007-08-17 15:43:07 geuzaine Exp $
+// $Id: OpenFile.cpp,v 1.151 2007-08-21 19:05:43 geuzaine Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -32,6 +32,7 @@
 #include "OpenFile.h"
 #include "CommandLine.h"
 #include "Views.h"
+#include "PView.h"
 #include "ReadImg.h"
 #include "OS.h"
 #include "HighOrder.h"
@@ -45,9 +46,8 @@ extern GUI *WID;
 void UpdateViewsInGUI();
 #endif
 
-extern Mesh *THEM;
-extern GModel *GMODEL;
 extern Context_T CTX;
+extern Mesh *THEM;
 
 void FixRelativePath(char *in, char *out){
   if(in[0] == '/' || in[0] == '\\' || (strlen(in)>2 && in[1] == ':')){
@@ -149,9 +149,7 @@ void SetBoundingBox(void)
 {
   if(CTX.forced_bbox) return;
 
-  SBoundingBox3d bb;
-
-  bb = GMODEL->bounds();
+  SBoundingBox3d bb = GModel::current()->bounds();
   
   if(bb.empty() && List_Nbr(CTX.post.list)) {
     for(int i = 0; i < List_Nbr(CTX.post.list); i++){
@@ -263,7 +261,7 @@ void ParseString(char *str)
     fprintf(fp, "\n");
     fclose(fp);
     ParseFile(CTX.tmp_filename_fullpath, 1);
-    if(GMODEL) GMODEL->importTHEM();
+    GModel::current()->importTHEM();
   }
 }
 
@@ -320,42 +318,45 @@ int MergeFile(char *name, int warn_if_missing)
 #endif
 
   CTX.geom.draw = 0; // don't try to draw the model while reading
+
+  GModel *m = GModel::current();
+
   int status = 0;
   if(!strcmp(ext, ".stl") || !strcmp(ext, ".STL")){
-    status = GMODEL->readSTL(name, CTX.geom.tolerance);
+    status = m->readSTL(name, CTX.geom.tolerance);
   }
   else if(!strcmp(ext, ".brep") || !strcmp(ext, ".rle") ||
 	  !strcmp(ext, ".brp") || !strcmp(ext, ".BRP")){
-    GMODEL->readOCCBREP(std::string(name));
+    status = m->readOCCBREP(std::string(name));
   }
   else if(!strcmp(ext, ".iges") || !strcmp(ext, ".IGES") ||
 	  !strcmp(ext, ".igs") || !strcmp(ext, ".IGS")){
-    GMODEL->readOCCIGES(std::string(name));
+    status = m->readOCCIGES(std::string(name));
   }
   else if(!strcmp(ext, ".step") || !strcmp(ext, ".STEP") ||
 	  !strcmp(ext, ".stp") || !strcmp(ext, ".STP")){
-    GMODEL->readOCCSTEP(std::string(name));
+    status = m->readOCCSTEP(std::string(name));
   }
   else if(!strcmp(ext, ".unv") || !strcmp(ext, ".UNV")){
-    status = GMODEL->readUNV(name);
+    status = m->readUNV(name);
   }
   else if(!strcmp(ext, ".wrl") || !strcmp(ext, ".WRL") || 
 	  !strcmp(ext, ".vrml") || !strcmp(ext, ".VRML") ||
 	  !strcmp(ext, ".iv") || !strcmp(ext, ".IV")){
-    status = GMODEL->readVRML(name);
+    status = m->readVRML(name);
   }
   else if(!strcmp(ext, ".mesh") || !strcmp(ext, ".MESH")){
-    status = GMODEL->readMESH(name);
+    status = m->readMESH(name);
   }
   else if(!strcmp(ext, ".bdf") || !strcmp(ext, ".BDF") ||
 	  !strcmp(ext, ".nas") || !strcmp(ext, ".NAS")){
-    status = GMODEL->readBDF(name);
+    status = m->readBDF(name);
   }
   else if(!strcmp(ext, ".p3d") || !strcmp(ext, ".P3D")){
-    status = GMODEL->readP3D(name);
+    status = m->readP3D(name);
   }
   else if(!strcmp(ext, ".fm") || !strcmp(ext, ".FM")) {
-    status = GMODEL->readF(name);
+    status = m->readF(name);
   }
 #if defined(HAVE_FLTK)
   else if(!strcmp(ext, ".pnm") || !strcmp(ext, ".PNM") ||
@@ -384,14 +385,20 @@ int MergeFile(char *name, int warn_if_missing)
     if(!strncmp(header, "$PTS", 4) || !strncmp(header, "$NO", 3) || 
        !strncmp(header, "$PARA", 5) || !strncmp(header, "$ELM", 4) ||
        !strncmp(header, "$MeshFormat", 11)) {
-      status = GMODEL->readMSH(name);
+      status = m->readMSH(name);
     }
     else if(!strncmp(header, "$PostFormat", 11) || 
 	    !strncmp(header, "$View", 5)) {
+#if 0 // FIXME: test new post-pro
+      PView *p = new PView(false);
+      PView::list.push_back(p);
+      status = p->getData()->read(name);
+#else
       status = ReadView(name);
+#endif
     }
     else {
-      status = GMODEL->readGEO(name);
+      status = m->readGEO(name);
     }
   }
 
@@ -400,7 +407,7 @@ int MergeFile(char *name, int warn_if_missing)
   CTX.geom.draw = 1;
   CTX.mesh.changed = ENT_ALL;
 
-  checkHighOrderTriangles ( GMODEL );
+  checkHighOrderTriangles(m);
 
   Msg(STATUS2, "Read '%s'", name);
   return status;
@@ -414,13 +421,14 @@ void OpenProject(char *name)
   }
   CTX.threads_lock = 1;
 
-  GMODEL->destroy();
+  GModel::current()->destroy();
   THEM->destroy();
 
   // Initialize pseudo random mesh generator to the same seed
   srand(1);
 
-  // temporary hack until we fill GMODEL on the fly during parsing
+  // temporary hack until we fill the current GModel on the fly during
+  // parsing
   ResetTemporaryBoundingBox();
 
   SetProjectName(name);
diff --git a/Post/Makefile b/Post/Makefile
index a9a567d9902538f790b270d00b6530a5576f7334..cd22637f4f158ba58ae77786ffc96456788bbed4 100644
--- a/Post/Makefile
+++ b/Post/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.3 2007-07-26 16:35:58 geuzaine Exp $
+# $Id: Makefile,v 1.4 2007-08-21 19:05:43 geuzaine Exp $
 #
 # Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 #
@@ -27,7 +27,11 @@ INCLUDE = -I../Common -I../DataStr -I../Geo -I../Mesh -I../Post\
           -I../contrib/MathEval -I../contrib/ANN/include/
 CFLAGS  =${OPTIM} ${FLAGS} ${INCLUDE}
 
-SRC = Views.cpp ViewsIO.cpp\
+SRC = PView.cpp\
+        PViewData.cpp PViewOptions.cpp\
+        PViewIO.cpp\
+      Views.cpp\
+        ViewsIO.cpp\
       AdaptiveViews.cpp\
       OctreePost.cpp\
       ColorTable.cpp
@@ -55,6 +59,53 @@ depend:
 	rm -f Makefile.new
 
 # DO NOT DELETE THIS LINE
+PView.o: PView.cpp PView.h ../Common/VertexArray.h ../Common/SmoothData.h \
+  ../Numeric/Numeric.h AdaptiveViews.h ../DataStr/List.h \
+  ../Common/GmshMatrix.h PViewData.h ../Geo/GModel.h ../Geo/GVertex.h \
+  ../Geo/GEntity.h ../Geo/Range.h ../Geo/SPoint3.h \
+  ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h ../Common/GmshDefines.h \
+  ../Geo/MVertex.h ../Geo/SPoint3.h ../Geo/GPoint.h ../Geo/SPoint2.h \
+  ../Geo/GEdge.h ../Geo/GEntity.h ../Geo/GVertex.h ../Geo/SVector3.h \
+  ../Geo/SPoint3.h ../Geo/SPoint3.h ../Geo/SPoint2.h ../Geo/MElement.h \
+  ../Geo/MVertex.h ../Geo/MEdge.h ../Geo/MVertex.h ../Geo/SVector3.h \
+  ../Common/Hash.h ../Geo/MFace.h ../Geo/MVertex.h ../Geo/SVector3.h \
+  ../Common/Context.h ../Geo/ExtrudeParams.h ../Geo/GFace.h \
+  ../Geo/GPoint.h ../Geo/GEntity.h ../Geo/GEdgeLoop.h ../Geo/GEdge.h \
+  ../Geo/MElement.h ../Geo/SPoint2.h ../Geo/SVector3.h ../Geo/Pair.h \
+  ../Geo/ExtrudeParams.h ../Geo/GRegion.h ../Geo/GEntity.h \
+  ../Geo/MElement.h ../Geo/ExtrudeParams.h ../Geo/SBoundingBox3d.h \
+  PViewOptions.h ColorTable.h ../Common/Message.h
+PViewData.o: PViewData.cpp PViewData.h ../Geo/GModel.h ../Geo/GVertex.h \
+  ../Geo/GEntity.h ../Geo/Range.h ../Geo/SPoint3.h \
+  ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h ../Common/GmshDefines.h \
+  ../Geo/MVertex.h ../Geo/SPoint3.h ../Geo/GPoint.h ../Geo/SPoint2.h \
+  ../Geo/GEdge.h ../Geo/GEntity.h ../Geo/GVertex.h ../Geo/SVector3.h \
+  ../Geo/SPoint3.h ../Geo/SPoint3.h ../Geo/SPoint2.h ../Geo/MElement.h \
+  ../Geo/MVertex.h ../Geo/MEdge.h ../Geo/MVertex.h ../Geo/SVector3.h \
+  ../Common/Hash.h ../Geo/MFace.h ../Geo/MVertex.h ../Geo/SVector3.h \
+  ../Numeric/Numeric.h ../Common/Context.h ../DataStr/List.h \
+  ../Geo/ExtrudeParams.h ../Common/SmoothData.h ../Geo/GFace.h \
+  ../Geo/GPoint.h ../Geo/GEntity.h ../Geo/GEdgeLoop.h ../Geo/GEdge.h \
+  ../Geo/MElement.h ../Geo/SPoint2.h ../Geo/SVector3.h ../Geo/Pair.h \
+  ../Geo/ExtrudeParams.h ../Geo/GRegion.h ../Geo/GEntity.h \
+  ../Geo/MElement.h ../Geo/ExtrudeParams.h ../Geo/SBoundingBox3d.h
+PViewOptions.o: PViewOptions.cpp PViewOptions.h ColorTable.h
+PViewIO.o: PViewIO.cpp PView.h ../Common/VertexArray.h \
+  ../Common/SmoothData.h ../Numeric/Numeric.h AdaptiveViews.h \
+  ../DataStr/List.h ../Common/GmshMatrix.h PViewData.h ../Geo/GModel.h \
+  ../Geo/GVertex.h ../Geo/GEntity.h ../Geo/Range.h ../Geo/SPoint3.h \
+  ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h ../Common/GmshDefines.h \
+  ../Geo/MVertex.h ../Geo/SPoint3.h ../Geo/GPoint.h ../Geo/SPoint2.h \
+  ../Geo/GEdge.h ../Geo/GEntity.h ../Geo/GVertex.h ../Geo/SVector3.h \
+  ../Geo/SPoint3.h ../Geo/SPoint3.h ../Geo/SPoint2.h ../Geo/MElement.h \
+  ../Geo/MVertex.h ../Geo/MEdge.h ../Geo/MVertex.h ../Geo/SVector3.h \
+  ../Common/Hash.h ../Geo/MFace.h ../Geo/MVertex.h ../Geo/SVector3.h \
+  ../Common/Context.h ../Geo/ExtrudeParams.h ../Geo/GFace.h \
+  ../Geo/GPoint.h ../Geo/GEntity.h ../Geo/GEdgeLoop.h ../Geo/GEdge.h \
+  ../Geo/MElement.h ../Geo/SPoint2.h ../Geo/SVector3.h ../Geo/Pair.h \
+  ../Geo/ExtrudeParams.h ../Geo/GRegion.h ../Geo/GEntity.h \
+  ../Geo/MElement.h ../Geo/ExtrudeParams.h ../Geo/SBoundingBox3d.h \
+  PViewOptions.h ColorTable.h ../Common/Message.h
 Views.o: Views.cpp ../Common/Gmsh.h ../Common/Message.h \
   ../DataStr/Malloc.h ../DataStr/List.h ../DataStr/Tree.h \
   ../DataStr/avl.h ../DataStr/Tools.h ../DataStr/List.h ../DataStr/Tree.h \
diff --git a/Post/PView.cpp b/Post/PView.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4ef6fecfb6a42d6404dc6926e7a86aac152077c3
--- /dev/null
+++ b/Post/PView.cpp
@@ -0,0 +1,39 @@
+// $Id: PView.cpp,v 1.1 2007-08-21 19:05:43 geuzaine Exp $
+//
+// Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+// 
+// Please report all bugs and problems to <gmsh@geuz.org>.
+//
+// Contributor(s):
+// 
+
+#include "PView.h"
+#include "Message.h"
+
+std::vector<PView*> PView::list;
+
+PView *PView::current()
+{ 
+  if(list.empty()){
+    Msg(GERROR, "No view available");
+    return 0;
+  }
+  // return the last one for now
+  return list.back();
+}
+
diff --git a/Post/PView.h b/Post/PView.h
new file mode 100644
index 0000000000000000000000000000000000000000..60dd9bd03944737b11cf89bdf1fa4d9510a9e3d1
--- /dev/null
+++ b/Post/PView.h
@@ -0,0 +1,103 @@
+#ifndef _PVIEW_H_
+#define _PVIEW_H_
+
+// Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+// 
+// Please report all bugs and problems to <gmsh@geuz.org>.
+
+#include <vector>
+#include <string>
+#include "VertexArray.h"
+#include "SmoothData.h"
+#include "AdaptiveViews.h"
+#include "PViewData.h"
+#include "PViewOptions.h"
+
+// a post-processing view
+class PView{
+ private:
+  // unique tag of the view
+  int _num;
+  // index of the view in the current view list
+  int _index;
+  // flag to mark that the view has changed
+  bool _changed;
+  // flag to mark that the view is an alias of another view
+  int _aliasOf;
+  // flag to mark that some other views link to this one
+  bool _links;
+  // flag to mark that this view is 'dirty' and should not be
+  // displayed
+  bool _dirty;
+  // name of the view
+  std::string _name;
+  // name of the file the view was loaded from
+  std::string _filename;
+  // the options
+  PViewOptions *_options;
+  // the data
+  PViewData *_data;
+ public:
+  PView(bool allocate=true) :
+    _num(0), _index(0), _changed(false), _aliasOf(-1), _links(false), 
+    _dirty(true), _name(""), _filename(""), _options(0), _data(0),
+    va_lines(0), va_triangles(0), normals(0), adaptive(0)
+  {
+    _data = new PViewDataList(allocate);
+    _options = new PViewOptions;
+  }
+  ~PView()
+  {
+    if(_options) delete _options;
+    if(_data) delete _data;
+    if(va_lines) delete va_lines;
+    if(va_triangles) delete va_triangles;
+    if(normals) delete normals;
+    if(adaptive) delete adaptive;
+  }
+  // the static list of all loaded views
+  static std::vector<PView*> list;
+  // the current view
+  static PView *current();
+  PViewOptions *getOptions(){ return _options; }  
+  PViewData *getData(){ return _data; }
+  int getIndex(){ return _index; }
+  void setIndex(int val){ _index = val; }
+  bool getChanged(){ return _changed; }
+  void setChanged(bool val){ _changed = val; }
+  bool getDirty(){ return _dirty; }
+  void setDirty(bool val){ _dirty = val; }
+  void setGlobalResolutionLevel(int level)
+  {
+    //if(adaptive) adaptive->setGlobalResolutionLevel(this, level);
+  }
+  void setAdaptiveResolutionLevel(int level, GMSH_Post_Plugin *plugin = 0)
+  {
+    //if(adaptive) adaptive->setAdaptiveResolutionLevel(this, level, plugin);
+  }
+
+  // vertex arrays to draw triangles and lines efficiently
+  VertexArray *va_lines, *va_triangles;
+  // smoothed normals
+  smooth_normals *normals;
+  // adaptative rendering for high-order datasets
+  Adaptive_Post_View *adaptive;
+
+};
+
+#endif
diff --git a/Post/PViewData.cpp b/Post/PViewData.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..82e601431f4ee16bbfd4157a356932e88049d5af
--- /dev/null
+++ b/Post/PViewData.cpp
@@ -0,0 +1,315 @@
+// $Id: PViewData.cpp,v 1.1 2007-08-21 19:05:43 geuzaine Exp $
+//
+// Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+// 
+// Please report all bugs and problems to <gmsh@geuz.org>.
+//
+// Contributor(s):
+// 
+
+#include "PViewData.h"
+
+PViewDataList::PViewDataList(bool allocate)
+  : DataSize(sizeof(double)), NbTimeStep(0), 
+    ScalarOnly(0), TextOnly(0), Min(VAL_INF), Max(-VAL_INF), Time(0),
+    NbSP(0), SP(0), NbVP(0), VP(0), NbTP(0), TP(0),
+    NbSL(0), SL(0), NbVL(0), VL(0), NbTL(0), TL(0),
+    NbSL2(0), SL2(0), NbVL2(0), VL2(0), NbTL2(0), TL2(0),
+    NbST(0), ST(0), NbVT(0), VT(0), NbTT(0), TT(0),
+    NbST2(0), ST2(0), NbVT2(0), VT2(0), NbTT2(0), TT2(0),
+    NbSQ(0), SQ(0), NbVQ(0), VQ(0), NbTQ(0), TQ(0),
+    NbSQ2(0), SQ2(0), NbVQ2(0), VQ2(0), NbTQ2(0), TQ2(0),
+    NbSS(0), SS(0), NbVS(0), VS(0), NbTS(0), TS(0),
+    NbSS2(0), SS2(0), NbVS2(0), VS2(0), NbTS2(0), TS2(0),
+    NbSH(0), SH(0), NbVH(0), VH(0), NbTH(0), TH(0),
+    NbSH2(0), SH2(0), NbVH2(0), VH2(0), NbTH2(0), TH2(0),
+    NbSI(0), SI(0), NbVI(0), VI(0), NbTI(0), TI(0),
+    NbSI2(0), SI2(0), NbVI2(0), VI2(0), NbTI2(0), TI2(0),
+    NbSY(0), SY(0), NbVY(0), VY(0), NbTY(0), TY(0),
+    NbSY2(0), SY2(0), NbVY2(0), VY2(0), NbTY2(0), TY2(0),
+    NbT2(0), T2D(0), T2C(0), NbT3(0), T3D(0), T3C(0)
+{
+  if(allocate){
+#define LCD List_Create(1, 1000, sizeof(double))
+    Time = LCD;
+    SP = LCD; VP = LCD; TP = LCD;
+    SL = LCD; VL = LCD; TL = LCD; SL2 = LCD; VL2 = LCD; TL2 = LCD; 
+    ST = LCD; VT = LCD; TT = LCD; ST2 = LCD; VT2 = LCD; TT2 = LCD; 
+    SQ = LCD; VQ = LCD; TQ = LCD; SQ2 = LCD; VQ2 = LCD; TQ2 = LCD; 
+    SS = LCD; VS = LCD; TS = LCD; SS2 = LCD; VS2 = LCD; TS2 = LCD; 
+    SH = LCD; VH = LCD; TH = LCD; SH2 = LCD; VH2 = LCD; TH2 = LCD; 
+    SI = LCD; VI = LCD; TI = LCD; SI2 = LCD; VI2 = LCD; TI2 = LCD; 
+    SY = LCD; VY = LCD; TY = LCD; SY2 = LCD; VY2 = LCD; TY2 = LCD; 
+#undef LCD
+    T2D = List_Create(1, 100, sizeof(double));
+    T2C = List_Create(1, 100, sizeof(char));
+    T3D = List_Create(1, 100, sizeof(double));
+    T3C = List_Create(1, 100, sizeof(char));
+    Grains = new std::map<int, List_T*>;
+    DisplayListsOfGrains= new std::map<int, int>;
+  }
+}
+
+PViewDataList::~PViewDataList()
+{
+  List_Delete(Time);
+  List_Delete(SP); List_Delete(VP); List_Delete(TP);
+  List_Delete(SL); List_Delete(VL); List_Delete(TL);
+  List_Delete(ST); List_Delete(VT); List_Delete(TT);
+  List_Delete(SQ); List_Delete(VQ); List_Delete(TQ);
+  List_Delete(SS); List_Delete(VS); List_Delete(TS);
+  List_Delete(SH); List_Delete(VH); List_Delete(TH);
+  List_Delete(SI); List_Delete(VI); List_Delete(TI);
+  List_Delete(SY); List_Delete(VY); List_Delete(TY);
+  List_Delete(T2D); List_Delete(T2C);
+  List_Delete(T3D); List_Delete(T3C);
+  if(Grains) delete Grains;
+  if(DisplayListsOfGrains) delete DisplayListsOfGrains;
+}
+
+void PViewDataList::finalize()
+{
+  // finalize text strings first, to get the max value of NbTimeStep
+  // for strings-only views (strings are designed to degrade
+  // gracefully when some have fewer time steps than others). If there
+  // are any elements in the view, this value will be replaced by the
+  // minimum number of time steps common to all elements.
+  _stat(T2D, T2C, 4); _stat(T3D, T3C, 5);
+
+  // convert all "old-style" (non adaptive) 2nd order elements into
+  // linear elements *and* free all the data associated with the
+  // 2nd order elements
+  //FIXME:   _splitCurvedElements();
+
+  // compute min/max and other statistics for all element lists
+  _stat(SP, 1, NbSP, 1); _stat(VP, 3, NbVP, 1); _stat(TP, 9, NbTP, 1);
+  _stat(SL, 1, NbSL, 2); _stat(VL, 3, NbVL, 2); _stat(TL, 9, NbTL, 2);
+  _stat(ST, 1, NbST, 3); _stat(VT, 3, NbVT, 3); _stat(TT, 9, NbTT, 3);
+  _stat(SQ, 1, NbSQ, 4); _stat(VQ, 3, NbVQ, 4); _stat(TQ, 9, NbTQ, 4);
+  _stat(SS, 1, NbSS, 4); _stat(VS, 3, NbVS, 4); _stat(TS, 9, NbTS, 4);
+  _stat(SH, 1, NbSH, 8); _stat(VH, 3, NbVH, 8); _stat(TH, 9, NbTH, 8);
+  _stat(SI, 1, NbSI, 6); _stat(VI, 3, NbVI, 6); _stat(TI, 9, NbTI, 6);
+  _stat(SY, 1, NbSY, 5); _stat(VY, 3, NbVY, 5); _stat(TY, 9, NbTY, 5);
+
+  // add dummy time values if none (or too few) time values are
+  // provided (e.g. using the old parsed format)
+  if(Time && List_Nbr(Time) < NbTimeStep) {
+    for(int i = List_Nbr(Time); i < NbTimeStep; i++) {
+      double d = (double)i;
+      List_Add(Time, &d);
+    }
+  }
+}
+
+void PViewDataList::_stat(List_T *D, List_T *C, int nb)
+{
+  // compute statistics for text lists
+  for(int i = 0; i < List_Nbr(D); i += nb){
+    double beg, end;
+    List_Read(D, i + nb - 1, &beg);
+    if(i > List_Nbr(D) - 2 * nb)
+      end = (double)List_Nbr(C);
+    else
+      List_Read(D, i + nb + nb - 1, &end);
+    char *c = (char*)List_Pointer(C, (int)beg);
+    int nbtime = 0;
+    for(int j = 0; j < (int)(end - beg); j++)
+      if(c[j] == '\0') nbtime++;
+    if(nbtime > NbTimeStep) 
+      NbTimeStep = nbtime;
+  }
+  if(nb == 5){
+    for(int i = 0; i < List_Nbr(D); i += nb){
+      double x, y, z;
+      List_Read(D, i, &x);
+      List_Read(D, i + 1, &y);
+      List_Read(D, i + 2, &z);
+      BBox += SPoint3(x, y, z);
+    }
+  }
+}
+
+double vonMises(double *V)
+{
+  double tr = (V[0] + V[4] + V[8]) / 3.;
+  double v11 = V[0] - tr, v12 = V[1],      v13 = V[2];
+  double v21 = V[3],      v22 = V[4] - tr, v23 = V[5];
+  double v31 = V[6],      v32 = V[7],      v33 = V[8] - tr;
+  return sqrt(1.5 * (v11 * v11 + v12 * v12 + v13 * v13 +
+                     v21 * v21 + v22 * v22 + v23 * v23 +
+                     v31 * v31 + v32 * v32 + v33 * v33));
+}
+
+void PViewDataList::_stat(List_T *list, int nbcomp, int nbelm, int nbnod)
+{
+  // compute statistics for element lists
+  if(!nbelm) return;
+
+  TextOnly = false;
+  if(nbcomp > 1) ScalarOnly = false;
+  
+  int nb = List_Nbr(list) / nbelm;
+  for(int i = 0; i < List_Nbr(list); i += nb){
+    int N = nb - 3 * nbnod;
+    double *X = (double *)List_Pointer_Fast(list, i);
+    double *Y = (double *)List_Pointer_Fast(list, i + 1 * nbnod);
+    double *Z = (double *)List_Pointer_Fast(list, i + 2 * nbnod);
+    double *V = (double *)List_Pointer_Fast(list, i + 3 * nbnod);
+
+    // update bounding box
+    for(int j = 0; j < nbnod; j++)
+      BBox += SPoint3(X[j], Y[j], Z[j]);
+
+    // update num time steps
+    if(Min == VAL_INF || Max == -VAL_INF){
+      NbTimeStep = N / (nbcomp * nbnod);
+      TimeStepMin.clear();
+      TimeStepMax.clear();
+      for(int j = 0; j < NbTimeStep; j++){	  
+	TimeStepMin.push_back(VAL_INF);
+	TimeStepMax.push_back(-VAL_INF);
+      }
+    }
+    else if(N / (nbcomp * nbnod) < NbTimeStep){
+      // if some elts have less steps, reduce the total number!
+      NbTimeStep = N / (nbcomp * nbnod);
+    }
+    
+    // update min/max
+    for(int j = 0; j < N; j += nbcomp) {
+      double l0;
+      if(nbcomp == 1)
+	l0 = V[j];
+      else if(nbcomp == 3)
+	l0 = sqrt(DSQR(V[j]) + DSQR(V[j + 1]) + DSQR(V[j + 2]));
+      else
+	l0 = vonMises(V + j); // FIXME: can do better?
+      Min = std::min(l0, Min);
+      Max = std::max(l0, Max);
+      int ts = j / (nbcomp * nbnod);
+      if(ts < NbTimeStep){ // security
+	TimeStepMin[ts] = std::min(l0, TimeStepMin[ts]);
+	TimeStepMax[ts] = std::max(l0, TimeStepMax[ts]);
+      }
+    }
+  }
+}
+
+void PViewDataList::_getListIndices(int index[24])
+{
+  int nb[24] = {NbSP, NbVP, NbTP,  NbSL, NbVL, NbTL,  NbST, NbVT, NbTT, 
+		NbSQ, NbVQ, NbTQ,  NbSS, NbVS, NbTS,  NbSH, NbVH, NbTH, 
+		NbSI, NbVI, NbTI,  NbSY, NbVY, NbTY};
+  for(int i = 0; i < 24; i++){
+    index[i] = 0;
+    for(int j = 0; j <= i; j++)
+      index[i] += nb[j];
+  }
+}
+
+void PViewDataList::_setLast(int ele, int dim, int nbnod, int nbcomp, 
+			     List_T *list, int nblist)
+{
+  _lastDimension = dim;
+  _lastNumNodes = nbnod;
+  _lastNumComponents = nbcomp;
+  int nb = List_Nbr(list) / nblist;
+  _lastXYZ = (double*)List_Pointer_Fast(list, ele * nb);
+  _lastVal = (double*)List_Pointer_Fast(list, ele * nb + 3 * _lastNumNodes);
+}
+
+void PViewDataList::_setLast(int ele)
+{
+  int idx[24];
+  _getListIndices(idx);
+  _lastElement = ele;
+  if(ele < idx[2]){ // points
+    if(ele < idx[0]) _setLast(ele, 0, 1, 1, SP, NbSP);
+    else if(ele < idx[1]) _setLast(ele - idx[0], 0, 1, 3, VP, NbVP);
+    else _setLast(ele - idx[1], 0, 1, 9, TP, NbTP);
+  }
+  else if(ele < idx[5]){ // lines
+    if(ele < idx[3]) _setLast(ele - idx[2], 1, 2, 1, SL, NbSL);
+    else if(ele < idx[4]) _setLast(ele - idx[3], 1, 2, 3, VL, NbVL);
+    else _setLast(ele - idx[4], 1, 2, 9, TL, NbTL);
+  }
+  else if(ele < idx[8]){ // triangles
+    if(ele < idx[6]) _setLast(ele - idx[5], 2, 3, 1, ST, NbST);
+    else if(ele < idx[7]) _setLast(ele - idx[6], 2, 3, 3, VT, NbVT);
+    else _setLast(ele - idx[7], 2, 3, 9, TT, NbTT);
+  }
+  else if(ele < idx[11]){ // quadrangles
+    if(ele < idx[9]) _setLast(ele - idx[8], 2, 4, 1, SQ, NbSQ);
+    else if(ele < idx[10]) _setLast(ele - idx[9], 2, 4, 3, VQ, NbVQ);
+    else _setLast(ele - idx[10], 2, 4, 9, TQ, NbTQ);
+  }
+  else if(ele < idx[14]){ // tetrahedra
+    if(ele < idx[12]) _setLast(ele - idx[11], 3, 4, 1, SS, NbSS);
+    else if(ele < idx[13]) _setLast(ele - idx[12], 3, 4, 3, VS, NbVS);
+    else _setLast(ele - idx[13], 3, 2, 9, TS, NbTS);
+  }
+  else if(ele < idx[17]){ // hexahedra
+    if(ele < idx[15]) _setLast(ele - idx[14], 3, 8, 1, SH, NbSH);
+    else if(ele < idx[16]) _setLast(ele - idx[15], 3, 8, 3, VH, NbVH);
+    else _setLast(ele - idx[16], 3, 8, 9, TH, NbTH);
+  }
+  else if(ele < idx[20]){ // prisms
+    if(ele < idx[18]) _setLast(ele - idx[17], 3, 6, 1, SI, NbSI);
+    else if(ele < idx[19]) _setLast(ele - idx[18], 3, 6, 3, VI, NbVI);
+    else _setLast(ele - idx[19], 3, 6, 9, TI, NbTI);
+  }
+  else{ // pyramids
+    if(ele < idx[21]) _setLast(ele - idx[20], 3, 5, 1, SY, NbSY);
+    else if(ele < idx[22]) _setLast(ele - idx[21], 3, 5, 3, VY, NbVY);
+    else _setLast(ele - idx[22], 3, 5, 9, TY, NbTY);
+  }
+}
+
+int PViewDataList::getDimension(int ele)
+{
+  if(ele != _lastElement) _setLast(ele);
+  return _lastDimension;
+}
+
+int PViewDataList::getNumNodes(int ele)
+{
+  if(ele != _lastElement) _setLast(ele);
+  return _lastNumNodes;
+}
+
+void PViewDataList::getNode(int ele, int nod, double &x, double &y, double &z)
+{
+  if(ele != _lastElement) _setLast(ele);
+  x = _lastXYZ[nod];
+  y = _lastXYZ[_lastNumNodes + nod];
+  z = _lastXYZ[2 * _lastNumNodes + nod];
+}
+
+int PViewDataList::getNumComponents(int ele)
+{
+  if(ele != _lastElement) _setLast(ele);
+  return _lastNumComponents;
+}
+
+void PViewDataList::getValue(int ele, int nod, int step, int comp, double &val)
+{
+  if(ele != _lastElement) _setLast(ele);
+  val = _lastVal[step * _lastNumNodes  * _lastNumComponents + 
+		 nod * _lastNumComponents +
+		 comp];
+}
diff --git a/Post/PViewData.h b/Post/PViewData.h
new file mode 100644
index 0000000000000000000000000000000000000000..be537e4e171a17530d614e33ee9566709b1eaa5a
--- /dev/null
+++ b/Post/PViewData.h
@@ -0,0 +1,149 @@
+#ifndef _PVIEW_DATA_H_
+#define _PVIEW_DATA_H_
+
+// Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+// 
+// Please report all bugs and problems to <gmsh@geuz.org>.
+
+#include <map>
+#include <vector>
+#include <string>
+#include "GModel.h"
+#include "SBoundingBox3d.h"
+#include "List.h"
+
+#define VAL_INF 1.e200
+
+// abstract interface to post-processing view data
+class PViewData {
+ public:
+  PViewData(){}
+  virtual ~PViewData(){}
+  virtual void finalize(){}
+  virtual int getNumTimeSteps() = 0;
+  virtual int getMin(int step=-1) = 0;
+  virtual int getMax(int step=-1) = 0;
+  virtual SBoundingBox3d getBoundingBox() = 0;
+  virtual int getNumPoints(){ return 0; }
+  virtual int getNumLines(){ return 0; }
+  virtual int getNumTriangles(){ return 0; }
+  virtual int getNumQuadrangles(){ return 0; }
+  virtual int getNumTetrahedra(){ return 0; }
+  virtual int getNumHexahedra(){ return 0; }
+  virtual int getNumPrisms(){ return 0; }
+  virtual int getNumPyramids(){ return 0; }
+  virtual int getNumElements() = 0;
+  virtual int getDimension(int ele) = 0;
+  virtual int getEntity(int ele){ return 0; }
+  virtual int getNumNodes(int ele) = 0;
+  virtual void getNode(int ele, int nod, double &x, double &y, double &z) = 0;
+  virtual int getNumComponents(int ele) = 0;
+  virtual void getValue(int ele, int node, int step, int comp, double &val) = 0;
+  virtual bool read(std::string filename){}
+};
+
+// data container using old-style lists of `discontinuous' element
+class PViewDataList : public PViewData {
+ public: 
+  // FIXME: all these members will be made private once the plugins
+  // have been rewritten
+  int DataSize; // size(double) or sizeof(float)
+  int NbTimeStep, ScalarOnly, TextOnly;
+  double Min, Max;
+  std::vector<double> TimeStepMin, TimeStepMax;
+  SBoundingBox3d BBox;
+  List_T *Time;
+  int NbSP, NbVP, NbTP;
+  List_T *SP, *VP, *TP; // points
+  int NbSL, NbVL, NbTL, NbSL2, NbVL2, NbTL2;
+  List_T *SL, *VL, *TL, *SL2, *VL2, *TL2; // lines
+  int NbST, NbVT, NbTT, NbST2, NbVT2, NbTT2;
+  List_T *ST, *VT, *TT, *ST2, *VT2, *TT2; // triangles
+  int NbSQ, NbVQ, NbTQ, NbSQ2, NbVQ2, NbTQ2;
+  List_T *SQ, *VQ, *TQ, *SQ2, *VQ2, *TQ2; // quadrangles
+  int NbSS, NbVS, NbTS, NbSS2, NbVS2, NbTS2;
+  List_T *SS, *VS, *TS, *SS2, *VS2, *TS2; // tetrahedra
+  int NbSH, NbVH, NbTH, NbSH2, NbVH2, NbTH2;
+  List_T *SH, *VH, *TH, *SH2, *VH2, *TH2; // hexahedra
+  int NbSI, NbVI, NbTI, NbSI2, NbVI2, NbTI2;
+  List_T *SI, *VI, *TI, *SI2, *VI2, *TI2; // prisms
+  int NbSY, NbVY, NbTY, NbSY2, NbVY2, NbTY2;
+  List_T *SY, *VY, *TY, *SY2, *VY2, *TY2; // pyramids
+  int NbT2, NbT3;
+  List_T *T2D, *T2C, *T3D, *T3C; // 2D and 3D text strings
+  std::map<int, List_T*> *Grains; // For LMGC90, grains shapes
+  std::map<int, int> *DisplayListsOfGrains; // For LMGC90, grains shapes
+ private:
+  int _lastElement, _lastDimension, _lastNumNodes, _lastNumComponents;
+  double *_lastXYZ, *_lastVal;
+  void _stat(List_T *D, List_T *C, int nb);
+  void _stat(List_T *list, int nbcomp, int nbelm, int nbnod);
+  void _setLast(int ele);
+  void _setLast(int ele, int dim, int nbnod, int nbcomp, List_T *list, int nblist);
+  void _getListIndices(int index[24]);
+ public:
+  PViewDataList(bool allocate=true);
+  ~PViewDataList();
+  void finalize();
+  int getNumTimeSteps(){ return NbTimeStep; }
+  int getMin(int step=-1){ return Min; }
+  int getMax(int step=-1){ return Max; }
+  SBoundingBox3d getBoundingBox(){ return BBox; }
+  int getNumPoints(){ return NbSP + NbVP + NbTP; }
+  int getNumLines(){ return NbSL + NbVL + NbTL; }
+  int getNumTriangles(){ return NbST + NbVT + NbTT; }
+  int getNumQuadrangles(){ return NbSQ + NbVQ + NbTQ; }
+  int getNumTetrahedra(){ return NbSS + NbVS + NbTS; }
+  int getNumHexahedra(){ return NbSH + NbVH + NbTH; }
+  int getNumPrisms(){ return NbSI + NbVI + NbTI; }
+  int getNumPyramids(){ return NbSY + NbVY + NbTY; }
+  int getNumElements()
+  {
+    return getNumPoints() + getNumLines() + getNumTriangles() + 
+      getNumQuadrangles() + getNumTetrahedra() + getNumHexahedra() + 
+      getNumPrisms() + getNumPyramids();
+  }
+  int getDimension(int ele);
+  int getNumNodes(int ele);
+  void getNode(int ele, int nod, double &x, double &y, double &z);
+  int getNumComponents(int ele);
+  void getValue(int ele, int node, int step, int comp, double &val);
+  bool read(std::string filename);
+};
+
+// data container using elements from a GModel
+class PViewDataGModel : public PViewData {
+ private:
+  GModel *_model;
+  PViewDataList *_cloneToList(); // create old-style data from this
+ public:
+  PViewDataGModel(){}
+  ~PViewDataGModel(){}
+  int getNumTimeSteps(){ return 1; }
+  int getMin(int step=-1){ return 0.; }
+  int getMax(int step=-1){ return 1.; }
+  SBoundingBox3d getBoundingBox(){ return SBoundingBox3d(); }
+  int getNumElements(){ return _model->numElements(); }
+  int getDimension(int ele){ return 0; }
+  int getNumNodes(int ele){ return 0; }
+  void getNode(int ele, int nod, double &x, double &y, double &z){}
+  int getNumComponents(int ele){ return 1; }
+  void getValue(int ele, int node, int step, int comp, double &val){}
+};
+
+#endif
diff --git a/Post/PViewOptions.cpp b/Post/PViewOptions.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..57da58f2db4d07e9158c0b116f0a04524c71e8d8
--- /dev/null
+++ b/Post/PViewOptions.cpp
@@ -0,0 +1,76 @@
+// $Id: PViewOptions.cpp,v 1.1 2007-08-21 19:05:43 geuzaine Exp $
+//
+// Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+// 
+// Please report all bugs and problems to <gmsh@geuz.org>.
+//
+// Contributor(s):
+// 
+
+#include "PViewOptions.h"
+
+PViewOptions::PViewOptions()
+{
+  // FIXME: remove this once Options.cpp uses PViewOptions!
+  Type = Plot3D;
+  AutoPosition = 1;
+  strcpy(Format, "%g");
+  Axes = 0;
+  for(int i = 0; i < 3; i++){
+    Offset[i] = Raise[i] = 0.;
+    for(int j = 0; j < 3; j++){
+      Transform[i][j] = 0.;
+    }
+  }
+  DisplacementFactor = 0.;
+  Explode = 1.;
+  ArrowSize = 50;
+  ArrowRelHeadRadius = 0.5;
+  ArrowRelStemRadius = 0.2;
+  ArrowRelStemLength = 0.7;
+  Normals = Tangents = 0.;
+  Visible = 1;
+  IntervalsType = Continuous;
+  NbIso = 15;
+  ArrowSizeProportional = 0;
+  Light = LightTwoSide = 1;
+  LightLines = SmoothNormals = 0;
+  AngleSmoothNormals = 90;
+  SaturateValues = 0;
+  FakeTransparency = 0;
+  ShowElement = 0;
+  ShowTime = ShowScale = 1;
+  ScaleType = Default;
+  RangeType = Linear;
+  VectorType = Arrow3D;
+  TensorType = VonMises;
+  GlyphLocation = COG;
+  TimeStep = 0;
+  DrawStrings = DrawPoints = DrawLines = DrawTriangles = DrawQuadrangles =
+    DrawTetrahedra = DrawHexahedra = DrawPrisms = DrawPyramids =
+    DrawScalars = DrawVectors = DrawTensors = 1;
+  Boundary = 0;
+  PointType = LineType = 0;
+  PointSize = LineWidth = 2;
+  UseStipple = 0;
+  ExternalViewIndex = ViewIndexForGenRaise = -1;
+  UseGenRaise = 0;
+  GenRaiseFactor = 0.;
+
+  GmshColorTable CT;
+}
diff --git a/Post/PViewOptions.h b/Post/PViewOptions.h
new file mode 100644
index 0000000000000000000000000000000000000000..06c222898d2397e43ba9ee5bc06e1f952b4a5eb8
--- /dev/null
+++ b/Post/PViewOptions.h
@@ -0,0 +1,118 @@
+#ifndef _PVIEW_OPTIONS_H_
+#define _PVIEW_OPTIONS_H_
+
+// Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+// 
+// Please report all bugs and problems to <gmsh@geuz.org>.
+
+#include <string>
+#include "ColorTable.h"
+
+class PViewOptions {
+ public:
+  enum PlotType {
+    Plot3D,
+    Plot2DSpace,
+    Plot2DTime
+  };
+  enum IntervalsType {
+    Iso,
+    Continuous,
+    Discrete,
+    Numeric
+  };
+  enum VectorType {
+    Segment,
+    Arrow,
+    Pyramid,
+    Arrow3D,
+    Displacement
+  };
+  enum TensorType {
+    VonMises,
+    LMGC90,
+    LMGC90_TYPE,
+    LMGC90_COORD,
+    LMGC90_PRES,
+    LMGC90_SN,
+    LMGC90_DEPX,
+    LMGC90_DEPY,
+    LMGC90_DEPZ,
+    LMGC90_DEPAV,
+    LMGC90_DEPNORM
+  };
+  enum GlyphLocation {
+    COG,
+    Vertex
+  };
+  enum RangeType {
+    Default,
+    Custom,
+    PerStep
+  };
+  enum ScaleType {
+    Linear,
+    Logarithmic,
+    DoubleLogarithmic
+  };
+
+  int Type;
+  int Position[2], Size[2], AutoPosition;
+  char Format[256];
+  int Axes, AxesAutoPosition, AxesTics[3];
+  char AxesFormat[3][256], AxesLabel[3][256];
+  double AxesPosition[6];
+  double CustomMin, CustomMax;
+  double Offset[3], Raise[3], Transform[3][3], DisplacementFactor, Explode;
+  double ArrowSize, ArrowRelHeadRadius, ArrowRelStemRadius, ArrowRelStemLength;
+  double Normals, Tangents;
+  int Visible, IntervalsType, NbIso, ArrowSizeProportional;
+  int Light, LightTwoSide, LightLines, SmoothNormals;
+  double AngleSmoothNormals;
+  int SaturateValues, FakeTransparency;
+  int ShowElement, ShowTime, ShowScale;
+  int ScaleType, RangeType;
+  int VectorType, TensorType, GlyphLocation;
+  int TimeStep;
+  int DrawStrings;
+  int DrawPoints, DrawLines, DrawTriangles, DrawQuadrangles;
+  int DrawTetrahedra, DrawHexahedra, DrawPrisms, DrawPyramids;
+  int DrawScalars, DrawVectors, DrawTensors;
+  int Boundary, PointType, LineType;
+  double PointSize, LineWidth;
+  GmshColorTable CT;
+  int UseStipple, Stipple[10][2];
+  char StippleString[10][32];
+  int ExternalViewIndex, ViewIndexForGenRaise;
+  int UseGenRaise;
+  double GenRaiseFactor;
+  char GenRaiseX[256], GenRaiseY[256], GenRaiseZ[256];
+  void *GenRaise_f[3];
+  struct{
+    unsigned int point, line, triangle, quadrangle;
+    unsigned int tetrahedron, hexahedron, prism, pyramid;
+    unsigned int tangents, normals;
+    unsigned int text2d, text3d, axes;
+  } color;
+ public:
+  // static reference container that contains default values
+  static PViewOptions reference;
+  PViewOptions();
+};
+
+#endif