diff --git a/Graphics/Visibility.cpp b/Graphics/Visibility.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7b30a18b0879339c330f6c9d70824c747d2cd1df
--- /dev/null
+++ b/Graphics/Visibility.cpp
@@ -0,0 +1,389 @@
+// $Id: Visibility.cpp,v 1.1 2001-12-03 10:01:06 geuzaine Exp $
+#include "Gmsh.h"
+#include "Geo.h"
+#include "CAD.h"
+#include "Mesh.h"
+#include "DataBase.h"
+#include "Parser.h"
+#include "Visibility.h"
+
+extern Mesh *THEM;
+
+static List_T *ElementaryEntities = NULL, *PhysicalEntities = NULL;
+static Tree_T *VisibleThroughPhysical[4] = {NULL,NULL,NULL,NULL};
+static List_T *NumxSymb = NULL;
+static int Sort = 1;
+
+int Entity::Num(){
+  switch(type){
+  case 1 :
+  case 2 :
+  case 3 :
+  case 4 : return data.physical ? data.physical->Num : 0;
+  case 5 : return data.vertex ? data.vertex->Num : 0;
+  case 6 : return data.curve ? data.curve->Num : 0;
+  case 7 : return data.surface ? data.surface->Num : 0;
+  case 8 : return data.volume ? data.volume->Num : 0;
+  default : return 0;
+  }
+}
+
+char * Entity::Type(){
+  switch(type){
+  case 1 :
+  case 5 : return "Point";
+  case 2 :
+  case 6 : return "Curve";
+  case 3 :
+  case 7 : return "Surface";
+  case 4 :
+  case 8 : return "Volume";
+  default : return "Unknown";
+  }
+}
+
+char * Entity::Name(){
+  char *tmp="";
+  return str?str:tmp;
+}
+
+static char browserline[512];
+char * Entity::BrowserLine(){
+  if(type){
+    sprintf(browserline, "\t%s\t%d\t%s", Type(), Num(), Name());
+    return browserline;
+  }
+  else
+    return Name();
+}
+
+int Entity::Visible(){
+  switch(type){
+  case 1 : 
+  case 2 : 
+  case 3 : 
+  case 4 : return data.physical ? data.physical->Visible : 0;
+  case 5 : return data.vertex ? data.vertex->Visible : 0;
+  case 6 : return data.curve ? data.curve->Visible : 0;
+  case 7 : return data.surface ? data.surface->Visible : 0;
+  case 8 : return data.volume ? data.volume->Visible : 0;
+  default : return 0;
+  }
+}
+
+void Entity::Visible(int mode){
+  Vertex *v;
+  Curve *c;
+  Surface *s;
+  Volume *V;
+  int i,j;
+
+  switch(type){
+  case 1 :
+    if(!data.physical) break;
+    data.physical->Visible = mode;
+    for(i=0;i<List_Nbr(data.physical->Entities);i++){
+      List_Read(data.physical->Entities,i,&j);
+      if((v=FindPoint(j,THEM))){
+	if(Tree_Search(VisibleThroughPhysical[0],&j)){
+	  v->Visible = v->Visible|mode;
+	}
+	else{
+	  v->Visible = mode;
+	  if(mode) Tree_Add(VisibleThroughPhysical[0],&j);
+	}
+      }
+    }
+    break;
+  case 2 :
+    if(!data.physical) break;
+    data.physical->Visible = mode;
+    for(i=0;i<List_Nbr(data.physical->Entities);i++){
+      List_Read(data.physical->Entities,i,&j);
+      if((c=FindCurve(abs(j),THEM))){
+	if(Tree_Search(VisibleThroughPhysical[1],&j)){
+	  c->Visible = c->Visible|mode;
+	}
+	else{
+	  c->Visible = mode;
+	  if(mode) Tree_Add(VisibleThroughPhysical[1],&j);
+	}
+      }
+    }
+    break;
+  case 3 :
+    if(!data.physical) break;
+    data.physical->Visible = mode;
+    for(i=0;i<List_Nbr(data.physical->Entities);i++){
+      List_Read(data.physical->Entities,i,&j);
+      if((s=FindSurface(abs(j),THEM))){
+	if(Tree_Search(VisibleThroughPhysical[2],&j)){
+	  s->Visible = s->Visible|mode;
+	}
+	else{
+	  s->Visible = mode;
+	  if(mode) Tree_Add(VisibleThroughPhysical[2],&j);
+	}
+      };
+    }
+    break;
+  case 4 :
+    if(!data.physical) break;
+    data.physical->Visible = mode;
+    for(i=0;i<List_Nbr(data.physical->Entities);i++){
+      List_Read(data.physical->Entities,i,&j);
+      if((V=FindVolume(abs(j),THEM))){
+	if(Tree_Search(VisibleThroughPhysical[3],&j)){
+	  V->Visible = V->Visible|mode;
+	}
+	else{
+	  V->Visible = mode;
+	  if(mode) Tree_Add(VisibleThroughPhysical[3],&j);
+	}
+      }
+    }
+    break;
+  case 5 : if(!data.vertex) break; data.vertex->Visible = mode; break;
+  case 6 : if(!data.curve) break; data.curve->Visible = mode; break;
+  case 7 : if(!data.surface) break; data.surface->Visible = mode; break;
+  case 8 : if(!data.volume) break; data.volume->Visible = mode; break;
+  }
+}
+
+static void Recur(Curve *c, int mode){
+  int k;
+  Vertex *v;
+  for(k=0;k<List_Nbr(c->Control_Points);k++){
+    List_Read(c->Control_Points,k,&v);
+    v->Visible = v->Visible|mode;
+  }
+}
+
+static void Recur(Surface *s, int mode){
+  int k,l;
+  Vertex *v;
+  Curve *c;
+  for(k=0;k<List_Nbr(s->Generatrices);k++){
+    List_Read(s->Generatrices,k,&c);
+    if(c->Num<0) c = FindCurve(-c->Num,THEM);
+    if(c){
+      c->Visible = c->Visible|mode;
+      for(l=0;l<List_Nbr(c->Control_Points);l++){
+	List_Read(c->Control_Points,l,&v);
+	v->Visible = v->Visible|mode;
+      }
+    }
+  }
+}
+
+static void Recur(Volume *V, int mode){
+  int k,l,m;
+  Vertex *v;
+  Curve *c;
+  Surface *s;
+  for(k=0;k<List_Nbr(V->Surfaces);k++){
+    List_Read(V->Surfaces,k,&s);
+    s->Visible = s->Visible|mode;
+    for(l=0;l<List_Nbr(s->Generatrices);l++){
+      List_Read(s->Generatrices,l,&c);
+      if(c->Num<0) c = FindCurve(-c->Num,THEM);
+      if(c){
+	c->Visible = c->Visible|mode;
+	for(m=0;m<List_Nbr(c->Control_Points);m++){
+	  List_Read(c->Control_Points,m,&v);
+	  v->Visible = v->Visible|mode;
+	}
+      }
+    }
+  }
+}
+
+void Entity::RecurVisible(){
+  int j,k,mode;
+  Curve *c;
+  Surface *s;
+  Volume *V;
+
+  mode = Visible();
+  if(mode){
+    switch(type){
+    case 1 : break;
+    case 2 :
+      if(!data.physical) break; 
+      for(j=0;j<List_Nbr(data.physical->Entities);j++){
+	List_Read(data.physical->Entities,j,&k);
+	if((c=FindCurve(abs(k),THEM))) Recur(c,mode);
+      }
+      break;
+    case 3 :
+      if(!data.physical) break; 
+      for(j=0;j<List_Nbr(data.physical->Entities);j++){
+	List_Read(data.physical->Entities,j,&k);
+	if((s=FindSurface(abs(k),THEM))) Recur(s,mode);
+      }
+      break;
+    case 4 :
+      if(!data.physical) break; 
+      for(j=0;j<List_Nbr(data.physical->Entities);j++){
+	List_Read(data.physical->Entities,j,&k);
+	if((V=FindVolume(abs(k),THEM))) Recur(V,mode);
+      }
+      break;
+    case 5 : break;
+    case 6 : if(!data.curve) break; Recur(data.curve,mode); break;
+    case 7 : if(!data.surface) break; Recur(data.surface,mode); break;
+    case 8 : if(!data.volume) break; Recur(data.volume,mode); break;
+    }
+  }
+}
+
+//////////////////////////////////////////
+
+void SetVisibilitySort(int sort){
+  if(Sort == sort)
+    Sort = -sort;
+  else
+    Sort = sort;
+}
+
+static int CompareEntity(const void *a, const void *b){
+  Entity *p=(Entity*)a, *q=(Entity*)b;
+  switch(Sort){
+  case 1  : return p->type - q->type;
+  case -1 : return q->type - p->type;
+  case 2  : return p->Num() - q->Num();
+  case -2 : return q->Num() - p->Num();
+  case 3  : return strcmp(p->Name(), q->Name());
+  case -3 : return strcmp(q->Name(), p->Name());
+  default : return 0;
+  }
+}
+
+static int CompareNxS(const void *a, const void *b){
+  NxS *p=(NxS*)a, *q=(NxS*)b;
+  return p->n - q->n;
+}
+
+static char * GetString(int num){
+  NxS nxs, *pnxs;
+  nxs.n = num;
+  if((pnxs = (NxS*)List_PQuery(NumxSymb,&nxs,CompareNxS)))
+    return pnxs->s;
+  else
+    return NULL;
+}
+
+static void AddPhysical(void *a, void *b){
+  PhysicalGroup *p=*(PhysicalGroup**)a;
+  Entity e;
+  switch(p->Typ){
+  case MSH_PHYSICAL_POINT  : e.type = 1; break;
+  case MSH_PHYSICAL_LINE   : e.type = 2; break;
+  case MSH_PHYSICAL_SURFACE: e.type = 3; break;
+  case MSH_PHYSICAL_VOLUME : e.type = 4; break;
+  }
+  e.data.physical = p;
+  e.str = GetString(p->Num);
+  List_Add(PhysicalEntities, &e);
+}
+
+static void AddVertex(void *a, void *b){
+  Vertex *v=*(Vertex**)a;
+  Entity e;
+  e.type = 5;
+  e.data.vertex = v;
+  e.str = GetString(v->Num);
+  List_Add(ElementaryEntities, &e);
+}
+
+static void AddCurve(void *a, void *b){
+  Curve *c=*(Curve**)a;
+  if(c->Num < 0) return;
+  Entity e;
+  e.type = 6;
+  e.data.curve = c;
+  e.str = GetString(c->Num);
+  List_Add(ElementaryEntities, &e);
+}
+
+static void AddSurface(void *a, void *b){
+  Surface *s=*(Surface**)a;
+  Entity e;
+  e.type = 7;
+  e.data.surface = s;
+  e.str = GetString(s->Num);
+  List_Add(ElementaryEntities, &e);
+}
+
+static void AddVolume(void *a, void *b){
+  Volume *v=*(Volume**)a;
+  Entity e;
+  e.type = 8;
+  e.data.volume = v;
+  e.str = GetString(v->Num);
+  List_Add(ElementaryEntities, &e);
+}
+
+List_T* GetVisibilityList(int type){
+  int i, j;
+  Symbol *s;
+  NxS nxs;
+
+  if(!ElementaryEntities) 
+    ElementaryEntities = List_Create(100,100,sizeof(Entity));
+  else
+    List_Reset(ElementaryEntities);
+
+  if(!PhysicalEntities)
+    PhysicalEntities = List_Create(100,100,sizeof(Entity));
+  else
+    List_Reset(PhysicalEntities);
+
+  if(!NumxSymb) 
+    NumxSymb = List_Create(100,100,sizeof(NxS));
+  else
+    List_Reset(NumxSymb);
+
+  for(i=0; i<List_Nbr(Symbol_L); i++){
+    s=(Symbol*)List_Pointer(Symbol_L,i);
+    for(j=0; j<List_Nbr(s->val); j++){
+      nxs.n = (int)(*(double*)List_Pointer(s->val, j));
+      nxs.s = s->Name;
+      List_Add(NumxSymb, &nxs);
+    }
+  }
+
+  List_Action(THEM->PhysicalGroups, AddPhysical);
+
+  Tree_Action(THEM->Points, AddVertex);
+  Tree_Action(THEM->Curves, AddCurve);
+  Tree_Action(THEM->Surfaces, AddSurface);
+  Tree_Action(THEM->Volumes, AddVolume);
+  
+  List_Sort(ElementaryEntities, CompareEntity);
+  List_Sort(PhysicalEntities, CompareEntity);
+
+  switch(type){
+  case ELEMENTARY : return ElementaryEntities;
+  case PHYSICAL : return PhysicalEntities;
+  default : return NULL;
+  }
+}
+
+void ClearVisibilityList(int type){
+  int i;
+  Entity *e;
+  List_T *list = (type==ELEMENTARY) ? ElementaryEntities : PhysicalEntities;
+  for(i=0;i<List_Nbr(list);i++){
+    e = (Entity*)List_Pointer(list, i);
+    e->Visible(0);
+  }
+}
+
+void InitVisibilityThroughPhysical(){
+  int i;
+  for(i=0;i<4;i++){
+    if(VisibleThroughPhysical[i]) Tree_Delete(VisibleThroughPhysical[i]);
+    VisibleThroughPhysical[i] = Tree_Create(sizeof(int),fcmp_absint);
+  }
+}
diff --git a/Graphics/Visibility.h b/Graphics/Visibility.h
new file mode 100644
index 0000000000000000000000000000000000000000..ad9b793b258eb58f0a403beb1a64a40edbd3f310
--- /dev/null
+++ b/Graphics/Visibility.h
@@ -0,0 +1,35 @@
+#ifndef _VISIBILITY_H_
+#define _VISIBILITY_H_
+
+typedef struct{
+  int n;
+  char *s;
+} NxS;
+
+class Entity {
+public :
+  int type;
+  union {
+    Vertex *vertex;
+    Curve *curve;
+    Surface *surface;
+    Volume *volume;
+    PhysicalGroup *physical;
+  } data;
+  char *str;
+
+  int   Num();
+  char *Type();
+  char *Name();
+  int   Visible();
+  void  Visible(int mode);
+  void  RecurVisible();
+  char *BrowserLine();
+};
+
+void    SetVisibilitySort(int sort);
+List_T* GetVisibilityList(int type);
+void    ClearVisibilityList(int type);
+void    InitVisibilityThroughPhysical();
+
+#endif