From 9905ea58a2823375ebcc5447207ac70a32e7242d Mon Sep 17 00:00:00 2001
From: Christophe Geuzaine <cgeuzaine@ulg.ac.be>
Date: Tue, 27 Apr 2004 00:11:55 +0000
Subject: [PATCH] Fixed orientation of polygons produced by CutTriangle2D so
 that we can use a TWO_SIDE light model everywhere. This also fixes the ugly
 "checkboard patterns" when using custom scales on continuous maps.

---
 Graphics/Draw.cpp        | 15 +++++---------
 Graphics/Iso.cpp         | 42 +++++++++++++++++++++++++++++++---------
 Graphics/Post.cpp        | 11 +----------
 Graphics/PostElement.cpp | 32 +++++++++++++++---------------
 Graphics/Scale.cpp       |  7 +------
 5 files changed, 56 insertions(+), 51 deletions(-)

diff --git a/Graphics/Draw.cpp b/Graphics/Draw.cpp
index 448010b313..0a0d15c42a 100644
--- a/Graphics/Draw.cpp
+++ b/Graphics/Draw.cpp
@@ -1,4 +1,4 @@
-// $Id: Draw.cpp,v 1.48 2004-03-30 18:17:06 geuzaine Exp $
+// $Id: Draw.cpp,v 1.49 2004-04-27 00:11:55 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -45,15 +45,12 @@ void Draw3d(void)
 #endif
   }
   glPolygonOffset(1.0, 1.0);
-
-  for(int i = 0; i < 6; i++)
-    if(CTX.clip[i])
-      glEnable((GLenum) (GL_CLIP_PLANE0 + i));
-
-  glShadeModel(GL_SMOOTH);
   glDepthFunc(GL_LESS);
   glEnable(GL_DEPTH_TEST);
   glDisable(GL_CULL_FACE);
+  for(int i = 0; i < 6; i++)
+    if(CTX.clip[i])
+      glEnable((GLenum) (GL_CLIP_PLANE0 + i));
 
   glPushMatrix();
   Draw_Mesh(&M);
@@ -63,9 +60,6 @@ void Draw3d(void)
 void Draw2d(void)
 {
   glDisable(GL_DEPTH_TEST);
-  glDisable(GL_LIGHTING);
-  glShadeModel(GL_FLAT);
-
   for(int i = 0; i < 6; i++)
     glDisable((GLenum) (GL_CLIP_PLANE0 + i));
 
@@ -175,6 +169,7 @@ void InitRenderModel(void)
   glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
   glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 40.);
   glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
+  glShadeModel(GL_SMOOTH);
   // let's add some shininess to all these automatically created materials
   specular[0] = CTX.shine;
   specular[1] = CTX.shine;
diff --git a/Graphics/Iso.cpp b/Graphics/Iso.cpp
index 230eb3bff3..21a307b765 100644
--- a/Graphics/Iso.cpp
+++ b/Graphics/Iso.cpp
@@ -1,4 +1,4 @@
-// $Id: Iso.cpp,v 1.21 2004-04-26 19:54:16 geuzaine Exp $
+// $Id: Iso.cpp,v 1.22 2004-04-27 00:11:55 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -51,15 +51,14 @@ void CutTriangle1D(double *X, double *Y, double *Z, double *Val,
 
 }
 
