diff --git a/Geo/GModelIO.cpp b/Geo/GModelIO.cpp
index b7811ef68e23f4b2ac628c9fa9d0a733d442fd26..1c02d3ef063380342ad18d926944e39573171fa2 100644
--- a/Geo/GModelIO.cpp
+++ b/Geo/GModelIO.cpp
@@ -1,4 +1,4 @@
-// $Id: GModelIO.cpp,v 1.16 2006-08-17 03:22:22 geuzaine Exp $
+// $Id: GModelIO.cpp,v 1.17 2006-08-17 05:10:44 geuzaine Exp $
 //
 // Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
 //
@@ -150,6 +150,18 @@ static void storeVerticesInEntities(std::map<int, MVertex*> &vertices)
   }
 }
 
+static void storeVerticesInEntities(std::vector<MVertex*> &vertices)
+{
+  for(unsigned int i = 0; i < vertices.size(); i++){
+    MVertex *v = vertices[i];
+    GEntity *ge = v->onWhat();
+    if(ge) 
+      ge->mesh_vertices.push_back(v);
+    else
+      delete v; // we delete all unused vertices
+  }
+}
+
 static void storePhysicalTagsInEntities(GModel *m, int dim,
 					std::map<int, std::map<int, std::string> > &map)
 {
@@ -749,6 +761,71 @@ static int skipUntil(FILE *fp, char *key)
   return 1;
 }
 
+static int readVerticesVRML(FILE *fp, std::map<int, MVertex*> &vertices,
+			    std::vector<MVertex*> &allvertices)
+{
+  int num = 0;
+  double x, y, z;
+  char buffer[256];
+  if(!fgets(buffer, sizeof(buffer), fp)) return 0;
+  while(sscanf(buffer, "%lf %lf %lf", &x, &y, &z)){
+    vertices[num++] = new MVertex(x, y, z);
+    if(!fgets(buffer, sizeof(buffer), fp)) return 0;
+  }
+  for(unsigned int i = 0; i < vertices.size(); i++)
+    allvertices.push_back(vertices[i]);
+  Msg(INFO, "%d vertices", vertices.size());
+  return vertices.size();
+}
+
+static int readElementsVRML(FILE *fp, std::map<int, MVertex*> &vertices, 
+			    std::vector<MElement*> &elements)
+{
+  int i;
+  std::vector<int> idx;
+  if(!fscanf(fp, "%d", &i)) return 0;
+  idx.push_back(i);
+  while(fscanf(fp, " , %d", &i)){
+    if(i != -1){
+      idx.push_back(i);
+    }
+    else{
+      // check if all the indices are valid
+      for(unsigned int j = 0; j < idx.size(); j++){
+	if(!vertices.count(idx[j])){
+	  Msg(GERROR, "Bad vertex index in VRML file");
+	  return 0;
+	}
+      }
+      // create the elements
+      if(idx.size() == 2){
+	elements.push_back(new MLine(vertices[idx[0]], vertices[idx[1]]));
+      }
+      else if(idx.size() > 2){
+	// if there are more than 3 indices we assume that we have a
+	// triangle strip
+	for(unsigned int j = 2; j < idx.size(); j++){
+	  if(j % 2)
+	    elements.push_back(new MTriangle(vertices[idx[j]], 
+					     vertices[idx[j - 1]],
+					     vertices[idx[j - 2]]));
+	  else
+	    elements.push_back(new MTriangle(vertices[idx[j - 2]],
+					     vertices[idx[j - 1]],
+					     vertices[idx[j]]));
+	}
+      }
+      idx.clear();
+    }
+  }
+  if(idx.size()){
+    Msg(GERROR, "Premature end of VRML file");
+    return 0;
+  }
+  Msg(INFO, "%d elements", elements.size());
+  return elements.size();
+}
+
 int GModel::readVRML(const std::string &name)
 {
   FILE *fp = fopen(name.c_str(), "r");
@@ -757,11 +834,16 @@ int GModel::readVRML(const std::string &name)
     return 0;
   }
 
