From b9de5da49fcb9b66da0bd9e716347779cdba30fd Mon Sep 17 00:00:00 2001
From: Christophe Geuzaine <cgeuzaine@ulg.ac.be>
Date: Sat, 16 Feb 2008 22:25:13 +0000
Subject: [PATCH] consistent surf display options and defaults

---
 Common/DefaultOptions.h |   4 +-
 Common/Options.cpp      |   4 +-
 Fltk/GUI.cpp            |   5 +-
 Geo/GFace.cpp           |  75 ++++++++++++-
 Geo/GFace.h             |   3 +
 Graphics/Geom.cpp       | 240 ++++++++++++++++------------------------
 6 files changed, 181 insertions(+), 150 deletions(-)

diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h
index be1f5cc07c..e04889cc3d 100644
--- a/Common/DefaultOptions.h
+++ b/Common/DefaultOptions.h
@@ -861,8 +861,8 @@ StringXNumber GeometryOptions_Number[] = {
     "Display geometry surfaces?" },
   { F|O, "SurfaceNumbers" , opt_geometry_surfaces_num , 0. , 
     "Display surface numbers?" },
-  { F|O, "SurfaceType" , opt_geometry_surface_type , 1. , 
-    "Display surfaces as wireframe (0) or solid (1)" },
+  { F|O, "SurfaceType" , opt_geometry_surface_type , 2. , 
+    "Surface display type (0=cross, 1=wireframe, 2=solid" },
 
   { F|O, "Tangents" , opt_geometry_tangents , 0. ,
     "Display size of tangent vectors (in pixels)" },
diff --git a/Common/Options.cpp b/Common/Options.cpp
index d67e17c82f..e28e864409 100644
--- a/Common/Options.cpp
+++ b/Common/Options.cpp
@@ -1,4 +1,4 @@
-// $Id: Options.cpp,v 1.380 2008-01-30 15:27:40 remacle Exp $
+// $Id: Options.cpp,v 1.381 2008-02-16 22:25:12 geuzaine Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -4077,6 +4077,8 @@ double opt_geometry_surface_type(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET) {
     CTX.geom.surface_type = (int)val;
+    if(CTX.geom.surface_type < 0 || CTX.geom.surface_type > 2)
+      CTX.geom.surface_type = 0;
   }
 #if defined(HAVE_FLTK)
   if(WID && (action & GMSH_GUI)) {
diff --git a/Fltk/GUI.cpp b/Fltk/GUI.cpp
index beaeca6b10..bb2ae978f0 100644
--- a/Fltk/GUI.cpp
+++ b/Fltk/GUI.cpp
@@ -1,4 +1,4 @@
-// $Id: GUI.cpp,v 1.652 2008-02-05 21:03:13 geuzaine Exp $
+// $Id: GUI.cpp,v 1.653 2008-02-16 22:25:12 geuzaine Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -367,6 +367,7 @@ static Fl_Menu_Item menu_line_display_post[] = {
 };
 
 static Fl_Menu_Item menu_surface_display[] = {
+  {"Cross",     0, 0, 0},
   {"Wireframe", 0, 0, 0},
   {"Solid",     0, 0, 0},
   {0}
@@ -745,7 +746,7 @@ int GUI::global_shortcuts(int event)
   }
   else if(Fl::test_shortcut(FL_ALT + 'd')){
     opt_geometry_surface_type(0, GMSH_SET | GMSH_GUI,
-			      !opt_geometry_surface_type(0, GMSH_GET, 0));
+			      opt_geometry_surface_type(0, GMSH_GET, 0) + 1);
     redraw_opengl();
     return 1;
   }
diff --git a/Geo/GFace.cpp b/Geo/GFace.cpp
index 07b1fa982f..593f7e6f0e 100644
--- a/Geo/GFace.cpp
+++ b/Geo/GFace.cpp
@@ -1,4 +1,4 @@
-// $Id: GFace.cpp,v 1.48 2008-02-07 13:17:18 geuzaine Exp $
+// $Id: GFace.cpp,v 1.49 2008-02-16 22:25:13 geuzaine Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -542,6 +542,79 @@ SPoint2 GFace::parFromPoint(const SPoint3 &p) const
   return SPoint2(U,V);
 }
 
