From f78a08a8cbf904d2081a4cd1ed31f289a0e4380d Mon Sep 17 00:00:00 2001
From: Christophe Geuzaine <cgeuzaine@ulg.ac.be>
Date: Fri, 26 Jan 2007 17:51:56 +0000
Subject: [PATCH] - nicer display of second order elements (don't draw internal
 edges) - nicer display of second order vertices (color like in 1.65)

---
 Common/Context.h          |  2 +-
 Common/DefaultOptions.h   |  3 ++
 Common/Options.cpp        | 33 +++++++++++------
 Common/Options.h          |  1 +
 Geo/MVertex.h             | 30 ++++++++++++++--
 Graphics/Mesh.cpp         | 75 +++++++++++++++++++++++++++------------
 Mesh/SecondOrder.cpp      | 20 +++++------
 doc/TODO                  |  7 +++-
 doc/texinfo/opt_mesh.texi |  5 +++
 9 files changed, 127 insertions(+), 49 deletions(-)

diff --git a/Common/Context.h b/Common/Context.h
index d47f674dad..2a65486c34 100644
--- a/Common/Context.h
+++ b/Common/Context.h
@@ -228,7 +228,7 @@ public :
       unsigned int tangents, normals;
     } geom;
     struct{
-      unsigned int vertex, line, triangle, quadrangle;
+      unsigned int vertex, vertex_sup, line, triangle, quadrangle;
       unsigned int tetrahedron, hexahedron, prism, pyramid;
       unsigned int carousel[20];
       unsigned int tangents, normals;
diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h
index 2dc828e0da..db0baaa058 100644
--- a/Common/DefaultOptions.h
+++ b/Common/DefaultOptions.h
@@ -1470,6 +1470,9 @@ StringXColor MeshOptions_Color[] = {
   { F|O, "Points" , opt_mesh_color_points , 
     {0, 0, 255, 255}, {0, 0, 255, 255}, {0, 0, 0, 255},
     "Mesh node color" },
+  { F|O, "PointsSup" , opt_mesh_color_points_sup , 
+    {255, 0, 255, 255}, {255, 0, 255, 255}, {0, 0, 0, 255},
+    "Second order mesh node color" },
   { F|O, "Lines" , opt_mesh_color_lines , 
     {0, 0, 0, 255}, {0, 0, 0, 255}, {0, 0, 0, 255},
     "Mesh line color" },
diff --git a/Common/Options.cpp b/Common/Options.cpp
index e6c70adf00..8db80e2915 100644
--- a/Common/Options.cpp
+++ b/Common/Options.cpp
@@ -1,4 +1,4 @@
-// $Id: Options.cpp,v 1.332 2007-01-24 10:53:04 geuzaine Exp $
+// $Id: Options.cpp,v 1.333 2007-01-26 17:51:55 geuzaine Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -7193,6 +7193,17 @@ unsigned int opt_mesh_color_points(OPT_ARGS_COL)
   return CTX.color.mesh.vertex;
 }
 
+unsigned int opt_mesh_color_points_sup(OPT_ARGS_COL)
+{
+  if(action & GMSH_SET) {
+    CTX.color.mesh.vertex_sup = val;
+  }
+#if defined(HAVE_FLTK)
+  CCC(CTX.color.mesh.vertex_sup, WID->mesh_col[1]);
+#endif
+  return CTX.color.mesh.vertex_sup;
+}
+
 unsigned int opt_mesh_color_lines(OPT_ARGS_COL)
 {
   if(action & GMSH_SET) {
@@ -7203,7 +7214,7 @@ unsigned int opt_mesh_color_lines(OPT_ARGS_COL)
     CTX.color.mesh.line = val;
   }
 #if defined(HAVE_FLTK)
-  CCC(CTX.color.mesh.line, WID->mesh_col[1]);
+  CCC(CTX.color.mesh.line, WID->mesh_col[2]);
 #endif
   return CTX.color.mesh.line;
 }
@@ -7218,7 +7229,7 @@ unsigned int opt_mesh_color_triangles(OPT_ARGS_COL)
     CTX.color.mesh.triangle = val;
   }
 #if defined(HAVE_FLTK)
-  CCC(CTX.color.mesh.triangle, WID->mesh_col[2]);
+  CCC(CTX.color.mesh.triangle, WID->mesh_col[3]);
 #endif
   return CTX.color.mesh.triangle;
 }