-  // Warning: this is by NO means a real VRML/Inventor parser: it just
-  // reads the special bunch of files I have to work with.
+  // This is by NO means a complete VRML/Inventor parser. It just
+  // reads a very limited subset of VRML/Inventor 1.0 and 2.1 by
+  // making plenty of bold assumptions on how the file is structured
+  // (for example, it assumes that all the tags are on separate
+  // lines).
 
   std::map<int, MVertex*> vertices;
-  std::map<int, std::vector<MElement*> > triangles;
+  std::vector<MVertex*> allvertices;
+  int elementTypes[2] = {LGN1, TRI1};
+  std::map<int, std::vector<MElement*> > elements[2];
   int region = 0;
   char buffer[256], str[256];
   while(!feof(fp)) {
@@ -770,51 +852,48 @@ int GModel::readVRML(const std::string &name)
       sscanf(buffer, "%s", str);
       if(!strcmp(str, "IndexedTriangleStripSet")){
 	region++;
-	Msg(INFO, "IndexedTriangleStripSet");
+	vertices.clear();
 	if(!skipUntil(fp, "vertex")) break;
-	int num = 0;
-	double x, y, z;
-	if(!fgets(buffer, sizeof(buffer), fp)) break;
-	while(sscanf(buffer, "%lf %lf %lf", &x, &y, &z)){
-	  vertices[num++] = new MVertex(x, y, z);
-	  if(!fgets(buffer, sizeof(buffer), fp)) break;
-	}
-	Msg(INFO, "%d vertices", vertices.size());
+	if(!readVerticesVRML(fp, vertices, allvertices)) break;
 	if(!skipUntil(fp, "coordIndex")) break;
-	int index;
-	if(!fscanf(fp, "%d", &index)) break;
-	std::vector<int> indices;
-	while(fscanf(fp, " , %d", &index)){
-	  if(index == -1){
-	    if(indices.size() < 3){
-	      Msg(GERROR, "Less than 3 indices in VRML triangle strip");
-	      break;
-	    }
-	    for(unsigned int i = 2; i < indices.size(); i++){
-	      triangles[region].push_back(new MTriangle(vertices[indices[i-2]], 
-							vertices[indices[i-1]], 
-							vertices[indices[i]]));
-	    }
-	    indices.clear();
-	  }
-	  else{
-	    indices.push_back(index);
-	  }
+	if(!readElementsVRML(fp, vertices, elements[1][region])) break;
+      }
+      else if(!strcmp(str, "Coordinate3")){
+	vertices.clear();
+	if(!skipUntil(fp, "point")) break;
+	if(!readVerticesVRML(fp, vertices, allvertices)) break;
+      }
+      else if(!strcmp(str, "IndexedFaceSet")){
+	region++;
+	if(!skipUntil(fp, "coordIndex")) break;
+	if(!readElementsVRML(fp, vertices, elements[1][region])) break;
+      }
+      else if(!strcmp(str, "IndexedLineSet")){
+	region++;
+	if(!skipUntil(fp, "coordIndex")) break;
+	if(!readElementsVRML(fp, vertices, elements[0][region])) break;
+      }
+      else if(!strcmp(str, "DEF")){
+	char str1[256], str2[256];
+	if(!sscanf(buffer, "%s %s %s", str1, str2, str)) break;
+	if(!strcmp(str, "IndexedFaceSet")){
+	  region++;
+	  if(!skipUntil(fp, "coordIndex")) break;
+	  if(!readElementsVRML(fp, vertices, elements[1][region])) break;
 	}
-	if(indices.size()){
-	  Msg(GERROR, "End of VRML triangle strip not found");
+	else if(!strcmp(str, "IndexedLineSet")){
+	  region++;
+	  if(!skipUntil(fp, "coordIndex")) break;
+	  if(!readElementsVRML(fp, vertices, elements[0][region])) break;
 	}
-	Msg(INFO, "%d triangles", triangles[region].size());
-      }
-      else{
-	// just ignore 
       }
     }
   }
 
-  storeElementsInEntities(this, TRI1, triangles);
+  for(int i = 0; i < 2; i++)
+    storeElementsInEntities(this, elementTypes[i], elements[i]);
   associateEntityWithVertices(this);
-  storeVerticesInEntities(vertices);
+  storeVerticesInEntities(allvertices);
 
   fclose(fp);
   return 1;