+bool GFace::buildRepresentationCross()
+{
+  if(geomType() != Plane){
+    // don't try again
+    cross.clear();
+    cross.push_back(SPoint3(0., 0., 0.));
+    return false;
+  }
+
+  std::list<GEdge*> ed = edges();
+  SBoundingBox3d bb;
+  for(std::list<GEdge*>::iterator it = ed.begin(); it != ed.end(); it++){
+    GEdge *ge = *it;
+    if(ge->geomType() == GEntity::DiscreteCurve || 
+       ge->geomType() == GEntity::BoundaryLayerCurve){
+      // don't try again
+      cross.clear();
+      cross.push_back(SPoint3(0., 0., 0.));
+      return false;
+    }
+    else{
+      Range<double> t_bounds = ge->parBounds(0);
+      GPoint p[3] = {ge->point(t_bounds.low()),
+		     ge->point(0.5 * (t_bounds.low() + t_bounds.high())),
+		     ge->point(t_bounds.high())};
+      for(int i = 0; i < 3; i++){
+	SPoint2 uv = parFromPoint(SPoint3(p[i].x(), p[i].y(), p[i].z()));
+	bb += SPoint3(uv.x(), uv.y(), 0.);
+      }
+    }
+  }
+  bb *= 1.1;
+  GPoint v0 = point(bb.min().x(), bb.min().y());
+  GPoint v1 = point(bb.max().x(), bb.min().y());
+  GPoint v2 = point(bb.max().x(), bb.max().y());
+  GPoint v3 = point(bb.min().x(), bb.max().y());
+  const int N = 100;
+  for(int dir = 0; dir < 2; dir++) {
+    int end_line = 0;
+    SPoint3 pt, pt_last_inside;
+    for(int i = 0; i < N; i++) {
+      double t = (double)i / (double)(N - 1);
+      double x, y, z;
+      if(!dir){
+	x = 0.5 * (t * (v0.x() + v1.x()) + (1. - t) * (v2.x() + v3.x()));
+	y = 0.5 * (t * (v0.y() + v1.y()) + (1. - t) * (v2.y() + v3.y()));
+	z = 0.5 * (t * (v0.z() + v1.z()) + (1. - t) * (v2.z() + v3.z()));
+      }
+      else{
+	x = 0.5 * (t * (v0.x() + v3.x()) + (1. - t) * (v2.x() + v1.x()));
+	y = 0.5 * (t * (v0.y() + v3.y()) + (1. - t) * (v2.y() + v1.y()));
+	z = 0.5 * (t * (v0.z() + v3.z()) + (1. - t) * (v2.z() + v1.z()));
+      }
+      pt.setPosition(x, y, z);
+      if(containsPoint(pt)){
+	pt_last_inside.setPosition(x, y, z);
+	if(!end_line) { cross.push_back(pt); end_line = 1; }
+      }
+      else {
+	if(end_line) { cross.push_back(pt_last_inside); end_line = 0; }
+      }
+    }
+    if(end_line) cross.push_back(pt_last_inside);
+  }
+  // if we couldn't determine a cross, add a dummy point so that
+  // we won't try again
+  if(!cross.size()){
+    cross.push_back(SPoint3(0., 0., 0.));
+    return false;
+  }
+  return true;
+}
+
 struct graphics_point{
   double xyz[3];
   SVector3 n;
diff --git a/Geo/GFace.h b/Geo/GFace.h
index d5cd90d7c9..e8ff468a15 100644
--- a/Geo/GFace.h
+++ b/Geo/GFace.h
@@ -136,6 +136,9 @@ class GFace : public GEntity
   // Returns a type-specific additional information string
   virtual std::string getAdditionalInfoString();
 
+  // Fills the crude representation cross
+  bool GFace::buildRepresentationCross();
+
   // Builds a STL triangulation and fills the vertex array
   // va_geom_triangles
   virtual bool buildSTLTriangulation();
diff --git a/Graphics/Geom.cpp b/Graphics/Geom.cpp
index 430a84fce3..4f89fe3b41 100644
--- a/Graphics/Geom.cpp
+++ b/Graphics/Geom.cpp
@@ -1,4 +1,4 @@
-// $Id: Geom.cpp,v 1.149 2008-02-05 23:16:44 geuzaine Exp $
+// $Id: Geom.cpp,v 1.150 2008-02-16 22:25:13 geuzaine Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -203,35 +203,78 @@ class drawGEdge {
 
 class drawGFace {
  private:
+  void _drawVertexArray(VertexArray *va, bool useNormalArray, int forceColor=0, 
+			unsigned int color=0)
+  {
+    if(!va) return;
+    glVertexPointer(3, GL_FLOAT, 0, va->getVertexArray());
+    glNormalPointer(GL_BYTE, 0, va->getNormalArray());
+    glColorPointer(4, GL_UNSIGNED_BYTE, 0, va->getColorArray());
+    glEnableClientState(GL_VERTEX_ARRAY);
+    if(useNormalArray){
+      glEnable(GL_LIGHTING);
+      glEnableClientState(GL_NORMAL_ARRAY);
+    }
+    else
+      glDisableClientState(GL_NORMAL_ARRAY);
+    if(forceColor){
+      glDisableClientState(GL_COLOR_ARRAY);
+      glColor4ubv((GLubyte *) & color);
+    }
+    else{
+      glEnableClientState(GL_COLOR_ARRAY);
+    }
+    if(CTX.polygon_offset) glEnable(GL_POLYGON_OFFSET_FILL);
+    if(CTX.geom.surface_type > 1)
+      glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+    else
+      glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+    glDrawArrays(GL_TRIANGLES, 0, va->getNumVertices());
+    glDisable(GL_POLYGON_OFFSET_FILL);
+    glDisable(GL_LIGHTING);
+    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+    glDisableClientState(GL_VERTEX_ARRAY);
+    glDisableClientState(GL_NORMAL_ARRAY);
+    glDisableClientState(GL_COLOR_ARRAY);
+  }
   void _drawParametricGFace(GFace *f)
   {
-    if(CTX.geom.surfaces && !f->va_geom_triangles) {
-      glEnable(GL_LINE_STIPPLE);
-      glLineStipple(1, 0x1F1F);
-      gl2psEnable(GL2PS_LINE_STIPPLE);
-      int N = 20;
-      Range<double> ubounds = f->parBounds(0);
-      Range<double> vbounds = f->parBounds(1);
-      const double uav = 0.5 * (ubounds.high() + ubounds.low());
-      const double vav = 0.5 * (vbounds.high() + vbounds.low());
-      const double ud = (ubounds.high() - ubounds.low());
-      const double vd = (vbounds.high() - vbounds.low());
-      glBegin(GL_LINE_STRIP);
-      for(int i = 0; i < N; i++) {
-	GPoint p = f->point(ubounds.low() + ud * (double)i / (double)(N - 1), vav);
-	glVertex3d(p.x(), p.y(), p.z());
+    if(CTX.geom.surfaces){
+      if(CTX.geom.surface_type > 0 && f->va_geom_triangles){
+	_drawVertexArray
+	  (f->va_geom_triangles, CTX.geom.light, 
+	   (f->geomType() == GEntity::ProjectionFace) ? true : f->getSelection(), 
+	   (f->geomType() == GEntity::ProjectionFace) ? CTX.color.geom.projection : 
+	   CTX.color.geom.selection);
       }
-      glEnd();
-      glBegin(GL_LINE_STRIP);
-      for(int i = 0; i < N; i++) {
-	GPoint p = f->point(uav, vbounds.low() + vd * (double)i / (double)(N - 1));
-	glVertex3d(p.x(), p.y(), p.z());
+      else{
+	glEnable(GL_LINE_STIPPLE);
+	glLineStipple(1, 0x1F1F);
+	gl2psEnable(GL2PS_LINE_STIPPLE);
+	int N = 20;
+	Range<double> ubounds = f->parBounds(0);
+	Range<double> vbounds = f->parBounds(1);
+	const double uav = 0.5 * (ubounds.high() + ubounds.low());
+	const double vav = 0.5 * (vbounds.high() + vbounds.low());
+	const double ud = (ubounds.high() - ubounds.low());
+	const double vd = (vbounds.high() - vbounds.low());
+	glBegin(GL_LINE_STRIP);
+	for(int i = 0; i < N; i++) {
+	  GPoint p = f->point(ubounds.low() + ud * (double)i / (double)(N - 1), vav);
+	  glVertex3d(p.x(), p.y(), p.z());
+	}
+	glEnd();
+	glBegin(GL_LINE_STRIP);
+	for(int i = 0; i < N; i++) {
+	  GPoint p = f->point(uav, vbounds.low() + vd * (double)i / (double)(N - 1));
+	  glVertex3d(p.x(), p.y(), p.z());
+	}
+	glEnd();
+	glDisable(GL_LINE_STIPPLE);
+	gl2psDisable(GL2PS_LINE_STIPPLE);
       }
-      glEnd();
-      glDisable(GL_LINE_STIPPLE);
-      gl2psDisable(GL2PS_LINE_STIPPLE);
     }
-    
+
     if(CTX.geom.surfaces_num) {
       GPoint p = f->point(0.5, 0.5);
       char Num[100];
@@ -256,88 +299,39 @@ class drawGFace {
   }
   void _drawPlaneGFace(GFace *f)
   {
-    // We create data here and the routine is not designed to be
-    // reentrant, so we must lock it to avoid race conditions when
-    // redraw events are fired in rapid succession
-    static bool busy = false;
-    if(!f->cross.size() && !busy) {
-      busy = true; 
-      std::list<GEdge*> edges = f->edges();
-      SBoundingBox3d bb;
-      for(std::list<GEdge*>::iterator it = edges.begin(); it != edges.end(); it++){
-	GEdge *ge = *it;
-	if(ge->geomType() == GEntity::DiscreteCurve || 
-	   ge->geomType() == GEntity::BoundaryLayerCurve){
-	  // don't try again
-	  f->cross.clear();
-	  f->cross.push_back(SPoint3(0., 0., 0.));
-	  busy = false;
-	  return;
-	}
-	else{
-	  Range<double> t_bounds = ge->parBounds(0);
-	  GPoint p[3] = {ge->point(t_bounds.low()),
-			 ge->point(0.5 * (t_bounds.low() + t_bounds.high())),
-			 ge->point(t_bounds.high())};
-	  for(int i = 0; i < 3; i++){
-	    SPoint2 uv = f->parFromPoint(SPoint3(p[i].x(), p[i].y(), p[i].z()));
-	    bb += SPoint3(uv.x(), uv.y(), 0.);
-	  }
-	}
-      }
-      bb *= 1.1;
-      GPoint v0 = f->point(bb.min().x(), bb.min().y());
-      GPoint v1 = f->point(bb.max().x(), bb.min().y());
-      GPoint v2 = f->point(bb.max().x(), bb.max().y());
-      GPoint v3 = f->point(bb.min().x(), bb.max().y());
-      const int N = 100;
-      for(int dir = 0; dir < 2; dir++) {
-	int end_line = 0;
-	SPoint3 pt, pt_last_inside;
-	for(int i = 0; i < N; i++) {
-	  double t = (double)i / (double)(N - 1);
-	  double x, y, z;
-	  if(!dir){
-	    x = 0.5 * (t * (v0.x() + v1.x()) + (1. - t) * (v2.x() + v3.x()));
-	    y = 0.5 * (t * (v0.y() + v1.y()) + (1. - t) * (v2.y() + v3.y()));
-	    z = 0.5 * (t * (v0.z() + v1.z()) + (1. - t) * (v2.z() + v3.z()));
-	  }
-	  else{
-	    x = 0.5 * (t * (v0.x() + v3.x()) + (1. - t) * (v2.x() + v1.x()));
-	    y = 0.5 * (t * (v0.y() + v3.y()) + (1. - t) * (v2.y() + v1.y()));
-	    z = 0.5 * (t * (v0.z() + v3.z()) + (1. - t) * (v2.z() + v1.z()));
-	  }
-	  pt.setPosition(x, y, z);
-	  if(f->containsPoint(pt)){
-	    pt_last_inside.setPosition(x, y, z);
-	    if(!end_line) { f->cross.push_back(pt); end_line = 1; }
-	  }
-	  else {
-	    if(end_line) { f->cross.push_back(pt_last_inside); end_line = 0; }
-	  }
-	}
-	if(end_line) f->cross.push_back(pt_last_inside);
+    if(!CTX.geom.surface_type || !f->va_geom_triangles ||
+       CTX.geom.surfaces_num || CTX.geom.normals){
+      // We create data here and the routine is not designed to be
+      // reentrant, so we must lock it to avoid race conditions when
+      // redraw events are fired in rapid succession
+      static bool busy = false;
+      if(!f->cross.size() && !busy) {
+	busy = true; 
+	f->buildRepresentationCross();
+	busy = false;
       }
-      // if we couldn't determine a cross, add a dummy point so that
-      // we won't try again
-      if(!f->cross.size()) f->cross.push_back(SPoint3(0., 0., 0.));
-      busy = false;
     }
 
-    if(f->cross.size() < 2) return;
-
-    if(CTX.geom.surfaces && !f->va_geom_triangles) {
-      glEnable(GL_LINE_STIPPLE);
-      glLineStipple(1, 0x1F1F);
-      gl2psEnable(GL2PS_LINE_STIPPLE);
-      glBegin(GL_LINES);
-      for(unsigned int i = 0; i < f->cross.size(); i++)
-	glVertex3d(f->cross[i].x(), f->cross[i].y(), f->cross[i].z());
-      glEnd();
-      glDisable(GL_LINE_STIPPLE);
-      gl2psDisable(GL2PS_LINE_STIPPLE);
+    if(CTX.geom.surfaces) {
+      if(CTX.geom.surface_type > 0 && f->va_geom_triangles){
+	_drawVertexArray(f->va_geom_triangles, CTX.geom.light, 
+			 f->getSelection(), CTX.color.geom.selection);
+      }
+      else{
+	glEnable(GL_LINE_STIPPLE);
+	glLineStipple(1, 0x1F1F);
+	gl2psEnable(GL2PS_LINE_STIPPLE);
+	glBegin(GL_LINES);
+	for(unsigned int i = 0; i < f->cross.size(); i++)
+	  glVertex3d(f->cross[i].x(), f->cross[i].y(), f->cross[i].z());
+	glEnd();
+	glDisable(GL_LINE_STIPPLE);
+	gl2psDisable(GL2PS_LINE_STIPPLE);
+      }
     }
 
+    if(f->cross.size() < 2) return;
+			  
     if(CTX.geom.surfaces_num) {
       char Num[100];
       sprintf(Num, "%d", f->tag());
@@ -362,40 +356,6 @@ class drawGFace {
 		  p.x(), p.y(), p.z(), n[0], n[1], n[2], CTX.geom.light);
     }
   }
-  void _drawVertexArray(VertexArray *va, bool useNormalArray, int forceColor=0, 
-			unsigned int color=0)
-  {
-    if(!va) return;
-    glVertexPointer(3, GL_FLOAT, 0, va->getVertexArray());
-    glNormalPointer(GL_BYTE, 0, va->getNormalArray());
-    glColorPointer(4, GL_UNSIGNED_BYTE, 0, va->getColorArray());
-    glEnableClientState(GL_VERTEX_ARRAY);
-    if(useNormalArray){
-      glEnable(GL_LIGHTING);
-      glEnableClientState(GL_NORMAL_ARRAY);
-    }
-    else
-      glDisableClientState(GL_NORMAL_ARRAY);
-    if(forceColor){
-      glDisableClientState(GL_COLOR_ARRAY);
-      glColor4ubv((GLubyte *) & color);
-    }
-    else{
-      glEnableClientState(GL_COLOR_ARRAY);
-    }
-    if(CTX.polygon_offset) glEnable(GL_POLYGON_OFFSET_FILL);
-    if(CTX.geom.surface_type > 0)
-      glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
-    else
-      glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
-    glDrawArrays(GL_TRIANGLES, 0, va->getNumVertices());
-    glDisable(GL_POLYGON_OFFSET_FILL);
-    glDisable(GL_LIGHTING);
-    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
-    glDisableClientState(GL_VERTEX_ARRAY);
-    glDisableClientState(GL_NORMAL_ARRAY);
-    glDisableClientState(GL_COLOR_ARRAY);
-  }
   
 public :
   void operator () (GFace *f)
@@ -421,13 +381,6 @@ public :
       glColor4ubv((GLubyte *) & CTX.color.geom.surface);
     }
 
-    if(CTX.geom.surfaces && f->va_geom_triangles)
-      _drawVertexArray
-	(f->va_geom_triangles, CTX.geom.light, 
-	 (f->geomType() == GEntity::ProjectionFace) ? true : f->getSelection(), 
-	 (f->geomType() == GEntity::ProjectionFace) ? CTX.color.geom.projection : 
-	 CTX.color.geom.selection);
-    
     if(f->geomType() == GEntity::Plane)
       _drawPlaneGFace(f);
     else
@@ -442,7 +395,6 @@ public :
   }
 };
 
-
 class drawGRegion {
  public :
   void operator () (GRegion *r)
-- 
GitLab