From b304b95e3f3fcee7d4fcefa1949377038b9fd6d3 Mon Sep 17 00:00:00 2001
From: Christophe Geuzaine <cgeuzaine@ulg.ac.be>
Date: Mon, 3 Nov 2008 21:44:29 +0000
Subject: [PATCH] quick hack to draw all models at once

---
 Common/Context.h        |  1 +
 Common/DefaultOptions.h |  2 +
 Common/Options.cpp      |  7 +++
 Common/Options.h        |  1 +
 Common/Visibility.h     |  4 +-
 Fltk/GUI.cpp            |  2 +-
 Fltk/GUI_Extras.cpp     | 28 +++++++++---
 Fltk/Makefile           |  3 +-
 Geo/GEntity.cpp         |  2 +-
 Geo/GFace.cpp           |  2 +-
 Geo/GModel.cpp          |  5 +++
 Geo/GModel.h            |  7 ++-
 Geo/GModelIO_Mesh.cpp   | 40 ++++++++++++-----
 Geo/MElement.h          |  3 +-
 Geo/MVertex.h           |  2 +-
 Graphics/Axes.cpp       | 64 +++++++++++++++++++++++++++
 Graphics/Draw.cpp       |  1 +
 Graphics/Draw.h         |  1 +
 Graphics/Geom.cpp       | 94 ++++++++++++----------------------------
 Graphics/Makefile       | 11 +++++
 Graphics/Mesh.cpp       | 95 +++++++++++++++++++++++------------------
 21 files changed, 240 insertions(+), 135 deletions(-)
 create mode 100644 Graphics/Axes.cpp

