From bdb7d91b6a39603cf706a341137246e466b76cc2 Mon Sep 17 00:00:00 2001
From: Christophe Geuzaine <cgeuzaine@ulg.ac.be>
Date: Wed, 23 May 2001 07:29:42 +0000
Subject: [PATCH] Mesh quality histograms

---
 Common/Context.h      |  1 +
 Common/GetOptions.cpp |  8 +++--
 Common/Options.cpp    |  3 +-
 Fltk/Callbacks.cpp    |  6 +++-
 Fltk/Callbacks.h      |  1 +
 Fltk/GUI.cpp          | 17 +++++++++--
 Fltk/Main.cpp         |  4 ++-
 Graphics/Mesh.cpp     |  3 +-
 Mesh/3D_Mesh.cpp      | 11 ++++---
 Mesh/3D_Mesh.h        |  3 --
 Mesh/Generator.cpp    |  7 +++--
 Mesh/Mesh.h           | 14 +++++++--
 Mesh/MeshQuality.cpp  | 69 +++++++++++++++++++++++++++++++++----------
 Mesh/Read_Mesh.cpp    |  9 ++++--
 doc/VERSIONS          |  5 ++--
 15 files changed, 121 insertions(+), 40 deletions(-)

diff --git a/Common/Context.h b/Common/Context.h
index 01c1d2a39f..3c65ac514b 100644
--- a/Common/Context.h
+++ b/Common/Context.h
@@ -134,6 +134,7 @@ public :
     int hidden, shade;
     int format, nb_smoothing, algo, degree;
     int point_insertion, speed_max, min_circ_points, constrained_bgmesh;
+    int histogram;
     double normals, tangents, explode;
     int color_scheme, color_carousel ;
     int use_cut_plane;
diff --git a/Common/GetOptions.cpp b/Common/GetOptions.cpp
index 9450992f4c..b2afeb891f 100644
--- a/Common/GetOptions.cpp
+++ b/Common/GetOptions.cpp
@@ -1,4 +1,4 @@
-// $Id: GetOptions.cpp,v 1.22 2001-05-22 08:30:26 geuzaine Exp $
+// $Id: GetOptions.cpp,v 1.23 2001-05-23 07:29:42 geuzaine Exp $
 
 #include "Gmsh.h"
 #include "GmshUI.h"