@@ -7233,7 +7244,7 @@ unsigned int opt_mesh_color_quadrangles(OPT_ARGS_COL)
     CTX.color.mesh.quadrangle = val;
   }
 #if defined(HAVE_FLTK)
-  CCC(CTX.color.mesh.quadrangle, WID->mesh_col[3]);
+  CCC(CTX.color.mesh.quadrangle, WID->mesh_col[4]);
 #endif
   return CTX.color.mesh.quadrangle;
 }
@@ -7248,7 +7259,7 @@ unsigned int opt_mesh_color_tetrahedra(OPT_ARGS_COL)
     CTX.color.mesh.tetrahedron = val;
   }
 #if defined(HAVE_FLTK)
-  CCC(CTX.color.mesh.tetrahedron, WID->mesh_col[4]);
+  CCC(CTX.color.mesh.tetrahedron, WID->mesh_col[5]);
 #endif
   return CTX.color.mesh.tetrahedron;
 }
@@ -7263,7 +7274,7 @@ unsigned int opt_mesh_color_hexahedra(OPT_ARGS_COL)
     CTX.color.mesh.hexahedron = val;
   }
 #if defined(HAVE_FLTK)
-  CCC(CTX.color.mesh.hexahedron, WID->mesh_col[5]);
+  CCC(CTX.color.mesh.hexahedron, WID->mesh_col[6]);
 #endif
   return CTX.color.mesh.hexahedron;
 }
@@ -7278,7 +7289,7 @@ unsigned int opt_mesh_color_prisms(OPT_ARGS_COL)
     CTX.color.mesh.prism = val;
   }
 #if defined(HAVE_FLTK)
-  CCC(CTX.color.mesh.prism, WID->mesh_col[6]);
+  CCC(CTX.color.mesh.prism, WID->mesh_col[7]);
 #endif
   return CTX.color.mesh.prism;
 }
@@ -7293,7 +7304,7 @@ unsigned int opt_mesh_color_pyramid(OPT_ARGS_COL)
     CTX.color.mesh.pyramid = val;
   }
 #if defined(HAVE_FLTK)
-  CCC(CTX.color.mesh.pyramid, WID->mesh_col[7]);
+  CCC(CTX.color.mesh.pyramid, WID->mesh_col[8]);
 #endif
   return CTX.color.mesh.pyramid;
 }
@@ -7304,7 +7315,7 @@ unsigned int opt_mesh_color_tangents(OPT_ARGS_COL)
     CTX.color.mesh.tangents = val;
   }
 #if defined(HAVE_FLTK)
-  CCC(CTX.color.mesh.tangents, WID->mesh_col[8]);
+  CCC(CTX.color.mesh.tangents, WID->mesh_col[9]);
 #endif
   return CTX.color.mesh.tangents;
 }
@@ -7315,7 +7326,7 @@ unsigned int opt_mesh_color_normals(OPT_ARGS_COL)
     CTX.color.mesh.normals = val;
   }
 #if defined(HAVE_FLTK)
-  CCC(CTX.color.mesh.normals, WID->mesh_col[9]);
+  CCC(CTX.color.mesh.normals, WID->mesh_col[10]);
 #endif
   return CTX.color.mesh.normals;
 }
@@ -7330,7 +7341,7 @@ unsigned int opt_mesh_color_(int i, OPT_ARGS_COL)
     CTX.color.mesh.carousel[i] = val;
   }
 #if defined(HAVE_FLTK)
-  CCC(CTX.color.mesh.carousel[i], WID->mesh_col[10+i]);
+  CCC(CTX.color.mesh.carousel[i], WID->mesh_col[11+i]);
 #endif
   return CTX.color.mesh.carousel[i];
 }
diff --git a/Common/Options.h b/Common/Options.h
index 751ec42d12..bbffc964b1 100644
--- a/Common/Options.h
+++ b/Common/Options.h
@@ -656,6 +656,7 @@ unsigned int opt_geometry_color_highlight2(OPT_ARGS_COL);
 unsigned int opt_geometry_color_tangents(OPT_ARGS_COL);
 unsigned int opt_geometry_color_normals(OPT_ARGS_COL);
 unsigned int opt_mesh_color_points(OPT_ARGS_COL); 
+unsigned int opt_mesh_color_points_sup(OPT_ARGS_COL); 
 unsigned int opt_mesh_color_lines(OPT_ARGS_COL); 
 unsigned int opt_mesh_color_triangles(OPT_ARGS_COL);
 unsigned int opt_mesh_color_quadrangles(OPT_ARGS_COL);