diff --git a/Common/Context.h b/Common/Context.h
index a399fb76fd..e0f76886ca 100644
--- a/Common/Context.h
+++ b/Common/Context.h
@@ -128,6 +128,7 @@ class Context_T {
   int expert_mode; // to disable some warnings for beginners
   int printing; // dynamic: equal to 1 while gmsh is printing
   int hide_unselected; // hide all unselected entities
+  int draw_all_models;
 
   // geometry options 
   struct{
diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h
index 6e8620042d..0fe1425b03 100644
--- a/Common/DefaultOptions.h
+++ b/Common/DefaultOptions.h
@@ -543,6 +543,8 @@ StringXNumber GeneralOptions_Number[] = {
 
   { F|O, "DoubleBuffer" , opt_general_double_buffer , 1. ,
     "Use a double buffered graphic window (on Unix, should be set to 0 when working on a remote host without GLX)" },
+  { F|O, "DrawAllModels" , opt_general_draw_all_models, 0. , 
+    "Draw all loaded models (instead of drawing only the current one)" },
   { F|O, "DrawBoundingBoxes" , opt_general_draw_bounding_box, 0. ,
     "Draw bounding boxes" },
 
diff --git a/Common/Options.cpp b/Common/Options.cpp
index 5fedc14b73..c1f84ca336 100644
--- a/Common/Options.cpp
+++ b/Common/Options.cpp
@@ -3072,6 +3072,13 @@ double opt_general_draw_bounding_box(OPT_ARGS_NUM)
   return CTX.draw_bbox;
 }
 
+double opt_general_draw_all_models(OPT_ARGS_NUM)
+{
+  if(action & GMSH_SET)
+    CTX.draw_all_models = (int)val;
+  return CTX.draw_all_models;
+}
+
 double opt_general_xmin(OPT_ARGS_NUM)
 {
   return CTX.min[0];
diff --git a/Common/Options.h b/Common/Options.h
index 2beecfcd63..0dc370d866 100644
--- a/Common/Options.h
+++ b/Common/Options.h
@@ -288,6 +288,7 @@ double opt_general_orthographic(OPT_ARGS_NUM);
 double opt_general_mouse_selection(OPT_ARGS_NUM);
 double opt_general_mouse_hover_meshes(OPT_ARGS_NUM);
 double opt_general_draw_bounding_box(OPT_ARGS_NUM);
+double opt_general_draw_all_models(OPT_ARGS_NUM);
 double opt_general_fast_redraw(OPT_ARGS_NUM);
 double opt_general_xmin(OPT_ARGS_NUM);
 double opt_general_xmax(OPT_ARGS_NUM);
diff --git a/Common/Visibility.h b/Common/Visibility.h
index 10a296d76c..8c37603794 100644
--- a/Common/Visibility.h
+++ b/Common/Visibility.h
@@ -56,7 +56,7 @@ class VisPhysical : public Vis {
   std::vector<GEntity*> _list;
  public:
   VisPhysical(int tag, int dim, std::vector<GEntity*> list) 
-    : _tag(tag), _dim(dim), _visible(true), _list(list)  {}
+    : _tag(tag), _dim(dim), _visible(1), _list(list)  {}
   ~VisPhysical(){}
   int getTag() const { return _tag; }
   int getDim() const { return _dim; }
@@ -76,7 +76,7 @@ class VisPartition : public Vis {
   int _tag;
   char _visible;
  public:
-  VisPartition(int tag) : _tag(tag), _visible(true) {}
+  VisPartition(int tag) : _tag(tag), _visible(1) {}
   ~VisPartition(){}
   int getTag() const { return _tag; }
   int getDim() const { return -1; }
diff --git a/Fltk/GUI.cpp b/Fltk/GUI.cpp
index 864cef904c..e2d117b721 100644
--- a/Fltk/GUI.cpp
+++ b/Fltk/GUI.cpp
@@ -1462,7 +1462,7 @@ void GUI::create_graphic_window()
   g_status_butt[5] = new Fl_Button(x, glheight + 2, sw, sht, "@-1gmsh_models");
   x += sw;
   g_status_butt[5]->callback(status_xyz1p_cb, (void *)"model");
-  g_status_butt[5]->tooltip("Switch current model");
+  g_status_butt[5]->tooltip("Change current model");
 
   g_status_butt[0] = new Fl_Button(x, glheight + 2, sw, sht, "X");
   x += sw;
diff --git a/Fltk/GUI_Extras.cpp b/Fltk/GUI_Extras.cpp
index 2ad2245e0b..3e87cce7c9 100644
--- a/Fltk/GUI_Extras.cpp
+++ b/Fltk/GUI_Extras.cpp
@@ -244,12 +244,20 @@ int perspective_editor()
 
 // Model chooser
 
-static void model_switch(Fl_Widget* w, void* data)
+static void model_switch(Fl_Widget* w, void *data)
 {
   Fl_Select_Browser *b = (Fl_Select_Browser *)w;
-  GModel::current(b->value() - 1);
+  if(b->value()) GModel::current(b->value() - 1);
   if(w->window()) w->window()->hide();
   CTX.mesh.changed = ENT_ALL;
+  // FIXME: need to call WID->reset_visibility();
+  Draw();
+}
+
+static void model_draw_all(Fl_Widget* w, void *data)
+{
+  Fl_Check_Button *b = (Fl_Check_Button*)w;
+  opt_general_draw_all_models(0, GMSH_SET | GMSH_GUI, (int)b->value());
   Draw();
 }
 
@@ -257,18 +265,26 @@ int model_chooser()
 {
   struct _menu{
     Fl_Menu_Window *window;
-    Fl_Select_Browser *browser;
+    Fl_Hold_Browser *browser;
+    Fl_Check_Button *butt;
   };
   static _menu *menu = NULL;
 
+  const int BH = 2 * GetFontSize() + 1;
+  const int WW = 200;
+
   if(!menu){
     menu = new _menu;
-    menu->window = new Fl_Menu_Window(200, 100);
+    menu->window = new Fl_Menu_Window(WW, 6 * BH);
     if(CTX.non_modal_windows) menu->window->set_non_modal();
     menu->window->border(0);
-    menu->browser = new Fl_Select_Browser(0, 0, 200, 100);
+    Fl_Box *l = new Fl_Box(0, 0, WW, BH, "Choose current model:");
+    l->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE | FL_ALIGN_CLIP);
+    menu->browser = new Fl_Hold_Browser(0, BH, WW, 4 * BH);
     menu->browser->callback(model_switch);
     menu->browser->when(FL_WHEN_RELEASE_ALWAYS);
+    menu->butt = new Fl_Check_Button(0, 5 * BH, WW, BH, "Draw all models");
+    menu->butt->callback(model_draw_all);
     menu->window->end();
   }
 
@@ -278,7 +294,9 @@ int model_chooser()
     char tmp[256];
     sprintf(tmp, "Model %d <<%s>>", i, GModel::list[i]->getName().c_str());
     menu->browser->add(tmp);
+    if(GModel::list[i] == GModel::current()) menu->browser->value(i + 1);
   }
+  menu->butt->value(CTX.draw_all_models);
 
   if(menu->window->non_modal() && !menu->window->shown())
     menu->window->show(); // fix ordering
diff --git a/Fltk/Makefile b/Fltk/Makefile
index db8ac0b785..b80141eee7 100644
--- a/Fltk/Makefile
+++ b/Fltk/Makefile
@@ -88,7 +88,8 @@ GUI.o: GUI.cpp ../Common/GmshUI.h ../Common/GmshDefines.h \
   ../Geo/GFace.h ../Geo/GEntity.h ../Geo/GPoint.h ../Geo/GEdgeLoop.h \
   ../Geo/GEdge.h ../Geo/SPoint2.h ../Geo/SVector3.h ../Geo/Pair.h \
   ../Geo/GRegion.h ../Geo/GEntity.h ../Geo/SPoint3.h \
-  ../Geo/SBoundingBox3d.h ../Geo/GeoStringInterface.h
+  ../Geo/SBoundingBox3d.h ../Geo/GeoStringInterface.h \
+  ../Common/GmshSocket.h
 GUI_Extras.o: GUI_Extras.cpp ../Common/GmshUI.h ../Common/GmshDefines.h \
   ../Common/CreateFile.h ../Common/Options.h ../Post/ColorTable.h \
   ../Common/Context.h ../Geo/CGNSOptions.h ../Mesh/PartitionOptions.h \
diff --git a/Geo/GEntity.cpp b/Geo/GEntity.cpp
index 37996510af..8e8c4e6b78 100644
--- a/Geo/GEntity.cpp
+++ b/Geo/GEntity.cpp
@@ -18,7 +18,7 @@
 extern Context_T CTX;
 
 GEntity::GEntity(GModel *m, int t)
-  : _model(m), _tag(t), _visible(true), _selection(0),
+  : _model(m), _tag(t), _visible(1), _selection(0),
     _allElementsVisible(1), va_lines(0), va_triangles(0)
 {
   _color = CTX.PACK_COLOR(0, 0, 255, 0);
diff --git a/Geo/GFace.cpp b/Geo/GFace.cpp
index aa3d2e6dd9..a36735c2ae 100644
--- a/Geo/GFace.cpp
+++ b/Geo/GFace.cpp
@@ -100,7 +100,7 @@ MElement *GFace::getMeshElement(unsigned int index)
 void GFace::resetMeshAttributes()
 {
   meshAttributes.recombine = 0;
-  meshAttributes.recombineAngle = 0.;
+  meshAttributes.recombineAngle = 45.;
   meshAttributes.Method = MESH_UNSTRUCTURED;
   meshAttributes.transfiniteArrangement = 0;
   meshAttributes.transfiniteSmoothing = -1;
diff --git a/Geo/GModel.cpp b/Geo/GModel.cpp
index 42bce53adc..f15bec8545 100644
--- a/Geo/GModel.cpp
+++ b/Geo/GModel.cpp
@@ -123,6 +123,11 @@ void GModel::destroyMeshCaches()
 #endif
 }
 
+bool GModel::empty() const
+{
+  return vertices.empty() && edges.empty() && faces.empty() && regions.empty();
+}
+
 GRegion *GModel::getRegionByTag(int n) const
 {
   GEntity tmp((GModel*)this, n);
diff --git a/Geo/GModel.h b/Geo/GModel.h
index 97ea56612a..dbee4f744b 100644
--- a/Geo/GModel.h
+++ b/Geo/GModel.h
@@ -117,11 +117,14 @@ class GModel
   void setName(std::string name){ modelName = name; }
   std::string getName(){ return modelName; }
 
-  // get the number of regions in this model.
+  // get the number of entities in this model
   int getNumRegions() const { return regions.size(); }
   int getNumFaces() const { return faces.size(); }
   int getNumEdges() const { return edges.size(); }
-  int getNumVertices() const  { return vertices.size(); }
+  int getNumVertices() const { return vertices.size(); }
+
+  // quickly check if the model is empty (contains no entities)
+  bool empty() const;
 
   typedef std::set<GRegion*, GEntityLessThan>::iterator riter;
   typedef std::set<GFace*, GEntityLessThan>::iterator fiter;
diff --git a/Geo/GModelIO_Mesh.cpp b/Geo/GModelIO_Mesh.cpp
index 5d98552906..5e414b7a5f 100644
--- a/Geo/GModelIO_Mesh.cpp
+++ b/Geo/GModelIO_Mesh.cpp
@@ -873,7 +873,7 @@ static int readElementsVRML(FILE *fp, std::vector<MVertex*> &vertexVector, int r
     return 0;
   }
   Msg::Info("%d elements", elements[0][region].size() + 
-      elements[1][region].size() + elements[2][region].size());
+            elements[1][region].size() + elements[2][region].size());
   return 1;
 }
 
@@ -2170,13 +2170,31 @@ int GModel::writeDIFF(const std::string &name, bool binary, bool saveAll,
   
   if(noPhysicalGroups()) saveAll = true;
 
+  // get all the entities in the model
+  std::vector<GEntity*> entities;
+  getEntities(entities);
+
   // get the number of vertices and index the vertices in a continuous
   // sequence
   int numVertices = indexMeshVertices(saveAll);
+  std::list<int> vertices_tag[numVertices];
 
-  // get all the entities in the model
-  std::vector<GEntity*> entities;
-  getEntities(entities);
+  for(unsigned int i = 0; i < entities.size(); i++){
+    if(entities[i]->physicals.size() || saveAll){
+      std::list<GFace*> lf = entities[i]->faces();
+      std::list<GFace*>::iterator it = lf.begin();
+      for(unsigned int k=0; k < lf.size(); k++){
+        for( unsigned int l=0; l<(*it)->mesh_vertices.size();l++)
+           vertices_tag[(*it)->mesh_vertices[l]->getIndex()-1].push_back((*it)->tag());
+        it++;
+      }
+    }
+  }
+  for(unsigned int i=0;i<numVertices;i++)
+    {
+     vertices_tag[i].unique();
+     vertices_tag[i].sort(); // optional
+    }
 
   // loop over all elements we need to save
   int numElements = 0, maxNumNodesPerElement = 0;
@@ -2211,7 +2229,6 @@ int GModel::writeDIFF(const std::string &name, bool binary, bool saveAll,
     }
   } 
 
-  // write mesh vertices
   fprintf(fp, "\n\n\n");
   fprintf(fp,"  Nodal coordinates and nodal boundary indicators,\n");
   fprintf(fp,"  the columns contain:\n");
@@ -2220,20 +2237,21 @@ int GModel::writeDIFF(const std::string &name, bool binary, bool saveAll,
   fprintf(fp,"   - no of boundary indicators that are set (ON)\n");
   fprintf(fp,"   - the boundary indicators that are set (ON) if any.\n");
   fprintf(fp,"#\n");
+
+  // write mesh vertices
   for(unsigned int i = 0; i < entities.size(); i++)
     for(unsigned int j = 0; j < entities[i]->mesh_vertices.size(); j++){
       entities[i]->mesh_vertices[j]->writeDIFF(fp, binary, scalingFactor);
-      fprintf(fp, " [%d] ", entities[i]->faces().size());
-      std::list<GFace*> lf = entities[i]->faces();
-      std::list<GFace*>::iterator it = lf.begin();
-      for(unsigned int k = 0; k < lf.size(); k++){
-        fprintf(fp," %d ", (*it)->tag());
+      fprintf(fp, " [%d] ", vertices_tag[entities[i]->mesh_vertices[j]->getIndex()-1].size());
+      std::list<int>::iterator it = vertices_tag[entities[i]->mesh_vertices[j]->getIndex()-1].begin();
+      for(unsigned k=0; k < vertices_tag[entities[i]->mesh_vertices[j]->getIndex()-1].size(); k++){
+        fprintf(fp," %d ", (*it));
         it++;
       }
       fprintf(fp,"\n");
     }
-  fprintf(fp, "\n");
   
+  fprintf(fp, "\n");
   fprintf(fp, "\n");
   fprintf(fp,     "  Element types and connectivity\n");
   fprintf(fp,     "  the columns contain:\n");
diff --git a/Geo/MElement.h b/Geo/MElement.h
index b5b6cde155..fe3c89df40 100644
--- a/Geo/MElement.h
+++ b/Geo/MElement.h
@@ -43,8 +43,7 @@ class MElement
   void _getFaceRep(MVertex *v0, MVertex *v1, MVertex *v2, 
                    double *x, double *y, double *z, SVector3 *n);
  public :
-  MElement(int num=0, int part=0) 
-    : _visible(true) 
+  MElement(int num=0, int part=0) : _visible(1) 
   {
     if(num){
       _num = num;
diff --git a/Geo/MVertex.h b/Geo/MVertex.h
index 9c9f5be8ac..a0e15c7fd0 100644
--- a/Geo/MVertex.h
+++ b/Geo/MVertex.h
@@ -42,7 +42,7 @@ class MVertex{
 
  public :
   MVertex(double x, double y, double z, GEntity *ge=0, int num=0) 
-    : _visible(true), _order(1), _x(x), _y(y), _z(z), _ge(ge)
+    : _visible(1), _order(1), _x(x), _y(y), _z(z), _ge(ge)
   {
     if(num){
       _num = num;
diff --git a/Graphics/Axes.cpp b/Graphics/Axes.cpp
new file mode 100644
index 0000000000..8add366b00
--- /dev/null
+++ b/Graphics/Axes.cpp
@@ -0,0 +1,64 @@
+// Gmsh - Copyright (C) 1997-2008 C. Geuzaine, J.-F. Remacle
+//
+// See the LICENSE.txt file for license information. Please report all
+// bugs and problems to <gmsh@geuz.org>.
+
+#include "GmshUI.h"
+#include "Draw.h"
+#include "Context.h"
+#include "gl2ps.h"
+#include "GModel.h"
+
+extern Context_T CTX;
+
+void Draw_Axes()
+{
+  bool geometryExists = false;
+  for(unsigned int i = 0; i < GModel::list.size(); i++){
+    if(!GModel::list[i]->empty()){
+      geometryExists = true;
+      break;
+    }
+  }
+    
+  if(geometryExists && (CTX.draw_bbox || !CTX.mesh.draw)) {
+    glColor4ubv((GLubyte *) & CTX.color.fg);
+    glLineWidth(CTX.line_width);
+    gl2psLineWidth(CTX.line_width * CTX.print.eps_line_width_factor);
+    Draw_Box(CTX.min[0], CTX.min[1], CTX.min[2], 
+             CTX.max[0], CTX.max[1], CTX.max[2]);
+    glColor3d(1.,0.,0.);
+    for(int j = 0; j < 6; j++)
+      if(CTX.clip[j] & 1 || CTX.clip[j] & 2)
+        Draw_PlaneInBoundingBox(CTX.min[0], CTX.min[1], CTX.min[2],
+                                CTX.max[0], CTX.max[1], CTX.max[2],
+                                CTX.clip_plane[j][0], CTX.clip_plane[j][1], 
+                                CTX.clip_plane[j][2], CTX.clip_plane[j][3]);
+  }
+
+  if(CTX.axes){
+    glColor4ubv((GLubyte *) & CTX.color.axes);
+    glLineWidth(CTX.line_width);
+    gl2psLineWidth(CTX.line_width * CTX.print.eps_line_width_factor);
+    if(!CTX.axes_auto_position){
+      Draw_Axes(CTX.axes, CTX.axes_tics, CTX.axes_format, CTX.axes_label, 
+                CTX.axes_position, CTX.axes_mikado);
+    }
+    else if(geometryExists){
+      double bb[6] = {CTX.min[0], CTX.max[0], CTX.min[1], 
+                      CTX.max[1], CTX.min[2], CTX.max[2]};
+      Draw_Axes(CTX.axes, CTX.axes_tics, CTX.axes_format, CTX.axes_label, 
+                bb, CTX.axes_mikado);
+    }
+  }
+
+  if(CTX.draw_rotation_center){
+    glColor4ubv((GLubyte *) & CTX.color.fg);
+    if(CTX.rotation_center_cg)
+      Draw_Sphere(CTX.point_size, CTX.cg[0], CTX.cg[1], CTX.cg[2], CTX.geom.light);
+    else
+      Draw_Sphere(CTX.point_size, CTX.rotation_center[0], CTX.rotation_center[1], 
+                  CTX.rotation_center[2], CTX.geom.light);
+  }
+
+}
diff --git a/Graphics/Draw.cpp b/Graphics/Draw.cpp
index 5cf90dd023..51b7e8337e 100644
--- a/Graphics/Draw.cpp
+++ b/Graphics/Draw.cpp
@@ -55,6 +55,7 @@ void Draw3d()
   InitProjection();
   InitRenderModel();
   InitPosition();
+  Draw_Axes();
   Draw_Geom();
   Draw_Mesh();
   Draw_Post();
diff --git a/Graphics/Draw.h b/Graphics/Draw.h
index bbc3c4de01..012f67e5bc 100644
--- a/Graphics/Draw.h
+++ b/Graphics/Draw.h
@@ -35,6 +35,7 @@ void Draw_String(std::string);
 void Draw_String(std::string, double style);
 void Draw_String_Center(std::string);
 void Draw_String_Right(std::string);
+void Draw_Axes();
 void Draw_Geom();
 void Draw_Mesh();
 void Draw_Post();
diff --git a/Graphics/Geom.cpp b/Graphics/Geom.cpp
index 4519ae1279..e321c6b77d 100644
--- a/Graphics/Geom.cpp
+++ b/Graphics/Geom.cpp
@@ -70,7 +70,8 @@ class drawGVertex {
     if(!v->getVisibility()) return;
     if(v->geomType() == GEntity::BoundaryLayerPoint) return;
 
-    if(CTX.render_mode == GMSH_SELECT) {
+    bool select = (CTX.render_mode == GMSH_SELECT && v->model() == GModel::current());
+    if(select) {
       glPushName(0);
       glPushName(v->tag());
     }
@@ -122,7 +123,7 @@ class drawGVertex {
       Draw_String(Num);
     }
     
-    if(CTX.render_mode == GMSH_SELECT) {
+    if(select) {
       glPopName();
       glPopName();
     }
@@ -140,7 +141,8 @@ class drawGEdge {
     if(e->geomType() == GEntity::DiscreteCurve) return;
     if(e->geomType() == GEntity::BoundaryLayerCurve) return;
     
-    if(CTX.render_mode == GMSH_SELECT) {
+    bool select = (CTX.render_mode == GMSH_SELECT && e->model() == GModel::current());
+    if(select) {
       glPushName(1);
       glPushName(e->tag());
     }
@@ -230,7 +232,7 @@ class drawGEdge {
 
     if(CTX.draw_bbox) drawBBox(e);
     
-    if(CTX.render_mode == GMSH_SELECT) {
+    if(select) {
       glPopName();
       glPopName();
     }
@@ -422,8 +424,9 @@ class drawGFace {
     if(!f->getVisibility()) return;
     if(f->geomType() == GEntity::DiscreteSurface) return;
     if(f->geomType() == GEntity::BoundaryLayerSurface) return;
-    
-    if(CTX.render_mode == GMSH_SELECT) {
+
+    bool select = (CTX.render_mode == GMSH_SELECT && f->model() == GModel::current());
+    if(select) {
       glPushName(2);
       glPushName(f->tag());
     }
@@ -447,7 +450,7 @@ class drawGFace {
     
     if(CTX.draw_bbox) drawBBox(f);
     
-    if(CTX.render_mode == GMSH_SELECT) {
+    if(select) {
       glPopName();
       glPopName();
     }
@@ -464,7 +467,8 @@ class drawGRegion {
     if(!r->getVisibility()) return;
     if(r->geomType() == GEntity::DiscreteVolume) return;
     
-    if(CTX.render_mode == GMSH_SELECT) {
+    bool select = (CTX.render_mode == GMSH_SELECT && r->model() == GModel::current());
+    if(select) {
       glPushName(3);
       glPushName(r->tag());
     }
@@ -495,7 +499,7 @@ class drawGRegion {
 
     if(CTX.draw_bbox) drawBBox(r);
 
-    if(CTX.render_mode == GMSH_SELECT) {
+    if(select) {
       glPopName();
       glPopName();
     }
@@ -517,68 +521,24 @@ void Draw_Geom()
     else
       glDisable((GLenum)(GL_CLIP_PLANE0 + i));
 
-  GModel *m = GModel::current();
-
   visContext ctx;
   //double mat[3][3] = {{2, 0, 0}, {0, 1, 0}, {0, 0, 1}};
   //visContextScaled ctx(mat);
 
-  if(CTX.geom.points || CTX.geom.points_num)
-    std::for_each(m->firstVertex(), m->lastVertex(), drawGVertex(&ctx));
-
-  if(CTX.geom.lines || CTX.geom.lines_num || CTX.geom.tangents)
-    std::for_each(m->firstEdge(), m->lastEdge(), drawGEdge(&ctx));
-
-  if(CTX.geom.surfaces || CTX.geom.surfaces_num || CTX.geom.normals)
-    std::for_each(m->firstFace(), m->lastFace(), drawGFace(&ctx));
-
-  if(CTX.geom.volumes || CTX.geom.volumes_num)
-    std::for_each(m->firstRegion(), m->lastRegion(), drawGRegion(&ctx));
-
-  for(int i = 0; i < 6; i++)
-    glDisable((GLenum)(GL_CLIP_PLANE0 + i));
-
-  bool geometryExists = m->getNumVertices() || m->getNumEdges() || 
-    m->getNumFaces() || m->getNumRegions();
-
-  if(geometryExists && (CTX.draw_bbox || !CTX.mesh.draw)) {
-    glColor4ubv((GLubyte *) & CTX.color.fg);
-    glLineWidth(CTX.line_width);
-    gl2psLineWidth(CTX.line_width * CTX.print.eps_line_width_factor);
-    Draw_Box(CTX.min[0], CTX.min[1], CTX.min[2], 
-             CTX.max[0], CTX.max[1], CTX.max[2]);
-    glColor3d(1.,0.,0.);
-    for(int i = 0; i < 6; i++)
-      if(CTX.clip[i] & 1 || CTX.clip[i] & 2)
-        Draw_PlaneInBoundingBox(CTX.min[0], CTX.min[1], CTX.min[2],
-                                CTX.max[0], CTX.max[1], CTX.max[2],
-                                CTX.clip_plane[i][0], CTX.clip_plane[i][1], 
-                                CTX.clip_plane[i][2], CTX.clip_plane[i][3]);
-  }
-  
-  if(CTX.axes){
-    glColor4ubv((GLubyte *) & CTX.color.axes);
-    glLineWidth(CTX.line_width);
-    gl2psLineWidth(CTX.line_width * CTX.print.eps_line_width_factor);
-    if(!CTX.axes_auto_position){
-      Draw_Axes(CTX.axes, CTX.axes_tics, CTX.axes_format, CTX.axes_label, 
-                CTX.axes_position, CTX.axes_mikado);
-    }
-    else if(geometryExists){
-      double bb[6] = {CTX.min[0], CTX.max[0], CTX.min[1], 
-                      CTX.max[1], CTX.min[2], CTX.max[2]};
-      Draw_Axes(CTX.axes, CTX.axes_tics, CTX.axes_format, CTX.axes_label, 
-                bb, CTX.axes_mikado);
+  for(unsigned int i = 0; i < GModel::list.size(); i++){
+    GModel *m = GModel::list[i];
+    if(CTX.draw_all_models || m == GModel::current()){
+      if(CTX.geom.points || CTX.geom.points_num)
+        std::for_each(m->firstVertex(), m->lastVertex(), drawGVertex(&ctx));
+      if(CTX.geom.lines || CTX.geom.lines_num || CTX.geom.tangents)
+        std::for_each(m->firstEdge(), m->lastEdge(), drawGEdge(&ctx));
+      if(CTX.geom.surfaces || CTX.geom.surfaces_num || CTX.geom.normals)
+        std::for_each(m->firstFace(), m->lastFace(), drawGFace(&ctx));
+      if(CTX.geom.volumes || CTX.geom.volumes_num)
+        std::for_each(m->firstRegion(), m->lastRegion(), drawGRegion(&ctx));
     }
   }
-
-  if(CTX.draw_rotation_center){
-    glColor4ubv((GLubyte *) & CTX.color.fg);
-    if(CTX.rotation_center_cg)
-      Draw_Sphere(CTX.point_size, CTX.cg[0], CTX.cg[1], CTX.cg[2], CTX.geom.light);
-    else
-      Draw_Sphere(CTX.point_size, CTX.rotation_center[0], CTX.rotation_center[1], 
-                  CTX.rotation_center[2], CTX.geom.light);
-  }
-
+  
+  for(int i = 0; i < 6; i++)
+    glDisable((GLenum)(GL_CLIP_PLANE0 + i));
 }
diff --git a/Graphics/Makefile b/Graphics/Makefile
index 0664926a26..fedfd4320a 100644
--- a/Graphics/Makefile
+++ b/Graphics/Makefile
@@ -22,6 +22,7 @@ SRC = Draw.cpp \
       Iso.cpp \
       Entity.cpp \
       ReadImg.cpp \
+      Axes.cpp \
       Scale.cpp \
       Graph2D.cpp \
       gl2ps.cpp\
@@ -126,6 +127,16 @@ ReadImg.o: ReadImg.cpp ReadImg.h ../Common/Message.h ../Common/GmshUI.h \
   ../Post/PView.h ../Geo/SPoint3.h ../Post/PViewDataList.h \
   ../Post/PViewData.h ../Geo/SBoundingBox3d.h ../Geo/SPoint3.h \
   ../Common/ListUtils.h
+Axes.o: Axes.cpp ../Common/GmshUI.h Draw.h ../Geo/SBoundingBox3d.h \
+  ../Geo/SPoint3.h ../Common/Context.h ../Geo/CGNSOptions.h \
+  ../Mesh/PartitionOptions.h gl2ps.h ../Geo/GModel.h ../Geo/GVertex.h \
+  ../Geo/GEntity.h ../Geo/Range.h ../Geo/SPoint3.h \
+  ../Geo/SBoundingBox3d.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/GFace.h ../Geo/GEntity.h \
+  ../Geo/GPoint.h ../Geo/GEdgeLoop.h ../Geo/GEdge.h ../Geo/SPoint2.h \
+  ../Geo/SVector3.h ../Geo/Pair.h ../Geo/GRegion.h ../Geo/GEntity.h \
+  ../Geo/SPoint3.h ../Geo/SBoundingBox3d.h
 Scale.o: Scale.cpp ../Common/GmshUI.h Draw.h ../Geo/SBoundingBox3d.h \
   ../Geo/SPoint3.h ../Post/PView.h ../Post/PViewOptions.h \
   ../Post/ColorTable.h ../Post/PViewData.h ../Common/Context.h \
diff --git a/Graphics/Mesh.cpp b/Graphics/Mesh.cpp
index fa730a958e..05ddc10a34 100644
--- a/Graphics/Mesh.cpp
+++ b/Graphics/Mesh.cpp
@@ -507,7 +507,9 @@ static void drawArrays(GEntity *e, VertexArray *va, GLint type, bool useNormalAr
 
   // If we want to be enable picking of individual elements we need to
   // draw each one separately
-  if(CTX.render_mode == GMSH_SELECT && CTX.pick_elements) {
+  bool select = (CTX.render_mode == GMSH_SELECT && CTX.pick_elements && 
+                 e->model() == GModel::current());
+  if(select) {
     if(va->getNumElementPointers() == va->getNumVertices()){
       for(int i = 0; i < va->getNumVertices(); i += va->getNumVerticesPerElement()){
         glPushName(va->getNumVerticesPerElement());
@@ -571,7 +573,8 @@ class drawMeshGVertex {
   {  
     if(!v->getVisibility()) return;
     
-    if(CTX.render_mode == GMSH_SELECT) {
+    bool select = (CTX.render_mode == GMSH_SELECT && v->model() == GModel::current());
+    if(select) {
       glPushName(0);
       glPushName(v->tag());
     }
@@ -579,7 +582,7 @@ class drawMeshGVertex {
     if(CTX.mesh.points || CTX.mesh.points_num)
       drawVerticesPerEntity(v);
 
-    if(CTX.render_mode == GMSH_SELECT) {
+    if(select) {
       glPopName();
       glPopName();
     }
@@ -620,8 +623,9 @@ class drawMeshGEdge {
   void operator () (GEdge *e)
   {  
     if(!e->getVisibility()) return;
-    
-    if(CTX.render_mode == GMSH_SELECT) {
+
+    bool select = (CTX.render_mode == GMSH_SELECT && e->model() == GModel::current());    
+    if(select) {
       glPushName(1);
       glPushName(e->tag());
     }
@@ -642,7 +646,7 @@ class drawMeshGEdge {
     if(CTX.mesh.tangents)
       drawTangents(e->lines);
 
-    if(CTX.render_mode == GMSH_SELECT) {
+    if(select) {
       glPopName();
       glPopName();
     }
@@ -713,7 +717,8 @@ class drawMeshGFace {
   {  
     if(!f->getVisibility()) return;
 
-    if(CTX.render_mode == GMSH_SELECT) {
+    bool select = (CTX.render_mode == GMSH_SELECT && f->model() == GModel::current());
+    if(select) {
       glPushName(2);
       glPushName(f->tag());
     }
@@ -751,8 +756,7 @@ class drawMeshGFace {
       if(CTX.mesh.triangles) drawVoronoiDual(f->triangles);
     }
 
-
-    if(CTX.render_mode == GMSH_SELECT) {
+    if(select) {
       glPopName();
       glPopName();
     }
@@ -836,7 +840,8 @@ class drawMeshGRegion {
   {  
     if(!r->getVisibility()) return;
 
-    if(CTX.render_mode == GMSH_SELECT) {
+    bool select = (CTX.render_mode == GMSH_SELECT && r->model() == GModel::current());
+    if(select) {
       glPushName(3);
       glPushName(r->tag());
     }
@@ -878,7 +883,7 @@ class drawMeshGRegion {
       if(CTX.mesh.pyramids) drawBarycentricDual(r->pyramids);
     }
 
-    if(CTX.render_mode == GMSH_SELECT) {
+    if(select) {
       glPopName();
       glPopName();
     }
@@ -890,17 +895,18 @@ class drawMeshGRegion {
 
 void Draw_Mesh()
 {
-  GModel *m = GModel::current();
+  if(!CTX.mesh.draw) return;
 
   // make sure to flag any model-dependent post-processing view as
   // changed if the underlying mesh has, before resetting the changed
   // flag
-  for(unsigned int i = 0; i < PView::list.size(); i++)
-    if(PView::list[i]->getData()->hasModel(m) && CTX.mesh.changed)
-      PView::list[i]->setChanged(true);
-  
-  if(!CTX.mesh.draw) return;
-  
+  for(unsigned int i = 0; i < GModel::list.size(); i++){
+    GModel *m = GModel::list[i];
+    for(unsigned int j = 0; j < PView::list.size(); j++)
+      if(PView::list[j]->getData()->hasModel(m) && CTX.mesh.changed)
+        PView::list[j]->setChanged(true);
+  }
+
   glPointSize(CTX.mesh.point_size);
   gl2psPointSize(CTX.mesh.point_size * CTX.print.eps_point_size_factor);
 
@@ -919,33 +925,40 @@ void Draw_Mesh()
       else
 	glDisable((GLenum)(GL_CLIP_PLANE0 + i));
   }
-  
+
   static bool busy = false;
   if(!busy){
     busy = true;
-    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(m->firstEdge(), m->lastEdge(), initMeshGEdge());
-      if(status >= 2 && CTX.mesh.changed & ENT_SURFACE){
-        if(m->normals) delete m->normals;
-        m->normals = new smooth_normals(CTX.mesh.angle_smooth_normals);
-        if(CTX.mesh.smooth_normals)
-          std::for_each(m->firstFace(), m->lastFace(), initSmoothNormalsGFace());
-        std::for_each(m->firstFace(), m->lastFace(), initMeshGFace());
+
+    for(unsigned int i = 0; i < GModel::list.size(); i++){
+      GModel *m = GModel::list[i];
+      if(CTX.draw_all_models || 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(m->firstEdge(), m->lastEdge(), initMeshGEdge());
+          if(status >= 2 && CTX.mesh.changed & ENT_SURFACE){
+            if(m->normals) delete m->normals;
+            m->normals = new smooth_normals(CTX.mesh.angle_smooth_normals);
+            if(CTX.mesh.smooth_normals)
+              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(m->firstRegion(), m->lastRegion(), initMeshGRegion());
+        }
+        if(status >= 0)
+          std::for_each(m->firstVertex(), m->lastVertex(), drawMeshGVertex());
+        if(status >= 1)
+          std::for_each(m->firstEdge(), m->lastEdge(), drawMeshGEdge());
+        if(status >= 2)
+          std::for_each(m->firstFace(), m->lastFace(), drawMeshGFace());
+        if(status >= 3)
+          std::for_each(m->firstRegion(), m->lastRegion(), drawMeshGRegion());
       }
-      if(status >= 3 && CTX.mesh.changed & ENT_VOLUME)
-        std::for_each(m->firstRegion(), m->lastRegion(), initMeshGRegion());
-    }
-    if(status >= 0)
-      std::for_each(m->firstVertex(), m->lastVertex(), drawMeshGVertex());
-    if(status >= 1)
-      std::for_each(m->firstEdge(), m->lastEdge(), drawMeshGEdge());
-    if(status >= 2)
-      std::for_each(m->firstFace(), m->lastFace(), drawMeshGFace());
-    if(status >= 3)
-      std::for_each(m->firstRegion(), m->lastRegion(), drawMeshGRegion());
+    }
+
     CTX.mesh.changed = 0;
     busy = false;
   }
-- 
GitLab