/*************************************/ /* Auteur : Rémi Synave */ /* Date de création : 10/03/10 */ /* Date de modification : 10/12/14 */ /* Version : 0.3 */ /*************************************/ /***************************************************************************/ /* This file is part of a2ri. */ /* */ /* a2ri is free software: you can redistribute it and/or modify it */ /* under the terms of the GNU Lesser General Public License as published */ /* by the Free Software Foundation, either version 3 of the License, or */ /* (at your option) any later version. */ /* */ /* a2ri is distributed in the hope that it will be useful, */ /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ /* GNU Lesser General Public License for more details. */ /* */ /* You should have received a copy of the GNU Lesser General Public */ /* License along with a2ri. */ /* If not, see . */ /***************************************************************************/ #include "io.h" /********** INTERMEDIATE TYPES AND FUNCTIONS **********/ /* Les fonctions intermédiaires sont préfixées de IF */ /* et les types intermédiaires de IT */ void IFaffichage_chargement ( FILE * is, long posmax) { long poscur; poscur = ftell (is); printf ("%c%c%c%c%c%c%c%c%c%c%c%c%c%lf %c", 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, ((poscur) * 100.0) / (posmax * 1.0), 37); } //fonction qui ecrit les aretes dans un fichier vef void IFsave_vef_write_edge ( vf_model * m, hashtable * table, FILE * os) { int p1, p2; int indexarete = 0; //pour toute les faces, on regarde si l'arete existe deja dans la table de hachage //si oui, on ne fait rien //sinon on entre l'arete dans la table et on l'ecrit dans le fichier. //on enregistre également son index pour l'écriture des faces définies par trois aretes for (int i = 0; i < m->nbface; i++) { p1 = m->fa[i].ve1; p2 = m->fa[i].ve2; vf_edge *edgetemp = hashtable_look_for (table, p1, p2); if (edgetemp == NULL) { edgetemp = (vf_edge *) malloc (sizeof (vf_edge)); a2ri_erreur_critique_si (edgetemp == NULL, "erreur allocation memoire pour edgetemp\nIFsave_vef_write_edge"); edgetemp->ve1 = p1; edgetemp->ve2 = p2; edgetemp->att_int = indexarete; indexarete++; fprintf (os, "%d %d\n", p1, p2); hashtable_add (table, edgetemp); } p1 = m->fa[i].ve2; p2 = m->fa[i].ve3; edgetemp = hashtable_look_for (table, p1, p2); if (edgetemp == NULL) { edgetemp = (vf_edge *) malloc (sizeof (vf_edge)); a2ri_erreur_critique_si (edgetemp == NULL, "erreur allocation memoire pour edgetemp\nIFsave_vef_write_edge"); edgetemp->ve1 = p1; edgetemp->ve2 = p2; edgetemp->att_int = indexarete; indexarete++; fprintf (os, "%d %d\n", p1, p2); hashtable_add (table, edgetemp); } p1 = m->fa[i].ve3; p2 = m->fa[i].ve1; edgetemp = hashtable_look_for (table, p1, p2); if (edgetemp == NULL) { edgetemp = (vf_edge *) malloc (sizeof (vf_edge)); a2ri_erreur_critique_si (edgetemp == NULL, "erreur allocation memoire pour edgetemp\nIFsave_vef_write_edge"); edgetemp->ve1 = p1; edgetemp->ve2 = p2; edgetemp->att_int = indexarete; indexarete++; fprintf (os, "%d %d\n", p1, p2); hashtable_add (table, edgetemp); } } } //fonction qui ecrit les aretes dans un fichier gts void IFsave_gts_write_edge ( vf_model * m, hashtable * table, FILE * os) { int p1, p2; int indexarete = 0; //pour toute les faces, on regarde si l'arete existe deja dans la table de hachage //si oui, on ne fait rien //sinon on entre l'arete dans la table et on l'ecrit dans le fichier. //on enregistre également son index pour l'écriture des faces définies par trois aretes for (int i = 0; i < m->nbface; i++) { p1 = m->fa[i].ve1; p2 = m->fa[i].ve2; vf_edge *edgetemp = hashtable_look_for (table, p1, p2); if (edgetemp == NULL) { edgetemp = (vf_edge *) malloc (sizeof (vf_edge)); a2ri_erreur_critique_si (edgetemp == NULL, "erreur allocation memoire pour edgetemp\nIFsave_gts_write_edge"); edgetemp->ve1 = p1; edgetemp->ve2 = p2; edgetemp->att_int = indexarete; indexarete++; fprintf (os, "%d %d\n", p1 + 1, p2 + 1); hashtable_add (table, edgetemp); } p1 = m->fa[i].ve2; p2 = m->fa[i].ve3; edgetemp = hashtable_look_for (table, p1, p2); if (edgetemp == NULL) { edgetemp = (vf_edge *) malloc (sizeof (vf_edge)); a2ri_erreur_critique_si (edgetemp == NULL, "erreur allocation memoire pour edgetemp\nIFsave_gts_write_edge"); edgetemp->ve1 = p1; edgetemp->ve2 = p2; edgetemp->att_int = indexarete; indexarete++; fprintf (os, "%d %d\n", p1 + 1, p2 + 1); hashtable_add (table, edgetemp); } p1 = m->fa[i].ve3; p2 = m->fa[i].ve1; edgetemp = hashtable_look_for (table, p1, p2); if (edgetemp == NULL) { edgetemp = (vf_edge *) malloc (sizeof (vf_edge)); a2ri_erreur_critique_si (edgetemp == NULL, "erreur allocation memoire pour edgetemp\nIFsave_gts_write_edge"); edgetemp->ve1 = p1; edgetemp->ve2 = p2; edgetemp->att_int = indexarete; indexarete++; fprintf (os, "%d %d\n", p1 + 1, p2 + 1); hashtable_add (table, edgetemp); } } } /********** MAIN FUNCTIONS **********/ /** Ouverture d'un fichier contenant un modèle @param file chemin du fichier à ouvrir @param m pointeur sur le modèle @return 1 si succès, 0 sinon */ int a2ri_vf_open_file ( char *file, vf_model * m) { char ext[5]; memcpy (ext, file + (strlen (file) - 4), 4); ext[4] = 0; //appel de la bonne fonction en fonction de l'extension du fichier if (!strcmp (ext, ".wrl")) return (a2ri_vf_load_wrl (file, m)); if (!strcmp (ext, ".asc")) return (a2ri_vf_load_asc (file, m)); if (!strcmp (ext, ".vef")) return (a2ri_vf_load_vef (file, m)); if (!strcmp (ext, ".pgn")) return (a2ri_vf_load_pgn (file, m)); if (!strcmp (ext, ".ply")) return (a2ri_vf_load_ply (file, m)); if (!strcmp (ext, ".off")) return (a2ri_vf_load_off (file, m)); if (!strcmp (ext, ".obj")) return (a2ri_vf_load_obj (file, m)); if (!strcmp (ext, ".gts")) return (a2ri_vf_load_gts (file, m)); if (!strcmp (ext, ".stl")) return (a2ri_vf_load_stl (file, m)); return 0; } /** Ouverture d'un fichier asc contenant un nuage de point @param file chemin du fichier à ouvrir @param m pointeur sur le modèle @return 1 si succès, 0 sinon */ int a2ri_vf_load_asc ( char *file, vf_model * m) { FILE *is = NULL; double coordx, coordy, coordz; int i; setlocale(LC_NUMERIC,"C"); is = fopen (file, "r"); if (is == NULL) return 0; i=0; fscanf (is, "%lf %lf %lf", &coordx, &coordy, &coordz); while(!feof(is)) { //fscanf (is, "%lf %lf %lf", &coordx, &coordy, &coordz); a2ri_vf_add_vertex (m, coordx, coordy, coordz); if (i == 0) { m->xmin = coordx; m->xmax = coordx; m->ymin = coordy; m->ymax = coordy; m->zmin = coordz; m->zmax = coordz; } else { //mis à jour de la bounding box du modèle if (coordx < m->xmin) m->xmin = coordx; if (coordx > m->xmax) m->xmax = coordx; if (coordy < m->ymin) m->ymin = coordy; if (coordy > m->ymax) m->ymax = coordy; if (coordz < m->zmin) m->zmin = coordz; if (coordz > m->zmax) m->zmax = coordz; } fscanf (is, "%lf %lf %lf", &coordx, &coordy, &coordz); fscanf (is, "%lf %lf %lf", &coordx, &coordy, &coordz); i=1; } fclose (is); setlocale(LC_NUMERIC,""); return 1; } /** Ouverture d'un fichier pgn contenant un modèle @param file chemin du fichier à ouvrir @param m pointeur sur le modèle @return 1 si succès, 0 sinon */ int a2ri_vf_load_pgn ( char *file, vf_model * m) { FILE *is = NULL; int nbvertex, nbface, ve1, ve2, ve3; double coordx, coordy, coordz; setlocale(LC_NUMERIC,"C"); is = fopen (file, "r"); if (is == NULL) return 0; //lecture du nombre de sommets et de faces fscanf (is, "%d %d", &nbvertex, &nbface); //lecture des sommets for (int i = 0; i < nbvertex; i++) { fscanf (is, "%lf %lf %lf", &coordx, &coordy, &coordz); a2ri_vf_add_vertex (m, coordx, coordy, coordz); if (i == 0) { m->xmin = coordx; m->xmax = coordx; m->ymin = coordy; m->ymax = coordy; m->zmin = coordz; m->zmax = coordz; } else { //mis à jour de la bounding box du modèle if (coordx < m->xmin) m->xmin = coordx; if (coordx > m->xmax) m->xmax = coordx; if (coordy < m->ymin) m->ymin = coordy; if (coordy > m->ymax) m->ymax = coordy; if (coordz < m->zmin) m->zmin = coordz; if (coordz > m->zmax) m->zmax = coordz; } } //lecture des faces for (int i = 0; i < nbface; i++) { fscanf (is, "%d %d %d", &ve1, &ve2, &ve3); a2ri_vf_add_face (m, ve1, ve2, ve3); fscanf (is, "%d", &ve1); } fclose (is); setlocale(LC_NUMERIC,""); return 1; } /** Ouverture d'un fichier obj contenant un modèle @param file chemin du fichier à ouvrir @param m pointeur sur le modèle @return 1 si succès, 0 sinon */ int a2ri_vf_load_obj ( char *file, vf_model * m) { FILE *is = NULL; int ve1, ve2, ve3; double coordx, coordy, coordz; char str[250], str_ve1[20], str_ve2[20], str_ve3[20]; setlocale(LC_NUMERIC,"C"); is = fopen (file, "r"); if (is == NULL) return 0; fscanf (is, "%s", str); while (strcmp (str, "v") != 0) fscanf (is, "%s", str); //lecture des sommets while (strcmp (str, "v") == 0 && !feof (is)) { fscanf (is, "%lf %lf %lf", &coordx, &coordy, &coordz); //ajout d'un sommet a2ri_vf_add_vertex (m, coordx, coordy, coordz); fscanf (is, "%s", str); //mis à jour de la bounding box if (m->nbvertex == 1) { m->xmin = coordx; m->xmax = coordx; m->ymin = coordy; m->ymax = coordy; m->zmin = coordz; m->zmax = coordz; } else { if (coordx < m->xmin) m->xmin = coordx; if (coordx > m->xmax) m->xmax = coordx; if (coordy < m->ymin) m->ymin = coordy; if (coordy > m->ymax) m->ymax = coordy; if (coordz < m->zmin) m->zmin = coordz; if (coordz > m->zmax) m->zmax = coordz; } } while (strcmp (str, "f") != 0 && !feof (is)) { fscanf (is, "%s", str); } //lecture des faces while (strcmp (str, "f") == 0 && !feof (is)) { fscanf (is, "%s %s %s", str_ve1, str_ve2, str_ve3); ve1 = atoi (str_ve1); ve2 = atoi (str_ve2); ve3 = atoi (str_ve3); ve1--; ve2--; ve3--; //ajout d'une face a2ri_vf_add_face (m, ve1, ve2, ve3); fscanf (is, "%s", str); if (str[0] >= '0' && str[0] <= '9') { ve2 = atoi (str); ve2--; a2ri_vf_add_face (m, ve3, ve2, ve1); fscanf (is, "%s", str); } } fclose (is); setlocale(LC_NUMERIC,""); return 1; } /** Ouverture d'un fichier wrl contenant un modèle @param file chemin du fichier à ouvrir @param m pointeur sur le modèle @return 1 si succès, 0 sinon */ int a2ri_vf_load_wrl1 ( char *file, vf_model * m) { FILE *is = NULL; char str[20]; char coordx[15], coordy[15], coordz[15]; setlocale(LC_NUMERIC,"C"); is = fopen (file, "r"); if (is == NULL) return 0; fscanf (is, "%s", str); while (strcmp (str, "point") && strcmp (str, "point[")) fscanf (is, "%s", str); if (!strcmp (str, "point")) fscanf (is, "%s", str); //lecture des sommets fscanf (is, "%s", coordx); int i = 0; while (strcmp (coordx, "}") && strcmp (coordx, "]")) { fscanf (is, "%s", coordy); fscanf (is, "%s", coordz); if (coordz[strlen (coordz) - 1] == ',') { memcpy (coordz, coordz, strlen (coordz) - 1); coordz[strlen (coordz)] = '\0'; } //ajout d'un sommet a2ri_vf_add_vertex (m, atof (coordx), atof (coordy), atof (coordz)); //mis à jour de la bounding box if (i == 0) { i++; m->xmin = atof (coordx); m->xmax = atof (coordx); m->ymin = atof (coordy); m->ymax = atof (coordy); m->zmin = atof (coordz); m->zmax = atof (coordz); } else { if (atof (coordx) < m->xmin) m->xmin = atof (coordx); if (atof (coordx) > m->xmax) m->xmax = atof (coordx); if (atof (coordy) < m->ymin) m->ymin = atof (coordy); if (atof (coordy) > m->ymax) m->ymax = atof (coordy); if (atof (coordz) < m->zmin) m->zmin = atof (coordz); if (atof (coordz) > m->zmax) m->zmax = atof (coordz); } fscanf (is, "%s", coordx); } fscanf (is, "%s", str); while (strcmp (str, "coordIndex") && strcmp (str, "coordIndex[")) fscanf (is, "%s", str); if (!strcmp (str, "coordIndex")) fscanf (is, "%s", str); //lecture des faces fscanf (is, "%s", coordx); while (strcmp (coordx, "}") && strcmp (coordx, "]")) { fscanf (is, "%s", coordy); fscanf (is, "%s", coordz); if (coordx[strlen (coordx) - 1] == ',') { memcpy (coordx, coordx, strlen (coordx) - 1); coordz[strlen (coordx)] = '\0'; } if (coordy[strlen (coordy) - 1] == ',') { memcpy (coordy, coordy, strlen (coordy) - 1); coordy[strlen (coordy)] = '\0'; } if (coordz[strlen (coordz) - 1] == ',') { memcpy (coordz, coordz, strlen (coordz) - 1); coordz[strlen (coordz)] = '\0'; } //ajout d'une face a2ri_vf_add_face (m, atoi (coordx), atoi (coordy), atoi (coordz)); // reading the -1 fscanf (is, "%s", coordy); if (coordy[strlen (coordy) - 1] == ',') { memcpy (coordy, coordy, strlen (coordy) - 1); coordy[strlen (coordy)] = '\0'; } if (atoi (coordy) != -1) { a2ri_vf_add_face (m, atoi (coordz), atoi (coordy), atoi (coordx)); fscanf (is, "%s", coordx); } fscanf (is, "%s", coordx); } fclose (is); setlocale(LC_NUMERIC,""); return 1; } /** Ouverture d'un fichier wrl contenant un modèle @param file chemin du fichier à ouvrir @param m pointeur sur le modèle @return 1 si succès, 0 sinon */ int a2ri_vf_load_wrl2 ( char *file, vf_model * m) { FILE *is = NULL; char str[20]; char coordx[15], coordy[15], coordz[15]; setlocale(LC_NUMERIC,"C"); is = fopen (file, "r"); if (is == NULL) return 0; fscanf (is, "%s", str); while (strcmp (str, "point") && strcmp (str, "point[")) fscanf (is, "%s", str); if (!strcmp (str, "point")) fscanf (is, "%s", str); //lecture des sommets fscanf (is, "%s", coordx); int i = 0; while (strcmp (coordx, "}") && strcmp (coordx, "]")) { fscanf (is, "%s", coordy); fscanf (is, "%s", coordz); if (coordz[strlen (coordz) - 1] == ',') { memcpy (coordz, coordz, strlen (coordz) - 1); coordz[strlen (coordz)] = '\0'; } //ajout d'un sommet a2ri_vf_add_vertex (m, atof (coordx), atof (coordy), atof (coordz)); //mis à jour de la bounding box if (i == 0) { i++; m->xmin = atof (coordx); m->xmax = atof (coordx); m->ymin = atof (coordy); m->ymax = atof (coordy); m->zmin = atof (coordz); m->zmax = atof (coordz); } else { if (atof (coordx) < m->xmin) m->xmin = atof (coordx); if (atof (coordx) > m->xmax) m->xmax = atof (coordx); if (atof (coordy) < m->ymin) m->ymin = atof (coordy); if (atof (coordy) > m->ymax) m->ymax = atof (coordy); if (atof (coordz) < m->zmin) m->zmin = atof (coordz); if (atof (coordz) > m->zmax) m->zmax = atof (coordz); } fscanf (is, "%s", coordx); } fscanf (is, "%s", str); while (strcmp (str, "coordIndex") && strcmp (str, "coordIndex[")) fscanf (is, "%s", str); if (!strcmp (str, "coordIndex")) fscanf (is, "%s", str); //lecture des faces fscanf (is, "%s", coordx); while (strcmp (coordx, "}") && strcmp (coordx, "]")) { fscanf (is, "%s", coordy); fscanf (is, "%s", coordz); //ajout d'une face a2ri_vf_add_face (m, atoi (coordx), atoi (coordy), atoi (coordz)); // reading the -1 fscanf (is, "%s", coordx); fscanf (is, "%s", coordx); } fclose (is); setlocale(LC_NUMERIC,""); return 1; } /** Ouverture d'un fichier wrl contenant un modèle @param file chemin du fichier à ouvrir @param m pointeur sur le modèle @return 1 si succès, 0 sinon */ int a2ri_vf_load_wrl ( char *file, vf_model * m) { FILE *is = NULL; char str[20]; is = fopen (file, "r"); if (is == NULL) return 0; fscanf (is, "%s", str); fscanf (is, "%s", str); if (!strcmp (str, "v1.0") || !strcmp (str, "V1.0")) return a2ri_vf_load_wrl1 (file, m); if (!strcmp (str, "v2.0") || !strcmp (str, "V2.0")) return a2ri_vf_load_wrl2 (file, m); return 0; } /** Ouverture d'un fichier vef contenant un modèle @param file chemin du fichier à ouvrir @param m pointeur sur le modèle @return 1 si succès, 0 sinon */ int a2ri_vf_load_vef ( char *file, vf_model * m) { FILE *is = NULL; int nbvertex, nbedge, nbface, ve1, ve2, ve3, ed1, ed2, ed3, classif; double coordx, coordy, coordz; setlocale(LC_NUMERIC,"C"); is = fopen (file, "r"); if (is == NULL) return 0; a2ri_vf_init (m); //lecture du nombre de sommets fscanf (is, "%d", &nbvertex); //lecture du nombre d'aretes fscanf (is, "%d", &nbedge); //lecture du nombre de faces fscanf (is, "%d", &nbface); //lecture des sommets for (int i = 0; i < nbvertex; i++) { fscanf (is, "%lf", &coordx); fscanf (is, "%lf", &coordy); fscanf (is, "%lf", &coordz); //ajout d'un sommet a2ri_vf_add_vertex (m, coordx, coordy, coordz); //mis à jour de la bounding box if (i == 0) { m->xmin = coordx; m->xmax = coordx; m->ymin = coordy; m->ymax = coordy; m->zmin = coordz; m->zmax = coordz; } else { if (coordx < m->xmin) m->xmin = coordx; if (coordx > m->xmax) m->xmax = coordx; if (coordy < m->ymin) m->ymin = coordy; if (coordy > m->ymax) m->ymax = coordy; if (coordz < m->zmin) m->zmin = coordz; if (coordz > m->zmax) m->zmax = coordz; } } //lecture des aretes et enregistrement dans un tableau temporaire vf_edge *temp = (vf_edge *) malloc (nbedge * sizeof (vf_edge)); a2ri_erreur_critique_si (temp == NULL, "erreur allocation memoire pour temp\na2ri_vf_load_vef"); for (int i = 0; i < nbedge; i++) { fscanf (is, "%d", &ve1); fscanf (is, "%d", &ve2); temp[i].ve1 = ve1; temp[i].ve2 = ve2; } //lecture des faces for (int i = 0; i < nbface; i++) { fscanf (is, "%d", &ed1); fscanf (is, "%d", &ed2); fscanf (is, "%d", &ed3); //recherche des trois sommets contenu dans les trois aretes if (temp[ed1].ve1 == temp[ed2].ve1 || temp[ed1].ve1 == temp[ed2].ve2) { ve1 = temp[ed1].ve1; ve3 = temp[ed1].ve2; } else { ve1 = temp[ed1].ve2; ve3 = temp[ed1].ve1; } if (temp[ed2].ve1 == temp[ed3].ve1 || temp[ed2].ve1 == temp[ed3].ve2) ve2 = temp[ed2].ve1; else ve2 = temp[ed2].ve2; //ajout de la face a2ri_vf_add_face (m, ve1, ve2, ve3); } //lecture des classification si disponible for (int i = 0; i < nbface; i++) { if (!feof (is)) { fscanf (is, "%d", &classif); m->fa[i].type = classif; } } fclose (is); setlocale(LC_NUMERIC,""); return 1; } /** Ouverture d'un fichier gts contenant un modèle @param file chemin du fichier à ouvrir @param m pointeur sur le modèle @return 1 si succès, 0 sinon */ int a2ri_vf_load_gts ( char *file, vf_model * m) { FILE *is = NULL; int nbvertex, nbedge, nbface, ve1, ve2, ve3, ed1, ed2, ed3, classif; double coordx, coordy, coordz; setlocale(LC_NUMERIC,"C"); is = fopen (file, "r"); if (is == NULL) return 0; a2ri_vf_init (m); //lecture du nombre de sommets fscanf (is, "%d", &nbvertex); //lecture du nombre d'aretes fscanf (is, "%d", &nbedge); //lecture du nombre de faces fscanf (is, "%d", &nbface); //lecture des sommets for (int i = 0; i < nbvertex; i++) { fscanf (is, "%lf", &coordx); fscanf (is, "%lf", &coordy); fscanf (is, "%lf", &coordz); //ajout d'un sommet a2ri_vf_add_vertex (m, coordx, coordy, coordz); //mis à jour de la bounding box if (i == 0) { m->xmin = coordx; m->xmax = coordx; m->ymin = coordy; m->ymax = coordy; m->zmin = coordz; m->zmax = coordz; } else { if (coordx < m->xmin) m->xmin = coordx; if (coordx > m->xmax) m->xmax = coordx; if (coordy < m->ymin) m->ymin = coordy; if (coordy > m->ymax) m->ymax = coordy; if (coordz < m->zmin) m->zmin = coordz; if (coordz > m->zmax) m->zmax = coordz; } } //lecture des aretes et enregistrement dans un tableau temporaire vf_edge *temp = (vf_edge *) malloc (nbedge * sizeof (vf_edge)); a2ri_erreur_critique_si (temp == NULL, "erreur allocation memoire pour temp\na2ri_vf_load_gts"); for (int i = 0; i < nbedge; i++) { fscanf (is, "%d", &ve1); fscanf (is, "%d", &ve2); ve1--; ve2--; temp[i].ve1 = ve1; temp[i].ve2 = ve2; } //lecture des faces for (int i = 0; i < nbface; i++) { fscanf (is, "%d", &ed1); fscanf (is, "%d", &ed2); fscanf (is, "%d", &ed3); ed1--; ed2--; ed3--; //recherche des trois sommets contenu dans les trois aretes if (temp[ed1].ve1 == temp[ed2].ve1 || temp[ed1].ve1 == temp[ed2].ve2) { ve1 = temp[ed1].ve1; ve3 = temp[ed1].ve2; } else { ve1 = temp[ed1].ve2; ve3 = temp[ed1].ve1; } if (temp[ed2].ve1 == temp[ed3].ve1 || temp[ed2].ve1 == temp[ed3].ve2) ve2 = temp[ed2].ve1; else ve2 = temp[ed2].ve2; //ajout de la face a2ri_vf_add_face (m, ve1, ve2, ve3); } //lecture des classification si disponible for (int i = 0; i < nbface; i++) { if (!feof (is)) { fscanf (is, "%d", &classif); m->fa[i].type = classif; } } fclose (is); setlocale(LC_NUMERIC,""); return 1; } /** Ouverture d'un fichier ply contenant un modèle @param file chemin du fichier à ouvrir @param m pointeur sur le modèle @return 1 si succès, 0 sinon */ int a2ri_vf_load_ply ( char *file, vf_model * m) { int prop = 0, nbpropvertex = 0, nbpropface = 0, nbvertex, nbface, ve1, ve2, ve3; char str[20]; double coordx, coordy, coordz; FILE *is = NULL; setlocale(LC_NUMERIC,"C"); is = fopen (file, "r"); if (is == NULL) return 0; fscanf (is, "%s", str); if (strcmp (str, "ply")) return 0; while (strcmp (str, "end_header")) { fscanf (is, "%s", str); if (prop == 1 && !strcmp (str, "property")) nbpropvertex++; if (prop == 2 && !strcmp (str, "property")) nbpropface++; if (!strcmp (str, "element")) { fscanf (is, "%s", str); //lecture du nombre de sommets if (!strcmp (str, "vertex")) { prop = 1; fscanf (is, "%d", &nbvertex); } //lecture du nombre de face else { if (!strcmp (str, "face")) { prop = 1; fscanf (is, "%d", &nbface); } } } } //lecture des sommets for (int i = 0; i < nbvertex; i++) { fscanf (is, "%lf %lf %lf", &coordx, &coordy, &coordz); //ajout d'un sommet a2ri_vf_add_vertex (m, coordx, coordy, coordz); //mis à jour de la bounding box if (i == 0) { m->xmin = coordx; m->xmax = coordx; m->ymin = coordy; m->ymax = coordy; m->zmin = coordz; m->zmax = coordz; } else { if (coordx < m->xmin) m->xmin = coordx; if (coordx > m->xmax) m->xmax = coordx; if (coordy < m->ymin) m->ymin = coordy; if (coordy > m->ymax) m->ymax = coordy; if (coordz < m->zmin) m->zmin = coordz; if (coordz > m->zmax) m->zmax = coordz; } for (int j = 0; j < nbpropvertex - 4; j++) fscanf (is, "%s", str); } //lecture des faces for (int i = 0; i < nbface; i++) { fscanf (is, "%d", &ve1); fscanf (is, "%d %d %d", &ve1, &ve2, &ve3); //ajout d'une face a2ri_vf_add_face (m, ve1, ve2, ve3); } fclose (is); setlocale(LC_NUMERIC,""); return 1; } /** Ouverture d'un fichier off contenant un modèle @param file chemin du fichier à ouvrir @param m pointeur sur le modèle @return 1 si succès, 0 sinon */ int a2ri_vf_load_off ( char *file, vf_model * m) { FILE *is = NULL; int nbvertex, nbface, ve1, ve2, ve3; double coordx, coordy, coordz; char str[250]; setlocale(LC_NUMERIC,"C"); is = fopen (file, "r"); if (is == NULL) return 0; fscanf (is, "%s", str); if (strcmp (str, "OFF")) return 0; //lecture du nombre de sommets et de faces fscanf (is, "%d %d %d", &nbvertex, &nbface, &ve1); //lecture des sommets for (int i = 0; i < nbvertex; i++) { fscanf (is, "%lf %lf %lf", &coordx, &coordy, &coordz); //ajout du sommet a2ri_vf_add_vertex (m, coordx, coordy, coordz); //mis à jour de la bounding box if (i == 0) { m->xmin = coordx; m->xmax = coordx; m->ymin = coordy; m->ymax = coordy; m->zmin = coordz; m->zmax = coordz; } else { if (coordx < m->xmin) m->xmin = coordx; if (coordx > m->xmax) m->xmax = coordx; if (coordy < m->ymin) m->ymin = coordy; if (coordy > m->ymax) m->ymax = coordy; if (coordz < m->zmin) m->zmin = coordz; if (coordz > m->zmax) m->zmax = coordz; } } //lecture des faces for (int i = 0; i < nbface; i++) { fscanf (is, "%d", &ve1); fscanf (is, "%d %d %d", &ve1, &ve2, &ve3); //ajout d'une face a2ri_vf_add_face (m, ve1, ve2, ve3); } fclose (is); setlocale(LC_NUMERIC,""); return 1; } /** Ouverture d'un fichier stl contenant un modèle @param file chemin du fichier à ouvrir @param m pointeur sur le modèle @return 1 si succès, 0 sinon */ int a2ri_vf_load_stl ( char *file, vf_model * m) { FILE *is = NULL; char str[250]; is = fopen (file, "r"); if (is == NULL) return 0; fscanf (is, "%s", str); fclose (is); if (!strcmp (str, "solid")) return a2ri_vf_load_ascii_stl (file, m); else return a2ri_vf_load_binary_stl (file, m); } /** Ouverture d'un fichier stl binaire contenant un modèle @param file chemin du fichier à ouvrir @param m pointeur sur le modèle @return 1 si succès, 0 sinon */ int a2ri_vf_load_binary_stl ( char *file, vf_model * m) { FILE *is = NULL; char str[80]; unsigned int nbface; unsigned char finligne; float coordx, coordy, coordz; int ve1 = 0, ve2 = 0, ve3 = 0; point3d ptmin, ptmax; space_partition sp; setlocale(LC_NUMERIC,"C"); is = fopen (file, "rb"); if (is == NULL) return 0; fread (&str, sizeof (char), 80, is); fread (&nbface, sizeof (unsigned int), 1, is); //recherche de la bounding box du modele numerique for (unsigned int i = 0; i < nbface; i++) { fread (&coordx, sizeof (float), 1, is); fread (&coordy, sizeof (float), 1, is); fread (&coordz, sizeof (float), 1, is); for (unsigned int j = 0; j < 3; j++) { //read the vertex fread (&coordx, sizeof (float), 1, is); fread (&coordy, sizeof (float), 1, is); fread (&coordz, sizeof (float), 1, is); if (i == 0 && j == 0) { m->xmin = coordx; m->xmax = coordx; m->ymin = coordy; m->ymax = coordy; m->zmin = coordz; m->zmax = coordz; } else { if (coordx < m->xmin) m->xmin = coordx; if (coordx > m->xmax) m->xmax = coordx; if (coordy < m->ymin) m->ymin = coordy; if (coordy > m->ymax) m->ymax = coordy; if (coordz < m->zmin) m->zmin = coordz; if (coordz > m->zmax) m->zmax = coordz; } } fread (&finligne, 1, 1, is); fread (&finligne, 1, 1, is); } point3d_init (&ptmin, m->xmin, m->ymin, m->zmin); point3d_init (&ptmax, m->xmax, m->ymax, m->zmax); int nb_part = (int) (pow (nbface/22.0, (1.0 / 3.0))) + 1; space_partition_new (&sp, ptmin, ptmax, nb_part, nb_part, nb_part); //retour au debut du fichier fseek (is, 0, SEEK_SET); fread (&str, sizeof (char), 80, is); fread (&nbface, sizeof (unsigned int), 1, is); for (unsigned int i = 0; i < nbface; i++) { fread (&coordx, sizeof (float), 1, is); fread (&coordy, sizeof (float), 1, is); fread (&coordz, sizeof (float), 1, is); for (unsigned int j = 0; j < 3; j++) { fread (&coordx, sizeof (float), 1, is); fread (&coordy, sizeof (float), 1, is); fread (&coordz, sizeof (float), 1, is); //read the vertex point3d_init (&ptmin, coordx, coordy, coordz); if (i == 0 && j == 0) { ve1 = 0; ptmin.att_int = space_partition_nb_points (&sp); space_partition_add_point (&sp, ptmin); a2ri_vf_add_vertex (m, ptmin.x, ptmin.y, ptmin.z); } else { point3d *ret=space_partition_contains_point (&sp, ptmin); if (ret!=NULL) { switch (j) { case 0: ve1 = ret->att_int; break; case 1: ve2 = ret->att_int; break; default: ve3 = ret->att_int; } } else { ptmin.att_int = space_partition_nb_points (&sp); switch (j) { case 0: ve1 = ptmin.att_int; break; case 1: ve2 = ptmin.att_int; break; default: ve3 = ptmin.att_int; } space_partition_add_point (&sp, ptmin); a2ri_vf_add_vertex (m, ptmin.x, ptmin.y, ptmin.z); } } } a2ri_vf_add_face (m, ve1, ve2, ve3); fread (&finligne, 1, 1, is); fread (&finligne, 1, 1, is); } fclose (is); setlocale(LC_NUMERIC,""); return 1; } /** Ouverture d'un fichier stl ascii contenant un modèle @param file chemin du fichier à ouvrir @param m pointeur sur le modèle @return 1 si succès, 0 sinon */ int a2ri_vf_load_ascii_stl ( char *file, vf_model * m) { FILE *is = NULL; int ve1, ve2, ve3, i = 0, fin = 0; double coordx, coordy, coordz; char str[250]; setlocale(LC_NUMERIC,"C"); is = fopen (file, "r"); if (is == NULL) return 0; fscanf (is, "%s", str); while (strcmp (str, "facet")) fscanf (is, "%s", str); while (!fin) { fscanf (is, "%s", str); //read normal fscanf (is, "%s", str); fscanf (is, "%s", str); fscanf (is, "%s", str); //read the 3 values of the normal fscanf (is, "%s", str); fscanf (is, "%s", str); //outer loop fscanf (is, "%s", str); //read vertex fscanf (is, "%s", str); coordx = atof (str); //coordx fscanf (is, "%s", str); coordy = atof (str); //coordy fscanf (is, "%s", str); coordz = atof (str); //coordz ve1 = a2ri_vf_search_vertex (*m, coordx, coordy, coordz); if (ve1 == -1) { ve1 = m->nbvertex; a2ri_vf_add_vertex (m, coordx, coordy, coordz); } if (i == 0) { m->xmin = coordx; m->xmax = coordx; m->ymin = coordy; m->ymax = coordy; m->zmin = coordz; m->zmax = coordz; i++; } else { if (coordx < m->xmin) m->xmin = coordx; if (coordx > m->xmax) m->xmax = coordx; if (coordy < m->ymin) m->ymin = coordy; if (coordy > m->ymax) m->ymax = coordy; if (coordz < m->zmin) m->zmin = coordz; if (coordz > m->zmax) m->zmax = coordz; } fscanf (is, "%s", str); //read vertex fscanf (is, "%s", str); coordx = atof (str); //coordx fscanf (is, "%s", str); coordy = atof (str); //coordy fscanf (is, "%s", str); coordz = atof (str); //coordz ve2 = a2ri_vf_search_vertex (*m, coordx, coordy, coordz); if (ve2 == -1) { ve2 = m->nbvertex; a2ri_vf_add_vertex (m, coordx, coordy, coordz); } if (coordx < m->xmin) m->xmin = coordx; if (coordx > m->xmax) m->xmax = coordx; if (coordy < m->ymin) m->ymin = coordy; if (coordy > m->ymax) m->ymax = coordy; if (coordz < m->zmin) m->zmin = coordz; if (coordz > m->zmax) m->zmax = coordz; fscanf (is, "%s", str); //read vertex fscanf (is, "%s", str); coordx = atof (str); //coordx fscanf (is, "%s", str); coordy = atof (str); //coordy fscanf (is, "%s", str); coordz = atof (str); //coordz; ve3 = a2ri_vf_search_vertex (*m, coordx, coordy, coordz); if (ve3 == -1) { ve3 = m->nbvertex; a2ri_vf_add_vertex (m, coordx, coordy, coordz); } if (coordx < m->xmin) m->xmin = coordx; if (coordx > m->xmax) m->xmax = coordx; if (coordy < m->ymin) m->ymin = coordy; if (coordy > m->ymax) m->ymax = coordy; if (coordz < m->zmin) m->zmin = coordz; if (coordz > m->zmax) m->zmax = coordz; a2ri_vf_add_face (m, ve1, ve2, ve3); fscanf (is, "%s", str); //read endloop fscanf (is, "%s", str); //read endfacet fscanf (is, "%s", str); //read facet ou endsolid fin = !strcmp (str, "endsolid"); } fclose (is); setlocale(LC_NUMERIC,""); return 1; } /** Enregistrement d'un modèle dans un format défini par l'extension du nom de fichier @param file nom du fichier @param m le modèle @return aucun */ int a2ri_vf_save_file ( char *file, vf_model m) { char ext[4]; memcpy (ext, file + (strlen (file) - 3), 3); ext[3] = 0; //enregistrement du modèle en fonction de l'extension if (!strcmp (ext, "wrl")) { return a2ri_vf_save_wrl (file, m); } if (!strcmp (ext, "vef")) { return a2ri_vf_save_vef (file, m); } if (!strcmp (ext, "pgn")) { return a2ri_vf_save_pgn (file, m); } if (!strcmp (ext, "ply")) { return a2ri_vf_save_ply (file, m); } if (!strcmp (ext, "off")) { return a2ri_vf_save_off (file, m); } if (!strcmp (ext, "obj")) { return a2ri_vf_save_obj (file, m); } if (!strcmp (ext, "gts")) { return a2ri_vf_save_gts (file, m); } if (!strcmp (ext, "stl")) { return a2ri_vf_save_stl (file, m); } return 0; } /** Enregistrement d'un modèle dans un fichier wr@param file chemin du fichier @param m modèle à sauvegarder @return 1 si succès, 0 sinon */ int a2ri_vf_save_wrl ( char *file, vf_model m) { setlocale(LC_NUMERIC,"C"); if (strlen (file) < 4) { strcat (file, ".wrl"); } char ext[5]; memcpy (ext, file + (strlen (file) - 4), 4); ext[4] = '\0'; if (strcmp (ext, ".wrl")) strcat (file, ".wrl"); FILE *os = NULL; os = fopen (file, "w"); if (os == NULL) return 0; //ecriture de l'en-tete fprintf (os, "#VRML V2.0 utf8\n"); fprintf (os, "Shape{\n"); fprintf (os, "appearance Appearance {\n"); fprintf (os, "material Material {\n"); fprintf (os, "}\n"); fprintf (os, "}\n"); fprintf (os, "geometry IndexedFaceSet{\n"); fprintf (os, "coord Coordinate{\n"); fprintf (os, "point[\n"); //ecriture des sommets for (int i = 0; i < m.nbvertex; i++) fprintf (os, "%f %f %f,\n", m.ve[i].x, m.ve[i].y, m.ve[i].z); fprintf (os, "]\n"); fprintf (os, "}\n"); //ecriture des faces fprintf (os, "coordIndex[\n"); for (int i = 0; i < m.nbface; i++) { int nb1 = m.fa[i].ve1; int nb2 = m.fa[i].ve2; int nb3 = m.fa[i].ve3; fprintf (os, "%d %d %d -1\n", nb1, nb2, nb3); } fprintf (os, "]\n"); fprintf (os, "}\n"); fprintf (os, "}\n"); fclose (os); setlocale(LC_NUMERIC,""); return 1; } /** Enregistrement d'un modèle dans un fichier wrl version 1.0 @param file chemin du fichier @param m modèle à sauvegarder @return 1 si succès, 0 sinon */ int a2ri_vf_save_wrl_v1 ( char *file, vf_model m) { setlocale(LC_NUMERIC,"C"); if (strlen (file) < 4) { strcat (file, ".wrl"); } char ext[5]; memcpy (ext, file + (strlen (file) - 4), 4); ext[4] = '\0'; if (strcmp (ext, ".wrl")) strcat (file, ".wrl"); FILE *os = NULL; os = fopen (file, "w"); if (os == NULL) return 0; //ecriture de l'en-tete fprintf (os, "#VRML V1.0 ascii\n"); fprintf (os, "Separator {\n"); fprintf (os, "Switch {\n"); fprintf (os, "DEF Pol{\n"); fprintf (os, "Separator {\n"); fprintf (os, "Coordinate3 {\n"); fprintf (os, "point[\n"); //ecriture des sommets for (int i = 0; i < m.nbvertex; i++) fprintf (os, "%f %f %f,\n", m.ve[i].x, m.ve[i].y, m.ve[i].z); fprintf (os, "]\n"); fprintf (os, "}\n"); //ecriture des faces fprintf (os, "IndexedFaceSet {\n"); fprintf (os, "coordIndex [\n"); for (int i = 0; i < m.nbface; i++) { int nb1 = m.fa[i].ve1; int nb2 = m.fa[i].ve2; int nb3 = m.fa[i].ve3; fprintf (os, "%d, %d, %d, -1,\n", nb1, nb2, nb3); } fprintf (os, "]\n"); fprintf (os, "}\n"); fprintf (os, "}\n"); fprintf (os, "}\n"); fclose (os); setlocale(LC_NUMERIC,""); return 1; } /** Enregistrement d'un modèle dans un fichier pgn @param file chemin du fichier @param m modèle à sauvegarder @return 1 si succès, 0 sinon */ int a2ri_vf_save_pgn ( char *file, vf_model m) { setlocale(LC_NUMERIC,"C"); if (strlen (file) < 4) { strcat (file, ".pgn"); } char ext[5]; memcpy (ext, file + (strlen (file) - 4), 4); ext[4] = '\0'; if (strcmp (ext, ".pgn")) strcat (file, ".pgn"); FILE *os = NULL; os = fopen (file, "w"); if (os == NULL) return 0; //ecriture du nombre de sommets et de faces fprintf (os, "%d %d\n", m.nbvertex, m.nbface); //ecriture des sommets for (int i = 0; i < m.nbvertex; i++) fprintf (os, "%lf %lf %lf\n", m.ve[i].x, m.ve[i].y, m.ve[i].z); fprintf (os, "\n"); //ecriture des faces for (int i = 0; i < m.nbface; i++) fprintf (os, "%d %d %d -1\n", m.fa[i].ve1, m.fa[i].ve2, m.fa[i].ve3); fclose (os); setlocale(LC_NUMERIC,""); return 1; } /** Enregistrement d'un modèle dans un fichier vef @param file chemin du fichier @param m modèle à sauvegarder @return 1 si succès, 0 sinon **/ int a2ri_vf_save_vef ( char *file, vf_model m) { hashtable *table = hashtable_new (m.nbvertex + m.nbface); hashtable *tabletemp = NULL; int p1, p2; setlocale(LC_NUMERIC,"C"); if (strlen (file) < 4) { strcat (file, ".vef"); } char ext[5]; memcpy (ext, file + (strlen (file) - 4), 4); ext[4] = '\0'; if (strcmp (ext, ".vef")) strcat (file, ".vef"); FILE *os = NULL; os = fopen (file, "w"); if (os == NULL) return 0; tabletemp = a2ri_vf_construction_edge_table (&m, NULL, 0); //ecriture du nombre de sommets, d'aretes et de faces fprintf (os, "%d %d %d\n", m.nbvertex, hashtable_size (tabletemp), m.nbface); hashtable_free (tabletemp); //ecriture des sommets for (int i = 0; i < m.nbvertex; i++) fprintf (os, "%lf %lf %lf\n", m.ve[i].x, m.ve[i].y, m.ve[i].z); fprintf (os, "\n"); //ecriture des aretes IFsave_vef_write_edge (&m, table, os); fprintf (os, "\n"); //ecriture des faces for (int i = 0; i < m.nbface; i++) { p1 = m.fa[i].ve1; p2 = m.fa[i].ve2; //recherche de l'arete dans la table de hachage vf_edge *edgetemp = hashtable_look_for (table, p1, p2); fprintf (os, "%d ", edgetemp->att_int); p1 = m.fa[i].ve2; p2 = m.fa[i].ve3; edgetemp = hashtable_look_for (table, p1, p2); fprintf (os, "%d ", edgetemp->att_int); p1 = m.fa[i].ve3; p2 = m.fa[i].ve1; edgetemp = hashtable_look_for (table, p1, p2); fprintf (os, "%d\n", edgetemp->att_int); } hashtable_free (table); fclose (os); setlocale(LC_NUMERIC,""); return 0; } /** Enregistrement d'un modèle dans un fichier gts @param file chemin du fichier @param m modèle à sauvegarder @return 1 si succès, 0 sinon **/ int a2ri_vf_save_gts ( char *file, vf_model m) { hashtable *table = hashtable_new (m.nbvertex + m.nbface); hashtable *tabletemp = NULL; int p1, p2; setlocale(LC_NUMERIC,"C"); if (strlen (file) < 4) { strcat (file, ".gts"); } char ext[5]; memcpy (ext, file + (strlen (file) - 4), 4); ext[4] = '\0'; if (strcmp (ext, ".gts")) strcat (file, ".gts"); FILE *os = NULL; os = fopen (file, "w"); if (os == NULL) return 0; tabletemp = a2ri_vf_construction_edge_table (&m, NULL, 0); //ecriture du nombre de sommets, d'aretes et de faces fprintf (os, "%d %d %d\n", m.nbvertex, hashtable_size (tabletemp), m.nbface); hashtable_free (tabletemp); //ecriture des sommets for (int i = 0; i < m.nbvertex; i++) fprintf (os, "%lf %lf %lf\n", m.ve[i].x, m.ve[i].y, m.ve[i].z); fprintf (os, "\n"); //ecriture des aretes IFsave_gts_write_edge (&m, table, os); fprintf (os, "\n"); //ecriture des faces for (int i = 0; i < m.nbface; i++) { p1 = m.fa[i].ve1; p2 = m.fa[i].ve2; //recherche de l'arete dans la table de hachage vf_edge *edgetemp = hashtable_look_for (table, p1, p2); fprintf (os, "%d ", edgetemp->att_int + 1); p1 = m.fa[i].ve2; p2 = m.fa[i].ve3; edgetemp = hashtable_look_for (table, p1, 2); fprintf (os, "%d ", edgetemp->att_int + 1); p1 = m.fa[i].ve3; p2 = m.fa[i].ve1; edgetemp = hashtable_look_for (table, p1, p2); fprintf (os, "%d\n", edgetemp->att_int + 1); } hashtable_free (table); fclose (os); setlocale(LC_NUMERIC,""); return 0; } /** Enregistrement d'un modèle dans un fichier off @param file chemin du fichier @param m modèle à sauvegarder @return 1 si succès, 0 sinon */ int a2ri_vf_save_off ( char *file, vf_model m) { setlocale(LC_NUMERIC,"C"); if (strlen (file) < 4) { strcat (file, ".off"); } char ext[5]; memcpy (ext, file + (strlen (file) - 4), 4); ext[4] = '\0'; if (strcmp (ext, ".off")) strcat (file, ".off"); FILE *os = NULL; os = fopen (file, "w"); if (os == NULL) return 0; //ecriture du nombre de sommets et de faces fprintf (os, "OFF\n%d %d 0\n", m.nbvertex, m.nbface); //ecriture des sommets for (int i = 0; i < m.nbvertex; i++) fprintf (os, "%lf %lf %lf\n", m.ve[i].x, m.ve[i].y, m.ve[i].z); fprintf (os, "\n"); //ecriture des faces for (int i = 0; i < m.nbface; i++) fprintf (os, "3 %d %d %d\n", m.fa[i].ve1, m.fa[i].ve2, m.fa[i].ve3); fclose (os); setlocale(LC_NUMERIC,""); return 1; } /** Enregistrement d'un modèle dans un fichier ply @param file chemin du fichier @param m modèle à sauvegarder @return 1 si succès, 0 sinon */ int a2ri_vf_save_ply ( char *file, vf_model m) { int ve1, ve2, ve3; setlocale(LC_NUMERIC,"C"); if (strlen (file) < 4) { strcat (file, ".ply"); } char ext[5]; memcpy (ext, file + (strlen (file) - 4), 4); ext[4] = '\0'; if (strcmp (ext, ".ply")) strcat (file, ".ply"); FILE *os = NULL; os = fopen (file, "w"); if (os == NULL) return 0; //ecriture des en-tetes fprintf (os, "ply\nformat ascii 1.0\ncomment zipper output\n"); fprintf (os, "element vertex %d\nproperty float x\nproperty float y\nproperty float z\nelement face %d\n", m.nbvertex, m.nbface); fprintf (os, "property list uchar int vertex_indices\nend_header\n"); //ecriture des sommets for (int i = 0; i < m.nbvertex; i++) fprintf (os, "%f %f %f\n", m.ve[i].x, m.ve[i].y, m.ve[i].z); //ecriture des faces for (int i = 0; i < m.nbface; i++) { ve1 = m.fa[i].ve1; ve2 = m.fa[i].ve2; ve3 = m.fa[i].ve3; fprintf (os, "3 %d %d %d \n", ve1, ve2, ve3); } fclose (os); setlocale(LC_NUMERIC,""); return 1; } /** Enregistrement d'un modèle dans un fichier obj @param file chemin du fichier @param m modèle à sauvegarder @return 1 si succès, 0 sinon */ int a2ri_vf_save_obj ( char *file, vf_model m) { setlocale(LC_NUMERIC,"C"); if (strlen (file) < 4) { strcat (file, ".obj"); } char ext[5]; memcpy (ext, file + (strlen (file) - 4), 4); ext[4] = '\0'; if (strcmp (ext, ".obj")) strcat (file, ".obj"); FILE *os = NULL; os = fopen (file, "w"); if (os == NULL) return 0; //ecriture des sommets for (int i = 0; i < m.nbvertex; i++) fprintf (os, "v %lf %lf %lf\n", m.ve[i].x, m.ve[i].y, m.ve[i].z); fprintf (os, "\n"); //ecriture des faces for (int i = 0; i < m.nbface; i++) fprintf (os, "f %d %d %d\n", m.fa[i].ve1 + 1, m.fa[i].ve2 + 1, m.fa[i].ve3 + 1); fclose (os); setlocale(LC_NUMERIC,""); return 1; } /** Enregistrement d'un modèle dans un fichier stl @param file chemin du fichier @param m modèle à sauvegarder @return 1 si succès, 0 sinon */ int a2ri_vf_save_stl ( char *file, vf_model m) { setlocale(LC_NUMERIC,"C"); if (strlen (file) < 4) { strcat (file, ".stl"); } char ext[5]; memcpy (ext, file + (strlen (file) - 4), 4); ext[4] = '\0'; if (strcmp (ext, ".stl")) strcat (file, ".stl"); FILE *os = NULL; os = fopen (file, "wb"); if (os == NULL) return 0; fwrite ("generated by A2RI ", 1, 80, os); fwrite (&(m.nbface), sizeof (unsigned int), 1, os); for (int i = 0; i < m.nbface; i++) { vector3d AB, AC, normale; vector3d_init (&AB, m.ve[m.fa[i].ve2].x - m.ve[m.fa[i].ve1].x, m.ve[m.fa[i].ve2].y - m.ve[m.fa[i].ve1].y, m.ve[m.fa[i].ve2].z - m.ve[m.fa[i].ve1].z); vector3d_init (&AC, m.ve[m.fa[i].ve3].x - m.ve[m.fa[i].ve1].x, m.ve[m.fa[i].ve3].y - m.ve[m.fa[i].ve1].y, m.ve[m.fa[i].ve3].z - m.ve[m.fa[i].ve1].z); normale = vector3d_vectorialproduct (AB, AC); float x, y, z; x = normale.dx; y = normale.dy; z = normale.dz; fwrite (&x, sizeof (float), 1, os); fwrite (&y, sizeof (float), 1, os); fwrite (&z, sizeof (float), 1, os); x = m.ve[m.fa[i].ve1].x; y = m.ve[m.fa[i].ve1].y; z = m.ve[m.fa[i].ve1].z; fwrite (&x, sizeof (float), 1, os); fwrite (&y, sizeof (float), 1, os); fwrite (&z, sizeof (float), 1, os); x = m.ve[m.fa[i].ve2].x; y = m.ve[m.fa[i].ve2].y; z = m.ve[m.fa[i].ve2].z; fwrite (&x, sizeof (float), 1, os); fwrite (&y, sizeof (float), 1, os); fwrite (&z, sizeof (float), 1, os); x = m.ve[m.fa[i].ve3].x; y = m.ve[m.fa[i].ve3].y; z = m.ve[m.fa[i].ve3].z; fwrite (&x, sizeof (float), 1, os); fwrite (&y, sizeof (float), 1, os); fwrite (&z, sizeof (float), 1, os); fwrite (" ", 1, 2, os); } fclose (os); setlocale(LC_NUMERIC,""); return 1; } /** Ouverture d'un fichier contenant un modèle @param file chemin du fichier à ouvrir @param m pointeur sur le modèle @return 1 si succès, 0 sinon */ int a2ri_vef_open_file ( char *file, vef_model * m) { char ext[5]; memcpy (ext, file + (strlen (file) - 4), 4); ext[4] = 0; //appel de la fonction correspondant à l'extension du fichier if (!strcmp (ext, ".wrl")) return (a2ri_vef_load_wrl (file, m)); if (!strcmp (ext, ".vef")) return (a2ri_vef_load_vef (file, m)); if (!strcmp (ext, ".pgn")) return (a2ri_vef_load_pgn (file, m)); if (!strcmp (ext, ".ply")) return (a2ri_vef_load_ply (file, m)); if (!strcmp (ext, ".off")) return (a2ri_vef_load_off (file, m)); if (!strcmp (ext, ".obj")) return (a2ri_vef_load_obj (file, m)); if (!strcmp (ext, ".gts")) return (a2ri_vef_load_gts (file, m)); if (!strcmp (ext, ".stl")) return (a2ri_vef_load_stl (file, m)); return 0; } /** Ouverture d'un fichier pgn contenant un modèle @param file chemin du fichier à ouvrir @param m pointeur sur le modèle @return 1 si succès, 0 sinon */ int a2ri_vef_load_pgn ( char *file, vef_model * m) { FILE *is = NULL; double coordx, coordy, coordz; int classif, ar1, ar2, ar3, nbvertex, nbface; setlocale(LC_NUMERIC,"C"); is = fopen (file, "r"); if (is == NULL) return 0; a2ri_vef_init (m); //lecture du nombre de sommets fscanf (is, "%d", &nbvertex); //lecture du nombre de faces fscanf (is, "%d", &nbface); //lecture des sommets for (int i = 0; i < nbvertex; i++) { fscanf (is, "%lf", &coordx); fscanf (is, "%lf", &coordy); fscanf (is, "%lf", &coordz); a2ri_vef_add_vertex (m, coordx, coordy, coordz); //mis à jour de la bounding box if (i == 0) { m->xmin = coordx; m->xmax = coordx; m->ymin = coordy; m->ymax = coordy; m->zmin = coordz; m->zmax = coordz; } else { if (coordx < m->xmin) m->xmin = coordx; if (coordx > m->xmax) m->xmax = coordx; if (coordy < m->ymin) m->ymin = coordy; if (coordy > m->ymax) m->ymax = coordy; if (coordz < m->zmin) m->zmin = coordz; if (coordz > m->zmax) m->zmax = coordz; } } //lecture des faces for (int i = 0; i < nbface; i++) { //lecture des trois sommets composant la face fscanf (is, "%d", &ar1); fscanf (is, "%d", &ar2); fscanf (is, "%d", &ar3); //ajout des aretes avec vérification au préalable de leur existence a2ri_vef_add_edge (m, ar1, ar2, 1); a2ri_vef_add_edge (m, ar2, ar3, 1); a2ri_vef_add_edge (m, ar3, ar1, 1); //recherche des aretes int ed1 = a2ri_vef_search_edge (*m, ar1, ar2); int ed2 = a2ri_vef_search_edge (*m, ar2, ar3); int ed3 = a2ri_vef_search_edge (*m, ar3, ar1); //ajout de la faces avec les trois aretes a2ri_vef_add_face (m, ed1, ed2, ed3); // reading the -1 fscanf (is, "%d", &ar1); } //lecture des classifications si disponible for (int i = 0; i < nbface; i++) { if (!feof (is)) { fscanf (is, "%d", &classif); m->fa[i].type = classif; } } fclose (is); setlocale(LC_NUMERIC,""); return 1; } /** Ouverture d'un fichier stl binaire contenant un modèle @param file chemin du fichier à ouvrir @param m pointeur sur le modèle @return 1 si succès, 0 sinon */ int a2ri_vef_load_binary_stl ( char *file, vef_model * m) { FILE *is = NULL; char str[80]; unsigned int nbface; unsigned char finligne; float coordx, coordy, coordz; int ve1, ve2, ve3, ed1, ed2, ed3; setlocale(LC_NUMERIC,"C"); is = fopen (file, "rb"); if (is == NULL) return 0; fread (&str, sizeof (char), 80, is); fread (&nbface, sizeof (unsigned int), 1, is); for (unsigned int i = 0; i < nbface; i++) { fread (&coordx, sizeof (float), 1, is); fread (&coordy, sizeof (float), 1, is); fread (&coordz, sizeof (float), 1, is); //read the normal fread (&coordx, sizeof (float), 1, is); fread (&coordy, sizeof (float), 1, is); fread (&coordz, sizeof (float), 1, is); //read the first vertex ve1 = a2ri_vef_search_vertex (*m, coordx, coordy, coordz); if (ve1 == -1) { ve1 = m->nbvertex; a2ri_vef_add_vertex (m, coordx, coordy, coordz); } if (i == 0) { m->xmin = coordx; m->xmax = coordx; m->ymin = coordy; m->ymax = coordy; m->zmin = coordz; m->zmax = coordz; } else { if (coordx < m->xmin) m->xmin = coordx; if (coordx > m->xmax) m->xmax = coordx; if (coordy < m->ymin) m->ymin = coordy; if (coordy > m->ymax) m->ymax = coordy; if (coordz < m->zmin) m->zmin = coordz; if (coordz > m->zmax) m->zmax = coordz; } fread (&coordx, sizeof (float), 1, is); fread (&coordy, sizeof (float), 1, is); fread (&coordz, sizeof (float), 1, is); //read the second vertex ve2 = a2ri_vef_search_vertex (*m, coordx, coordy, coordz); if (ve2 == -1) { ve2 = m->nbvertex; a2ri_vef_add_vertex (m, coordx, coordy, coordz); } if (coordx < m->xmin) m->xmin = coordx; if (coordx > m->xmax) m->xmax = coordx; if (coordy < m->ymin) m->ymin = coordy; if (coordy > m->ymax) m->ymax = coordy; if (coordz < m->zmin) m->zmin = coordz; if (coordz > m->zmax) m->zmax = coordz; fread (&coordx, sizeof (float), 1, is); fread (&coordy, sizeof (float), 1, is); fread (&coordz, sizeof (float), 1, is); //read the third vertex ve3 = a2ri_vef_search_vertex (*m, coordx, coordy, coordz); if (ve3 == -1) { ve3 = m->nbvertex; a2ri_vef_add_vertex (m, coordx, coordy, coordz); } if (coordx < m->xmin) m->xmin = coordx; if (coordx > m->xmax) m->xmax = coordx; if (coordy < m->ymin) m->ymin = coordy; if (coordy > m->ymax) m->ymax = coordy; if (coordz < m->zmin) m->zmin = coordz; if (coordz > m->zmax) m->zmax = coordz; ed1 = a2ri_vef_search_edge (*m, ve1, ve2); ed2 = a2ri_vef_search_edge (*m, ve1, ve3); ed3 = a2ri_vef_search_edge (*m, ve2, ve3); if (ed1 == -1) { ed1 = m->nbedge; a2ri_vef_add_edge (m, ve1, ve2, 0); } if (ed2 == -1) { ed2 = m->nbedge; a2ri_vef_add_edge (m, ve1, ve3, 0); } if (ed3 == -1) { ed3 = m->nbedge; a2ri_vef_add_edge (m, ve2, ve3, 0); } a2ri_vef_add_face (m, ed2, ed1, ed3); fread (&finligne, 1, 1, is); fread (&finligne, 1, 1, is); } fclose (is); setlocale(LC_NUMERIC,""); return 1; } /** Ouverture d'un fichier stl ascii contenant un modèle @param file chemin du fichier à ouvrir @param m pointeur sur le modèle @return 1 si succès, 0 sinon */ int a2ri_vef_load_ascii_stl ( char *file, vef_model * m) { FILE *is = NULL; int ve1, ve2, ve3, i = 0, fin = 0, ed1, ed2, ed3; double coordx, coordy, coordz; char str[250]; setlocale(LC_NUMERIC,"C"); is = fopen (file, "r"); if (is == NULL) return 0; fscanf (is, "%s", str); while (strcmp (str, "facet")) fscanf (is, "%s", str); while (!fin) { fscanf (is, "%s", str); //read normal fscanf (is, "%s", str); fscanf (is, "%s", str); fscanf (is, "%s", str); //read the 3 values of the normal fscanf (is, "%s", str); fscanf (is, "%s", str); //outer loop fscanf (is, "%s", str); //read vertex fscanf (is, "%s", str); coordx = atof (str); //coordx fscanf (is, "%s", str); coordy = atof (str); //coordy fscanf (is, "%s", str); coordz = atof (str); //coordz ve1 = a2ri_vef_search_vertex (*m, coordx, coordy, coordz); if (ve1 == -1) { ve1 = m->nbvertex; a2ri_vef_add_vertex (m, coordx, coordy, coordz); } if (i == 0) { m->xmin = coordx; m->xmax = coordx; m->ymin = coordy; m->ymax = coordy; m->zmin = coordz; m->zmax = coordz; i++; } else { if (coordx < m->xmin) m->xmin = coordx; if (coordx > m->xmax) m->xmax = coordx; if (coordy < m->ymin) m->ymin = coordy; if (coordy > m->ymax) m->ymax = coordy; if (coordz < m->zmin) m->zmin = coordz; if (coordz > m->zmax) m->zmax = coordz; } fscanf (is, "%s", str); //read vertex fscanf (is, "%s", str); coordx = atof (str); //coordx fscanf (is, "%s", str); coordy = atof (str); //coordy fscanf (is, "%s", str); coordz = atof (str); //coordz ve2 = a2ri_vef_search_vertex (*m, coordx, coordy, coordz); if (ve2 == -1) { ve2 = m->nbvertex; a2ri_vef_add_vertex (m, coordx, coordy, coordz); } if (coordx < m->xmin) m->xmin = coordx; if (coordx > m->xmax) m->xmax = coordx; if (coordy < m->ymin) m->ymin = coordy; if (coordy > m->ymax) m->ymax = coordy; if (coordz < m->zmin) m->zmin = coordz; if (coordz > m->zmax) m->zmax = coordz; fscanf (is, "%s", str); //read vertex fscanf (is, "%s", str); coordx = atof (str); //coordx fscanf (is, "%s", str); coordy = atof (str); //coordy fscanf (is, "%s", str); coordz = atof (str); //coordz; ve3 = a2ri_vef_search_vertex (*m, coordx, coordy, coordz); if (ve3 == -1) { ve3 = m->nbvertex; a2ri_vef_add_vertex (m, coordx, coordy, coordz); } if (coordx < m->xmin) m->xmin = coordx; if (coordx > m->xmax) m->xmax = coordx; if (coordy < m->ymin) m->ymin = coordy; if (coordy > m->ymax) m->ymax = coordy; if (coordz < m->zmin) m->zmin = coordz; if (coordz > m->zmax) m->zmax = coordz; ed1 = a2ri_vef_search_edge (*m, ve1, ve2); ed2 = a2ri_vef_search_edge (*m, ve1, ve3); ed3 = a2ri_vef_search_edge (*m, ve2, ve3); if (ed1 == -1) { ed1 = m->nbedge; a2ri_vef_add_edge (m, ve1, ve2, 0); } if (ed2 == -1) { ed2 = m->nbedge; a2ri_vef_add_edge (m, ve1, ve3, 0); } if (ed3 == -1) { ed3 = m->nbedge; a2ri_vef_add_edge (m, ve2, ve3, 0); } a2ri_vef_add_face (m, ed2, ed1, ed3); fscanf (is, "%s", str); //read endloop fscanf (is, "%s", str); //read endfacet fscanf (is, "%s", str); //read facet ou endsolid fin = !strcmp (str, "endsolid"); } fclose (is); setlocale(LC_NUMERIC,""); return 1; } /** Ouverture d'un fichier stl contenant un modèle @param file chemin du fichier à ouvrir @param m pointeur sur le modèle @return 1 si succès, 0 sinon */ int a2ri_vef_load_stl ( char *file, vef_model * m) { FILE *is = NULL; char str[250]; is = fopen (file, "r"); if (is == NULL) return 0; fscanf (is, "%s", str); fclose (is); if (!strcmp (str, "solid")) return a2ri_vef_load_ascii_stl (file, m); else return a2ri_vef_load_binary_stl (file, m); } /** Ouverture d'un fichier obj contenant un modèle @param file chemin du fichier à ouvrir @param m pointeur sur le modèle @return 1 si succès, 0 sinon */ int a2ri_vef_load_obj ( char *file, vef_model * m) { FILE *is = NULL; int ve1, ve2, ve3; double coordx, coordy, coordz; char str[250]; setlocale(LC_NUMERIC,"C"); is = fopen (file, "r"); if (is == NULL) return 0; fscanf (is, "%s", str); while (strcmp (str, "v") != 0) fscanf (is, "%s", str); //lecture des sommets while (strcmp (str, "g") != 0) { fscanf (is, "%lf %lf %lf", &coordx, &coordy, &coordz); //ajout d'un sommet a2ri_vef_add_vertex (m, coordx, coordy, coordz); fscanf (is, "%s", str); //mis à jour de la bounding box if (m->nbvertex == 1) { m->xmin = coordx; m->xmax = coordx; m->ymin = coordy; m->ymax = coordy; m->zmin = coordz; m->zmax = coordz; } else { if (coordx < m->xmin) m->xmin = coordx; if (coordx > m->xmax) m->xmax = coordx; if (coordy < m->ymin) m->ymin = coordy; if (coordy > m->ymax) m->ymax = coordy; if (coordz < m->zmin) m->zmin = coordz; if (coordz > m->zmax) m->zmax = coordz; } } fscanf (is, "%s", str); fscanf (is, "%s", str); //lecture des faces while (!feof (is)) { //lecture des trois sommets fscanf (is, "%d %d %d", &ve1, &ve2, &ve3); ve1--; ve2--; ve3--; //ajout des aretes avec vérification au préalable de leur existence a2ri_vef_add_edge (m, ve1, ve2, 1); a2ri_vef_add_edge (m, ve2, ve3, 1); a2ri_vef_add_edge (m, ve3, ve1, 1); //recherche des aretes int ed1 = a2ri_vef_search_edge (*m, ve1, ve2); int ed2 = a2ri_vef_search_edge (*m, ve2, ve3); int ed3 = a2ri_vef_search_edge (*m, ve3, ve1); //ajout de la faces avec les trois aretes a2ri_vef_add_face (m, ed1, ed2, ed3); fscanf (is, "%s", str); //si la face compte plus de trois sommets, on relit et on ajoute des aretes et une seconde face if (strcmp (str, "f") != 0) { ve2 = atoi (str); ve2--; a2ri_vef_add_edge (m, ve1, ve2, 1); a2ri_vef_add_edge (m, ve2, ve3, 1); a2ri_vef_add_edge (m, ve3, ve1, 1); int ed1 = a2ri_vef_search_edge (*m, ve1, ve2); int ed2 = a2ri_vef_search_edge (*m, ve2, ve3); int ed3 = a2ri_vef_search_edge (*m, ve3, ve1); a2ri_vef_add_face (m, ed1, ed3, ed2); fscanf (is, "%s", str); } } fclose (is); setlocale(LC_NUMERIC,""); return 1; } /** Ouverture d'un fichier wrl contenant un modèle @param file chemin du fichier à ouvrir @param m pointeur sur le modèle @return 1 si succès, 0 sinon */ int a2ri_vef_load_wrl ( char *file, vef_model * m) { FILE *is = NULL; char str[20]; char coordx[15], coordy[15], coordz[15]; setlocale(LC_NUMERIC,"C"); is = fopen (file, "r"); if (is == NULL) return 0; fscanf (is, "%s", str); while (strcmp (str, "point") && strcmp (str, "point[")) fscanf (is, "%s", str); if (!strcmp (str, "point")) fscanf (is, "%s", str); // reading the file until coordx = } or ] fscanf (is, "%s", coordx); int i = 0; //lecture des sommets while (strcmp (coordx, "}") && strcmp (coordx, "]")) { fscanf (is, "%s", coordy); fscanf (is, "%s", coordz); if (coordz[strlen (coordz) - 1] == ',') { memcpy (coordz, coordz, strlen (coordz) - 1); coordz[strlen (coordz)] = '\0'; } a2ri_vef_add_vertex (m, atof (coordx), atof (coordy), atof (coordz)); //mis à jour de la bounding box if (i == 0) { i++; m->xmin = atof (coordx); m->xmax = atof (coordx); m->ymin = atof (coordy); m->ymax = atof (coordy); m->zmin = atof (coordz); m->zmax = atof (coordz); } else { if (atof (coordx) < m->xmin) m->xmin = atof (coordx); if (atof (coordx) > m->xmax) m->xmax = atof (coordx); if (atof (coordy) < m->ymin) m->ymin = atof (coordy); if (atof (coordy) > m->ymax) m->ymax = atof (coordy); if (atof (coordz) < m->zmin) m->zmin = atof (coordz); if (atof (coordz) > m->zmax) m->zmax = atof (coordz); } fscanf (is, "%s", coordx); } fscanf (is, "%s", str); while (strcmp (str, "coordIndex") && strcmp (str, "coordIndex[")) fscanf (is, "%s", str); if (!strcmp (str, "coordIndex")) fscanf (is, "%s", str); //lecture des faces fscanf (is, "%s", coordx); while (strcmp (coordx, "}") && strcmp (coordx, "]")) { //lecture des trois sommets composant la face fscanf (is, "%s", coordy); fscanf (is, "%s", coordz); //ajout des aretes avec vérification au préalable de leur existence a2ri_vef_add_edge (m, atoi (coordx), atoi (coordy), 1); a2ri_vef_add_edge (m, atoi (coordy), atoi (coordz), 1); a2ri_vef_add_edge (m, atoi (coordz), atoi (coordx), 1); //recherche des aretes int ed1 = a2ri_vef_search_edge (*m, atoi (coordx), atoi (coordy)); int ed2 = a2ri_vef_search_edge (*m, atoi (coordy), atoi (coordz)); int ed3 = a2ri_vef_search_edge (*m, atoi (coordz), atoi (coordx)); //ajout de la faces avec les trois aretes a2ri_vef_add_face (m, ed1, ed2, ed3); // reading the -1 fscanf (is, "%s", coordx); fscanf (is, "%s", coordx); } fclose (is); setlocale(LC_NUMERIC,""); return 1; } /** Ouverture d'un fichier vef contenant un modèle @param file chemin du fichier à ouvrir @param m pointeur sur le modèle @return 1 si succès, 0 sinon */ int a2ri_vef_load_vef ( char *file, vef_model * m) { FILE *is = NULL; int nbvertex, nbedge, nbface, ve1, ve2, ed1, ed2, ed3, classif; double coordx, coordy, coordz; setlocale(LC_NUMERIC,"C"); is = fopen (file, "r"); if (is == NULL) return 0; a2ri_vef_init (m); //lecture du nombre de sommets fscanf (is, "%d", &nbvertex); //lecture du nombre d'aretes fscanf (is, "%d", &nbedge); //lecture du nombre de face fscanf (is, "%d", &nbface); //lecture des sommets for (int i = 0; i < nbvertex; i++) { fscanf (is, "%lf", &coordx); fscanf (is, "%lf", &coordy); fscanf (is, "%lf", &coordz); a2ri_vef_add_vertex (m, coordx, coordy, coordz); //mis à jour de la bounding box if (i == 0) { m->xmin = coordx; m->xmax = coordx; m->ymin = coordy; m->ymax = coordy; m->zmin = coordz; m->zmax = coordz; } else { if (coordx < m->xmin) m->xmin = coordx; if (coordx > m->xmax) m->xmax = coordx; if (coordy < m->ymin) m->ymin = coordy; if (coordy > m->ymax) m->ymax = coordy; if (coordz < m->zmin) m->zmin = coordz; if (coordz > m->zmax) m->zmax = coordz; } } //lecture des aretes for (int i = 0; i < nbedge; i++) { fscanf (is, "%d", &ve1); fscanf (is, "%d", &ve2); a2ri_vef_add_edge (m, ve1, ve2, 0); } //lecture des faces for (int i = 0; i < nbface; i++) { fscanf (is, "%d", &ed1); fscanf (is, "%d", &ed2); fscanf (is, "%d", &ed3); a2ri_vef_add_face (m, ed1, ed2, ed3); } //lecture des classifications si disponible for (int i = 0; i < nbface; i++) { if (!feof (is)) { fscanf (is, "%d", &classif); m->fa[i].type = classif; } } fclose (is); setlocale(LC_NUMERIC,""); return 1; } /** Ouverture d'un fichier gts contenant un modèle @param file chemin du fichier à ouvrir @param m pointeur sur le modèle @return 1 si succès, 0 sinon */ int a2ri_vef_load_gts ( char *file, vef_model * m) { FILE *is = NULL; int nbvertex, nbedge, nbface, ve1, ve2, ed1, ed2, ed3, classif; double coordx, coordy, coordz; setlocale(LC_NUMERIC,"C"); is = fopen (file, "r"); if (is == NULL) return 0; a2ri_vef_init (m); //lecture du nombre de sommets fscanf (is, "%d", &nbvertex); //lecture du nombre d'aretes fscanf (is, "%d", &nbedge); //lecture du nombre de face fscanf (is, "%d", &nbface); //lecture des sommets for (int i = 0; i < nbvertex; i++) { fscanf (is, "%lf", &coordx); fscanf (is, "%lf", &coordy); fscanf (is, "%lf", &coordz); a2ri_vef_add_vertex (m, coordx, coordy, coordz); //mis à jour de la bounding box if (i == 0) { m->xmin = coordx; m->xmax = coordx; m->ymin = coordy; m->ymax = coordy; m->zmin = coordz; m->zmax = coordz; } else { if (coordx < m->xmin) m->xmin = coordx; if (coordx > m->xmax) m->xmax = coordx; if (coordy < m->ymin) m->ymin = coordy; if (coordy > m->ymax) m->ymax = coordy; if (coordz < m->zmin) m->zmin = coordz; if (coordz > m->zmax) m->zmax = coordz; } } //lecture des aretes for (int i = 0; i < nbedge; i++) { fscanf (is, "%d", &ve1); fscanf (is, "%d", &ve2); ve1--; ve2--; a2ri_vef_add_edge (m, ve1, ve2, 0); } //lecture des faces for (int i = 0; i < nbface; i++) { fscanf (is, "%d", &ed1); fscanf (is, "%d", &ed2); fscanf (is, "%d", &ed3); ed1--; ed2--; ed3--; a2ri_vef_add_face (m, ed1, ed2, ed3); } //lecture des classifications si disponible for (int i = 0; i < nbface; i++) { if (!feof (is)) { fscanf (is, "%d", &classif); m->fa[i].type = classif; } } fclose (is); setlocale(LC_NUMERIC,""); return 1; } /** Ouverture d'un fichier ply contenant un modèle @param file chemin du fichier à ouvrir @param m pointeur sur le modèle @return 1 si succès, 0 sinon */ int a2ri_vef_load_ply ( char *file, vef_model * m) { int prop = 0, nbpropvertex = 0, nbpropface = 0, nbvertex, nbface, ve1, ve2, ve3; char str[20]; double coordx, coordy, coordz; FILE *is = NULL; setlocale(LC_NUMERIC,"C"); is = fopen (file, "r"); if (is == NULL) return 0; fscanf (is, "%s", str); if (strcmp (str, "ply")) return 0; while (strcmp (str, "end_header")) { fscanf (is, "%s", str); if (prop == 1 && !strcmp (str, "property")) nbpropvertex++; if (prop == 2 && !strcmp (str, "property")) nbpropface++; if (!strcmp (str, "element")) { fscanf (is, "%s", str); //lecture du nombre de sommets if (!strcmp (str, "vertex")) { prop = 1; fscanf (is, "%d", &nbvertex); } //lecture du nombre de faces else { prop = 1; fscanf (is, "%d", &nbface); } } } //lecture des sommets for (int i = 0; i < nbvertex; i++) { fscanf (is, "%lf %lf %lf", &coordx, &coordy, &coordz); a2ri_vef_add_vertex (m, coordx, coordy, coordz); //mis à jour de la bounding box if (i == 0) { m->xmin = coordx; m->xmax = coordx; m->ymin = coordy; m->ymax = coordy; m->zmin = coordz; m->zmax = coordz; } else { if (coordx < m->xmin) m->xmin = coordx; if (coordx > m->xmax) m->xmax = coordx; if (coordy < m->ymin) m->ymin = coordy; if (coordy > m->ymax) m->ymax = coordy; if (coordz < m->zmin) m->zmin = coordz; if (coordz > m->zmax) m->zmax = coordz; } for (int j = 0; j < nbpropvertex - 4; j++) fscanf (is, "%s", str); } //lecture des faces for (int i = 0; i < nbface; i++) { fscanf (is, "%d", &ve1); //lecture des trois sommets composant la face fscanf (is, "%d %d %d", &ve1, &ve2, &ve3); //ajout des aretes avec vérification au préalable de leur existence a2ri_vef_add_edge (m, ve1, ve2, 1); a2ri_vef_add_edge (m, ve2, ve3, 1); a2ri_vef_add_edge (m, ve3, ve1, 1); //recherche des aretes int ed1 = a2ri_vef_search_edge (*m, ve1, ve2); int ed2 = a2ri_vef_search_edge (*m, ve2, ve3); int ed3 = a2ri_vef_search_edge (*m, ve3, ve1); //ajout de la faces avec les trois aretes a2ri_vef_add_face (m, ed1, ed2, ed3); } fclose (is); setlocale(LC_NUMERIC,""); return 1; } /** Ouverture d'un fichier off contenant un modèle @param file chemin du fichier à ouvrir @param m pointeur sur le modèle @return 1 si succès, 0 sinon */ int a2ri_vef_load_off ( char *file, vef_model * m) { FILE *is = NULL; char str[20]; double coordx, coordy, coordz; int classif, ar1, ar2, ar3, nbvertex, nbface; setlocale(LC_NUMERIC,"C"); is = fopen (file, "r"); if (is == NULL) return 0; a2ri_vef_init (m); fscanf (is, "%s", str); if (strcmp (str, "OFF")) return 0; //lecture du nombre de sommets fscanf (is, "%d", &nbvertex); //lecture du nombre de faces fscanf (is, "%d", &nbface); fscanf (is, "%d", &ar1); //lecture des sommets for (int i = 0; i < nbvertex; i++) { fscanf (is, "%lf", &coordx); fscanf (is, "%lf", &coordy); fscanf (is, "%lf", &coordz); a2ri_vef_add_vertex (m, coordx, coordy, coordz); //mis à jour de la bounding box if (i == 0) { m->xmin = coordx; m->xmax = coordx; m->ymin = coordy; m->ymax = coordy; m->zmin = coordz; m->zmax = coordz; } else { if (coordx < m->xmin) m->xmin = coordx; if (coordx > m->xmax) m->xmax = coordx; if (coordy < m->ymin) m->ymin = coordy; if (coordy > m->ymax) m->ymax = coordy; if (coordz < m->zmin) m->zmin = coordz; if (coordz > m->zmax) m->zmax = coordz; } } //lecture des faces for (int i = 0; i < nbface; i++) { //lecture des trois sommets composant la face fscanf (is, "%d", &ar1); fscanf (is, "%d", &ar1); fscanf (is, "%d", &ar2); fscanf (is, "%d", &ar3); //ajout des aretes avec vérification au préalable de leur existence a2ri_vef_add_edge (m, ar1, ar2, 1); a2ri_vef_add_edge (m, ar2, ar3, 1); a2ri_vef_add_edge (m, ar3, ar1, 1); //recherche des aretes int ed1 = a2ri_vef_search_edge (*m, ar1, ar2); int ed2 = a2ri_vef_search_edge (*m, ar2, ar3); int ed3 = a2ri_vef_search_edge (*m, ar3, ar1); //ajout de la faces avec les trois aretes a2ri_vef_add_face (m, ed1, ed2, ed3); } //lecture des classifications si disponible for (int i = 0; i < nbface; i++) { if (!feof (is)) { fscanf (is, "%d", &classif); m->fa[i].type = classif; } } fclose (is); setlocale(LC_NUMERIC,""); return 1; } /** Enregistrement d'un modèle dans un format défini par l'extension du nom de fichier @param file nom du fichier @param m le modèle @return aucun */ int a2ri_vef_save_file ( char *file, vef_model m) { char ext[4]; memcpy (ext, file + (strlen (file) - 3), 3); ext[3] = 0; //appel de la fonction d'enregistrement en fonction du type de l'extension du fichier if (!strcmp (ext, "wrl")) return a2ri_vef_save_wrl (file, m); if (!strcmp (ext, "vef")) return a2ri_vef_save_vef (file, m); if (!strcmp (ext, "pgn")) return a2ri_vef_save_pgn (file, m); if (!strcmp (ext, "ply")) return a2ri_vef_save_ply (file, m); if (!strcmp (ext, "off")) return a2ri_vef_save_off (file, m); if (!strcmp (ext, "obj")) return a2ri_vef_save_obj (file, m); if (!strcmp (ext, "gts")) return a2ri_vef_save_gts (file, m); return 0; } /** Enregistrement d'un modèle dans un fichier wrl @param file chemin du fichier @param m modèle à sauvegarder @return 1 si succès, 0 sinon */ int a2ri_vef_save_wrl ( char *file, vef_model m) { setlocale(LC_NUMERIC,"C"); if (strlen (file) < 4) { strcat (file, ".wrl"); } char ext[5]; memcpy (ext, file + (strlen (file) - 4), 4); ext[4] = '\0'; if (strcmp (ext, ".wrl")) strcat (file, ".wrl"); FILE *os = NULL; os = fopen (file, "w"); if (os == NULL) return 0; //ecriture de l'en-tete fprintf (os, "#VRML V2.0 utf8\n"); fprintf (os, "Shape{\n"); fprintf (os, "appearance Appearance {\n"); fprintf (os, "material Material {\n"); fprintf (os, "}\n"); fprintf (os, "}\n"); fprintf (os, "geometry IndexedFaceSet{\n"); fprintf (os, "coord Coordinate{\n"); fprintf (os, "point[\n"); //ecriture des sommets for (int i = 0; i < m.nbvertex; i++) fprintf (os, "%f %f %f,\n", m.ve[i].x, m.ve[i].y, m.ve[i].z); fprintf (os, "]\n"); fprintf (os, "}\n"); //ecriture des faces fprintf (os, "coordIndex[\n"); for (int i = 0; i < m.nbface; i++) { int nb1, nb2, nb3; vef_face_get_vertices (m.fa[i], m.ed, &nb1, &nb2, &nb3); fprintf (os, "%d %d %d -1\n", nb1, nb2, nb3); } fprintf (os, "]\n"); fprintf (os, "}\n"); fprintf (os, "}\n"); fclose (os); setlocale(LC_NUMERIC,""); return 1; } /** Enregistrement d'un modèle dans un fichier pgn @param file chemin du fichier @param m modèle à sauvegarder @return 1 si succès, 0 sinon */ int a2ri_vef_save_pgn ( char *file, vef_model m) { setlocale(LC_NUMERIC,"C"); if (strlen (file) < 4) { strcat (file, ".pgn"); } char ext[5]; memcpy (ext, file + (strlen (file) - 4), 4); ext[4] = '\0'; if (strcmp (ext, ".pgn")) strcat (file, ".pgn"); FILE *os = NULL; os = fopen (file, "w"); if (os == NULL) return 0; //ecriture du nombre de sommets et faces fprintf (os, "%d %d \n\n", m.nbvertex, m.nbface); //ecriture des sommets for (int i = 0; i < m.nbvertex; i++) fprintf (os, "%f %f %f\n", m.ve[i].x, m.ve[i].y, m.ve[i].z); //ecriture des faces for (int i = 0; i < m.nbface; i++) { int ve1, ve2, ve3; vef_face_get_vertices (m.fa[i], m.ed, &ve1, &ve2, &ve3); fprintf (os, "%d %d %d -1\n", ve1, ve2, ve3); } fclose (os); setlocale(LC_NUMERIC,""); return 1; } /** Enregistrement d'un modèle dans un fichier vef @param file chemin du fichier @param m modèle à sauvegarder @return 1 si succès, 0 sinon */ int a2ri_vef_save_vef ( char *file, vef_model m) { setlocale(LC_NUMERIC,"C"); if (strlen (file) < 4) { strcat (file, ".vef"); } char ext[5]; memcpy (ext, file + (strlen (file) - 4), 4); ext[4] = '\0'; if (strcmp (ext, ".vef")) strcat (file, ".vef"); FILE *os = NULL; os = fopen (file, "w"); if (os == NULL) return 0; //ecriture des nombre de sommets, aretes et faces fprintf (os, "%d %d %d\n\n", m.nbvertex, m.nbedge, m.nbface); //ecriture des sommets for (int i = 0; i < m.nbvertex; i++) fprintf (os, "%f %f %f\n", m.ve[i].x, m.ve[i].y, m.ve[i].z); //ecriture des aretes for (int i = 0; i < m.nbedge; i++) fprintf (os, "%d %d\n", m.ed[i].ve1, m.ed[i].ve2); //ecriture des faces for (int i = 0; i < m.nbface; i++) fprintf (os, "%d %d %d\n", m.fa[i].ed1, m.fa[i].ed2, m.fa[i].ed3); fclose (os); setlocale(LC_NUMERIC,""); return 1; } /** Enregistrement d'un modèle dans un fichier gts @param file chemin du fichier @param m modèle à sauvegarder @return 1 si succès, 0 sinon */ int a2ri_vef_save_gts ( char *file, vef_model m) { setlocale(LC_NUMERIC,"C"); if (strlen (file) < 4) { strcat (file, ".gts"); } char ext[5]; memcpy (ext, file + (strlen (file) - 4), 4); ext[4] = '\0'; if (strcmp (ext, ".gts")) strcat (file, ".gts"); FILE *os = NULL; os = fopen (file, "w"); if (os == NULL) return 0; //ecriture des nombre de sommets, aretes et faces fprintf (os, "%d %d %d\n\n", m.nbvertex, m.nbedge, m.nbface); //ecriture des sommets for (int i = 0; i < m.nbvertex; i++) fprintf (os, "%f %f %f\n", m.ve[i].x, m.ve[i].y, m.ve[i].z); //ecriture des aretes for (int i = 0; i < m.nbedge; i++) fprintf (os, "%d %d\n", m.ed[i].ve1 + 1, m.ed[i].ve2 + 1); //ecriture des faces for (int i = 0; i < m.nbface; i++) fprintf (os, "%d %d %d\n", m.fa[i].ed1 + 1, m.fa[i].ed2 + 1, m.fa[i].ed3 + 1); fclose (os); setlocale(LC_NUMERIC,""); return 1; } /** Enregistrement d'un modèle dans un fichier off @param file chemin du fichier @param m modèle à sauvegarder @return 1 si succès, 0 sinon */ int a2ri_vef_save_off ( char *file, vef_model m) { setlocale(LC_NUMERIC,"C"); if (strlen (file) < 4) { strcat (file, ".off"); } char ext[5]; memcpy (ext, file + (strlen (file) - 4), 4); ext[4] = '\0'; if (strcmp (ext, ".off")) strcat (file, ".off"); FILE *os = NULL; os = fopen (file, "w"); if (os == NULL) return 0; //ecriture de l'en-tete et des nombres de sommets et faces fprintf (os, "OFF\n%d %d 0\n\n", m.nbvertex, m.nbface); //ecriture des sommets for (int i = 0; i < m.nbvertex; i++) fprintf (os, "%f %f %f\n", m.ve[i].x, m.ve[i].y, m.ve[i].z); //ecriture des faces for (int i = 0; i < m.nbface; i++) { int ve1, ve2, ve3; vef_face_get_vertices (m.fa[i], m.ed, &ve1, &ve2, &ve3); fprintf (os, "3 %d %d %d \n", ve1, ve2, ve3); } fclose (os); setlocale(LC_NUMERIC,""); return 1; } /** Enregistrement d'un modèle dans un fichier ply @param file chemin du fichier @param m modèle à sauvegarder @return 1 si succès, 0 sinon */ int a2ri_vef_save_ply ( char *file, vef_model m) { setlocale(LC_NUMERIC,"C"); if (strlen (file) < 4) { strcat (file, ".ply"); } char ext[5]; memcpy (ext, file + (strlen (file) - 4), 4); ext[4] = '\0'; if (strcmp (ext, ".ply")) strcat (file, ".ply"); FILE *os = NULL; os = fopen (file, "w"); if (os == NULL) return 0; //ecriture de l'en-tete avec le nombre de sommets et de faces fprintf (os, "ply\nformat ascii 1.0\ncomment zipper output\n"); fprintf (os, "element vertex %d\nproperty float x\nproperty float y\nproperty float z\nelement face %d\n", m.nbvertex, m.nbface); fprintf (os, "property list uchar int vertex_indices\nend_header\n"); //ecriture des sommets for (int i = 0; i < m.nbvertex; i++) fprintf (os, "%f %f %f\n", m.ve[i].x, m.ve[i].y, m.ve[i].z); //ecriture des faces for (int i = 0; i < m.nbface; i++) { int ve1, ve2, ve3; vef_face_get_vertices (m.fa[i], m.ed, &ve1, &ve2, &ve3); fprintf (os, "3 %d %d %d \n", ve1, ve2, ve3); } fclose (os); setlocale(LC_NUMERIC,""); return 1; } /** Enregistrement d'un modèle dans un fichier obj @param file chemin du fichier @param m modèle à sauvegarder @return 1 si succès, 0 sinon */ int a2ri_vef_save_obj ( char *file, vef_model m) { setlocale(LC_NUMERIC,"C"); if (strlen (file) < 4) { strcat (file, ".obj"); } char ext[5]; memcpy (ext, file + (strlen (file) - 4), 4); ext[4] = '\0'; if (strcmp (ext, ".obj")) strcat (file, ".obj"); FILE *os = NULL; os = fopen (file, "w"); if (os == NULL) return 0; //ecriture des sommets for (int i = 0; i < m.nbvertex; i++) fprintf (os, "v %f %f %f\n", m.ve[i].x, m.ve[i].y, m.ve[i].z); fprintf (os, "\n"); //ecriture des faces for (int i = 0; i < m.nbface; i++) { int ve1, ve2, ve3; vef_face_get_vertices (m.fa[i], m.ed, &ve1, &ve2, &ve3); fprintf (os, "f %d %d %d\n", ve1 + 1, ve2 + 1, ve3 + 1); } fclose (os); setlocale(LC_NUMERIC,""); return 1; }