diff --git a/Geo/MVertex.h b/Geo/MVertex.h
index 8b1660578a..3501aa8735 100644
--- a/Geo/MVertex.h
+++ b/Geo/MVertex.h
@@ -56,6 +56,9 @@ class MVertex{
   virtual char getVisibility(){ return _visible; }
   virtual void setVisibility(char val){ _visible = val; }
   
+  // get the "order" of the vertex
+  virtual int getOrder(){ return 1; }
+
   // get/set the coordinates
   inline double x() const {return _x;}
   inline double y() const {return _y;}
@@ -99,6 +102,13 @@ class MVertex{
   void writeBDF(FILE *fp, int format=0, double scalingFactor=1.0);
 };
 
+class MVertex2 : public MVertex {
+ public:
+  MVertex2(double x, double y, double z, GEntity *ge=0, int num=0) 
+    : MVertex(x, y, z, ge, num){}
+  virtual int getOrder(){ return 2; }
+};
+
 class MEdgeVertex : public MVertex{
  protected:
   double _u;
@@ -107,11 +117,18 @@ class MEdgeVertex : public MVertex{
     : MVertex(x, y, z, ge), _u(u)
   {
   }
-  ~MEdgeVertex(){}
+  virtual ~MEdgeVertex(){}
   virtual bool getParameter(int i, double &par){ par = _u; return true; }
   virtual bool setParameter(int i, double par){ _u = par; return true; }
 };
 
+class MEdgeVertex2 : public MEdgeVertex{
+ public:
+  MEdgeVertex2(double x, double y, double z, GEntity *ge, double u) 
+    : MEdgeVertex(x, y, z, ge, u) {}
+  virtual int getOrder(){ return 2; }
+};
+
 class MFaceVertex : public MVertex{
  protected:
   double _u, _v;
@@ -120,11 +137,18 @@ class MFaceVertex : public MVertex{
     : MVertex(x, y, z, ge), _u(u), _v(v)
   {
   }
-  ~MFaceVertex(){}
+  virtual ~MFaceVertex(){}
   virtual bool getParameter(int i, double &par){ par = (i ? _v : _u); return true; }
   virtual bool setParameter(int i, double par){ if(!i) _u = par; else _v = par; return true; }
 };
 
+class MFaceVertex2 : public MFaceVertex{
+ public:
+  MFaceVertex2(double x, double y, double z, GEntity *ge, double u, double v) 
+    : MFaceVertex(x, y, z, ge, u, v){}
+  virtual int getOrder(){ return 2; }
+};
+
 template<class T>
 class MDataFaceVertex : public MFaceVertex{
  private:
@@ -134,7 +158,7 @@ class MDataFaceVertex : public MFaceVertex{
     : MFaceVertex(x, y, z, ge, u, v), _data(data)
   {
   }
-  ~MDataFaceVertex(){}
+  virtual ~MDataFaceVertex(){}
   virtual bool getData(T &data){ data = _data; return true; }
   virtual void *getData(){ return (void*)&_data; }
 };
diff --git a/Graphics/Mesh.cpp b/Graphics/Mesh.cpp
index 1947d0b8ec..b76c422a80 100644
--- a/Graphics/Mesh.cpp
+++ b/Graphics/Mesh.cpp
@@ -1,4 +1,4 @@
-// $Id: Mesh.cpp,v 1.194 2007-01-25 08:56:14 geuzaine Exp $
+// $Id: Mesh.cpp,v 1.195 2007-01-26 17:51:55 geuzaine Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -129,6 +129,14 @@ static bool areAllElementsVisible(std::vector<T*> &elements)
   return true;
 }
 
+template<class T>
+static bool areSomeElementsCurved(std::vector<T*> &elements)
+{
+  for(unsigned int i = 0; i < elements.size(); i++)
+    if(elements[i]->getPolynomialOrder() > 1 ) return true;
+  return false;
+}
+
 static int getLabelStep(int total)
 {
   int step;
@@ -226,19 +234,26 @@ static void drawVertexLabel(GEntity *e, MVertex *v, int partition=-1)
     sprintf(str, "%d", e->tag());
   else
     sprintf(str, "%d", v->getNum());
+
+  if(v->getOrder() > 1)
+    glColor4ubv((GLubyte *) & CTX.color.mesh.vertex_sup);
+  else
+    glColor4ubv((GLubyte *) & CTX.color.mesh.vertex);	
   glRasterPos3d(v->x(), v->y(), v->z());
   Draw_String(str);
 }
 
 static void drawVerticesPerEntity(GEntity *e)
 {
-  glColor4ubv((GLubyte *) & CTX.color.mesh.vertex);
-
   if(CTX.mesh.points) {
     if(CTX.mesh.point_type) {
       for(unsigned int i = 0; i < e->mesh_vertices.size(); i++){
 	MVertex *v = e->mesh_vertices[i];
 	if(!v->getVisibility()) continue;
+	if(v->getOrder() > 1)
+	  glColor4ubv((GLubyte *) & CTX.color.mesh.vertex_sup);
+	else
+	  glColor4ubv((GLubyte *) & CTX.color.mesh.vertex);	
 	Draw_Sphere(CTX.mesh.point_size, v->x(), v->y(), v->z(), CTX.mesh.light);
       }
     }
@@ -247,6 +262,10 @@ static void drawVerticesPerEntity(GEntity *e)
       for(unsigned int i = 0; i < e->mesh_vertices.size(); i++){
 	MVertex *v = e->mesh_vertices[i];
 	if(!v->getVisibility()) continue;
+	if(v->getOrder() > 1)
+	  glColor4ubv((GLubyte *) & CTX.color.mesh.vertex_sup);
+	else
+	  glColor4ubv((GLubyte *) & CTX.color.mesh.vertex);	
 	glVertex3d(v->x(), v->y(), v->z());
       }
       glEnd();
@@ -262,14 +281,16 @@ static void drawVerticesPerEntity(GEntity *e)
 template<class T>
 static void drawVerticesPerElement(GEntity *e, std::vector<T*> &elements)
 {
-  glColor4ubv((GLubyte *) & CTX.color.mesh.vertex);
-  
   for(unsigned int i = 0; i < elements.size(); i++){
     MElement *ele = elements[i];
     for(int j = 0; j < ele->getNumVertices(); j++){
       MVertex *v = ele->getVertex(j);
       if(isElementVisible(ele) && v->getVisibility()){
 	if(CTX.mesh.points) {
+	  if(v->getOrder() > 1)
+	    glColor4ubv((GLubyte *) & CTX.color.mesh.vertex_sup);
+	  else
+	    glColor4ubv((GLubyte *) & CTX.color.mesh.vertex);	
 	  if(CTX.mesh.point_type)
 	    Draw_Sphere(CTX.mesh.point_size, v->x(), v->y(), v->z(), CTX.mesh.light);
 	  else{
@@ -423,7 +444,7 @@ static void addElementsInArrays(GEntity *e, std::vector<T*> &elements)
 	}
       }
     }
-    else{
+    if(!ele->getNumFacesRep() || ele->getPolynomialOrder() > 1){
       SPoint3 pc;
       if(CTX.mesh.explode != 1.) pc = ele->barycenter();
       for(int j = 0; j < ele->getNumEdgesRep(); j++){
@@ -619,14 +640,14 @@ class initMeshGFace {
       CTX.mesh.triangles && areAllElementsVisible(f->triangles) && 
       CTX.mesh.quadrangles && areAllElementsVisible(f->quadrangles);
 
-    bool useEdges = CTX.mesh.surfaces_edges ? true : false;
-    if(CTX.mesh.surfaces_faces /*this will change!*/ || 
-       CTX.mesh.explode != 1. || !m->allElementsVisible)
-      useEdges = false;
+    bool curvedElements = 
+      areSomeElementsCurved(f->triangles) || 
+      areSomeElementsCurved(f->quadrangles);
 
-    // mouse selection of individual elements is complicated if we
-    // don't draw everything per element
-    if(CTX.pick_elements) useEdges = false;
+    bool useEdges = CTX.mesh.surfaces_edges ? true : false;
+    if(CTX.mesh.surfaces_faces || CTX.mesh.explode != 1. || 
+       CTX.pick_elements || !m->allElementsVisible)
+      useEdges = false; // cannot use edges in these cases
 
     // Further optimizations are possible when useEdges is true:
     // 1) store the unique vertices in the vertex array and use
@@ -643,6 +664,9 @@ class initMeshGFace {
       addEdgesInArrays(f);
     }
     else if(CTX.mesh.surfaces_edges || CTX.mesh.surfaces_faces){
+      if(curvedElements) // cannot simply draw polygon outlines!
+	m->va_lines = new VertexArray(2, 6 * f->triangles.size() 
+				      + 8 * f->quadrangles.size());
       m->va_triangles = new VertexArray(3, f->triangles.size());
       m->va_quads = new VertexArray(4, f->quadrangles.size());
       if(CTX.mesh.triangles) addElementsInArrays(f, f->triangles);
@@ -736,20 +760,20 @@ class initMeshGRegion {
       CTX.mesh.pyramids && areAllElementsVisible(r->pyramids);
 
     bool useEdges = CTX.mesh.volumes_edges ? true : false;
-    if(CTX.mesh.volumes_faces /*this will change!*/ || 
-       CTX.mesh.explode != 1. || !m->allElementsVisible)
-      useEdges = false;
-    
-    // mouse selection of individual elements is complicated if we
-    // don't draw everything per element
-    if(CTX.pick_elements) useEdges = false;
+    if(CTX.mesh.volumes_faces || CTX.mesh.explode != 1. || 
+       CTX.pick_elements || !m->allElementsVisible)
+      useEdges = false; // cannot use edges in these cases
+
+    bool curvedElements = 
+      areSomeElementsCurved(r->tetrahedra) || 
+      areSomeElementsCurved(r->hexahedra) ||
+      areSomeElementsCurved(r->prisms) ||
+      areSomeElementsCurved(r->pyramids);
 
     bool useSkin = CTX.mesh.volumes_faces ? true : false;
     if(CTX.mesh.explode != 1. || !m->allElementsVisible)
       useSkin = false;
-
-    // TODO
-    useSkin = false;
+    useSkin = false; // FIXME: to do
     
     if(useSkin){ 
       Msg(DEBUG, "Using boundary faces to draw volume %d", r->tag());
@@ -765,6 +789,11 @@ class initMeshGRegion {
       addEdgesInArrays(r);
     }
     else if(CTX.mesh.volumes_edges || CTX.mesh.volumes_faces){
+      if(curvedElements) // cannot simply draw polygon outlines!
+	m->va_lines = new VertexArray(2, 12 * r->tetrahedra.size() +
+				      24 * r->hexahedra.size() +
+				      18 * r->prisms.size() +
+				      16 * r->pyramids.size());
       m->va_triangles = new VertexArray(3, 4 * r->tetrahedra.size() +
 					2 * r->prisms.size() + 
 					4 * r->pyramids.size());
diff --git a/Mesh/SecondOrder.cpp b/Mesh/SecondOrder.cpp
index d9f2bc452b..cadc79b241 100644
--- a/Mesh/SecondOrder.cpp
+++ b/Mesh/SecondOrder.cpp
@@ -1,4 +1,4 @@
-// $Id: SecondOrder.cpp,v 1.49 2007-01-22 16:31:43 geuzaine Exp $
+// $Id: SecondOrder.cpp,v 1.50 2007-01-26 17:51:56 geuzaine Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -43,7 +43,7 @@ void getEdgeVertices(GEdge *ge, MElement *ele, std::vector<MVertex*> &ve,
       MVertex *v, *v0 = edge.getVertex(0), *v1 = edge.getVertex(1);
       if(linear || ge->geomType() == GEntity::DiscreteCurve){
 	SPoint3 pc = edge.barycenter();
-	v = new MVertex(pc.x(), pc.y(), pc.z(), ge);
+	v = new MVertex2(pc.x(), pc.y(), pc.z(), ge);
       }
       else{
 	double u0 = 1e6, u1 = 1e6;
@@ -63,12 +63,12 @@ void getEdgeVertices(GEdge *ge, MElement *ele, std::vector<MVertex*> &ve,
 	if(u0 < 1e6 && u1 < 1e6){
 	  double uc = 0.5 * (u0 + u1);
 	  GPoint pc = ge->point(uc);
-	  v = new MEdgeVertex(pc.x(), pc.y(), pc.z(), ge, uc);
+	  v = new MEdgeVertex2(pc.x(), pc.y(), pc.z(), ge, uc);
 	}
 	else{
 	  // we should normally never end up here
 	  SPoint3 pc = edge.barycenter();
-	  v = new MVertex(pc.x(), pc.y(), pc.z(), ge);
+	  v = new MVertex2(pc.x(), pc.y(), pc.z(), ge);
 	}
       }
       edgeVertices[p] = v;
@@ -92,7 +92,7 @@ void getEdgeVertices(GFace *gf, MElement *ele, std::vector<MVertex*> &ve,
       MVertex *v, *v0 = edge.getVertex(0), *v1 = edge.getVertex(1);
       if(linear || gf->geomType() == GEntity::DiscreteSurface){
 	SPoint3 pc = edge.barycenter();
-	v = new MVertex(pc.x(), pc.y(), pc.z(), gf);
+	v = new MVertex2(pc.x(), pc.y(), pc.z(), gf);
       }
       else{
 	SPoint2 p0 = gf->parFromPoint(SPoint3(v0->x(), v0->y(), v0->z()));
@@ -100,7 +100,7 @@ void getEdgeVertices(GFace *gf, MElement *ele, std::vector<MVertex*> &ve,
 	double uc = 0.5 * (p0[0] + p1[0]);
 	double vc = 0.5 * (p0[1] + p1[1]);
 	GPoint pc = gf->point(uc, vc);
-	v = new MFaceVertex(pc.x(), pc.y(), pc.z(), gf, uc, vc);
+	v = new MFaceVertex2(pc.x(), pc.y(), pc.z(), gf, uc, vc);
       }
       edgeVertices[p] = v;
       gf->mesh_vertices.push_back(v);
@@ -121,7 +121,7 @@ void getEdgeVertices(GRegion *gr, MElement *ele, std::vector<MVertex*> &ve,
     }
     else{
       SPoint3 pc = edge.barycenter();
-      MVertex *v = new MVertex(pc.x(), pc.y(), pc.z(), gr);
+      MVertex *v = new MVertex2(pc.x(), pc.y(), pc.z(), gr);
       edgeVertices[p] = v;
       gr->mesh_vertices.push_back(v);
       ve.push_back(v);
@@ -145,7 +145,7 @@ void getFaceVertices(GFace *gf, MElement *ele, std::vector<MVertex*> &vf,
       MVertex *v;
       if(linear || gf->geomType() == GEntity::DiscreteSurface){
 	SPoint3 pc = face.barycenter();
-	v = new MVertex(pc.x(), pc.y(), pc.z(), gf);
+	v = new MVertex2(pc.x(), pc.y(), pc.z(), gf);
       }
       else{
 	SPoint2 p0 = gf->parFromPoint(SPoint3(p[0]->x(), p[0]->y(), p[0]->z()));
@@ -155,7 +155,7 @@ void getFaceVertices(GFace *gf, MElement *ele, std::vector<MVertex*> &vf,
 	double uc = 0.25 * (p0[0] + p1[0] + p2[0] + p3[0]);
 	double vc = 0.25 * (p0[1] + p1[1] + p2[1] + p3[1]);
 	GPoint pc = gf->point(uc, vc);
-	v = new MFaceVertex(pc.x(), pc.y(), pc.z(), gf, uc, vc);
+	v = new MFaceVertex2(pc.x(), pc.y(), pc.z(), gf, uc, vc);
       }
       faceVertices[p] = v;
       gf->mesh_vertices.push_back(v);
@@ -178,7 +178,7 @@ void getFaceVertices(GRegion *gr, MElement *ele, std::vector<MVertex*> &vf,
     }
     else{
       SPoint3 pc = face.barycenter();
-      MVertex *v = new MVertex(pc.x(), pc.y(), pc.z(), gr);
+      MVertex *v = new MVertex2(pc.x(), pc.y(), pc.z(), gr);
       faceVertices[p] = v;
       gr->mesh_vertices.push_back(v);
       vf.push_back(v);
diff --git a/doc/TODO b/doc/TODO
index 0d0d02fc76..08d0868ba4 100644
--- a/doc/TODO
+++ b/doc/TODO
@@ -1,4 +1,9 @@
-$Id: TODO,v 1.39 2007-01-22 16:31:44 geuzaine Exp $
+$Id: TODO,v 1.40 2007-01-26 17:51:56 geuzaine Exp $
+
+********************************************************************
+
+better drawing of 2nd order elements (no extra edges in the middle, 
+2nd order nodes in different color)
 
 ********************************************************************
 
diff --git a/doc/texinfo/opt_mesh.texi b/doc/texinfo/opt_mesh.texi
index a7cf88c753..207f7c34dd 100644
--- a/doc/texinfo/opt_mesh.texi
+++ b/doc/texinfo/opt_mesh.texi
@@ -374,6 +374,11 @@ Mesh node color@*
 Default value: @code{@{0,0,255@}}@*
 Saved in: @code{General.OptionsFileName}
 
+@item Mesh.Color.PointsSup
+Second order mesh node color@*
+Default value: @code{@{255,0,255@}}@*
+Saved in: @code{General.OptionsFileName}
+
 @item Mesh.Color.Lines
 Mesh line color@*
 Default value: @code{@{0,0,0@}}@*
-- 
GitLab