@@ -33,7 +33,7 @@ void Print_Usage(char *name){
   Msg(DIRECT, "  -0                    parse input files, output flattened geometry, and exit");
   Msg(DIRECT, "Mesh options:");
   Msg(DIRECT, "  -1, -2, -3            perform batch 1D, 2D and 3D mesh generation");
-  Msg(DIRECT, "  -o file               specify output file name");
+  Msg(DIRECT, "  -o file               specify mesh output file name");
   Msg(DIRECT, "  -format msh|unv|gref  set output mesh format (default: msh)");
   Msg(DIRECT, "  -algo iso|aniso       select 2D mesh algorithm (default: iso)");
   Msg(DIRECT, "  -smooth int           set mesh smoothing (default: 0)");
@@ -44,6 +44,7 @@ void Print_Usage(char *name){
   Msg(DIRECT, "  -rand float           set random perturbation factor (default: 1.e-4)");
   Msg(DIRECT, "  -bgm file             load backround mesh from file");
   Msg(DIRECT, "  -constrain            constrain background mesh with characteristic lengths");
+  Msg(DIRECT, "  -histogram            print mesh quality histogram");
 #ifndef _BLACKBOX
   Msg(DIRECT, "  -interactive          display 2D mesh construction interactively");
   Msg(DIRECT, "Post-processing options:");
@@ -122,6 +123,9 @@ void Get_Options (int argc, char *argv[], int *nbfiles) {
       else if(!strcmp(argv[i]+1, "3")){ 
         CTX.batch = 3; i++;
       }
+      else if(!strcmp(argv[i]+1, "histogram")){ 
+        CTX.mesh.histogram = 1; i++;
+      }
       else if(!strcmp(argv[i]+1, "o")){ 
         i++;
         if(argv[i] != NULL) CTX.output_filename = argv[i++];
diff --git a/Common/Options.cpp b/Common/Options.cpp
index 13381fcffb..0966731896 100644
--- a/Common/Options.cpp
+++ b/Common/Options.cpp
@@ -1,4 +1,4 @@
-// $Id: Options.cpp,v 1.22 2001-05-22 08:30:26 geuzaine Exp $
+// $Id: Options.cpp,v 1.23 2001-05-23 07:29:42 geuzaine Exp $
 
 #include "Gmsh.h"
 #include "GmshUI.h"
@@ -92,6 +92,7 @@ void Init_Options(int num){
   CTX.mesh.draw = 1 ;  
   CTX.post.draw = 1 ;
   CTX.threads_lock = 0 ; //very primitive locking during mesh generation
+  CTX.mesh.histogram = 0 ;
 
   // For motif versions only:
   CTX.overlay = 1 ;
diff --git a/Fltk/Callbacks.cpp b/Fltk/Callbacks.cpp
index 27e9856193..02a9827321 100644
--- a/Fltk/Callbacks.cpp
+++ b/Fltk/Callbacks.cpp
@@ -1,4 +1,4 @@
-// $Id: Callbacks.cpp,v 1.58 2001-05-22 11:30:51 geuzaine Exp $
+// $Id: Callbacks.cpp,v 1.59 2001-05-23 07:29:42 geuzaine Exp $
 
 #include <sys/types.h>
 #include <signal.h>
@@ -422,6 +422,10 @@ void opt_statistics_cb(CALLBACK_ARGS) {
 void opt_statistics_update_cb(CALLBACK_ARGS) {
   WID->set_statistics();
 }
+void opt_statistics_histogram_cb(CALLBACK_ARGS) {
+  Print_Histogram(M.Histogram[(int)data]);
+  WID->create_message_window();
+}
 
 // Option Messages Menu
 
diff --git a/Fltk/Callbacks.h b/Fltk/Callbacks.h
index 27e093bb05..f9c77062cf 100644
--- a/Fltk/Callbacks.h
+++ b/Fltk/Callbacks.h
@@ -66,6 +66,7 @@ void opt_post_ok_cb(CALLBACK_ARGS) ;
 
 void opt_statistics_cb(CALLBACK_ARGS) ;
 void opt_statistics_update_cb(CALLBACK_ARGS) ;
+void opt_statistics_histogram_cb(CALLBACK_ARGS) ;
 
 // Option Message Menu
 
diff --git a/Fltk/GUI.cpp b/Fltk/GUI.cpp
index 2b1955a73c..a4587e53b3 100644
--- a/Fltk/GUI.cpp
+++ b/Fltk/GUI.cpp
@@ -1,4 +1,4 @@
-// $Id: GUI.cpp,v 1.78 2001-05-20 19:24:53 geuzaine Exp $
+// $Id: GUI.cpp,v 1.79 2001-05-23 07:29:42 geuzaine Exp $
 
 // To make the interface as visually consistent as possible, please:
 // - use the BH, BW, WB, IW values for button heights/widths, window borders, etc.
@@ -1455,7 +1455,7 @@ void GUI::create_statistics_window(){
   if(!init_statistics_window){
     init_statistics_window = 1 ;
 
-    int width = 22*CTX.fontsize;
+    int width = 24*CTX.fontsize;
     int height = 5*WB+16*BH ;
 
     stat_window = new Fl_Window(width,height);
@@ -1490,6 +1490,17 @@ void GUI::create_statistics_window(){
 	stat_value[15] = new Fl_Output(2*WB, 2*WB+12*BH, IW, BH, "Gamma factor");
 	stat_value[16] = new Fl_Output(2*WB, 2*WB+13*BH, IW, BH, "Eta factor");
 	stat_value[17] = new Fl_Output(2*WB, 2*WB+14*BH, IW, BH, "Rho factor");
+
+	Fl_Button* b0 = new Fl_Button(width-BB-2*WB, 2*WB+12*BH, BB, BH, "List");
+	b0->labelsize(CTX.fontsize);
+	b0->callback(opt_statistics_histogram_cb, (void*)0);
+	Fl_Button* b1 = new Fl_Button(width-BB-2*WB, 2*WB+13*BH, BB, BH, "List");
+	b1->labelsize(CTX.fontsize);
+	b1->callback(opt_statistics_histogram_cb, (void*)1);
+	Fl_Button* b2 = new Fl_Button(width-BB-2*WB, 2*WB+14*BH, BB, BH, "List");
+	b2->labelsize(CTX.fontsize);
+	b2->callback(opt_statistics_histogram_cb, (void*)2);
+
 	o->end();
       }
       { 
@@ -1515,7 +1526,7 @@ void GUI::create_statistics_window(){
     }
 
     { 
-      Fl_Return_Button* o = new Fl_Return_Button(width-2*BB-BB/4-2*WB, height-BH-WB, BB+BB/4, BH, "Update");
+      Fl_Button* o = new Fl_Button(width-2*BB-2*WB, height-BH-WB, BB, BH, "Update");
       o->labelsize(CTX.fontsize);
       o->callback(opt_statistics_update_cb);
     }
diff --git a/Fltk/Main.cpp b/Fltk/Main.cpp
index 1947f019b3..fa1d7be34a 100644
--- a/Fltk/Main.cpp
+++ b/Fltk/Main.cpp
@@ -1,4 +1,4 @@
-// $Id: Main.cpp,v 1.26 2001-05-22 08:30:26 geuzaine Exp $
+// $Id: Main.cpp,v 1.27 2001-05-23 07:29:42 geuzaine Exp $
 
 #include <signal.h>
 
@@ -91,6 +91,8 @@ int main(int argc, char *argv[]){
       }
       else
         Print_Geo(THEM, CTX.output_filename);
+      if(CTX.mesh.histogram)
+	Print_Histogram(THEM->Histogram[0]);
       exit(1);
     }    
   }
diff --git a/Graphics/Mesh.cpp b/Graphics/Mesh.cpp
index b5f766a933..5f961be92d 100644
--- a/Graphics/Mesh.cpp
+++ b/Graphics/Mesh.cpp
@@ -1,4 +1,4 @@
-// $Id: Mesh.cpp,v 1.26 2001-05-21 20:19:08 geuzaine Exp $
+// $Id: Mesh.cpp,v 1.27 2001-05-23 07:29:42 geuzaine Exp $
 
 #include "Gmsh.h"
 #include "GmshUI.h"
@@ -212,6 +212,7 @@ void Draw_Simplex_Volume (void *a, void *b){
     fulldraw = 1;
   }
 
+
   double Xc = .25 * ((*s)->V[0]->Pos.X + (*s)->V[1]->Pos.X + 
                      (*s)->V[2]->Pos.X + (*s)->V[3]->Pos.X);
   double Yc = .25 * ((*s)->V[0]->Pos.Y + (*s)->V[1]->Pos.Y + 
diff --git a/Mesh/3D_Mesh.cpp b/Mesh/3D_Mesh.cpp
index 6e82ff4e7a..46a58fedc7 100644
--- a/Mesh/3D_Mesh.cpp
+++ b/Mesh/3D_Mesh.cpp
@@ -1,4 +1,4 @@
-// $Id: 3D_Mesh.cpp,v 1.17 2001-05-20 19:24:53 geuzaine Exp $
+// $Id: 3D_Mesh.cpp,v 1.18 2001-05-23 07:29:42 geuzaine Exp $
 
 /*
  
@@ -870,7 +870,10 @@ void Maillage_Volume (void *data, void *dum){
   THEM->Statistics[10] += Tree_Nbr(v->Hexahedra);
   THEM->Statistics[11] += Tree_Nbr(v->Prisms);
 
-  Gamma_Maillage (v, &THEM->Statistics[17], &THEM->Statistics[18], &THEM->Statistics[19]);
-  Eta_Maillage (v, &THEM->Statistics[20], &THEM->Statistics[21], &THEM->Statistics[22]);
-  R_Maillage (v, &THEM->Statistics[23], &THEM->Statistics[24], &THEM->Statistics[25]);
+  if(v->Typ == 99999){
+    Gamma_Maillage (THEM, &THEM->Statistics[17], &THEM->Statistics[18], &THEM->Statistics[19]);
+    Eta_Maillage (THEM, &THEM->Statistics[20], &THEM->Statistics[21], &THEM->Statistics[22]);
+    R_Maillage (THEM, &THEM->Statistics[23], &THEM->Statistics[24], &THEM->Statistics[25]);
+  }
+
 }
diff --git a/Mesh/3D_Mesh.h b/Mesh/3D_Mesh.h
index 48c20ce139..2b0d87bd67 100644
--- a/Mesh/3D_Mesh.h
+++ b/Mesh/3D_Mesh.h
@@ -4,9 +4,6 @@
 Brick LaBrique (Grid_T * pGrid, double X, double Y, double Z);
 void AddSimplexInGrid (Mesh * m, Simplex * s, int boule_boite);
 int Coherence (Volume * v, Mesh * m);
-void Gamma_Maillage (Volume * v, double *gamma, double *gammamax, double *gammamin);
-void Eta_Maillage (Volume * v, double *gamma, double *gammamax, double *gammamin);
-void R_Maillage (Volume * v, double *gamma, double *gammamax, double *gammamin);
 int Pt_In_Volume (double X, double Y, double Z, Mesh * m,
                   double *l, double tol);
 void findminmax (void *a, void *b);
diff --git a/Mesh/Generator.cpp b/Mesh/Generator.cpp
index 3965383be8..8df21722e2 100644
--- a/Mesh/Generator.cpp
+++ b/Mesh/Generator.cpp
@@ -1,4 +1,4 @@
-// $Id: Generator.cpp,v 1.15 2001-04-26 17:58:00 remacle Exp $
+// $Id: Generator.cpp,v 1.16 2001-05-23 07:29:42 geuzaine Exp $
 
 #include "Gmsh.h"
 #include "Const.h"
@@ -42,7 +42,10 @@ void ApplyLcFactor(Mesh *M){
 }
 
 void Maillage_Dimension_0 (Mesh * M){
-  for (int i = 0; i < 50; i++) M->Statistics[i] = 0.0;
+  for (int i = 0; i < 50; i++)
+    M->Statistics[i] = 0.0;
+  for (int i = 0; i < NB_HISTOGRAM; i++)
+    M->Histogram[0][i] = M->Histogram[1][i] = M->Histogram[2][i] = 0;
   // This is the default type of BGM (lc associated with 
   // points of the geometry). It can be changed to
   // - ONFILE by loading a view containing a bgmesh
diff --git a/Mesh/Mesh.h b/Mesh/Mesh.h
index e0b9a30851..a93304aed3 100644
--- a/Mesh/Mesh.h
+++ b/Mesh/Mesh.h
@@ -52,6 +52,8 @@
 #define BOULE 1
 #define BOITE 2
 
+#define NB_HISTOGRAM 100
+
 typedef struct _POINT PointRecord, *PointPeek;
 typedef struct _CONTOUR ContourRecord, *ContourPeek;
 typedef struct _DOC DocRecord, *DocPeek;
@@ -376,12 +378,13 @@ struct _Mesh{
   Tree_T *Volumes;              /* Volumes                               */
   Tree_T *SurfaceLoops;         /* Surface Loops                         */
   Tree_T *EdgeLoops;            /* Edge Loops                            */
-  List_T *PhysicalGroups;       /* Physical Groups                      */
+  List_T *PhysicalGroups;       /* Physical Groups                       */
   Tree_T *VertexEdges;          /* 2nd order Vertices on edges           */
   Grid_T Grid;                  /* Grille de recherches rapides          */
   LcField BGM;                  /* Background mesh                       */
-  double Statistics[50];        /* Statistiques pour le maillage         */
-  GMSHMetric *Metric;           /* Metrique */
+  double Statistics[50];        /* Mesh statistics                       */
+  int Histogram[3][NB_HISTOGRAM]; /* Quality histograms                 */
+  GMSHMetric *Metric;           /* Metric                                */
   MeshParameters MeshParams;
 };
 
@@ -448,4 +451,9 @@ void ActionLissSurf (void *data, void *dummy);
 void Recombine (Tree_T *TreeAllVert, Tree_T *TreeAllElg, double a);
 void ApplyLcFactor(Mesh *M);
 
+void Gamma_Maillage (Mesh * m, double *gamma, double *gammamax, double *gammamin);
+void Eta_Maillage (Mesh * m, double *gamma, double *gammamax, double *gammamin);
+void R_Maillage (Mesh * m, double *gamma, double *gammamax, double *gammamin);
+void Print_Histogram(int *h);
+
 #endif
diff --git a/Mesh/MeshQuality.cpp b/Mesh/MeshQuality.cpp
index e6725df2af..ae6c7dcf62 100644
--- a/Mesh/MeshQuality.cpp
+++ b/Mesh/MeshQuality.cpp
@@ -1,4 +1,4 @@
-// $Id: MeshQuality.cpp,v 1.3 2001-01-08 08:05:45 geuzaine Exp $
+// $Id: MeshQuality.cpp,v 1.4 2001-05-23 07:29:42 geuzaine Exp $
 
 #include "Gmsh.h"
 #include "Const.h"
@@ -14,8 +14,8 @@
              sqrt(6)    max(lij)
  */
 
-double GAMMAMAX, GAMMAMIN, GAMMA;
-int NbCalcGamma;
+static double GAMMAMAX, GAMMAMIN, GAMMA;
+static int NbCalcGamma, *Histogram;
 
 void CalculateGamma (void *a, void *b){
   Simplex *s = *(Simplex **) a;
@@ -24,6 +24,9 @@ void CalculateGamma (void *a, void *b){
   GAMMAMAX = DMAX (GAMMAMAX, gamma);
   GAMMA += gamma;
   GAMMAMIN = DMIN (GAMMAMIN, gamma);
+  for(int i=0; i<NB_HISTOGRAM; i++)
+    if(gamma > i/(double)NB_HISTOGRAM && gamma < (i+1)/(double)NB_HISTOGRAM)
+      Histogram[i]++;
 }
 
 void CalculateEta (void *a, void *b){
@@ -33,6 +36,9 @@ void CalculateEta (void *a, void *b){
   GAMMAMAX = DMAX (GAMMAMAX, gamma);
   GAMMA += gamma;
   GAMMAMIN = DMIN (GAMMAMIN, gamma);
+  for(int i=0; i<NB_HISTOGRAM; i++)
+    if(gamma > i/(double)NB_HISTOGRAM && gamma < (i+1)/(double)NB_HISTOGRAM)
+      Histogram[i]++;
 }
 
 void CalculateR (void *a, void *b){
@@ -42,43 +48,76 @@ void CalculateR (void *a, void *b){
   GAMMAMAX = DMAX (GAMMAMAX, gamma);
   GAMMA += gamma;
   GAMMAMIN = DMIN (GAMMAMIN, gamma);
+  for(int i=0; i<NB_HISTOGRAM; i++)
+    if(gamma > i/(double)NB_HISTOGRAM && gamma < (i+1)/(double)NB_HISTOGRAM)
+      Histogram[i]++;
 }
 
-void Gamma_Maillage (Volume * v, double *gamma, double *gammamax, double *gammamin){
+
+
+static void g(void *a, void *b){
+  Volume *v = *(Volume**)a;
+  Tree_Action (v->Simplexes, CalculateGamma);  
+  Msg(DEBUG, "Gamma computed in volume %d (%d values)", v->Num, NbCalcGamma);
+}
+
+void Gamma_Maillage (Mesh * m, double *gamma, double *gammamax, double *gammamin){
   GAMMA = 0.0;
   GAMMAMAX = 0.0;
   GAMMAMIN = 1.0;
   NbCalcGamma = 0;
-  Tree_Action (v->Simplexes, CalculateGamma);
-  if (!NbCalcGamma)
-    NbCalcGamma = 1;
+  Histogram = m->Histogram[0];
+  for(int i=0; i<NB_HISTOGRAM; i++) Histogram[i] = 0;
+  Tree_Action (m->Volumes, g);
+  if(!NbCalcGamma) NbCalcGamma = 1;
   *gamma = GAMMA / (double) NbCalcGamma;
   *gammamax = GAMMAMAX;
   *gammamin = GAMMAMIN;
 }
 
-void Eta_Maillage (Volume * v, double *gamma, double *gammamax, double *gammamin){
+static void e(void *a, void *b){
+  Volume *v = *(Volume**)a;
+  Tree_Action (v->Simplexes, CalculateEta);  
+  Msg(DEBUG, "Eta computed in volume %d (%d values)", v->Num, NbCalcGamma);
+}
+
+void Eta_Maillage (Mesh * m, double *gamma, double *gammamax, double *gammamin){
   GAMMA = 0.0;
   GAMMAMAX = 0.0;
   GAMMAMIN = 1.0;
   NbCalcGamma = 0;
-  Tree_Action (v->Simplexes, CalculateEta);
-  if (!NbCalcGamma)
-    NbCalcGamma = 1;
+  Histogram = m->Histogram[1];
+  for(int i=0; i<NB_HISTOGRAM; i++) Histogram[i] = 0;
+  Tree_Action (m->Volumes, e);
+  if(!NbCalcGamma) NbCalcGamma = 1;
   *gamma = GAMMA / (double) NbCalcGamma;
   *gammamax = GAMMAMAX;
   *gammamin = GAMMAMIN;
 }
 
-void R_Maillage (Volume * v, double *gamma, double *gammamax, double *gammamin){
+static void r(void *a, void *b){
+  Volume *v = *(Volume**)a;
+  Tree_Action (v->Simplexes, CalculateR);  
+  Msg(DEBUG, "Rho computed in volume %d (%d values)", v->Num, NbCalcGamma);
+}
+
+void R_Maillage (Mesh * m, double *gamma, double *gammamax, double *gammamin){
   GAMMA = 0.0;
   GAMMAMAX = 0.0;
   GAMMAMIN = 1.0;
   NbCalcGamma = 0;
-  Tree_Action (v->Simplexes, CalculateR);
-  if (!NbCalcGamma)
-    NbCalcGamma = 1;
+  Histogram = m->Histogram[2];
+  for(int i=0; i<NB_HISTOGRAM; i++) Histogram[i] = 0;
+  Tree_Action (m->Volumes, r);
+  if(!NbCalcGamma) NbCalcGamma = 1;
   *gamma = GAMMA / (double) NbCalcGamma;
   *gammamax = GAMMAMAX;
   *gammamin = GAMMAMIN;
 }
+
+
+void Print_Histogram(int *h){
+  for(int i=0;i<NB_HISTOGRAM;i++)
+    Msg(DIRECT, "%g %d", (i+1)/(double)NB_HISTOGRAM, h[i]);
+}
+
diff --git a/Mesh/Read_Mesh.cpp b/Mesh/Read_Mesh.cpp
index 069eda40c0..204075cf2e 100644
--- a/Mesh/Read_Mesh.cpp
+++ b/Mesh/Read_Mesh.cpp
@@ -1,8 +1,9 @@
-// $Id: Read_Mesh.cpp,v 1.13 2001-05-20 19:24:53 geuzaine Exp $
+// $Id: Read_Mesh.cpp,v 1.14 2001-05-23 07:29:42 geuzaine Exp $
 
 #include "Gmsh.h"
 #include "Geo.h"
 #include "Mesh.h"
+#include "3D_Mesh.h"
 #include "Create.h"
 #include "MinMax.h"
 
@@ -204,8 +205,12 @@ void Read_Mesh_MSH (Mesh *M, FILE *File_GEO){
     
   }   
 
-  if(Tree_Nbr(M->Volumes))
+  if(Tree_Nbr(M->Volumes)){
     M->status = 3 ;
+    Gamma_Maillage(M, &M->Statistics[17], &M->Statistics[18], &M->Statistics[19]);
+    Eta_Maillage(M, &M->Statistics[20], &M->Statistics[21], &M->Statistics[22]);
+    R_Maillage(M, &M->Statistics[23], &M->Statistics[24], &M->Statistics[25]);
+  }
   else if(Tree_Nbr(M->Surfaces))
     M->status = 2 ;
   else if(Tree_Nbr(M->Curves))
diff --git a/doc/VERSIONS b/doc/VERSIONS
index 803e879b70..f55c75c836 100644
--- a/doc/VERSIONS
+++ b/doc/VERSIONS
@@ -1,8 +1,9 @@
-$Id: VERSIONS,v 1.17 2001-05-20 19:24:53 geuzaine Exp $
+$Id: VERSIONS,v 1.18 2001-05-23 07:29:42 geuzaine Exp $
 
 New in 1.20: Various bug fixes (Includes & Functions, solver
 command...) and small enhancements (menu reorganization, constrained
-background mesh, mesh visibility options, geometry edition, ...)
+background mesh, mesh visibility options, geometry edition, quality
+histograms...)
 
 New in 1.19: Fixed seg. fault for scalar simplex post-processing; new
 Solver menu; interface for GetDP solver through sockets; fixed
-- 
GitLab