From 30998d8aa1254f2d2228851ea5469074933ecdb4 Mon Sep 17 00:00:00 2001 From: Gengis Date: Tue, 15 Apr 2025 18:30:03 +0200 Subject: [PATCH 1/7] Adding the tetra-metrics functionality, we compute the quality and edge lengths of a tetrahedron and we display it in the terminal and in the rendering window. --- src/compil.date | 2 +- src/geometry.c | 1 + src/grafic.h | 8 +++++ src/medit.h | 2 +- src/mesh.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++ src/mesh.h | 11 +++++++ src/mouse.c | 43 +++++++++++++++++++++---- src/picking.c | 19 ++++++++++- src/scene.c | 67 +++++++++++++++++++++++++++++++++++++- src/sproto.h | 5 +++ 10 files changed, 234 insertions(+), 10 deletions(-) diff --git a/src/compil.date b/src/compil.date index 1ca0c76..e6fc0f1 100644 --- a/src/compil.date +++ b/src/compil.date @@ -1 +1 @@ -#define COMPIL "2021-05-20 07:58:25" \ No newline at end of file +#define COMPIL "2025-04-12 19:08:57" \ No newline at end of file diff --git a/src/geometry.c b/src/geometry.c index 9cc3f2e..8025ff4 100644 --- a/src/geometry.c +++ b/src/geometry.c @@ -1,6 +1,7 @@ #include "medit.h" #include "extern.h" #include "sproto.h" +#include "mesh.h" extern int getIso(pScene sc,double norm,double *hsv); diff --git a/src/grafic.h b/src/grafic.h index b542c7f..407a2bb 100644 --- a/src/grafic.h +++ b/src/grafic.h @@ -1,6 +1,8 @@ #ifndef _GRAFIC_H #define _GRAFIC_H +#include "mesh.h" + #define MAX_LIST 4 #define MAXISO 5 @@ -232,6 +234,12 @@ typedef struct scene { ubyte type; ubyte isotyp; ubyte picked; + + /* Ajout des champs pour le mode qualité des tétraèdres */ + TetraMetrics currentTetraMetrics; // Store the metrics of the selected tetrahedron + ubyte displayTetraMetrics; // Flag activating/deactivating the display of the + // tetrahedron metrics + } Scene; typedef Scene * pScene; diff --git a/src/medit.h b/src/medit.h index 3f1fe86..3f1bd75 100644 --- a/src/medit.h +++ b/src/medit.h @@ -88,4 +88,4 @@ typedef Canvas * pCanvas; -#endif \ No newline at end of file +#endif diff --git a/src/mesh.c b/src/mesh.c index 2900c6a..eca0039 100644 --- a/src/mesh.c +++ b/src/mesh.c @@ -1,6 +1,7 @@ #include "medit.h" #include "extern.h" #include "sproto.h" +#include "mesh.h" #define FLOAT_MAX 1.e20 ubyte dosurf; @@ -475,3 +476,88 @@ int meshUpdate(pScene sc,pMesh mesh) { return(1); } + +// tolérance pour éviter une division par zéro +static const double epsd2 = 1e-12; + +TetraMetrics compute_mesh_quality_edges_length(pMesh mesh, int tetraIndex) { + TetraMetrics metrics; + + // Accès au tétraèdre ciblé (se méfier de la convention des indices 1 base etc) + pTetra tet = &mesh->tetra[tetraIndex]; + + // Récupérer les 4 points constituants du tétraèdre + pPoint p1 = &mesh->point[tet->v[0]]; + pPoint p2 = &mesh->point[tet->v[1]]; + pPoint p3 = &mesh->point[tet->v[2]]; + pPoint p4 = &mesh->point[tet->v[3]]; + + // Calculer les 6 longueurs d'arêtes + double d12 = sqrt(pow(p2->c[0] - p1->c[0], 2) + + pow(p2->c[1] - p1->c[1], 2) + + pow(p2->c[2] - p1->c[2], 2)); + double d13 = sqrt(pow(p3->c[0] - p1->c[0], 2) + + pow(p3->c[1] - p1->c[1], 2) + + pow(p3->c[2] - p1->c[2], 2)); + double d14 = sqrt(pow(p4->c[0] - p1->c[0], 2) + + pow(p4->c[1] - p1->c[1], 2) + + pow(p4->c[2] - p1->c[2], 2)); + double d23 = sqrt(pow(p3->c[0] - p2->c[0], 2) + + pow(p3->c[1] - p2->c[1], 2) + + pow(p3->c[2] - p2->c[2], 2)); + double d24 = sqrt(pow(p4->c[0] - p2->c[0], 2) + + pow(p4->c[1] - p2->c[1], 2) + + pow(p4->c[2] - p2->c[2], 2)); + double d34 = sqrt(pow(p4->c[0] - p3->c[0], 2) + + pow(p4->c[1] - p3->c[1], 2) + + pow(p4->c[2] - p3->c[2], 2)); + + // Stocker les longueurs d'arêtes dans la structure + metrics.edgeLengths[0] = d12; + metrics.edgeLengths[1] = d13; + metrics.edgeLengths[2] = d14; + metrics.edgeLengths[3] = d23; + metrics.edgeLengths[4] = d24; + metrics.edgeLengths[5] = d34; + + // Calcul du volume à partir de 3 vecteurs issus du point p1 : + // ab = p2 - p1, ac = p3 - p1, ad = p4 - p1 + double ab[3] = { p2->c[0] - p1->c[0], + p2->c[1] - p1->c[1], + p2->c[2] - p1->c[2] }; + double ac[3] = { p3->c[0] - p1->c[0], + p3->c[1] - p1->c[1], + p3->c[2] - p1->c[2] }; + double ad[3] = { p4->c[0] - p1->c[0], + p4->c[1] - p1->c[1], + p4->c[2] - p1->c[2] }; + + // Calcul du produit vectoriel (ac x ad) + double cross[3] = { + ac[1]*ad[2] - ac[2]*ad[1], + ac[2]*ad[0] - ac[0]*ad[2], + ac[0]*ad[1] - ac[1]*ad[0] + }; + + // Calcul du produit scalaire (ab · (ac x ad)) pour obtenir 6*Volume + double vol6 = ab[0]*cross[0] + ab[1]*cross[1] + ab[2]*cross[2]; + + // Vérifier que le volume n'est pas trop petit (pour éviter la division par zéro) + if(fabs(vol6) < epsd2) { + metrics.quality = 0.0; + return metrics; + } + + // Calculer S = somme des carrés des longueurs d'arête + double S = d12*d12 + d13*d13 + d14*d14 + d23*d23 + d24*d24 + d34*d34; + if(S < epsd2) { + metrics.quality = 0.0; + return metrics; + } + + // La formule de tet_quality + metrics.quality = vol6 / (S * sqrt(S)); + + return metrics; +} + diff --git a/src/mesh.h b/src/mesh.h index 9e8df19..ecd4f92 100644 --- a/src/mesh.h +++ b/src/mesh.h @@ -16,6 +16,17 @@ typedef unsigned short uShort; #endif +#ifndef _TETRA_METRICS_H +#define _TETRA_METRICS_H + +typedef struct { + int id; // Identifiant du tétraèdre + double quality; // La qualité du tétraèdre, calculée par la formule tet_quality + double edgeLengths[6]; // Les longueurs des 6 arêtes du tétraèdre +} TetraMetrics; + +#endif + typedef struct spoint { double c[3]; int tmp,mark; diff --git a/src/mouse.c b/src/mouse.c index eeb9a56..7837af2 100644 --- a/src/mouse.c +++ b/src/mouse.c @@ -1,6 +1,7 @@ #include "medit.h" #include "extern.h" #include "sproto.h" +#include "mesh.h" #ifndef ON #define ON 1 @@ -150,7 +151,7 @@ void mouse(int button,int state,int x,int y) { tr->mstate = state; tr->mbutton = button; - /* check if ctrl-shift-alt pressed */ + /* check if shift-alt pressed */ keyact = glutGetModifiers(); if ( state == GLUT_DOWN ) { @@ -159,11 +160,41 @@ void mouse(int button,int state,int x,int y) { if ( button == GLUT_LEFT_BUTTON ) { if ( keyact & GLUT_ACTIVE_SHIFT ) { - /* entity designation */ - picking = GL_TRUE; - if ( sc->picklist ) glDeleteLists(sc->picklist,1); - sc->picklist = pickingScene(sc,x,y,0); - return; + // Picking mode for the tetrahedron with SHIFT for computing the metrics. + picking = GL_TRUE; + if ( sc->picklist ) glDeleteLists(sc->picklist,1); + sc->picklist = pickingScene(sc,x,y,0); + printf("\n ====== SHIFT Mode activated ======\npicking attempt, select a tetrahedron to display its metrics\n"); + + int tetIndex = pickingTetrahedron(sc, x, y); + + if (tetIndex > 0) { + printf("\n ======== Results of pickingTetrahedron =======\ntetIndex = %d, reftype = %d\n", tetIndex, reftype); + + TetraMetrics metrics = compute_mesh_quality_edges_length(cv.mesh[sc->idmesh], tetIndex); + metrics.id = tetIndex; + sc->currentTetraMetrics = metrics; + sc->displayTetraMetrics = 1; + printf("Tetra %d: Quality = %g\n", tetIndex, metrics.quality); + printf("Edge lengths: %g, %g, %g, %g, %g, %g\n", + metrics.edgeLengths[0], + metrics.edgeLengths[1], + metrics.edgeLengths[2], + metrics.edgeLengths[3], + metrics.edgeLengths[4], + metrics.edgeLengths[5]); + } else { + sc->displayTetraMetrics = 0; + printf("Non-tetrahedron object selected.\n"); + + if (sc->picklist) { + glDeleteLists(sc->picklist, 1); + sc->picklist = pickingScene(sc,x,y,0); + } + + return; + } + } else if ( keyact & GLUT_ACTIVE_ALT ) { /* zoom */ diff --git a/src/picking.c b/src/picking.c index 5dabd8f..7f70e5c 100644 --- a/src/picking.c +++ b/src/picking.c @@ -1,7 +1,7 @@ #include "medit.h" #include "extern.h" #include "sproto.h" - +#include "mesh.h" typedef struct color { GLuint rMask,gMask,bMask,aMask; @@ -915,6 +915,23 @@ GLuint pickingScene(pScene sc,int x,int y,int ident) { return(dlist); } +int pickingTetrahedron(pScene sc, int x, int y) { + if (sc->picklist == 0) { + // If no display list has been generated, we make a classic call + GLuint dlist = pickingScene(sc, x, y, 0); + if (dlist == 0) + return -1; // No element has been selected + } + // After the appeal to pickingScene, the global variables like refitem et reftype + // have been updated. + if (reftype == LTets) { + // refitem already contains the tetrahedron index, such that : + // refitem = item - (mesh->nt + mesh->nq) + return refitem; + } + return -1; // If the element is not a tetrahedron +} + GLuint pickItem(pMesh mesh,pScene sc,int numit) { pMaterial pm; diff --git a/src/scene.c b/src/scene.c index 13978ff..d6a91a7 100644 --- a/src/scene.c +++ b/src/scene.c @@ -1,7 +1,7 @@ #include "medit.h" #include "extern.h" #include "sproto.h" - +#include "mesh.h" extern GLboolean hasStereo; extern int *pilmat,ipilmat,refmat,reftype,refitem; @@ -9,6 +9,64 @@ extern short schw,schh; extern ubyte quiet,fullscreen,tiling,stereoMode; +void displayTetraMetrics(pScene sc) { + if (!sc->displayTetraMetrics) + return; + + // Saving the projection matrix + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + // Configuring an orthographic matric + gluOrtho2D(0, sc->par.xs, 0, sc->par.ys); + + // Saving the matrix MODELVIEW + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + // Choosing a color for the text (white here) + glColor3f(1.0, 1.0, 1.0); + + // Position of the text : here (10, sc->par.ys - 20) + // sc->par.xs is the width of the window, sc->par.ys its height. + // So we place the text 10 pixels away from the left side & 20 pixels below the upper side. + glRasterPos2i(10, sc->par.ys - 20); + + // Preparing the string for the tetrahedron quality + char info[256]; + sprintf(info, "Tetra %d: Quality = %g", sc->currentTetraMetrics.id, sc->currentTetraMetrics.quality); + // Positioning the text + for (int i = 0; info[i] != '\0'; i++) { + glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, info[i]); + } + + // Positioning a 2nd line to display the edge lengths. + glRasterPos2i(10, sc->par.ys - 40); + sprintf(info, "Edge lengths: %g %g %g %g %g %g", + sc->currentTetraMetrics.edgeLengths[0], + sc->currentTetraMetrics.edgeLengths[1], + sc->currentTetraMetrics.edgeLengths[2], + sc->currentTetraMetrics.edgeLengths[3], + sc->currentTetraMetrics.edgeLengths[4], + sc->currentTetraMetrics.edgeLengths[5]); + // Displaying the edge lengths + for (int i = 0; info[i] != '\0'; i++) { + glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, info[i]); + } + + // Restauring the matrix MODELVIEW en pop + glPopMatrix(); + + // Restauring the projection matrix and pulling it out of 2D mode + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + + // Coming back to MODELVIEW default mode + glMatrixMode(GL_MODELVIEW); +} + + /* return current active scene */ int currentScene() { int k,idw; @@ -651,6 +709,8 @@ void redrawScene() { glTranslatef(sc->cx,sc->cy,sc->cz); drawModel(sc); if ( sc->type & S_DECO ) redrawStatusBar(sc); + + displayTetraMetrics(sc); } else { @@ -686,6 +746,8 @@ void redrawScene() { drawModel(sc); if ( sc->type & S_DECO ) redrawStatusBar(sc); + displayTetraMetrics(sc); + /* right view */ glDrawBuffer(GL_BACK_RIGHT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -707,8 +769,11 @@ void redrawScene() { glTranslatef(sc->cx,sc->cy,sc->cz); drawModel(sc); if ( sc->type & S_DECO ) redrawStatusBar(sc); + + displayTetraMetrics(sc); } + /* refresh screen */ if ( saveimg && animate ) glutSwapBuffers(); diff --git a/src/sproto.h b/src/sproto.h index 9a6e97d..647e1c5 100644 --- a/src/sproto.h +++ b/src/sproto.h @@ -143,6 +143,8 @@ void meshCoord(pMesh ,int ); void meshBox(pMesh mesh,int bb); void meshRef(pScene sc,pMesh mesh); int meshUpdate(pScene sc,pMesh mesh); +TetraMetrics compute_mesh_quality_edges_length(pMesh mesh, int tetraIndex); + /* mlists.c */ GLuint listTriaMap(pScene ,pMesh ); @@ -165,6 +167,7 @@ void redrawOverlay(int stretchX,int stretchY); void motionCamera(int x,int y); void mouseCamera(int button,int state,int x,int y); void animateCamera(); +extern int reftype; /* normal.c */ GLuint drawNormals(pMesh mesh,pScene sc); @@ -202,6 +205,7 @@ GLuint pickingList(pScene ,int ,int ); GLuint pickingPoint(pScene sc,int x,int y); GLuint pickItem(pMesh ,pScene ,int ); GLuint pickingScene(pScene sc,int x,int y,int ident); +int pickingTetrahedron(pScene sc, int x, int y); /* prierr.c */ void prierr(int typerr,int indice); @@ -226,6 +230,7 @@ void deleteScene(pScene sc); void initGrafix(pScene sc,pMesh mesh); int createScene(pScene sc,int idmesh); void streamIdle(); +void displayTetraMetrics(pScene sc); /* scissor.c */ void scissorScene(); From 3ea46c36bac76cb04d7f90bbd4de95254a138ae6 Mon Sep 17 00:00:00 2001 From: Gengis Date: Tue, 15 Apr 2025 21:55:35 +0200 Subject: [PATCH 2/7] =?UTF-8?q?Fixing=20the=20quality=20:=20adding=20the?= =?UTF-8?q?=20alpha=20coefficient=20(12=E2=88=9A3)=20to=20mormalize=20the?= =?UTF-8?q?=20quality=20to=201=20for=20a=20regular=20tetrahedron?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/mesh.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/mesh.c b/src/mesh.c index eca0039..111704f 100644 --- a/src/mesh.c +++ b/src/mesh.c @@ -483,7 +483,7 @@ static const double epsd2 = 1e-12; TetraMetrics compute_mesh_quality_edges_length(pMesh mesh, int tetraIndex) { TetraMetrics metrics; - // Accès au tétraèdre ciblé (se méfier de la convention des indices 1 base etc) + // Accès au tétraèdre ciblé pTetra tet = &mesh->tetra[tetraIndex]; // Récupérer les 4 points constituants du tétraèdre @@ -555,9 +555,12 @@ TetraMetrics compute_mesh_quality_edges_length(pMesh mesh, int tetraIndex) { return metrics; } - // La formule de tet_quality - metrics.quality = vol6 / (S * sqrt(S)); - + // Calcul de la qualité selon la formule modifiée : + // Pour un tétraèdre régulier de longueur d'arête l, + // le rapport calculé est 1/(12sqrt(3)), on multiplie + // par 12sqrt(3) pour obtenir 1. + metrics.quality = (vol6 * (12 * sqrt(3))) / (S * sqrt(S)); + return metrics; } From edbd71ca4c3f59d292519e73f3ba634521625372 Mon Sep 17 00:00:00 2001 From: Gengis Date: Wed, 16 Apr 2025 12:12:14 +0200 Subject: [PATCH 3/7] Cleaning some comments and fixing a double comment that I did not see before for the triangles picking. Also a better display of the messages in the terminal. --- src/compil.date | 2 +- src/grafic.h | 6 +++--- src/mesh.c | 29 +++++++++++++++-------------- src/mesh.h | 6 +++--- src/mouse.c | 40 +++++++++++++++++++++++++++------------- src/scene.c | 6 +++--- 6 files changed, 52 insertions(+), 37 deletions(-) diff --git a/src/compil.date b/src/compil.date index e6fc0f1..02d4bed 100644 --- a/src/compil.date +++ b/src/compil.date @@ -1 +1 @@ -#define COMPIL "2025-04-12 19:08:57" \ No newline at end of file +#define COMPIL "2025-04-15 21:58:38" \ No newline at end of file diff --git a/src/grafic.h b/src/grafic.h index 407a2bb..c5e05a4 100644 --- a/src/grafic.h +++ b/src/grafic.h @@ -235,10 +235,10 @@ typedef struct scene { ubyte isotyp; ubyte picked; - /* Ajout des champs pour le mode qualité des tétraèdres */ + /* Adding the field for the quality mode of the tetrahedra */ TetraMetrics currentTetraMetrics; // Store the metrics of the selected tetrahedron - ubyte displayTetraMetrics; // Flag activating/deactivating the display of the - // tetrahedron metrics + ubyte displayTetraMetrics; // Flag activating/deactivating the + // display of the tetrahedron metrics } Scene; typedef Scene * pScene; diff --git a/src/mesh.c b/src/mesh.c index 111704f..0c8cf88 100644 --- a/src/mesh.c +++ b/src/mesh.c @@ -477,22 +477,22 @@ int meshUpdate(pScene sc,pMesh mesh) { return(1); } -// tolérance pour éviter une division par zéro +// tolerance to prevent a division by zero static const double epsd2 = 1e-12; TetraMetrics compute_mesh_quality_edges_length(pMesh mesh, int tetraIndex) { TetraMetrics metrics; - // Accès au tétraèdre ciblé + // Accessing the targeted tetrahedron pTetra tet = &mesh->tetra[tetraIndex]; - // Récupérer les 4 points constituants du tétraèdre + // Getting the 4 points forming the tetrahedron pPoint p1 = &mesh->point[tet->v[0]]; pPoint p2 = &mesh->point[tet->v[1]]; pPoint p3 = &mesh->point[tet->v[2]]; pPoint p4 = &mesh->point[tet->v[3]]; - // Calculer les 6 longueurs d'arêtes + // Computing the 6 edge lengths double d12 = sqrt(pow(p2->c[0] - p1->c[0], 2) + pow(p2->c[1] - p1->c[1], 2) + pow(p2->c[2] - p1->c[2], 2)); @@ -512,7 +512,7 @@ TetraMetrics compute_mesh_quality_edges_length(pMesh mesh, int tetraIndex) { pow(p4->c[1] - p3->c[1], 2) + pow(p4->c[2] - p3->c[2], 2)); - // Stocker les longueurs d'arêtes dans la structure + // Storing the 6 edge lengths in our structure metrics.edgeLengths[0] = d12; metrics.edgeLengths[1] = d13; metrics.edgeLengths[2] = d14; @@ -520,7 +520,7 @@ TetraMetrics compute_mesh_quality_edges_length(pMesh mesh, int tetraIndex) { metrics.edgeLengths[4] = d24; metrics.edgeLengths[5] = d34; - // Calcul du volume à partir de 3 vecteurs issus du point p1 : + // Computing the volume using 3 arrays coming from the point p1 : // ab = p2 - p1, ac = p3 - p1, ad = p4 - p1 double ab[3] = { p2->c[0] - p1->c[0], p2->c[1] - p1->c[1], @@ -532,33 +532,34 @@ TetraMetrics compute_mesh_quality_edges_length(pMesh mesh, int tetraIndex) { p4->c[1] - p1->c[1], p4->c[2] - p1->c[2] }; - // Calcul du produit vectoriel (ac x ad) + // Computing the cross product (ac x ad) double cross[3] = { ac[1]*ad[2] - ac[2]*ad[1], ac[2]*ad[0] - ac[0]*ad[2], ac[0]*ad[1] - ac[1]*ad[0] }; - // Calcul du produit scalaire (ab · (ac x ad)) pour obtenir 6*Volume + // Computing the scalar product (ab · (ac x ad)) to get the 6*Volume double vol6 = ab[0]*cross[0] + ab[1]*cross[1] + ab[2]*cross[2]; - // Vérifier que le volume n'est pas trop petit (pour éviter la division par zéro) + // Verifying the volume is not too small + // (to prevent the division by zero) if(fabs(vol6) < epsd2) { metrics.quality = 0.0; return metrics; } - // Calculer S = somme des carrés des longueurs d'arête + // Computing S = sum of the squared edge lengths double S = d12*d12 + d13*d13 + d14*d14 + d23*d23 + d24*d24 + d34*d34; if(S < epsd2) { metrics.quality = 0.0; return metrics; } - // Calcul de la qualité selon la formule modifiée : - // Pour un tétraèdre régulier de longueur d'arête l, - // le rapport calculé est 1/(12sqrt(3)), on multiplie - // par 12sqrt(3) pour obtenir 1. + // Computing the quality with respect to the modified formula : + // For a regular tetrahedron of edge length l, + // The ratio computed is 1/(12sqrt(3)), we multiply + // by 12sqrt(3) to obtain 1. metrics.quality = (vol6 * (12 * sqrt(3))) / (S * sqrt(S)); return metrics; diff --git a/src/mesh.h b/src/mesh.h index ecd4f92..8339ccc 100644 --- a/src/mesh.h +++ b/src/mesh.h @@ -20,9 +20,9 @@ typedef unsigned short uShort; #define _TETRA_METRICS_H typedef struct { - int id; // Identifiant du tétraèdre - double quality; // La qualité du tétraèdre, calculée par la formule tet_quality - double edgeLengths[6]; // Les longueurs des 6 arêtes du tétraèdre + int id; // Id of the tetrahedron + double quality; // Quality of the tetrahedron, with tet_quality + double edgeLengths[6]; // The lengths of the 6 tetrahedron edges } TetraMetrics; #endif diff --git a/src/mouse.c b/src/mouse.c index 7837af2..a98ccad 100644 --- a/src/mouse.c +++ b/src/mouse.c @@ -151,45 +151,59 @@ void mouse(int button,int state,int x,int y) { tr->mstate = state; tr->mbutton = button; - /* check if shift-alt pressed */ + /* check the actions on the keys */ keyact = glutGetModifiers(); if ( state == GLUT_DOWN ) { tracking = GL_TRUE; lasttime = glutGet(GLUT_ELAPSED_TIME); + /* check if shift+click pressed */ if ( button == GLUT_LEFT_BUTTON ) { if ( keyact & GLUT_ACTIVE_SHIFT ) { - // Picking mode for the tetrahedron with SHIFT for computing the metrics. + // Picking mode for computing tetrahedron metrics using SHIFT. picking = GL_TRUE; + + printf("\n=================================================\n"); + printf("===== SHIFT Mode Activated: Picking Attempt =====\n"); + printf("=================================================\n"); + + // Clean up any previous display list if ( sc->picklist ) glDeleteLists(sc->picklist,1); + + // Create a new display list to highlight the selected object sc->picklist = pickingScene(sc,x,y,0); - printf("\n ====== SHIFT Mode activated ======\npicking attempt, select a tetrahedron to display its metrics\n"); - - int tetIndex = pickingTetrahedron(sc, x, y); - if (tetIndex > 0) { - printf("\n ======== Results of pickingTetrahedron =======\ntetIndex = %d, reftype = %d\n", tetIndex, reftype); + int tetIndex = pickingTetrahedron(sc, x, y); + if (tetIndex > 0) { TetraMetrics metrics = compute_mesh_quality_edges_length(cv.mesh[sc->idmesh], tetIndex); metrics.id = tetIndex; sc->currentTetraMetrics = metrics; sc->displayTetraMetrics = 1; - printf("Tetra %d: Quality = %g\n", tetIndex, metrics.quality); - printf("Edge lengths: %g, %g, %g, %g, %g, %g\n", + + // Print the computed metrics + printf("\n====================== Tetrahedron Metrics ===================\n"); + printf("Tetrahedron %d:\n", tetIndex); + printf(" Quality: %g\n", metrics.quality); + printf(" Edge Lengths: %.5g, %.5g, %.5g, %.5g, %.5g, %.5g\n", metrics.edgeLengths[0], metrics.edgeLengths[1], metrics.edgeLengths[2], metrics.edgeLengths[3], metrics.edgeLengths[4], metrics.edgeLengths[5]); + printf("==============================================================\n"); } else { sc->displayTetraMetrics = 0; - printf("Non-tetrahedron object selected.\n"); - + + printf("\n---------------------------------------------\n"); + printf("No tetrahedron object selected.\n"); + printf("---------------------------------------------\n"); + // Optional, cleanup the display list if needed if (sc->picklist) { - glDeleteLists(sc->picklist, 1); - sc->picklist = pickingScene(sc,x,y,0); + //glDeleteLists(sc->picklist, 1); + //sc->picklist = pickingScene(sc,x,y,0); } return; diff --git a/src/scene.c b/src/scene.c index d6a91a7..a06dc22 100644 --- a/src/scene.c +++ b/src/scene.c @@ -17,7 +17,7 @@ void displayTetraMetrics(pScene sc) { glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); - // Configuring an orthographic matric + // Configuring an orthographic matrix gluOrtho2D(0, sc->par.xs, 0, sc->par.ys); // Saving the matrix MODELVIEW @@ -55,10 +55,10 @@ void displayTetraMetrics(pScene sc) { glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, info[i]); } - // Restauring the matrix MODELVIEW en pop + // Restoring the matrix MODELVIEW en pop glPopMatrix(); - // Restauring the projection matrix and pulling it out of 2D mode + // Restoring the projection matrix and pulling it out of 2D mode glMatrixMode(GL_PROJECTION); glPopMatrix(); From af2c75e77905ba77b1d1c3b3467a89546d9bebdf Mon Sep 17 00:00:00 2001 From: Gengis Date: Wed, 16 Apr 2025 16:10:16 +0200 Subject: [PATCH 4/7] Deleting the messages "Displaying..." and "No tetrahedron object selected" because they are saying the obvious. --- src/mouse.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/src/mouse.c b/src/mouse.c index a98ccad..df72f14 100644 --- a/src/mouse.c +++ b/src/mouse.c @@ -164,10 +164,6 @@ void mouse(int button,int state,int x,int y) { // Picking mode for computing tetrahedron metrics using SHIFT. picking = GL_TRUE; - printf("\n=================================================\n"); - printf("===== SHIFT Mode Activated: Picking Attempt =====\n"); - printf("=================================================\n"); - // Clean up any previous display list if ( sc->picklist ) glDeleteLists(sc->picklist,1); @@ -183,8 +179,6 @@ void mouse(int button,int state,int x,int y) { sc->displayTetraMetrics = 1; // Print the computed metrics - printf("\n====================== Tetrahedron Metrics ===================\n"); - printf("Tetrahedron %d:\n", tetIndex); printf(" Quality: %g\n", metrics.quality); printf(" Edge Lengths: %.5g, %.5g, %.5g, %.5g, %.5g, %.5g\n", metrics.edgeLengths[0], @@ -193,21 +187,16 @@ void mouse(int button,int state,int x,int y) { metrics.edgeLengths[3], metrics.edgeLengths[4], metrics.edgeLengths[5]); - printf("==============================================================\n"); } else { sc->displayTetraMetrics = 0; - printf("\n---------------------------------------------\n"); - printf("No tetrahedron object selected.\n"); - printf("---------------------------------------------\n"); // Optional, cleanup the display list if needed if (sc->picklist) { //glDeleteLists(sc->picklist, 1); //sc->picklist = pickingScene(sc,x,y,0); } - - return; } + return; } else if ( keyact & GLUT_ACTIVE_ALT ) { From a57093153109609a2bfe517e028f261aaf2a08e4 Mon Sep 17 00:00:00 2001 From: Gengis Date: Wed, 16 Apr 2025 16:19:57 +0200 Subject: [PATCH 5/7] Deleting the compil.date, because it is generated by cmake. --- src/compil.date | 1 - 1 file changed, 1 deletion(-) delete mode 100644 src/compil.date diff --git a/src/compil.date b/src/compil.date deleted file mode 100644 index 02d4bed..0000000 --- a/src/compil.date +++ /dev/null @@ -1 +0,0 @@ -#define COMPIL "2025-04-15 21:58:38" \ No newline at end of file From 654e015946c5021871de83e12a92311d4a734a4e Mon Sep 17 00:00:00 2001 From: Gengis Date: Thu, 17 Apr 2025 02:05:59 +0200 Subject: [PATCH 6/7] Better organization of the code, putting some functions in a more suitable place. --- src/mouse.c | 29 +---------------------------- src/picking.c | 49 ++++++++++++++++++++++++++++++++++++------------- 2 files changed, 37 insertions(+), 41 deletions(-) diff --git a/src/mouse.c b/src/mouse.c index df72f14..13ba9de 100644 --- a/src/mouse.c +++ b/src/mouse.c @@ -169,35 +169,8 @@ void mouse(int button,int state,int x,int y) { // Create a new display list to highlight the selected object sc->picklist = pickingScene(sc,x,y,0); - - int tetIndex = pickingTetrahedron(sc, x, y); - - if (tetIndex > 0) { - TetraMetrics metrics = compute_mesh_quality_edges_length(cv.mesh[sc->idmesh], tetIndex); - metrics.id = tetIndex; - sc->currentTetraMetrics = metrics; - sc->displayTetraMetrics = 1; - - // Print the computed metrics - printf(" Quality: %g\n", metrics.quality); - printf(" Edge Lengths: %.5g, %.5g, %.5g, %.5g, %.5g, %.5g\n", - metrics.edgeLengths[0], - metrics.edgeLengths[1], - metrics.edgeLengths[2], - metrics.edgeLengths[3], - metrics.edgeLengths[4], - metrics.edgeLengths[5]); - } else { - sc->displayTetraMetrics = 0; - - // Optional, cleanup the display list if needed - if (sc->picklist) { - //glDeleteLists(sc->picklist, 1); - //sc->picklist = pickingScene(sc,x,y,0); - } - } return; - + } else if ( keyact & GLUT_ACTIVE_ALT ) { /* zoom */ diff --git a/src/picking.c b/src/picking.c index 7f70e5c..595f6fe 100644 --- a/src/picking.c +++ b/src/picking.c @@ -899,6 +899,7 @@ GLuint pickingScene(pScene sc,int x,int y,int ident) { case LTets: drawTets(sc,mesh,refitem); infoEntity(sc,mesh,refitem,LTets); + pickingTetrahedron(sc, x, y); break; case LHexa: drawHexa(sc,mesh,refitem); @@ -915,23 +916,45 @@ GLuint pickingScene(pScene sc,int x,int y,int ident) { return(dlist); } -int pickingTetrahedron(pScene sc, int x, int y) { +int pickingTetrahedron(pScene sc, int x, int y) { if (sc->picklist == 0) { // If no display list has been generated, we make a classic call - GLuint dlist = pickingScene(sc, x, y, 0); - if (dlist == 0) - return -1; // No element has been selected - } - // After the appeal to pickingScene, the global variables like refitem et reftype - // have been updated. - if (reftype == LTets) { - // refitem already contains the tetrahedron index, such that : - // refitem = item - (mesh->nt + mesh->nq) - return refitem; + GLuint dlist = pickingScene(sc, x, y, 0); + if (dlist == 0){ + sc->displayTetraMetrics = 0; + return -1; // No element has been selected + } } - return -1; // If the element is not a tetrahedron -} + // reftype/refitem have just been updated + if ( reftype == LTets ){ + int tetIndex = refitem; + + // Computing and storing the metrics + TetraMetrics metrics = compute_mesh_quality_edges_length(cv.mesh[sc->idmesh], tetIndex); + metrics.id = tetIndex; + sc->currentTetraMetrics = metrics; + sc->displayTetraMetrics = 1; + + // Print the computed metrics in the shell + printf(" Quality: %g\n", metrics.quality); + printf(" Edge Lengths: %.5g, %.5g, %.5g, %.5g, %.5g, %.5g\n", + metrics.edgeLengths[0], + metrics.edgeLengths[1], + metrics.edgeLengths[2], + metrics.edgeLengths[3], + metrics.edgeLengths[4], + metrics.edgeLengths[5]); + + return tetIndex; + + } + + // Not a tetrahedron + sc->displayTetraMetrics = 0; + return -1; + +} GLuint pickItem(pMesh mesh,pScene sc,int numit) { pMaterial pm; From 08b810252855d4c138aa4217a4fe15a9c6cf0bb7 Mon Sep 17 00:00:00 2001 From: Gengis Date: Thu, 17 Apr 2025 14:27:38 +0200 Subject: [PATCH 7/7] Deleting a block that is not really necessary anymore. --- src/picking.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/picking.c b/src/picking.c index 595f6fe..c9dcc0f 100644 --- a/src/picking.c +++ b/src/picking.c @@ -917,14 +917,7 @@ GLuint pickingScene(pScene sc,int x,int y,int ident) { } int pickingTetrahedron(pScene sc, int x, int y) { - if (sc->picklist == 0) { - // If no display list has been generated, we make a classic call - GLuint dlist = pickingScene(sc, x, y, 0); - if (dlist == 0){ - sc->displayTetraMetrics = 0; - return -1; // No element has been selected - } - } + // reftype/refitem have just been updated if ( reftype == LTets ){