-// Contour computation for triangles. FIXME: the orientation of the
-// newly created polygons is wrong.
+// Contour computation for triangles
 
 void CutTriangle2D(double *X, double *Y, double *Z, double *Val,
                    double V1, double V2, double *Xp2, double *Yp2,
                    double *Zp2, int *Np2, double *Vp2)
 {
   int i, io[3], j, iot, Np, Fl;
-  double Xp[5], Yp[5], Zp[5], Vp[5];
+  double Xp[10], Yp[10], Zp[10], Vp[10];
 
   *Np2 = 0;
 
@@ -170,8 +169,8 @@ void CutTriangle2D(double *X, double *Y, double *Z, double *Val,
   *Np2 = 1;
 
   for(i = 1; i < Np; i++) {
-    if((Xp[i] != Xp2[(*Np2) - 1]) || (Yp[i] != Yp2[(*Np2) - 1])
-       || (Zp[i] != Zp2[(*Np2) - 1])) {
+    if((Xp[i] != Xp2[(*Np2) - 1]) || (Yp[i] != Yp2[(*Np2) - 1]) || 
+       (Zp[i] != Zp2[(*Np2) - 1])) {
       Vp2[*Np2] = Vp[i];
       Xp2[*Np2] = Xp[i];
       Yp2[*Np2] = Yp[i];
@@ -180,11 +179,36 @@ void CutTriangle2D(double *X, double *Y, double *Z, double *Val,
     }
   }
 
-  if(Xp2[0] == Xp2[(*Np2) - 1] && Yp2[0] == Yp2[(*Np2) - 1]
-     && Zp2[0] == Zp2[(*Np2) - 1]) {
+  if(Xp2[0] == Xp2[(*Np2) - 1] && Yp2[0] == Yp2[(*Np2) - 1] && 
+     Zp2[0] == Zp2[(*Np2) - 1]) {
     (*Np2)--;
   }
 
+  // check and fix orientation
+  double in1[3] = { X[1]-X[0], Y[1]-Y[0], Z[1]-Z[0]};
+  double in2[3] = { X[2]-X[0], Y[2]-Y[0], Z[2]-Z[0]};
+  double inn[3];
+  prodve(in1, in2, inn);
+  double out1[3] = { Xp2[1]-Xp2[0], Yp2[1]-Yp2[0], Zp2[1]-Zp2[0]};
+  double out2[3] = { Xp2[2]-Xp2[0], Yp2[2]-Yp2[0], Zp2[2]-Zp2[0]};
+  double outn[3];
+  prodve(out1, out2, outn);
+  double res;
+  prosca(inn, outn, &res);
+  if(res < 0){
+    for(i = 0; i < *Np2; i++){
+      Vp[i] = Vp2[*Np2-i-1];
+      Xp[i] = Xp2[*Np2-i-1];
+      Yp[i] = Yp2[*Np2-i-1];
+      Zp[i] = Zp2[*Np2-i-1];
+    }
+    for(i = 0; i < *Np2; i++){
+      Vp2[i] = Vp[i];
+      Xp2[i] = Xp[i];
+      Yp2[i] = Yp[i];
+      Zp2[i] = Zp[i];
+    }
+  }
 }
 
 // Iso for lines
@@ -314,7 +338,7 @@ void EnhanceSimplexPolygon(Post_View * View, int nb,    // nb of points in polyg
   double gr[3];
   double n[3], xx;
   prodve(v1, v2, n);
-  //norme(n);  not necessary since GL_NORMALIZE is enabled
+  norme(n);
   gradSimplex(X, Y, Z, Val, gr);
   prosca(gr, n, &xx);
 
diff --git a/Graphics/Post.cpp b/Graphics/Post.cpp
index 258477364e..11536af24b 100644
--- a/Graphics/Post.cpp
+++ b/Graphics/Post.cpp
@@ -1,4 +1,4 @@
-// $Id: Post.cpp,v 1.59 2004-04-26 19:56:45 geuzaine Exp $
+// $Id: Post.cpp,v 1.60 2004-04-27 00:11:55 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -456,15 +456,6 @@ void Draw_Post(void)
         glLineWidth(v->LineWidth);
         gl2psLineWidth(v->LineWidth * CTX.print.eps_line_width_factor);
 
-        // force this
-        if(v->IntervalsType == DRAW_POST_CONTINUOUS) {
-          glShadeModel(GL_SMOOTH);
-          glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
-        }
-        else {  // there is a bug in CutTriangle2D!! See Iso.cpp
-          glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
-        }
-
         switch (v->RangeType) {
         case DRAW_POST_RANGE_DEFAULT:
           ValMin = v->Min;
diff --git a/Graphics/PostElement.cpp b/Graphics/PostElement.cpp
index a119f1778f..7d9a0b53ca 100644
--- a/Graphics/PostElement.cpp
+++ b/Graphics/PostElement.cpp
@@ -1,4 +1,4 @@
-// $Id: PostElement.cpp,v 1.27 2004-04-26 19:54:16 geuzaine Exp $
+// $Id: PostElement.cpp,v 1.28 2004-04-27 00:11:55 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -23,12 +23,6 @@
 //   Laurent Stainier
 //   Jean-Luc Flejou
 
-// OK, I understand why the Cut2D stuff does not work correctly with a
-// TWO_FACE light: the normal has too be coherent with the vertex
-// ordering of the polygon. Doing i=nb-1; i>=0; i-- works when the
-// classic order does not. So we really have to check the ordering of
-// the output of cut2d...
-
 #include "Gmsh.h"
 #include "GmshUI.h"
 #include "Geo.h"
@@ -424,10 +418,9 @@ void Draw_ScalarTriangle(Post_View * View, int preproNormals,
           norms[3 * i] = nn[0];
           norms[3 * i + 1] = nn[1];
           norms[3 * i + 2] = nn[2];
-          if(!View->
-             get_normal(X[i] + Raise[0][i], Y[i] + Raise[1][i],
-                        Z[i] + Raise[2][i], norms[3 * i], norms[3 * i + 1],
-                        norms[3 * i + 2])) {
+          if(!View->get_normal(X[i] + Raise[0][i], Y[i] + Raise[1][i],
+			       Z[i] + Raise[2][i], norms[3 * i], norms[3 * i + 1],
+			       norms[3 * i + 2])) {
             //don't print this (unless we fix draw_vector_triangle with displacement)
             //Msg(WARNING, "Oups, did not find smoothed normal");
           }
@@ -468,13 +461,12 @@ void Draw_ScalarTriangle(Post_View * View, int preproNormals,
   }
   else {
 
-    if(View->Light) glEnable(GL_LIGHTING);
-    glEnable(GL_POLYGON_OFFSET_FILL);
-
     if(View->IntervalsType == DRAW_POST_CONTINUOUS) {
       if(Val[0] >= ValMin && Val[0] <= ValMax &&
          Val[1] >= ValMin && Val[1] <= ValMax &&
          Val[2] >= ValMin && Val[2] <= ValMax) {
+	if(View->Light) glEnable(GL_LIGHTING);
+	glEnable(GL_POLYGON_OFFSET_FILL);
         glBegin(GL_TRIANGLES);
         PaletteContinuous(View, ValMin, ValMax, Val[0]);
         glNormal3dv(&norms[0]);
@@ -486,10 +478,14 @@ void Draw_ScalarTriangle(Post_View * View, int preproNormals,
         glNormal3dv(&norms[6]);
         glVertex3d(X[2] + Raise[0][2], Y[2] + Raise[1][2], Z[2] + Raise[2][2]);
         glEnd();
+	glDisable(GL_POLYGON_OFFSET_FILL);
+	glDisable(GL_LIGHTING);
       }
       else {
         CutTriangle2D(X, Y, Z, Val, ValMin, ValMax, Xp, Yp, Zp, &nb, value);
         if(nb >= 3) {
+	  if(View->Light) glEnable(GL_LIGHTING);
+	  glEnable(GL_POLYGON_OFFSET_FILL);
           glBegin(GL_POLYGON);
           for(int i = 0; i < nb; i++) {
             PaletteContinuous(View, ValMin, ValMax, value[i]);
@@ -498,6 +494,8 @@ void Draw_ScalarTriangle(Post_View * View, int preproNormals,
 		       Zp[i] + View->Raise[2] * value[i]);
           }
           glEnd();
+	  glDisable(GL_POLYGON_OFFSET_FILL);
+	  glDisable(GL_LIGHTING);
         }
       }
     }
@@ -510,12 +508,16 @@ void Draw_ScalarTriangle(Post_View * View, int preproNormals,
                         View->GVFI(ValMin, ValMax, View->NbIso + 1, k + 1),
                         Xp, Yp, Zp, &nb, value);
           if(nb >= 3) {
+	    if(View->Light) glEnable(GL_LIGHTING);
+	    glEnable(GL_POLYGON_OFFSET_FILL);
             glBegin(GL_POLYGON);
             for(int i = 0; i < nb; i++)
               glVertex3d(Xp[i] + View->Raise[0] * value[i],
 			 Yp[i] + View->Raise[1] * value[i], 
 			 Zp[i] + View->Raise[2] * value[i]);
             glEnd();
+	    glDisable(GL_POLYGON_OFFSET_FILL);
+	    glDisable(GL_LIGHTING);
           }
         }
         else {
@@ -531,8 +533,6 @@ void Draw_ScalarTriangle(Post_View * View, int preproNormals,
       }
     }
     
-    glDisable(GL_POLYGON_OFFSET_FILL);
-    glDisable(GL_LIGHTING);
   }
 }
 
diff --git a/Graphics/Scale.cpp b/Graphics/Scale.cpp
index b3e35a9672..27fc30acb0 100644
--- a/Graphics/Scale.cpp
+++ b/Graphics/Scale.cpp
@@ -1,4 +1,4 @@
-// $Id: Scale.cpp,v 1.41 2004-04-20 19:15:14 geuzaine Exp $
+// $Id: Scale.cpp,v 1.42 2004-04-27 00:11:55 geuzaine Exp $
 //
 // Copyright (C) 1997-2004 C. Geuzaine, J.-F. Remacle
 //
@@ -68,11 +68,6 @@ void draw_scale(Post_View * v,
     glEnd();
   }
 
-  if(v->IntervalsType == DRAW_POST_CONTINUOUS)
-    glShadeModel(GL_SMOOTH);
-  else
-    glShadeModel(GL_FLAT);
-
   switch(v->RangeType){
   case DRAW_POST_RANGE_CUSTOM:
     ValMin = v->CustomMin;
-- 
GitLab