1 /*============================================================================
2  *  Définition de la fonction
3  *   de lecture d'un fichier de maillage au format EnSight 6 ou EnSight Gold
4  *============================================================================*/
5 
6 /*
7   This file is part of Code_Saturne, a general-purpose CFD tool.
8 
9   Copyright (C) 1998-2021 EDF S.A.
10 
11   This program is free software; you can redistribute it and/or modify it under
12   the terms of the GNU General Public License as published by the Free Software
13   Foundation; either version 2 of the License, or (at your option) any later
14   version.
15 
16   This program is distributed in the hope that it will be useful, but WITHOUT
17   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18   FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
19   details.
20 
21   You should have received a copy of the GNU General Public License along with
22   this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
23   Street, Fifth Floor, Boston, MA 02110-1301, USA.
24 */
25 
26 /*----------------------------------------------------------------------------*/
27 
28 /*============================================================================
29  *                                 Visibilité
30  *============================================================================*/
31 
32 /*----------------------------------------------------------------------------
33  *  Fichiers `include' librairie standard C
34  *----------------------------------------------------------------------------*/
35 
36 #include <assert.h>
37 #include <stdlib.h>
38 #include <stdio.h>
39 #include <string.h>
40 
41 
42 /*----------------------------------------------------------------------------
43  *  Fichiers `include' visibles du  paquetage global "Utilitaire"
44  *----------------------------------------------------------------------------*/
45 
46 #include "ecs_def.h"
47 #include "ecs_elt_typ_liste.h"
48 #include "ecs_file.h"
49 #include "ecs_mem.h"
50 #include "ecs_tab.h"
51 
52 
53 /*----------------------------------------------------------------------------
54  *  Fichiers `include' visibles des paquetages visibles
55  *----------------------------------------------------------------------------*/
56 
57 #include "ecs_descr.h"
58 #include "ecs_descr_chaine.h"
59 #include "ecs_maillage.h"
60 #include "ecs_maillage_priv.h"
61 
62 
63 /*----------------------------------------------------------------------------
64  *  Fichiers `include' visibles du  paquetage courant
65  *----------------------------------------------------------------------------*/
66 
67 #include "ecs_maillage_pre.h"
68 
69 
70 /*----------------------------------------------------------------------------
71  *  Fichier  `include' du  paquetage courant associe au fichier courant
72  *----------------------------------------------------------------------------*/
73 
74 #include "ecs_pre_ens.h"
75 
76 
77 /*----------------------------------------------------------------------------
78  *  Fichiers `include' privés   du  paquetage courant
79  *----------------------------------------------------------------------------*/
80 
81 
82 /*============================================================================
83  *                    Déclaration de paramètres et macros
84  *============================================================================*/
85 
86 /* Pour une lecture de 80 caracteres par ligne  */
87 /* auxquels il faut ajouter le `\n' et le `\0'  */
88 /* pour l'affectation dans la chaîne réceptrice */
89 #define ECS_LOC_LNG_MAX_CHAINE_ENS  82
90 
91 
92 /*============================================================================
93  *                  Définition de structures locales
94  *============================================================================*/
95 
96 /* Définition de noeuds */
97 
98 typedef struct {
99   ecs_int_t        nbr_noeuds;  /* Nombre de noeuds */
100   ecs_int_t       *id_noeud;    /* Labels des noeuds */
101   ecs_coord_t     *coord;       /* Coordonnées (entrelacées) */
102   ecs_int_t        num_part;    /* Numéro de part associé */
103 } ecs_loc_noeuds_ens_t;
104 
105 
106 /* Définition de connectivités */
107 
108 typedef struct {
109   ecs_int_t        nbr_ele;   /* Nombre d'éléments */
110   ecs_elt_typ_t    elt_typ;   /* Type d'élément */
111   int32_t         *nbr_n;     /* Nbr. sommets/faces (polygones/polyèdres) */
112   int32_t         *nbr_f;     /* Nbr. faces/elem (polyèdres) */
113   int32_t         *connect;   /* Connectivité sommets */
114   int              num_part;  /* Numéro de part associé */
115 } ecs_loc_elems_ens_t;
116 
117 
118 /*============================================================================
119  *                              Fonctions privées
120  *============================================================================*/
121 
122 /*----------------------------------------------------------------------------
123  * Ouverture et détermination du type du fichier geo
124  *----------------------------------------------------------------------------*/
125 
126 static ecs_file_t *
ecs_loc_pre_ens__ouverture_fic_geo(const char * nom_fic_geo)127 ecs_loc_pre_ens__ouverture_fic_geo(const char  *nom_fic_geo)
128 {
129   ecs_file_t   *fic;
130   ecs_int_t  nbr_char_lus;
131 
132   char  chaine[ECS_LOC_LNG_MAX_CHAINE_ENS];
133 
134   int32_t  test_endian;
135 
136   /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
137 
138   /* Ouverture du fichier Géométrie et vérification du format */
139   /*----------------------------------------------------------*/
140 
141   fic = ecs_file_open(nom_fic_geo,
142                       ECS_FILE_MODE_READ,
143                       ECS_FILE_TYPE_BINARY);
144 
145   /* Par défaut, on suppose un fichier binaire C */
146 
147   nbr_char_lus = ecs_file_read_try(chaine, sizeof(char), 80, fic);
148 
149   /* Si le fichier est trop court pour contenir l'entête binaire, c'est au
150      mieux un fichier texte */
151 
152   if (nbr_char_lus < 80) {
153 
154     ecs_file_set_type(fic, ECS_FILE_TYPE_TEXT);
155 
156     ecs_file_rewind(fic);
157 
158   }
159 
160   /* Pour un fichier binaire Fortran, les 4 premiers octets correspondent à
161      la taille de l'enregistrement, et le contenu vient après -> on décale */
162 
163   else if (strncmp(chaine + 4,
164                    "Fortran Binary",
165                    strlen("Fortran Binary")) == 0) {
166 
167     ecs_file_set_type(fic, ECS_FILE_TYPE_FORTRAN_BINARY);
168 
169     test_endian = *((int32_t *)chaine);
170 
171     if (test_endian == 80)
172       ecs_file_set_swap_endian(fic, 0);
173 
174     else{
175       ecs_file_swap_endian(&test_endian, &test_endian, 4, 1);
176       if (test_endian == 80)
177         ecs_file_set_swap_endian(fic, 1);
178 
179       else
180         ecs_error(__FILE__, __LINE__, 0,
181                   _("EnSight: file \"%s\" seems to be\n"
182                     "of Fortran binary type but its header is of the wrong\n"
183                     "size or it is of an unknown Fortran binary variant."),
184                   ecs_file_get_name(fic));
185     }
186 
187     /* On se replace après l'entête "Fortran Binary" */
188 
189     ecs_file_rewind(fic);
190     ecs_file_read(chaine, sizeof(char), 80, fic);
191 
192   }
193 
194   /* Si le fichier est binaire, on vérifiera plus tard l'aspect
195      "big-endian/little-endian" */
196 
197   else if (strncmp(chaine, "C Binary", strlen("C Binary")) != 0) {
198 
199     ecs_file_set_type(fic, ECS_FILE_TYPE_TEXT);
200 
201     ecs_file_rewind(fic);
202 
203   }
204 
205   return fic;
206 }
207 
208 /*----------------------------------------------------------------------------
209  *  Lecture d'une chaîne de caractères dans un fichier géométrique EnSight.
210  *  Comme les chaînes à lire ne dépassent jamais 80 caractères, on
211  *  pourra utiliser un tampon statique.
212  *----------------------------------------------------------------------------*/
213 
214 static void
ecs_loc_pre_ens__lit_chaine(const ecs_file_t * fic_geo,char ligne[ECS_LOC_LNG_MAX_CHAINE_ENS],int * num_ligne)215 ecs_loc_pre_ens__lit_chaine(const ecs_file_t  *fic_geo,
216                             char   ligne[ECS_LOC_LNG_MAX_CHAINE_ENS],
217                             int   *num_ligne)
218 {
219   size_t ind;
220 
221   if (ecs_file_get_type(fic_geo) != ECS_FILE_TYPE_TEXT) {
222 
223     ecs_file_read(ligne, sizeof(char), 80, fic_geo);
224     ligne[80] = '\0';
225 
226   }
227   else {
228 
229     ecs_file_gets(ligne, ECS_LOC_LNG_MAX_CHAINE_ENS, fic_geo, num_ligne);
230 
231     for (ind = strlen(ligne) - 1;
232          ind > 0 && (ligne[ind] == '\n' || ligne[ind] == '\r');
233          ind--);
234     ligne[ind + 1] = '\0';
235 
236   }
237 
238 }
239 
240 /*----------------------------------------------------------------------------
241  *  Lecture d'une chaîne de caractères dans un fichier géométrique EnSight.
242  *  Comme les chaînes à lire ne dépassent jamais 80 caractères, on
243  *  pourra utiliser un tampon statique.
244  *  Dans le cas d'un fichier binaire, les chaines à lire sont toujours
245  *  exactement de longueur 80 caractères.
246  *  Si l'on ne peut lire une chaîne (i.e. fin de fichier), on renvoie NULL;
247  *  Sinon, on renvoie un pointeur sur "ligne".
248  *----------------------------------------------------------------------------*/
249 
250 static char *
ecs_loc_pre_ens__lit_chaine_essai(const ecs_file_t * fic_geo,char ligne[ECS_LOC_LNG_MAX_CHAINE_ENS],int * num_ligne)251 ecs_loc_pre_ens__lit_chaine_essai(const ecs_file_t  *fic_geo,
252                                   char ligne[ECS_LOC_LNG_MAX_CHAINE_ENS] ,
253                                   int *num_ligne)
254 {
255   char   *ret;
256   size_t  ind;
257 
258   if (ecs_file_get_type(fic_geo) != ECS_FILE_TYPE_TEXT) {
259 
260     if (ecs_file_read_try(ligne, sizeof(char), 80, fic_geo) == 80) {
261       ligne[80] = '\0';
262       ret = ligne;
263     }
264     else
265       ret = NULL;
266 
267   }
268   else {
269 
270     ret = ecs_file_gets_try(ligne, ECS_LOC_LNG_MAX_CHAINE_ENS,
271                             fic_geo, num_ligne);
272 
273     if (ret != NULL) {
274 
275       for (ind = strlen(ligne) - 1;
276            ind > 0 && (ligne[ind] == '\n' || ligne[ind] == '\r');
277            ind--);
278       ligne[ind + 1] = '\0';
279 
280     }
281 
282   }
283 
284   return ret;
285 }
286 
287 /*----------------------------------------------------------------------------
288  *  Lecture d'un tableau d'entiers dans un fichier géométrique EnSight Gold.
289  *  Si le tableau val est fourni en argument, on le suppose bien dimensionné
290  *  et on le remplit; sinon, si val est à NULL, on alloue un tableau.
291  *  On renvoie un pointeur sur le tableau utilisé, qu'il soit fourni en
292  *  argument ou alloué ici. Dans ce dernier cas, l'utilisateur aura la
293  *  responsabilité de le libérer.
294  *----------------------------------------------------------------------------*/
295 
296 static int32_t *
ecs_loc_pre_ens__lit_int(const ecs_file_t * fic_geo,ecs_int_t nbr,int32_t * val,const int l_format,int * num_ligne)297 ecs_loc_pre_ens__lit_int(const ecs_file_t  *fic_geo,
298                          ecs_int_t          nbr,
299                          int32_t           *val,
300                          const int          l_format,
301                          int               *num_ligne)
302 {
303   char         ligne[ECS_LOC_LNG_MAX_CHAINE_ENS];
304   char         sub[11];
305   ecs_int_t    pos_ligne;
306   int          ic;
307   int          val_lue;
308 
309   ecs_int_t    cpt_lus = 0;
310   int32_t    * val_loc = val;
311 
312   assert(l_format <= 10);
313 
314   if (val_loc == NULL)
315     ECS_MALLOC(val_loc, nbr, int32_t);
316 
317 
318   if (ecs_file_get_type(fic_geo) != ECS_FILE_TYPE_TEXT)
319     ecs_file_read(val_loc, sizeof(int32_t), nbr, fic_geo);
320 
321   else {
322 
323     sub[l_format] = '\0';
324 
325     ic = 0;
326 
327     while (cpt_lus < nbr) {
328 
329       ecs_file_gets(ligne,
330                     ECS_LOC_LNG_MAX_CHAINE_ENS,
331                     fic_geo,
332                     num_ligne);
333 
334       /* éventuellement plusieurs valeurs sur la ligne */
335 
336       pos_ligne = 0;
337 
338       while (   cpt_lus < nbr
339              && (   ligne[pos_ligne] != '\0'
340                  && ligne[pos_ligne] != '\n'
341                  && ligne[pos_ligne] != '\r')) {
342         sub[ic] = ligne[pos_ligne];
343         ic++;
344         pos_ligne++;
345         if (ic == l_format) {
346           val_lue = atoi(sub);
347           val_loc[cpt_lus] = (int32_t)val_lue;
348           cpt_lus++;
349           ic = 0;
350         }
351       }
352 
353     }
354 
355   }
356 
357   return val_loc;
358 }
359 
360 /*----------------------------------------------------------------------------
361  *  Lecture d'un tableau de réels dans un fichier géométrique EnSight.
362  *  Si le tableau val est fourni en argument, on le suppose bien dimensionné
363  *  et on le remplit ; sinon, si val est à NULL, on alloue un tableau.
364  *  On renvoie un pointeur sur le tableau utilisé, qu'il soit fourni en
365  *  argument ou alloué ici. Dans ce dernier cas, l'utilisateur aura la
366  *  responsabilité de le libérer.
367  *----------------------------------------------------------------------------*/
368 
369 static float *
ecs_loc_pre_ens__lit_float(const ecs_file_t * fic_geo,ecs_int_t nbr,float * val,int * num_ligne)370 ecs_loc_pre_ens__lit_float(const ecs_file_t  *fic_geo,
371                            ecs_int_t          nbr,
372                            float             *val,
373                            int               *num_ligne)
374 {
375   char         ligne[ECS_LOC_LNG_MAX_CHAINE_ENS];
376   char         sub[13];
377   ecs_int_t    pos_ligne;
378   int          ic;
379   float        val_lue;
380 
381   const int        l_format = 12;
382 
383   ecs_int_t        cpt_lus = 0;
384   float  * val_loc = val;
385 
386   if (val_loc == NULL)
387     ECS_MALLOC(val_loc, nbr, float);
388 
389   if (ecs_file_get_type(fic_geo) != ECS_FILE_TYPE_TEXT)
390     ecs_file_read(val_loc, sizeof(float), nbr, fic_geo);
391 
392   else {
393 
394     sub[l_format] = '\0';
395 
396     ic = 0;
397 
398     while (cpt_lus < nbr) {
399 
400       ecs_file_gets(ligne,
401                     ECS_LOC_LNG_MAX_CHAINE_ENS,
402                     fic_geo,
403                     num_ligne);
404 
405       /* éventuellement plusieurs valeurs sur la ligne */
406 
407       pos_ligne = 0;
408 
409       while (   cpt_lus < nbr
410              && (   ligne[pos_ligne] != '\0'
411                  && ligne[pos_ligne] != '\n'
412                  && ligne[pos_ligne] != '\r')) {
413         sub[ic] = ligne[pos_ligne];
414         ic++;
415         pos_ligne++;
416         if (ic == l_format) {
417           val_lue = atof(sub);
418           val_loc[cpt_lus] = (float)val_lue;
419           cpt_lus++;
420           ic = 0;
421         }
422       }
423 
424     }
425 
426   }
427 
428   return val_loc;
429 }
430 
431 /*----------------------------------------------------------------------------
432  *  Lecture d'un tableau de coordonnées dans un fichier géométrique EnSight 6
433  *  (ids et coordonnées mixtes en mode texte : 1 entier et 3 réels par ligne) .
434  *  Les tableaux val_id et val_coord sont supposés bien dimensionnés
435  *  (val_id étant optionnel).
436  *----------------------------------------------------------------------------*/
437 
438 static void
ecs_loc_pre_ens__lit_tab_coo_6(const ecs_file_t * fic_geo,ecs_int_t nbr_lignes,int32_t * val_id,float * val_coord,int * num_ligne)439 ecs_loc_pre_ens__lit_tab_coo_6(const ecs_file_t  *fic_geo,
440                                ecs_int_t          nbr_lignes,
441                                int32_t           *val_id,
442                                float             *val_coord,
443                                int               *num_ligne)
444 {
445   char         ligne[ECS_LOC_LNG_MAX_CHAINE_ENS];
446   char         sub[13];
447   ecs_int_t    pos_ligne;
448   int          ic;
449   int          icoo;
450 
451   int          l_format_int = 8;
452   int          l_format_real = 12;
453   ecs_int_t    cpt_lignes_lues = 0;
454 
455   if (ecs_file_get_type(fic_geo) != ECS_FILE_TYPE_TEXT) {
456 
457     /* Dans le cas binaire, les tableaux des id (entiers) et coordonnées
458        (réels) ne sont pas entrelacés */
459 
460     if (val_id != NULL)
461       ecs_file_read(val_id, sizeof(int32_t), nbr_lignes, fic_geo);
462 
463     ecs_file_read(val_coord, sizeof(float), nbr_lignes * 3, fic_geo);
464 
465   }
466   else {
467 
468     sub[l_format_real] = '\0';
469 
470     while (cpt_lignes_lues < nbr_lignes) {
471 
472       ecs_file_gets(ligne,
473                     ECS_LOC_LNG_MAX_CHAINE_ENS,
474                     fic_geo,
475                     num_ligne);
476 
477       pos_ligne = 0;
478 
479       if (val_id != NULL) {
480         for (ic = 0; ic < l_format_int; ic++)
481           sub[ic] = ligne[pos_ligne++];
482         sub[l_format_int] = '\0';
483         val_id[cpt_lignes_lues] = (int32_t)(atoi(sub));
484       }
485 
486       sub[l_format_real] = '\0';
487       for (icoo = 0; icoo < 3; icoo++) {
488         for (ic = 0; ic < l_format_real; ic++)
489           sub[ic] = ligne[pos_ligne++];
490         val_coord[cpt_lignes_lues*3 + icoo] = (float)(atof(sub));
491       }
492 
493       cpt_lignes_lues++;
494 
495     }
496   }
497 }
498 
499 /*----------------------------------------------------------------------------
500  *  Lecture d'un tableau de connectivités dans un fichier géométrique
501  *  EnSight 6 (ids et connectivités mixtes en mode texte) .
502  *  Les tableaux val_id et val_connect sont supposés bien dimensionnés.
503  *----------------------------------------------------------------------------*/
504 
505 static void
ecs_loc_pre_ens__lit_tab_connect(const ecs_file_t * fic_geo,ecs_int_t nbr_lignes,bool lit_id,ecs_int_t nbr_som_elt,int32_t * val_id,int32_t * val_connect,int * num_ligne)506 ecs_loc_pre_ens__lit_tab_connect(const ecs_file_t  *fic_geo,
507                                  ecs_int_t          nbr_lignes,
508                                  bool               lit_id,
509                                  ecs_int_t          nbr_som_elt,
510                                  int32_t           *val_id,
511                                  int32_t           *val_connect,
512                                  int               *num_ligne)
513 {
514   char         ligne[ECS_LOC_LNG_MAX_CHAINE_ENS];
515   char         sub[9];
516   ecs_int_t    pos_ligne;
517   ecs_int_t    cpt_val_ligne;
518   ecs_int_t    cpt_som_ligne;
519   int          ic;
520   int          val_lue;
521 
522   int          l_format = 8;
523   ecs_int_t    cpt_lignes_lues = 0;
524 
525   if (ecs_file_get_type(fic_geo) != ECS_FILE_TYPE_TEXT) {
526 
527     /* Dans le cas binaire, les tableaux des id et les connectivités
528        ne sont pas entrelacés */
529 
530     if (lit_id == true)
531       ecs_file_read(val_id, sizeof(int32_t), nbr_lignes, fic_geo);
532 
533     ecs_file_read(val_connect, sizeof(int32_t),
534                   nbr_lignes * nbr_som_elt, fic_geo);
535 
536   }
537   else {
538 
539     sub[l_format] = '\0';
540 
541     cpt_som_ligne = 0;
542     cpt_val_ligne = 0;
543     ic = 0;
544 
545     while (cpt_lignes_lues < nbr_lignes) { /* Lignes entières, peuvent être
546                                               lues via plusieurs appels à
547                                               ecs_file_gets si plus
548                                               de 80 caractères */
549 
550       ecs_file_gets(ligne,
551                     ECS_LOC_LNG_MAX_CHAINE_ENS,
552                     fic_geo,
553                     num_ligne);
554 
555       /* éventuellement plusieurs valeurs sur la ligne */
556 
557       pos_ligne = 0;
558 
559       while (   cpt_lignes_lues < nbr_lignes
560              && (   ligne[pos_ligne] != '\0'
561                  && ligne[pos_ligne] != '\n'
562                  && ligne[pos_ligne] != '\r')) {
563 
564         sub[ic] = ligne[pos_ligne];
565         ic++;
566         pos_ligne++;
567 
568         if (ic == l_format) {
569 
570           val_lue = atoi(sub);
571 
572           if (lit_id == true && cpt_val_ligne == 0)
573             val_id[cpt_lignes_lues] = (int32_t)val_lue;
574           else {
575             val_connect[cpt_lignes_lues*nbr_som_elt + cpt_som_ligne]
576               = (int32_t)val_lue;
577             cpt_som_ligne++;
578           }
579 
580           if (cpt_som_ligne == nbr_som_elt) {
581             cpt_val_ligne = 0;
582             cpt_som_ligne = 0;
583             cpt_lignes_lues++;
584           }
585           else
586             cpt_val_ligne++;
587 
588           ic = 0;
589 
590         }
591       }
592     }
593   }
594 }
595 
596 /*----------------------------------------------------------------------------
597  *  Lecture des noeuds au format EnSight Gold ;
598  *----------------------------------------------------------------------------*/
599 
600 static void
ecs_loc_pre_ens__lit_noeuds_gold(ecs_file_t * fic,ecs_int_t num_part,bool lire_id_noeud,bool importer_part,ecs_int_t * taille_noeuds,ecs_loc_noeuds_ens_t ** noeuds,char chaine[],int * num_ligne)601 ecs_loc_pre_ens__lit_noeuds_gold(ecs_file_t             *fic,
602                                  ecs_int_t               num_part,
603                                  bool                    lire_id_noeud,
604                                  bool                    importer_part,
605                                  ecs_int_t              *taille_noeuds,
606                                  ecs_loc_noeuds_ens_t  **noeuds,
607                                  char                    chaine[],
608                                  int                    *num_ligne)
609 {
610 
611   ecs_int_t     ind;
612   ecs_int_t     ind_coo;
613   ecs_int_t     nbr_noeuds;
614 
615   int32_t       val_int_lue;
616 
617   ecs_loc_noeuds_ens_t  *noeuds_loc;
618 
619   int32_t      *id_noeud_loc = NULL;
620   ecs_int_t    *id_noeud_tmp = NULL;
621   float        *coord_loc    = NULL;
622   ecs_coord_t  *coord_tmp    = NULL;
623 
624   /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
625 
626   ecs_loc_pre_ens__lit_chaine(fic, chaine, num_ligne);
627 
628   if (strncmp(chaine, "coordinates", strlen("coordinates")) != 0)
629     ecs_error(__FILE__, __LINE__, 0,
630               _("EnSight: field \"%s\" encountered where\n"
631                 "\"coordinates\" was expected."), chaine);
632 
633   ecs_loc_pre_ens__lit_int(fic, 1, &val_int_lue, 10, num_ligne);
634 
635   nbr_noeuds = val_int_lue;
636 
637   printf(_("    %10d nodes\n"), (int)nbr_noeuds);
638 
639   /* Lecture des labels s'il y a lieu */
640 
641   if (lire_id_noeud == true)
642     id_noeud_loc = ecs_loc_pre_ens__lit_int(fic, nbr_noeuds,
643                                             NULL, 10, num_ligne);
644 
645   /* Lecture des coordonnées */
646 
647   coord_loc = ecs_loc_pre_ens__lit_float(fic, nbr_noeuds * 3,
648                                          NULL, num_ligne);
649 
650   if (importer_part == true) {
651 
652     ECS_REALLOC(*noeuds, (*taille_noeuds) + 1, ecs_loc_noeuds_ens_t);
653 
654     noeuds_loc = (*noeuds) + (*taille_noeuds);
655 
656     *taille_noeuds += 1;
657 
658     /* Conversion des id noeuds */
659 
660     if (id_noeud_loc == NULL || sizeof(int32_t) == sizeof(ecs_int_t))
661       id_noeud_tmp = (ecs_int_t *)id_noeud_loc;
662 
663     else {
664       ECS_MALLOC(id_noeud_tmp, nbr_noeuds, ecs_int_t);
665       for (ind = 0; ind < nbr_noeuds; ind++)
666         id_noeud_tmp[ind] = id_noeud_loc[ind];
667       ECS_FREE(id_noeud_loc);
668     }
669 
670     /* Entrelacage des coordonnées */
671 
672     ECS_MALLOC(coord_tmp, nbr_noeuds*3, ecs_coord_t);
673 
674     for (ind = 0; ind < nbr_noeuds; ind++) {
675       for (ind_coo = 0; ind_coo < 3; ind_coo++)
676         coord_tmp[ind*3 + ind_coo] = coord_loc[nbr_noeuds*ind_coo + ind];
677     }
678 
679     ECS_FREE(coord_loc);
680 
681     noeuds_loc->nbr_noeuds = (ecs_int_t)nbr_noeuds;
682     noeuds_loc->id_noeud   = id_noeud_tmp;
683     noeuds_loc->coord      = coord_tmp;
684     noeuds_loc->num_part   = num_part;
685 
686   }
687   else {
688 
689     ECS_FREE(coord_loc);
690     ECS_FREE(id_noeud_loc);
691 
692   }
693 }
694 
695 /*----------------------------------------------------------------------------
696  *  Lecture des noeuds au format EnSight 6 ;
697  *----------------------------------------------------------------------------*/
698 
699 static void
ecs_loc_pre_ens__lit_noeuds_6(ecs_file_t * fic,bool lire_id_noeud,ecs_int_t * taille_noeuds,ecs_loc_noeuds_ens_t ** noeuds,char chaine[],int * num_ligne)700 ecs_loc_pre_ens__lit_noeuds_6(ecs_file_t             *fic,
701                               bool                    lire_id_noeud,
702                               ecs_int_t              *taille_noeuds,
703                               ecs_loc_noeuds_ens_t  **noeuds,
704                               char                    chaine[],
705                               int                    *num_ligne)
706 {
707   ecs_int_t    ind;
708   ecs_int_t    nbr_noeuds;
709 
710   int32_t      val_int_lue;
711 
712   int32_t       *id_noeud_loc = NULL;
713   ecs_int_t     *id_noeud_tmp = NULL;
714   float         *coord_loc    = NULL;
715   ecs_coord_t   *coord_tmp    = NULL;
716 
717   /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
718 
719   ecs_loc_pre_ens__lit_chaine(fic, chaine, num_ligne);
720 
721   if (strncmp(chaine, "coordinates", strlen("coordinates")) != 0)
722     ecs_error(__FILE__, __LINE__, 0,
723               _("EnSight: field \"%s\" encountered where\n"
724                 "\"coordinates\" was expected."), chaine);
725 
726   ecs_loc_pre_ens__lit_int(fic, 1, &val_int_lue, 8, num_ligne);
727 
728   nbr_noeuds = val_int_lue;
729 
730   if (lire_id_noeud == true)
731     ECS_MALLOC(id_noeud_loc, nbr_noeuds,  int32_t);
732   else
733     id_noeud_loc = NULL;
734 
735   ECS_MALLOC(coord_loc, nbr_noeuds*3,  float);
736 
737   ecs_loc_pre_ens__lit_tab_coo_6(fic,
738                                  nbr_noeuds ,
739                                  id_noeud_loc ,
740                                  coord_loc ,
741                                  num_ligne);
742 
743   if (coord_loc != NULL) {
744     *taille_noeuds = 1;
745     ECS_MALLOC(*noeuds, (*taille_noeuds),  ecs_loc_noeuds_ens_t);
746   }
747   else
748     ecs_error(__FILE__, __LINE__, 0,
749               _("EnSight: no node defined in file\n\"%s\"."),
750               ecs_file_get_name(fic));
751 
752   /* Conversion des id noeuds */
753 
754   if (id_noeud_loc == NULL || sizeof(int32_t) == sizeof(ecs_int_t))
755     id_noeud_tmp = (ecs_int_t *)id_noeud_loc;
756 
757   else {
758     ECS_MALLOC(id_noeud_tmp, nbr_noeuds, ecs_int_t);
759     for (ind = 0; ind < nbr_noeuds; ind++)
760       id_noeud_tmp[ind] = id_noeud_loc[ind];
761     ECS_FREE(id_noeud_loc);
762   }
763 
764   /* Conversion des coordonnées */
765 
766   ECS_MALLOC(coord_tmp, nbr_noeuds*3, ecs_coord_t);
767 
768   for (ind = 0; ind < 3*nbr_noeuds; ind++) {
769     coord_tmp[ind] = coord_loc[ind];
770   }
771 
772   ECS_FREE(coord_loc);
773 
774   (*noeuds)->nbr_noeuds = (ecs_int_t)nbr_noeuds;
775   (*noeuds)->id_noeud   = id_noeud_tmp;
776   (*noeuds)->coord      = coord_tmp;
777   (*noeuds)->num_part   =  -1;
778 }
779 
780 /*----------------------------------------------------------------------------
781  * Retourne le type de l'élément ainsi que son nombre de sommet
782  *----------------------------------------------------------------------------*/
783 
784 static void
ecs_loc_pre_ens__type_elem(ecs_file_t * fic,const char chaine[],int * nbr_som_elt,ecs_elt_typ_t * elt_typ)785 ecs_loc_pre_ens__type_elem(ecs_file_t     *fic,
786                            const char      chaine[],
787                            int            *nbr_som_elt,
788                            ecs_elt_typ_t  *elt_typ)
789 {
790   /*----------------------------*/
791   /* Décodage du type d'élément */
792   /*----------------------------*/
793 
794   if (strncmp(chaine, "g_", strlen("g_")) == 0)
795     ecs_error(__FILE__, __LINE__, 0,
796               _("EnSight: error reading file \"%s\".\n"
797                 "The current \"part\" contains ghost cells,\n"
798                 "not currently handled."),
799               ecs_file_get_name(fic));
800 
801   else if (strncmp(chaine, "bar", strlen("bar")) == 0) {
802     *elt_typ         = ECS_ELT_TYP_NUL;
803     *nbr_som_elt     = atoi(chaine+strlen("bar"));
804   }
805   else if (strncmp(chaine, "tria", strlen("tria")) == 0) {
806     *elt_typ         = ECS_ELT_TYP_FAC_TRIA;
807     *nbr_som_elt     = atoi(chaine+strlen("tria"));
808   }
809   else if (strncmp(chaine, "quad", strlen("quad")) == 0) {
810     *elt_typ         = ECS_ELT_TYP_FAC_QUAD;
811     *nbr_som_elt     = atoi(chaine+strlen("quad"));
812   }
813   else if (strncmp(chaine, "tetra", strlen("tetra")) == 0) {
814     *elt_typ         = ECS_ELT_TYP_CEL_TETRA;
815     *nbr_som_elt     = atoi(chaine+strlen("tetra"));
816   }
817   else if (strncmp(chaine, "pyramid", strlen("pyramid")) == 0) {
818     *elt_typ         = ECS_ELT_TYP_CEL_PYRAM;
819     *nbr_som_elt     = atoi(chaine+strlen("pyramid"));
820   }
821   else if (strncmp(chaine, "penta", strlen("penta")) == 0) {
822     *elt_typ         = ECS_ELT_TYP_CEL_PRISM;
823     *nbr_som_elt     = atoi(chaine+strlen("penta"));
824   }
825   else if (strncmp(chaine, "hexa", strlen("hexa")) == 0) {
826     *elt_typ         = ECS_ELT_TYP_CEL_HEXA;
827     *nbr_som_elt     = atoi(chaine+strlen("hexa"));
828   }
829   else if (strncmp(chaine, "nsided", strlen("nsided")) == 0) {
830     *elt_typ         = ECS_ELT_TYP_FAC_POLY;
831     *nbr_som_elt     = 0;
832   }
833   else if (strncmp(chaine, "nfaced", strlen("nfaced")) == 0) {
834     *elt_typ         = ECS_ELT_TYP_CEL_POLY;
835     *nbr_som_elt     = 0;
836   }
837   else {
838     ecs_error(__FILE__, __LINE__, 0,
839               _("EnSight: error reading file \"%s\".\n"
840                 "The current \"part\" contains a section of type:\n"
841                 "\"%s\"\n"
842                 "not currently handled."),
843               ecs_file_get_name(fic), chaine);
844   }
845 }
846 
847 /*----------------------------------------------------------------------------
848  * Transformation des éléments en éléments linéaires.
849  * Cette fonction renvoie un pointeur sur le tableau de connectivité réalloué.
850  *----------------------------------------------------------------------------*/
851 
852 static int32_t *
ecs_loc_pre_ens__ele_lin(int32_t * connect_loc,ecs_int_t nbr_ele,ecs_int_t taille_ele,ecs_int_t taille_ele_lin)853 ecs_loc_pre_ens__ele_lin(int32_t     *connect_loc,
854                          ecs_int_t    nbr_ele,
855                          ecs_int_t    taille_ele,
856                          ecs_int_t    taille_ele_lin)
857 {
858   ecs_int_t    ielt;
859   ecs_int_t    iloc;
860   ecs_int_t    ipos_lin;
861   ecs_int_t    ipos_ens;
862 
863   ipos_lin = 0;
864 
865   for (ielt = 0; ielt < nbr_ele; ielt++) {
866 
867     ipos_ens = ielt * taille_ele;
868 
869     for (iloc = 0; iloc < taille_ele_lin; iloc++)
870       connect_loc[ipos_lin++] = connect_loc[ipos_ens++];
871 
872   }
873 
874   ECS_REALLOC(connect_loc, ipos_lin, int32_t);
875 
876   return connect_loc;
877 }
878 
879 /*----------------------------------------------------------------------------
880  * Lecture des éléments format EnSight Gold; renvoie le nombre d'éléments lus,
881  * ou -1 si l'on a affaire à une "part"
882  *----------------------------------------------------------------------------*/
883 
884 static ecs_int_t
ecs_loc_pre_ens__lit_elem_gold(ecs_file_t * fic,ecs_int_t num_part,bool lire_id_elem,bool importer_part,const ecs_loc_noeuds_ens_t * noeuds,ecs_int_t * taille_elems,ecs_loc_elems_ens_t ** elems,char chaine[],int * num_ligne)885 ecs_loc_pre_ens__lit_elem_gold(ecs_file_t                   *fic,
886                                ecs_int_t                     num_part,
887                                bool                          lire_id_elem,
888                                bool                          importer_part,
889                                const ecs_loc_noeuds_ens_t   *noeuds,
890                                ecs_int_t                    *taille_elems,
891                                ecs_loc_elems_ens_t         **elems,
892                                char                          chaine[],
893                                int                          *num_ligne)
894 {
895   int            nbr_som_elt;
896 
897   ecs_int_t      ind;
898   ecs_int_t      taille_connect;
899   ecs_int_t      taille_lect;
900 
901   ecs_elt_typ_t   elt_typ;
902 
903   int32_t     * id_elem;
904 
905   ecs_loc_elems_ens_t  *elems_loc;
906 
907   ecs_int_t  nbr_som_elt_lin = 0;
908   int32_t    nbr_elt_loc = 0;
909   int32_t  * nbr_n_loc = NULL;
910   int32_t  * nbr_f_loc = NULL;
911   int32_t  * connect_loc = NULL;
912 
913   const ecs_int_t  l_fmt_int = 10;
914 
915   /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
916 
917   /* On s'assure qu'on n'a pas affaire à une "part" */
918 
919   if (strncmp(chaine, "part", strlen("part")) == 0)
920     return -1;
921 
922   /*----------------------------*/
923   /* Décodage du type d'élément */
924   /*----------------------------*/
925 
926   ecs_loc_pre_ens__type_elem(fic, chaine, &nbr_som_elt, &elt_typ);
927 
928   /* Lecture du nombre d'éléments */
929   /*------------------------------*/
930 
931   ecs_loc_pre_ens__lit_int(fic, 1, &nbr_elt_loc, l_fmt_int, num_ligne);
932 
933   printf(_("    %10d %-10s elements\n"), (int)nbr_elt_loc, chaine);
934 
935   /*------------------------------------------------*/
936   /* Lecture éventuelle des labels des éléments     */
937   /*------------------------------------------------*/
938 
939   if (lire_id_elem == true) {
940     id_elem = ecs_loc_pre_ens__lit_int(fic,
941                                        (ecs_int_t)nbr_elt_loc,
942                                        NULL,
943                                        l_fmt_int,
944                                        num_ligne);
945     ECS_FREE(id_elem);
946   }
947 
948   /*------------------------------------------------*/
949   /* Lecture de la connectivité nodale des elements */
950   /*------------------------------------------------*/
951 
952   if (elt_typ == ECS_ELT_TYP_FAC_POLY) {
953 
954     nbr_n_loc = ecs_loc_pre_ens__lit_int(fic,
955                                          (ecs_int_t)nbr_elt_loc,
956                                          NULL,
957                                          l_fmt_int,
958                                          num_ligne);
959     taille_lect = 0;
960     for (ind = 0; ind < (ecs_int_t)nbr_elt_loc; ind++)
961       taille_lect += nbr_n_loc[ind];
962 
963     taille_connect = taille_lect;
964 
965   }
966   else if (elt_typ == ECS_ELT_TYP_CEL_POLY) {
967 
968     ecs_int_t taille_int = 0;
969 
970     nbr_f_loc = ecs_loc_pre_ens__lit_int(fic,
971                                          (ecs_int_t)nbr_elt_loc,
972                                          NULL,
973                                          l_fmt_int,
974                                          num_ligne);
975     taille_lect = 0;
976 
977     for (ind = 0; ind < (ecs_int_t)nbr_elt_loc; ind++)
978       taille_int += nbr_f_loc[ind];
979 
980     nbr_n_loc = ecs_loc_pre_ens__lit_int(fic,
981                                          taille_int,
982                                          NULL,
983                                          l_fmt_int,
984                                          num_ligne);
985 
986     for (ind = 0; ind < taille_int; ind++)
987       taille_lect += nbr_n_loc[ind];
988 
989     taille_connect = taille_lect;
990 
991   }
992   else  {
993     nbr_som_elt_lin = ecs_fic_elt_typ_liste_c[elt_typ].nbr_som;
994     taille_lect    = nbr_elt_loc * nbr_som_elt;
995     taille_connect = nbr_elt_loc * nbr_som_elt_lin;
996   }
997   connect_loc = ecs_loc_pre_ens__lit_int(fic,
998                                          taille_lect,
999                                          NULL,
1000                                          l_fmt_int,
1001                                          num_ligne);
1002 
1003   if (importer_part == true && elt_typ != ECS_ELT_TYP_NUL) {
1004 
1005     ECS_REALLOC(*elems, (*taille_elems) + 1, ecs_loc_elems_ens_t);
1006 
1007     elems_loc = (*elems) + (*taille_elems);
1008 
1009     *taille_elems += 1;
1010 
1011     /* Suppression références noeuds non sommets éventuels */
1012 
1013     if (taille_lect > taille_connect) {
1014       connect_loc = ecs_loc_pre_ens__ele_lin(connect_loc,
1015                                              (ecs_int_t)nbr_elt_loc,
1016                                              nbr_som_elt,
1017                                              nbr_som_elt_lin);
1018 
1019     }
1020 
1021     /* Application des labels des sommets */
1022 
1023     if (noeuds->id_noeud != NULL) {
1024 
1025       for (ind = 0; ind < taille_connect; ind++){
1026         assert(   (connect_loc[ind]-1) >= 0
1027                && (connect_loc[ind]-1) < noeuds->nbr_noeuds);
1028         connect_loc[ind] = noeuds->id_noeud[connect_loc[ind]-1];
1029       }
1030     }
1031 
1032     elems_loc->nbr_ele  = nbr_elt_loc;
1033     elems_loc->elt_typ  = elt_typ;
1034     elems_loc->nbr_n    = nbr_n_loc;
1035     elems_loc->nbr_f    = nbr_f_loc;
1036     elems_loc->connect  = connect_loc;
1037     elems_loc->num_part = num_part;
1038 
1039   }
1040   else {
1041 
1042     if (nbr_n_loc != NULL)
1043       ECS_FREE(nbr_n_loc);
1044 
1045     if (nbr_f_loc != NULL)
1046       ECS_FREE(nbr_f_loc);
1047 
1048     ECS_FREE(connect_loc);
1049 
1050   }
1051 
1052   return nbr_elt_loc;
1053 
1054 }
1055 
1056 /*----------------------------------------------------------------------------
1057  * Lecture des éléments format EnSight 6; renvoie le nombre d'éléments lus,
1058  * ou -1 si l'on a affaire à une "part"
1059  *----------------------------------------------------------------------------*/
1060 
1061 static ecs_int_t
ecs_loc_pre_ens__lit_elem_6(ecs_file_t * fic,int num_part,bool lire_id_elem,bool importer_part,ecs_int_t * taille_elems,ecs_loc_elems_ens_t ** elems,char chaine[],int * num_ligne)1062 ecs_loc_pre_ens__lit_elem_6(ecs_file_t            *fic,
1063                             int                    num_part,
1064                             bool                   lire_id_elem,
1065                             bool                   importer_part,
1066                             ecs_int_t             *taille_elems,
1067                             ecs_loc_elems_ens_t  **elems,
1068                             char                   chaine[],
1069                             int                   *num_ligne)
1070 {
1071   int            nbr_som_elt;
1072 
1073   ecs_int_t      nbr_som_elt_lin;
1074   ecs_int_t      taille_connect;
1075   ecs_int_t      taille_lect;
1076 
1077   ecs_elt_typ_t   elt_typ;
1078 
1079   int32_t  * id_elem;
1080 
1081   ecs_loc_elems_ens_t  *elems_loc;
1082 
1083   int32_t    nbr_elt_loc = 0;
1084   int32_t  * nbr_n_loc = NULL;
1085   int32_t  * nbr_f_loc = NULL;
1086   int32_t  * connect_loc = NULL;
1087 
1088   const ecs_int_t  l_fmt_int = 8;
1089 
1090   /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
1091 
1092   /* On s'assure qu'on n'a pas affaire à une "part" */
1093 
1094   if (strncmp(chaine, "part", strlen("part")) == 0)
1095     return -1;
1096 
1097   /*----------------------------*/
1098   /* Décodage du type d'élément */
1099   /*----------------------------*/
1100 
1101   ecs_loc_pre_ens__type_elem(fic, chaine, &nbr_som_elt, &elt_typ);
1102 
1103   /* Lecture du nombre d'éléments */
1104   /*------------------------------*/
1105 
1106   ecs_loc_pre_ens__lit_int(fic, 1, &nbr_elt_loc, l_fmt_int, num_ligne);
1107 
1108   printf(_("    %10d %-10s elements\n"), (int)nbr_elt_loc, chaine);
1109 
1110   /*------------------------------------------------*/
1111   /* Lecture éventuelle des labels des éléments     */
1112   /* et Lecture de la connectivité                  */
1113   /*------------------------------------------------*/
1114 
1115   ECS_MALLOC(id_elem, nbr_elt_loc, int32_t);
1116   ECS_MALLOC(connect_loc, nbr_elt_loc * nbr_som_elt, int32_t);
1117 
1118   ecs_loc_pre_ens__lit_tab_connect(fic ,
1119                                    nbr_elt_loc  ,
1120                                    lire_id_elem ,
1121                                    nbr_som_elt ,
1122                                    id_elem ,
1123                                    connect_loc ,
1124                                    num_ligne);
1125   ECS_FREE(id_elem);
1126 
1127   nbr_som_elt_lin = ecs_fic_elt_typ_liste_c[elt_typ].nbr_som;
1128   taille_lect    = nbr_elt_loc * nbr_som_elt;
1129   taille_connect = nbr_elt_loc * nbr_som_elt_lin;
1130 
1131   if (importer_part == true && elt_typ != ECS_ELT_TYP_NUL) {
1132 
1133     ECS_REALLOC(*elems, (*taille_elems) + 1, ecs_loc_elems_ens_t);
1134 
1135     elems_loc = (*elems) + (*taille_elems);
1136 
1137     *taille_elems += 1;
1138 
1139     /* Suppression références noeuds non sommets éventuels */
1140 
1141     if (taille_lect > taille_connect) {
1142       connect_loc = ecs_loc_pre_ens__ele_lin(connect_loc,
1143                                              (ecs_int_t)nbr_elt_loc,
1144                                              nbr_som_elt,
1145                                              nbr_som_elt_lin);
1146 
1147     }
1148 
1149     elems_loc->nbr_ele  = nbr_elt_loc;
1150     elems_loc->elt_typ  = elt_typ;
1151     elems_loc->nbr_n    = nbr_n_loc;
1152     elems_loc->nbr_f    = nbr_f_loc;
1153     elems_loc->connect  = connect_loc;
1154     elems_loc->num_part = num_part;
1155 
1156   }
1157   else {
1158 
1159     ECS_FREE(connect_loc);
1160 
1161   }
1162   return nbr_elt_loc;
1163 }
1164 
1165 /*----------------------------------------------------------------------------
1166  *  Vérification qu'un groupe de noeuds est bien défini avec des
1167  *  labels croissants, et tri le cas échéant.
1168  *----------------------------------------------------------------------------*/
1169 
1170 static void
ecs_loc_pre_ens__trie_noeuds(ecs_loc_noeuds_ens_t * noeuds)1171 ecs_loc_pre_ens__trie_noeuds(ecs_loc_noeuds_ens_t  *noeuds)
1172 {
1173   ecs_int_t         ind;
1174   ecs_int_t         ind_coo;
1175 
1176   ecs_tab_int_t     id_noeud_loc;
1177   ecs_tab_int_t     id_trie;
1178   ecs_tab_int_t     renum;
1179 
1180   bool              a_trier = false;
1181 
1182   ecs_coord_t      *coord_tmp    = NULL;
1183 
1184   /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
1185 
1186   if (noeuds->id_noeud == NULL)
1187     return;
1188 
1189   a_trier = false;
1190 
1191   for (ind = 0; ind < noeuds->nbr_noeuds - 1; ind++) {
1192 
1193     if (noeuds->id_noeud[ind + 1] <= noeuds->id_noeud[ind]) {
1194 
1195       a_trier = true;
1196       break;
1197 
1198     }
1199 
1200   }
1201 
1202   /* Si l'on a des sommets à trier */
1203 
1204   if (a_trier == true) {
1205 
1206     id_noeud_loc.nbr = noeuds->nbr_noeuds;
1207     id_noeud_loc.val = noeuds->id_noeud;
1208 
1209     /* Tri effectif */
1210 
1211     ECS_MALLOC(renum.val, noeuds->nbr_noeuds, ecs_int_t);
1212     renum.nbr = noeuds->nbr_noeuds;
1213 
1214     id_trie = ecs_tab_int__trie_et_renvoie(id_noeud_loc,
1215                                            renum);
1216 
1217     ECS_FREE(noeuds->id_noeud);
1218 
1219     noeuds->id_noeud = id_trie.val;
1220 
1221     ECS_MALLOC(coord_tmp, noeuds->nbr_noeuds*3, ecs_coord_t);
1222 
1223     for (ind = 0; ind < noeuds->nbr_noeuds; ind++) {
1224       for (ind_coo = 0; ind_coo < 3; ind_coo++)
1225         coord_tmp[ind*3 + ind_coo]
1226           = noeuds->coord[(renum.val[ind])*3 + ind_coo];
1227 
1228     }
1229 
1230     ECS_FREE(renum.val);
1231 
1232     ECS_FREE(noeuds->coord);
1233 
1234     noeuds->coord = coord_tmp;
1235  }
1236 }
1237 
1238 /*----------------------------------------------------------------------------
1239  *  Fusion de deux blocs de définitions de noeuds ; le premier ensemble
1240  *  (noeuds_ref) est étendu au besoin, le deuxième est supprimé (i.e.
1241  *  ses tableaux sont libérés, et il n'est plus valide à l'issue de
1242  *  cette fonction).
1243  *----------------------------------------------------------------------------*/
1244 
1245 static void
ecs_loc_pre_ens__fusion_noeuds(ecs_loc_noeuds_ens_t * noeuds_ref,ecs_loc_noeuds_ens_t * noeuds_add)1246 ecs_loc_pre_ens__fusion_noeuds(ecs_loc_noeuds_ens_t  *noeuds_ref,
1247                                ecs_loc_noeuds_ens_t  *noeuds_add)
1248 {
1249   ecs_int_t          cpt_add;
1250   ecs_int_t          ind_add;
1251   ecs_int_t          ind_ref;
1252   ecs_int_t          ind_tot;
1253   ecs_int_t          ind_coo;
1254   ecs_int_t          nbr_noeuds_tot;
1255 
1256   ecs_int_t        * id_new    = NULL;
1257   ecs_coord_t      * coord_new = NULL;
1258 
1259   /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
1260 
1261   if (noeuds_ref->id_noeud == NULL || noeuds_ref->id_noeud == NULL)
1262     ecs_error(__FILE__, __LINE__, 0,
1263               _("EnSight: error merging node groups.\n"
1264                 "At least one of the groups has no \"id\", and they\n"
1265                 "should not be merged (internal logic problem)."));
1266 
1267 
1268   ind_ref = 0;
1269   cpt_add = 0;
1270 
1271   for (ind_add = 0; ind_add < noeuds_add->nbr_noeuds; ind_add++) {
1272 
1273     while (   ind_ref < noeuds_ref->nbr_noeuds
1274            && noeuds_ref->id_noeud[ind_ref] < noeuds_add->id_noeud[ind_add])
1275       ind_ref++;
1276 
1277     if (   ind_ref == noeuds_ref->nbr_noeuds
1278         || (ind_ref < noeuds_ref->nbr_noeuds
1279             && (   noeuds_ref->id_noeud[ind_ref]
1280                 != noeuds_add->id_noeud[ind_add])))
1281       cpt_add++;
1282 
1283   }
1284 
1285   /* Si l'on a des sommets à fusionner */
1286 
1287   if (cpt_add > 0) {
1288 
1289     nbr_noeuds_tot = noeuds_ref->nbr_noeuds + cpt_add;
1290 
1291     ECS_MALLOC(id_new,    nbr_noeuds_tot,   ecs_int_t);
1292     ECS_MALLOC(coord_new, nbr_noeuds_tot*3, ecs_coord_t);
1293 
1294     ind_ref = 0;
1295     ind_tot = 0;
1296     cpt_add = 0;
1297 
1298     for (ind_add = 0; ind_add < noeuds_add->nbr_noeuds; ind_add++) {
1299 
1300       while (   ind_ref < noeuds_ref->nbr_noeuds
1301              && noeuds_ref->id_noeud[ind_ref] < noeuds_add->id_noeud[ind_add]) {
1302         id_new[ind_tot] = noeuds_ref->id_noeud[ind_ref];
1303         for (ind_coo = 0; ind_coo < 3; ind_coo++)
1304           coord_new[ind_tot*3 + ind_coo]
1305             = noeuds_ref->coord[ind_ref*3 + ind_coo];
1306         ind_tot++;
1307         ind_ref++;
1308       }
1309 
1310       if (   ind_ref == noeuds_ref->nbr_noeuds
1311           || (ind_ref < noeuds_ref->nbr_noeuds
1312               && (   noeuds_ref->id_noeud[ind_ref]
1313                   != noeuds_add->id_noeud[ind_add]))) {
1314         id_new[ind_tot] = noeuds_add->id_noeud[ind_add];
1315         for (ind_coo = 0; ind_coo < 3; ind_coo++)
1316           coord_new[ind_tot*3 + ind_coo]
1317             = noeuds_add->coord[ind_add*3 + ind_coo];
1318         ind_tot++;
1319       }
1320 
1321     }
1322 
1323     /* Il peut rester des éléments dans la liste de référence */
1324 
1325     while (   ind_ref < noeuds_ref->nbr_noeuds ) {
1326       id_new[ind_tot] = noeuds_ref->id_noeud[ind_ref];
1327       for (ind_coo = 0; ind_coo < 3; ind_coo++)
1328         coord_new[ind_tot*3 + ind_coo]
1329           = noeuds_ref->coord[ind_ref*3 + ind_coo];
1330       ind_tot++;
1331       ind_ref++;
1332     }
1333 
1334     ECS_FREE(noeuds_ref->id_noeud);
1335     ECS_FREE(noeuds_ref->coord);
1336 
1337     /* On remplace les anciennes valeurs de référence par les
1338        valeurs fusionnées */
1339 
1340     noeuds_ref->nbr_noeuds = ind_tot;
1341     noeuds_ref->id_noeud   = id_new;
1342     noeuds_ref->coord      = coord_new;
1343 
1344   }
1345 
1346   /* On libère les valeurs à fusionner */
1347 
1348   ECS_FREE(noeuds_add->id_noeud);
1349   ECS_FREE(noeuds_add->coord);
1350 }
1351 
1352 /*----------------------------------------------------------------------------
1353  *  Concaténation des éléments pour préparer le transfert dans la structure
1354  *   de maillage ; la liste des élémens liste_elems est libérée, et remplacée
1355  *   par la structure renvoyée.
1356  *
1357  *  Les références aux ids des noeuds sont transformés en indices, et
1358  *   les ids des noeuds ensuite supprimés.
1359  *----------------------------------------------------------------------------*/
1360 
1361 static void
ecs_loc_pre_ens__concat_elems(ecs_maillage_t * maillage,ecs_int_t taille_liste_elems,ecs_loc_noeuds_ens_t * liste_noeuds,ecs_loc_elems_ens_t ** liste_elems)1362 ecs_loc_pre_ens__concat_elems(ecs_maillage_t         *maillage,
1363                               ecs_int_t               taille_liste_elems,
1364                               ecs_loc_noeuds_ens_t   *liste_noeuds,
1365                               ecs_loc_elems_ens_t   **liste_elems)
1366 {
1367   ecs_entmail_t    entmail_e;
1368 
1369   ecs_int_t      ient;
1370   ecs_int_t      ielt;
1371   ecs_int_t      ielts_loc;
1372   ecs_int_t      ifac;
1373   ecs_int_t      isom;
1374   ecs_int_t      nbr_som_elt;
1375   ecs_int_t      nbr_som_fac;
1376   ecs_int_t      pos_elt;
1377 
1378   ecs_loc_elems_ens_t  * elems_loc;
1379   ecs_elt_typ_t          typ_geo;
1380 
1381   /* Déclarations des variables de stockage        */
1382   /* avant transfert dans la structure du maillage */
1383   /*-----------------------------------------------*/
1384 
1385   size_t       cpt_elt_ent        [ECS_N_ENTMAIL]; /* Nbr. elts par entité */
1386   ecs_int_t    cpt_coul_ent       [ECS_N_ENTMAIL]; /* Compteur de couleurs */
1387   ecs_int_t    cpt_val_som_ent    [ECS_N_ENTMAIL]; /* Taille connect.      */
1388   ecs_int_t    icoul              [ECS_N_ENTMAIL]; /* Couleur en cours     */
1389   ecs_int_t  * val_coul_ent       [ECS_N_ENTMAIL]; /* Tableau des couleurs */
1390   ecs_size_t * cpt_elt_coul_ent   [ECS_N_ENTMAIL];
1391   ecs_size_t * elt_pos_som_ent    [ECS_N_ENTMAIL]; /* Positions sommets    */
1392   ecs_int_t  * elt_val_som_ent    [ECS_N_ENTMAIL]; /* Numéros des sommets  */
1393   ecs_int_t  * elt_val_color_ent  [ECS_N_ENTMAIL]; /* Couleurs éléments    */
1394 
1395   /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
1396 
1397   /*====================================================*/
1398   /* Initialisations et allocations des tableaux locaux */
1399   /*====================================================*/
1400 
1401   /* Attention au decalage de `1' !!!         */
1402   /* On n'alloue pas les tableaux locaux pour */
1403   /* `ECS_ENTMAIL_DEB = ECS_ENTMAIL_SOM'      */
1404 
1405   for (ient = ECS_ENTMAIL_FAC; ient < ECS_N_ENTMAIL; ient++) {
1406 
1407     cpt_elt_ent        [ient] = 0;
1408     cpt_val_som_ent    [ient] = 0;
1409 
1410     elt_pos_som_ent    [ient] = NULL;
1411     elt_val_som_ent    [ient] = NULL;
1412     elt_val_color_ent  [ient] = NULL;
1413 
1414     cpt_coul_ent       [ient] = 0;
1415     val_coul_ent       [ient] = NULL;
1416     cpt_elt_coul_ent   [ient] = NULL;
1417 
1418   }
1419 
1420   /* Vérification que la liste des éléments n'est pas vide */
1421 
1422   assert(taille_liste_elems != 0);
1423   assert(liste_elems != NULL);
1424 
1425   /* Boucle sur la liste des éléments pour le dimensionnement */
1426   /*----------------------------------------------------------*/
1427 
1428   for (ielts_loc = 0; ielts_loc < taille_liste_elems; ielts_loc++) {
1429 
1430     elems_loc = (*liste_elems) + ielts_loc;
1431 
1432     /* Identification de l'entité concernée */
1433 
1434     typ_geo = elems_loc->elt_typ;
1435     entmail_e = ecs_maillage_pre__ret_typ_geo(elems_loc->elt_typ);
1436 
1437     /* Nombre d'éléments à ajouter */
1438 
1439     cpt_elt_ent[entmail_e] += elems_loc->nbr_ele;
1440 
1441     /* Traitement des éléments "classiques" */
1442 
1443     if (typ_geo != ECS_ELT_TYP_CEL_POLY && typ_geo != ECS_ELT_TYP_FAC_POLY) {
1444 
1445       nbr_som_elt = ecs_fic_elt_typ_liste_c[typ_geo].nbr_som;
1446 
1447       cpt_val_som_ent[entmail_e] += (elems_loc->nbr_ele * nbr_som_elt);
1448 
1449     }
1450 
1451     /* Traitement des Polygones */
1452 
1453     else if (typ_geo == ECS_ELT_TYP_FAC_POLY) {
1454 
1455       for (ielt = 0; ielt < elems_loc->nbr_ele; ielt++)
1456 
1457         cpt_val_som_ent[entmail_e] += (elems_loc->nbr_n[ielt]);
1458 
1459     }
1460 
1461     /* Traitement des Polyèdres */
1462 
1463     else if (typ_geo == ECS_ELT_TYP_CEL_POLY) {
1464 
1465       ecs_int_t  cpt_fac_loc = 0;
1466 
1467       for (ielt = 0; ielt < elems_loc->nbr_ele; ielt++) {
1468 
1469         for (ifac = 0; ifac < elems_loc->nbr_f[ielt]; ifac++) {
1470 
1471           /* Le premier noeud de chaque face est répété en queue pour la
1472              détection de fin de face -> + 1 pour la taille */
1473 
1474           cpt_val_som_ent[entmail_e] += elems_loc->nbr_n[cpt_fac_loc] + 1;
1475 
1476           cpt_fac_loc++;
1477 
1478         }
1479 
1480       }
1481 
1482     } /* Fin du traitement selon le type d'entité */
1483 
1484   }
1485 
1486   /* Allocations et initialisation */
1487   /*-------------------------------*/
1488 
1489   for (ient = ECS_ENTMAIL_FAC; ient < ECS_N_ENTMAIL; ient++) {
1490 
1491     if (cpt_elt_ent[ient] > 0) {
1492 
1493       ECS_MALLOC(elt_pos_som_ent[ient],
1494                  cpt_elt_ent[ient] + 1,
1495                  ecs_size_t);
1496 
1497       elt_pos_som_ent[ient][0] = 1;
1498 
1499       ECS_MALLOC(elt_val_som_ent[ient],
1500                  cpt_val_som_ent[ient],
1501                  ecs_int_t);
1502 
1503       ECS_MALLOC(elt_val_color_ent[ient]  ,
1504                  cpt_elt_ent[ient],
1505                  ecs_int_t);
1506     }
1507   }
1508 
1509   /* Remise à zéro des compteurs de dimensionnement */
1510 
1511   for (ient = ECS_ENTMAIL_FAC; ient < ECS_N_ENTMAIL; ient++) {
1512 
1513     cpt_elt_ent[ient]     = 0;
1514     cpt_val_som_ent[ient] = 0;
1515 
1516   }
1517 
1518   /* Boucle sur la liste des éléments pour construction */
1519   /* des variables de stockage pour le transfert dans   */
1520   /* la structure de maillage                           */
1521   /*----------------------------------------------------*/
1522 
1523   for (ielts_loc = 0; ielts_loc < taille_liste_elems; ielts_loc++) {
1524 
1525     elems_loc = (*liste_elems) + ielts_loc;
1526 
1527     /* Identification de l'entité concernée */
1528     /*--------------------------------------*/
1529 
1530     typ_geo = elems_loc->elt_typ;
1531     entmail_e = ecs_maillage_pre__ret_typ_geo(elems_loc->elt_typ);
1532 
1533 
1534     /* Couleur des éléments lus positionnée au numéro du part auquel
1535        appartiennent les éléments */
1536 
1537     for (icoul[entmail_e] = 0;
1538          icoul[entmail_e] < cpt_coul_ent[entmail_e]
1539            && val_coul_ent[entmail_e][icoul[entmail_e]] != elems_loc->num_part;
1540          icoul[entmail_e]++);
1541 
1542     if (icoul[entmail_e] == cpt_coul_ent[entmail_e]) {
1543 
1544       /* La valeur de la couleur n'a pas encore été stockée */
1545 
1546       ECS_REALLOC(val_coul_ent[entmail_e],
1547                   cpt_coul_ent[entmail_e] + 1,
1548                   ecs_int_t);
1549       ECS_REALLOC(cpt_elt_coul_ent[entmail_e],
1550                   cpt_coul_ent[entmail_e] + 1,
1551                   ecs_size_t);
1552 
1553       cpt_elt_coul_ent[entmail_e][icoul[entmail_e]] = 0;
1554       val_coul_ent[entmail_e][icoul[entmail_e]] = elems_loc->num_part;
1555       cpt_coul_ent[entmail_e]++;
1556     }
1557 
1558     /* Traitement des éléments "classiques" */
1559     /*--------------------------------------*/
1560 
1561     if (typ_geo != ECS_ELT_TYP_CEL_POLY && typ_geo != ECS_ELT_TYP_FAC_POLY) {
1562 
1563       nbr_som_elt = ecs_fic_elt_typ_liste_c[typ_geo].nbr_som;
1564 
1565       for (ielt = 0; ielt < elems_loc->nbr_ele; ielt++) {
1566 
1567         /* Construction connectivité */
1568 
1569         pos_elt = elt_pos_som_ent[entmail_e][cpt_elt_ent[entmail_e]];
1570 
1571         elt_pos_som_ent[entmail_e][cpt_elt_ent[entmail_e] + 1]
1572           = pos_elt + nbr_som_elt;
1573 
1574         for (isom = 0; isom < nbr_som_elt; isom++)
1575           elt_val_som_ent[entmail_e][pos_elt - 1 + isom]
1576             = elems_loc->connect[ielt*nbr_som_elt + isom];
1577 
1578         /* Affectation couleurs */
1579 
1580         cpt_elt_coul_ent[entmail_e][icoul[entmail_e]]++;
1581         elt_val_color_ent[entmail_e][cpt_elt_ent[entmail_e]]
1582           = icoul[entmail_e] + 1;
1583 
1584         /* Mise à jour compteurs */
1585 
1586         cpt_elt_ent[entmail_e] += 1;
1587         cpt_val_som_ent[entmail_e] += nbr_som_elt;
1588 
1589       }
1590 
1591     }
1592 
1593     /* Traitement des Polygones */
1594     /*--------------------------*/
1595 
1596     else if (typ_geo == ECS_ELT_TYP_FAC_POLY) {
1597 
1598       ecs_int_t  cpt_som_loc = 0;
1599 
1600       for (ielt = 0; ielt < elems_loc->nbr_ele; ielt++) {
1601 
1602         nbr_som_elt = elems_loc->nbr_n[ielt];
1603 
1604         /* Construction connectivité */
1605 
1606         pos_elt = elt_pos_som_ent[entmail_e][cpt_elt_ent[entmail_e]];
1607 
1608         elt_pos_som_ent[entmail_e][cpt_elt_ent[entmail_e] + 1]
1609           = pos_elt + nbr_som_elt;
1610 
1611         for (isom = 0; isom < nbr_som_elt; isom++)
1612           elt_val_som_ent[entmail_e][pos_elt - 1 + isom]
1613             = elems_loc->connect[cpt_som_loc++];
1614 
1615         /* Affectation couleurs */
1616 
1617         cpt_elt_coul_ent[entmail_e][icoul[entmail_e]]++;
1618         elt_val_color_ent[entmail_e][cpt_elt_ent[entmail_e]]
1619           = icoul[entmail_e] + 1;
1620 
1621         /* Mise à jour compteurs */
1622 
1623         cpt_elt_ent[entmail_e] += 1;
1624         cpt_val_som_ent[entmail_e] += nbr_som_elt;
1625 
1626       }
1627     }
1628 
1629     /* Traitement des Polyèdres */
1630     /*--------------------------*/
1631 
1632     else if (typ_geo == ECS_ELT_TYP_CEL_POLY) {
1633 
1634       ecs_int_t nbr_fac_elt;       /* nombre de faces par élément */
1635       ecs_int_t ifac_elt;
1636 
1637       ecs_int_t  num_som_deb_fac;
1638       ecs_int_t  cpt_fac_loc = 0;
1639       ecs_int_t  cpt_som_loc = 0;
1640 
1641       /* Remplissage de la connectivité */
1642 
1643       for (ielt = 0; ielt < elems_loc->nbr_ele; ielt++) {
1644 
1645         nbr_fac_elt = elems_loc->nbr_f[ielt];
1646 
1647         /* Construction connectivité */
1648 
1649         pos_elt = elt_pos_som_ent[entmail_e][cpt_elt_ent[entmail_e]];
1650 
1651         for (ifac_elt = 0; ifac_elt < nbr_fac_elt; ifac_elt++) {
1652 
1653           nbr_som_fac = elems_loc->nbr_n[cpt_fac_loc];
1654 
1655           /* Le premier noeud de chaque face est répété en queue pour la
1656              détection de fin de face */
1657 
1658           num_som_deb_fac = elems_loc->connect[cpt_som_loc];
1659 
1660           for (isom = 0; isom < nbr_som_fac; isom++)
1661             elt_val_som_ent[entmail_e][cpt_val_som_ent[entmail_e] + isom]
1662               = elems_loc->connect[cpt_som_loc++];
1663 
1664           elt_val_som_ent[entmail_e][cpt_val_som_ent[entmail_e] + isom]
1665               = num_som_deb_fac;
1666 
1667           /* Mise à jour partielle compteurs */
1668 
1669           cpt_val_som_ent[entmail_e] += nbr_som_fac + 1;
1670 
1671           cpt_fac_loc++;
1672 
1673         }
1674 
1675         elt_pos_som_ent[entmail_e][cpt_elt_ent[entmail_e] + 1]
1676           = cpt_val_som_ent[entmail_e] + 1;
1677 
1678         /* Affectation couleurs */
1679 
1680         cpt_elt_coul_ent[entmail_e][icoul[entmail_e]]++;
1681         elt_val_color_ent[entmail_e][cpt_elt_ent[entmail_e]]
1682           = icoul[entmail_e] + 1;
1683 
1684         /* Mise à jour partielle compteurs */
1685 
1686         cpt_elt_ent[entmail_e] += 1;
1687 
1688       }
1689 
1690     } /* Fin du traitement selon le type d'entité */
1691 
1692     /* Libération mémoire */
1693 
1694     if (elems_loc->nbr_n != NULL)
1695       ECS_FREE(elems_loc->nbr_n);
1696 
1697     if (elems_loc->nbr_f != NULL)
1698       ECS_FREE(elems_loc->nbr_f);
1699 
1700     ECS_FREE(elems_loc->connect);
1701 
1702   }
1703 
1704   ECS_FREE(*liste_elems);
1705 
1706 
1707   /* Transformation des références en indices */
1708   /*==========================================*/
1709 
1710   if (liste_noeuds->id_noeud != NULL) {
1711 
1712     for (ient = ECS_ENTMAIL_FAC ; ient < ECS_N_ENTMAIL ; ient++)
1713       if (elt_val_som_ent[ient] != NULL)
1714         ecs_maillage_pre__label_en_indice
1715           (liste_noeuds->nbr_noeuds,
1716            elt_pos_som_ent[ient][cpt_elt_ent[ient]],
1717            liste_noeuds->id_noeud,
1718            elt_val_som_ent[ient]) ;
1719 
1720     ECS_FREE(liste_noeuds->id_noeud) ;
1721   }
1722 
1723   /* Transfert des valeurs lues dans les structures d'entité de maillage */
1724   /*=====================================================================*/
1725 
1726   ecs_maillage_pre__cree_elt(maillage,
1727                              cpt_elt_ent,
1728                              elt_pos_som_ent,
1729                              elt_val_som_ent,
1730                              NULL,
1731                              elt_val_color_ent,
1732                              cpt_coul_ent,
1733                              val_coul_ent,
1734                              cpt_elt_coul_ent);
1735 }
1736 
1737 /*----------------------------------------------------------------------------
1738  *  Détection big-endian/Little-endian au format EnSight 6 binaire C ;
1739  *  On se place au moment de l'appel au début de la définition des noeuds.
1740  *----------------------------------------------------------------------------*/
1741 
1742 static void
ecs_loc_pre_ens__c_bin_endian_6(ecs_file_t * fic,bool lire_id_noeud)1743 ecs_loc_pre_ens__c_bin_endian_6(ecs_file_t  *fic,
1744                                 bool         lire_id_noeud)
1745 {
1746   char          chaine[ECS_LOC_LNG_MAX_CHAINE_ENS];
1747 
1748   ecs_int_t     nbr_noeuds;
1749   int32_t       val_int_lue;
1750 
1751   ecs_int_t     ret = 0;
1752 
1753   bool          swap_endian = false;
1754 
1755   /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
1756 
1757   if (ecs_file_get_type(fic) != ECS_FILE_TYPE_BINARY)
1758     return;
1759 
1760   ecs_loc_pre_ens__lit_chaine(fic, chaine, NULL);
1761 
1762   if (strncmp(chaine, "coordinates", strlen("coordinates")) != 0)
1763     ecs_error(__FILE__, __LINE__, 0,
1764               _("EnSight: field \"%s\" encountered where\n"
1765                 "\"coordinates\" was expected."), chaine);
1766 
1767   ecs_loc_pre_ens__lit_int(fic, 1, &val_int_lue, 8, NULL);
1768 
1769   nbr_noeuds = (ecs_int_t)val_int_lue;
1770 
1771   /* Première permutation big-endian/little-endian si valeur impossible */
1772 
1773   if (nbr_noeuds < 0) {
1774 
1775     swap_endian = true;
1776 
1777     /* On revient en arrière pour la suite */
1778 
1779     ret = ecs_file_seek(fic, -1 * sizeof(int32_t), ECS_FILE_SEEK_CUR);
1780 
1781     if (ret == 0)
1782       ret = ecs_file_seek(fic, -80 * sizeof(char), ECS_FILE_SEEK_CUR);
1783   }
1784 
1785   /* Sinon, si la valeur lue pour le nombre de noeuds est plausible,
1786      on vérifie si elle est effectivement possible */
1787 
1788   else {
1789 
1790     if (lire_id_noeud == true)
1791       ret = ecs_file_seek(fic,
1792                           nbr_noeuds * sizeof(int32_t),
1793                           ECS_FILE_SEEK_CUR);
1794 
1795     if (ret == 0)
1796       ret = ecs_file_seek(fic,
1797                           nbr_noeuds * 3 * sizeof(float),
1798                           ECS_FILE_SEEK_CUR);
1799 
1800     /* Si on arrive effectivement à la fin de fichier, c'est
1801        que le fichier contient des noeuds, mais pas de "parts" ;
1802        sinon, on doit avoir un "part", ou c'est que l'on n'a
1803        pas les bonnes dimensions de tableaux, et donc probablement
1804        pas la bonne interprétation du nombre de noeuds lus
1805        -> on doit inverser le paramétrage big-endian/little-endian */
1806 
1807     if (ret == 0 && ecs_file_eof(fic) == 0) {
1808 
1809       if (ecs_file_read_try(chaine, sizeof(char), 80, fic) == 80) {
1810 
1811         if (strncmp(chaine, "part", strlen("part")) != 0)
1812           swap_endian = true;
1813       }
1814       else
1815         swap_endian = true;
1816     }
1817 
1818     /* Si l'on n'a pu se positionner, c'est probablement que l'on n'a
1819        probablement pas la bonne interprétation du nombre de noeuds lus,
1820        et que l'on a cherché à dépasser la fin du fichier
1821        -> on doit inverser le paramétrage big-endian/little-endian */
1822 
1823     else if (ret != 0)
1824       swap_endian = true;
1825 
1826     /* On revient à la position de départ */
1827 
1828     ecs_file_rewind(fic);
1829 
1830     ret = ecs_file_seek(fic, 80 * 5 * sizeof(char), ECS_FILE_SEEK_CUR);
1831   }
1832 
1833   /* Si l'on n'a pas pu se repositionner, on a une erreur */
1834 
1835   if (ret != 0) {
1836 
1837     ecs_file_read_check_error(fic, 0);
1838 
1839     ecs_error(__FILE__, __LINE__, 0,
1840               _("EnSight: positioning (seek) error\n"
1841                 "in file \"%s\"."), ecs_file_get_name(fic));
1842   }
1843 
1844   /* Modification bi-endian/little-endian si nécessaire */
1845 
1846   if (swap_endian == true) {
1847 
1848     if (ecs_file_get_swap_endian(fic) == 1)
1849       ecs_file_set_swap_endian(fic, 0);
1850     else
1851       ecs_file_set_swap_endian(fic, 1);
1852 
1853   }
1854 }
1855 
1856 /*----------------------------------------------------------------------------
1857  *  Lecture d'un fichier au format EnSight Gold
1858  *   et affectation des données dans la structure de maillage
1859  *----------------------------------------------------------------------------*/
1860 
1861 static ecs_maillage_t  *
ecs_loc_pre_ens__lit_geo_gold(const char * nom_fic_geo,int num_part)1862 ecs_loc_pre_ens__lit_geo_gold(const char       *nom_fic_geo,
1863                               int               num_part)
1864 {
1865   char   chaine[ECS_LOC_LNG_MAX_CHAINE_ENS];
1866   char   chaine_aux[ECS_LOC_LNG_MAX_CHAINE_ENS];
1867 
1868   char    *ret = NULL;
1869 
1870   ecs_int_t   nbr_elt_lus = 0;
1871   bool        pb_rub;
1872   bool        lire_node_id;
1873   bool        lire_elem_id;
1874   bool        importer_part;
1875 
1876   ecs_file_t  *fic;
1877 
1878   float    coo_min_max[6];
1879 
1880   ecs_int_t        taille_liste_noeuds = 0;
1881   ecs_int_t        taille_liste_elems = 0;
1882 
1883   ecs_loc_noeuds_ens_t  *liste_noeuds = NULL;
1884   ecs_loc_elems_ens_t   *liste_elems = NULL;
1885 
1886   int         num_ligne = 1;
1887   bool        fin_lecture = false;
1888   bool        affiche_extents = false;
1889 
1890   /* Création d'un maillage initialement vide (valeur de retour) */
1891 
1892   ecs_maillage_t  *maillage = ecs_maillage__cree_nodal();
1893 
1894   /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
1895 
1896   /* Ouverture du fichier geo */
1897   /*--------------------------*/
1898 
1899   fic = ecs_loc_pre_ens__ouverture_fic_geo(nom_fic_geo);
1900 
1901   /* Lecture de l'entête */
1902   /*---------------------*/
1903 
1904   /* 2 lignes de description */
1905 
1906   ecs_loc_pre_ens__lit_chaine(fic, chaine, &num_ligne);
1907 
1908   printf(_("\n"
1909            "  Description:\n\n  %s\n"), chaine);
1910 
1911   ecs_loc_pre_ens__lit_chaine(fic, chaine, &num_ligne);
1912 
1913   printf("  %s\n\n", chaine);
1914 
1915   /* Infos sur ids sommets */
1916 
1917   ecs_loc_pre_ens__lit_chaine(fic, chaine, &num_ligne);
1918 
1919   pb_rub = false;
1920 
1921   if (strncmp(chaine, "node id", strlen("node id")) != 0)
1922     pb_rub = true;
1923   else if (sscanf(chaine, "%*s %*s %s", chaine_aux) != 1)
1924     pb_rub = true;
1925 
1926   if (pb_rub == true)
1927     ecs_error(__FILE__, __LINE__, 0,
1928               _("EnSight: \"node id\" field missing or badly placed."));
1929   else
1930     printf("  node id :    %s\n", chaine_aux);
1931 
1932   if (   (strncmp(chaine_aux, "given",  strlen("given"))   == 0)
1933       || (strncmp(chaine_aux, "ignore", strlen("ignore"))  == 0))
1934     lire_node_id = true;
1935   else
1936     lire_node_id = false;
1937 
1938   /* Infos sur ids éléments */
1939 
1940   ecs_loc_pre_ens__lit_chaine(fic, chaine, &num_ligne);
1941 
1942   pb_rub = false;
1943 
1944   if (strncmp(chaine, "element id", strlen("element id")) != 0)
1945     pb_rub = true;
1946   else if (sscanf(chaine, "%*s %*s %s", chaine_aux) != 1)
1947     pb_rub = true;
1948 
1949   if (pb_rub == true)
1950     ecs_error(__FILE__, __LINE__, 0,
1951               _("EnSight: \"element id\" field missing or badly placed"));
1952   else
1953     printf("  element id : %s\n\n", chaine_aux);
1954 
1955   if (   (strncmp(chaine_aux, "given",  strlen("given"))   == 0)
1956       || (strncmp(chaine_aux, "ignore", strlen("ignore"))  == 0))
1957     lire_elem_id = true;
1958   else
1959     lire_elem_id = false;
1960 
1961   /* "Extents" ou début de "part" */
1962 
1963   ret = ecs_loc_pre_ens__lit_chaine_essai(fic, chaine, &num_ligne);
1964 
1965   if (ret != NULL && strncmp(chaine, "extents", strlen("extents")) == 0) {
1966 
1967     ecs_loc_pre_ens__lit_float(fic, 6, coo_min_max, &num_ligne);
1968 
1969     /* On ne peut pas encore afficher les "extents", car l'on n'a
1970        pas encoré détecté l'aspect "big-endian/little-endian"
1971        d'un fichier binaire C, et les octets peuvent donc être permutés */
1972 
1973     affiche_extents = true;
1974 
1975     ret = ecs_loc_pre_ens__lit_chaine_essai(fic, chaine, &num_ligne);
1976 
1977   }
1978   else if (ret != NULL && strncmp(chaine, "part", strlen("part")) != 0)
1979     ecs_error(__FILE__, __LINE__, 0,
1980               _("EnSight: \"%s\" field encountered where\n"
1981                 "\"extents\" or \"part\" was expected."), chaine);
1982 
1983   if (ret == NULL)
1984     ecs_error(__FILE__, __LINE__, 0,
1985               _("File \"%s\"\n"
1986                 "defines no \"part\" (i.e. mesh)."),
1987               ecs_file_get_name(fic));
1988 
1989   /* Début des "parts" */
1990   /*-------------------*/
1991 
1992   while (fin_lecture == false)  {
1993 
1994     int32_t  num_part_lu;
1995     int32_t  cpt_part_lu = 0;
1996 
1997     /* Numéro de part */
1998 
1999     ecs_loc_pre_ens__lit_int(fic, 1, &num_part_lu, 10, &num_ligne);
2000 
2001     /* Détection "big-endian/little-endian" pour un fichier binaire C */
2002 
2003     if (cpt_part_lu == 0 && ecs_file_get_type(fic) == ECS_FILE_TYPE_BINARY) {
2004 
2005       if (num_part_lu < 0 || num_part_lu > 1000) {
2006         ecs_file_swap_endian(&num_part_lu, &num_part_lu, 4, 1);
2007         if (num_part_lu < 0 || num_part_lu > 1000)
2008           ecs_error
2009             (__FILE__, __LINE__, 0,
2010              _("EnSight: file \"%s\" seems to be\n"
2011                "of C binary type but the number of the first \"part\"\n"
2012                "is < 0 ou > 1000 and provokes the failure of the automatic\n"
2013                "\"big-endian/little-endian\" detection."),
2014              ecs_file_get_name(fic));
2015         else {
2016           if (ecs_file_get_swap_endian(fic) == 1)
2017             ecs_file_set_swap_endian(fic, 0);
2018           else
2019             ecs_file_set_swap_endian(fic, 1);
2020           /* Correction extents */
2021           ecs_file_swap_endian(coo_min_max,
2022                                coo_min_max,
2023                                sizeof(float),
2024                                6);
2025         }
2026       }
2027 
2028     }
2029 
2030     /* On peut maintenant afficher les "extents" */
2031 
2032     if (affiche_extents == true) {
2033       printf(_("  xmin = %12.5e; xmax = %12.5e\n"
2034                "  ymin = %12.5e; ymax = %12.5e\n"
2035                "  zmin = %12.5e; zmax = %12.5e\n\n"),
2036              coo_min_max[0], coo_min_max[1], coo_min_max[2],
2037              coo_min_max[3], coo_min_max[4], coo_min_max[5]);
2038       affiche_extents = false;
2039     }
2040 
2041     if (taille_liste_elems > 0 && lire_node_id == false) {
2042       printf(_("  Remark: no vertex ids given\n"
2043                "  --> impossible to merge EnSight \"parts\",\n"
2044                "      so the following \"parts\" are ignored.\n\n"));
2045       break;
2046     }
2047     else if (num_part > 0 && num_part != num_part_lu) {
2048       importer_part = false;
2049       printf(_("  part %2d (ignored): "), (int)num_part_lu);
2050     }
2051     else {
2052       importer_part = true;
2053       printf(_("  part %2d: "), (int)num_part_lu);
2054     }
2055 
2056     /* Description */
2057 
2058     ecs_loc_pre_ens__lit_chaine(fic, chaine, &num_ligne);
2059 
2060     printf("%s\n\n", chaine);
2061 
2062     /* Lecture des noeuds */
2063     /*--------------------*/
2064 
2065     ecs_loc_pre_ens__lit_noeuds_gold(fic,
2066                                      (ecs_int_t)num_part_lu,
2067                                      lire_node_id,
2068                                      importer_part,
2069                                      &taille_liste_noeuds,
2070                                      &liste_noeuds,
2071                                      chaine,
2072                                      &num_ligne);
2073 
2074     /* Lecture des éléments */
2075     /*----------------------*/
2076 
2077     do {
2078 
2079       ret = ecs_loc_pre_ens__lit_chaine_essai(fic, chaine, &num_ligne);
2080 
2081       if (ret == NULL)
2082         fin_lecture = true;
2083 
2084       else
2085 
2086         nbr_elt_lus = ecs_loc_pre_ens__lit_elem_gold
2087                         (fic,
2088                          (ecs_int_t)num_part_lu,
2089                          lire_elem_id,
2090                          importer_part,
2091                          liste_noeuds + taille_liste_noeuds - 1,
2092                          &taille_liste_elems,
2093                          &liste_elems,
2094                          chaine,
2095                          &num_ligne);
2096 
2097     } while (nbr_elt_lus > -1 && fin_lecture == false);
2098 
2099     printf("\n");
2100 
2101     /* Fusion des définitions des noeuds */
2102 
2103     if (importer_part)
2104 
2105       ecs_loc_pre_ens__trie_noeuds(liste_noeuds + taille_liste_noeuds - 1);
2106 
2107     if (taille_liste_noeuds == 2) {
2108 
2109       ecs_loc_pre_ens__fusion_noeuds(liste_noeuds,
2110                                      liste_noeuds + 1);
2111 
2112       taille_liste_noeuds = 1; /* La réallocation éventuelle à 2 entités
2113                                    de liste_noeuds[] sera inutile mais
2114                                    triviale et sans risque */
2115     }
2116 
2117     /* Autres parts ? */
2118 
2119     cpt_part_lu++;
2120 
2121     if (num_part > 0 && num_part == num_part_lu)
2122       fin_lecture = true;
2123   }
2124 
2125   /* Si l'on n'a pas trouvé de "part" (ou pas celle demandée),
2126      la liste des noeuds n'est encore pas définie */
2127 
2128   if (liste_noeuds == NULL) {
2129     if (num_part > 0)
2130       ecs_error(__FILE__, __LINE__, 0,
2131                 _("EnSight: file \"%s\" does not contain a\n"
2132                   "\"part\" with the required number (%d)."),
2133                 ecs_file_get_name(fic), (int)num_part);
2134     else
2135       ecs_error(__FILE__, __LINE__, 0,
2136                 _("EnSight: file \"%s\" does not contain any \"part\"."),
2137                 ecs_file_get_name(fic));
2138   }
2139 
2140   /* Fermeture du fichier de lecture du maillage */
2141 
2142   ecs_file_free(fic);
2143 
2144   /* Remplissage de la structure de maillage */
2145   /*-----------------------------------------*/
2146 
2147   /* Traitement des sommets */
2148 
2149   ecs_maillage_pre__cree_som(maillage,
2150                              liste_noeuds[0].nbr_noeuds,
2151                              liste_noeuds[0].coord);
2152 
2153   /* Traitement des éléments */
2154 
2155   /* Concaténation des éléments par leur dimension */
2156 
2157   ecs_loc_pre_ens__concat_elems(maillage,
2158                                 taille_liste_elems,
2159                                 &(liste_noeuds[0]),
2160                                 &liste_elems);
2161 
2162   ECS_FREE(liste_noeuds);
2163 
2164   /* Renvoi de la structure de maillage */
2165 
2166   return maillage;
2167 }
2168 
2169 /*----------------------------------------------------------------------------
2170  *  Lecture d'un fichier au format EnSight 6
2171  *   et affectation des données dans la structure de maillage
2172  *----------------------------------------------------------------------------*/
2173 
2174 static ecs_maillage_t  *
ecs_loc_pre_ens__lit_geo_6(const char * nom_fic_geo,const ecs_int_t num_part)2175 ecs_loc_pre_ens__lit_geo_6(const char       *nom_fic_geo,
2176                            const ecs_int_t   num_part)
2177 {
2178   char              chaine[ECS_LOC_LNG_MAX_CHAINE_ENS];
2179   char              chaine_aux[ECS_LOC_LNG_MAX_CHAINE_ENS];
2180 
2181   char             *ret = NULL;
2182 
2183   ecs_int_t         nbr_elt_lus = 0;
2184   bool              pb_rub;
2185   bool              lire_node_id;
2186   bool              lire_elem_id;
2187   bool              importer_part;
2188 
2189   ecs_file_t       *fic;
2190 
2191   ecs_int_t         taille_liste_noeuds = 0;
2192   ecs_int_t         taille_liste_elems = 0;
2193 
2194   ecs_loc_noeuds_ens_t  *liste_noeuds = NULL;
2195   ecs_loc_elems_ens_t   *liste_elems = NULL;
2196 
2197   int         num_ligne   = 1;
2198   bool        fin_lecture = false;
2199 
2200   /* Création d'un maillage initialament vide (valeur de retour) */
2201 
2202   ecs_maillage_t  *maillage = ecs_maillage__cree_nodal();
2203 
2204   /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
2205 
2206   /* Ouverture du fichier Géométrie et vérification du format */
2207   /*----------------------------------------------------------*/
2208 
2209   fic = ecs_loc_pre_ens__ouverture_fic_geo(nom_fic_geo);
2210 
2211   /* Lecture de l'entête */
2212   /*---------------------*/
2213 
2214   /* 2 lignes de description */
2215 
2216   ecs_loc_pre_ens__lit_chaine(fic, chaine, &num_ligne);
2217 
2218   printf(_("\n"
2219            "  Description:\n\n  %s\n"), chaine);
2220 
2221   ecs_loc_pre_ens__lit_chaine(fic, chaine, &num_ligne);
2222 
2223   printf("  %s\n\n", chaine);
2224 
2225   /* Infos sur ids sommets */
2226 
2227   ecs_loc_pre_ens__lit_chaine(fic, chaine, &num_ligne);
2228 
2229   pb_rub = false;
2230 
2231   if (strncmp(chaine, "node id", strlen("node id")) != 0)
2232     pb_rub = true;
2233   else if (sscanf(chaine, "%*s %*s %s", chaine_aux) != 1)
2234     pb_rub = true;
2235 
2236   if (pb_rub == true)
2237     ecs_error(__FILE__, __LINE__, 0,
2238               _("EnSight: \"node id\" field missing or badly placed."));
2239   else
2240     printf("  node id:    %s\n", chaine_aux);
2241 
2242   if (   (strncmp(chaine_aux, "given",  strlen("given"))   == 0)
2243       || (strncmp(chaine_aux, "ignore", strlen("ignore"))  == 0))
2244     lire_node_id = true;
2245   else
2246     lire_node_id = false;
2247 
2248 
2249   /* Infos sur ids éléments */
2250 
2251   ecs_loc_pre_ens__lit_chaine(fic, chaine, &num_ligne);
2252 
2253   pb_rub = false;
2254 
2255   if (strncmp(chaine, "element id", strlen("element id")) != 0)
2256     pb_rub = true;
2257   else if (sscanf(chaine, "%*s %*s %s", chaine_aux) != 1)
2258     pb_rub = true;
2259 
2260   if (pb_rub == true)
2261     ecs_error(__FILE__, __LINE__, 0,
2262               _("EnSight: \"element id\" field missing or badly placed"));
2263   else
2264     printf("  element id: %s\n\n", chaine_aux);
2265 
2266   if (   (strncmp(chaine_aux, "given",  strlen("given"))   == 0)
2267       || (strncmp(chaine_aux, "ignore", strlen("ignore"))  == 0))
2268     lire_elem_id = true;
2269   else
2270     lire_elem_id = false;
2271 
2272   /* Détection big-endian/little-endian en cas de fichier binaire C */
2273   /*----------------------------------------------------------------*/
2274 
2275   if (ecs_file_get_type(fic) == ECS_FILE_TYPE_BINARY)
2276 
2277     ecs_loc_pre_ens__c_bin_endian_6(fic, lire_node_id);
2278 
2279 
2280   /* Lecture des noeuds */
2281   /*--------------------*/
2282 
2283   ecs_loc_pre_ens__lit_noeuds_6(fic,
2284                                 lire_node_id,
2285                                 &taille_liste_noeuds,
2286                                 &liste_noeuds,
2287                                 chaine,
2288                                 &num_ligne);
2289 
2290   ret = ecs_loc_pre_ens__lit_chaine_essai(fic, chaine, &num_ligne);
2291 
2292   if (ret == NULL)
2293     ecs_error(__FILE__, __LINE__, 0,
2294               _("File \"%s\"\n"
2295                 "defines no \"part\" (i.e. mesh)."),
2296               ecs_file_get_name(fic));
2297 
2298   else if (ret != NULL && strncmp(chaine, "part", strlen("part")) != 0)
2299     ecs_error(__FILE__, __LINE__, 0,
2300               _("EnSight: \"%s\" field encountered where\n"
2301                 "\"part\" was expected."), chaine);
2302 
2303 
2304   /* Début des "parts" */
2305   /*-------------------*/
2306 
2307   while (fin_lecture == false)  {
2308 
2309     int32_t  num_part_lu;
2310     int32_t  cpt_part_lu = 0;
2311 
2312     /* Numéro de part */
2313 
2314     num_part_lu = atoi(chaine+strlen("part"));
2315 
2316     /* Détection "big-endian/little-endian" pour un fichier binaire C */
2317 
2318 
2319     /* Pour EnSight6 on peut toujours fusionner */
2320 
2321     if (num_part > 0 && num_part != num_part_lu) {
2322       importer_part = false;
2323       printf(_("  part %2d (ignored): "), (int)num_part_lu);
2324     }
2325     else {
2326       importer_part = true;
2327       printf(_("  part %2d: "), (int)num_part_lu);
2328     }
2329 
2330     /* Description */
2331 
2332     ecs_loc_pre_ens__lit_chaine(fic, chaine, &num_ligne);
2333 
2334     printf("%s\n\n", chaine);
2335 
2336     /* Tri des noeuds */
2337 
2338     ecs_loc_pre_ens__trie_noeuds(liste_noeuds + taille_liste_noeuds - 1);
2339 
2340     /* Lecture des éléments */
2341     /*----------------------*/
2342 
2343     do {
2344 
2345       ret = ecs_loc_pre_ens__lit_chaine_essai(fic, chaine, &num_ligne);
2346 
2347       if (ret == NULL)
2348         fin_lecture = true;
2349 
2350       else
2351 
2352         nbr_elt_lus
2353           = ecs_loc_pre_ens__lit_elem_6(fic,
2354                                         (ecs_int_t)num_part_lu,
2355                                         lire_elem_id,
2356                                         importer_part,
2357                                         &taille_liste_elems,
2358                                         &liste_elems,
2359                                         chaine,
2360                                         &num_ligne);
2361 
2362     } while (nbr_elt_lus > -1 && fin_lecture == false);
2363 
2364     printf("\n");
2365 
2366     /* Autres parts ? */
2367 
2368     cpt_part_lu++;
2369 
2370     if (num_part > 0 && num_part == num_part_lu)
2371       fin_lecture = true;
2372 
2373   }
2374 
2375   /* Si l'on n'a pas trouvé de "part" (ou pas celle demandée),
2376      la liste des noeuds n'est encore pas définie */
2377 
2378   if (liste_elems == NULL) {
2379     if (num_part > 0)
2380       ecs_error(__FILE__, __LINE__, 0,
2381                 _("EnSight: file \"%s\" does not contain a\n"
2382                   "\"part\" with the required number (%d)."),
2383                 ecs_file_get_name(fic), (int)num_part);
2384     else
2385       ecs_error(__FILE__, __LINE__, 0,
2386                 _("EnSight: file \"%s\" does not contain any \"part\"."),
2387                 ecs_file_get_name(fic));
2388   }
2389 
2390   /* Fermeture du fichier de lecture du maillage */
2391 
2392   ecs_file_free(fic);
2393 
2394   /* Remplissage de la structure de maillage */
2395   /*-----------------------------------------*/
2396 
2397   /* Traitement des sommets */
2398 
2399   ecs_maillage_pre__cree_som(maillage,
2400                              liste_noeuds[0].nbr_noeuds,
2401                              liste_noeuds[0].coord);
2402 
2403   /* Traitement des éléments */
2404 
2405   /* Concaténation des éléments par leur dimension */
2406 
2407   ecs_loc_pre_ens__concat_elems(maillage,
2408                                 taille_liste_elems,
2409                                 &(liste_noeuds[0]),
2410                                 &liste_elems);
2411 
2412   ECS_FREE(liste_noeuds);
2413 
2414   /* Renvoi de la structure de maillage */
2415 
2416   return maillage;
2417 }
2418 
2419 /*============================================================================
2420  *                             Fonctions publiques
2421  *============================================================================*/
2422 
2423 /*----------------------------------------------------------------------------
2424  *  Lecture d'un fichier au format EnSight Gold
2425  *   et affectation des données dans la structure de maillage
2426  *----------------------------------------------------------------------------*/
2427 
2428 ecs_maillage_t *
ecs_pre_ens__lit_maillage(const char * nom_fic_case,int num_maillage)2429 ecs_pre_ens__lit_maillage(const char  *nom_fic_case,
2430                           int          num_maillage)
2431 {
2432   char             *nom_fic_geo;
2433   int               timeset;
2434   int               fileset;
2435   size_t            ind;
2436   ecs_file_t       *fic;
2437 
2438   char              ligne[ECS_LOC_LNG_MAX_CHAINE_ENS];
2439   char              nom_fic_geo_base[ECS_LOC_LNG_MAX_CHAINE_ENS];
2440 
2441   int               num_ligne = 1;
2442 
2443   bool              fmt_ensight      = false;
2444   bool              fmt_ensight_gold = false;
2445 
2446   char             *ret = NULL;
2447 
2448   ecs_maillage_t   *maillage = NULL;
2449 
2450   /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
2451 
2452   printf(_("\n\n"
2453            "Reading mesh from file in EnSight format\n"
2454            "----------------------\n"));
2455 
2456   printf(_("  \"case\" file: %s\n"), nom_fic_case);
2457 
2458   /* Ouverture du fichier Case */
2459 
2460   fic = ecs_file_open(nom_fic_case,
2461                       ECS_FILE_MODE_READ,
2462                       ECS_FILE_TYPE_TEXT);
2463 
2464   /* Vérification du format */
2465 
2466   do {
2467     ret = ecs_file_gets_try(ligne, ECS_LOC_LNG_MAX_CHAINE_ENS, fic, &num_ligne);
2468   } while (ret != NULL && strncmp(ligne, "FORMAT", strlen("FORMAT")) != 0);
2469 
2470   if (ret != NULL) {
2471 
2472     do {
2473       ret = ecs_file_gets_try(ligne, ECS_LOC_LNG_MAX_CHAINE_ENS,
2474                               fic, &num_ligne);
2475     } while (ret != NULL && strncmp(ligne, "type:", strlen("type:")) != 0);
2476 
2477   }
2478 
2479   if (ret != NULL) {
2480 
2481     for (ind = strlen("type:");
2482          ligne[ind] != '\0' && (ligne[ind] == ' ' || ligne[ind] == '\t');
2483          ind++);
2484 
2485     if (strncmp(ligne + ind, "ensight", strlen("ensight")) == 0) {
2486 
2487       fmt_ensight = true;
2488 
2489       ind += strlen("ensight");
2490       while (ligne[ind] != '\0' && (ligne[ind] == ' ' || ligne[ind] == '\t'))
2491         ind++;
2492 
2493       if (strncmp(ligne + ind, "gold", strlen("gold")) == 0)
2494 
2495         fmt_ensight_gold = true;
2496 
2497     }
2498 
2499   }
2500 
2501   if (fmt_ensight == false)
2502     ecs_error(__FILE__, __LINE__, 0,
2503               _("File \"%s\" does not seem to be a valid\n"
2504                 "EnSight 6 or Gold case file."),
2505               nom_fic_case);
2506 
2507   /* Recherche des infos sur le fichier géométrique */
2508 
2509   do {
2510     ret = ecs_file_gets_try(ligne, ECS_LOC_LNG_MAX_CHAINE_ENS,
2511                             fic, &num_ligne);
2512   } while (ret != NULL && strncmp(ligne, "GEOMETRY", strlen("GEOMETRY")) != 0);
2513 
2514   if (ret != NULL) {
2515 
2516     do {
2517       ret = ecs_file_gets_try(ligne, ECS_LOC_LNG_MAX_CHAINE_ENS,
2518                               fic, &num_ligne);
2519     } while (ret != NULL && strncmp(ligne, "model:", strlen("model:")) != 0);
2520 
2521   }
2522 
2523   if (ret != NULL) {
2524 
2525     /* La rubrique model: contient deux numéros optionnels (numéro de pas de
2526        temps et de jeux de fichiers), le nom de base du ou des fichiers
2527        géométriques, et éventuellement l'option "change_coords_only" */
2528 
2529     if (sscanf(ligne, "%*s %d %d %s",
2530                &timeset, &fileset, nom_fic_geo_base) != 3) {
2531       if (sscanf(ligne, "%*s %d %s",
2532                  &timeset, nom_fic_geo_base) != 2) {
2533         if (sscanf(ligne, "%*s %s",
2534                    nom_fic_geo_base) != 1)
2535           ecs_error(__FILE__, __LINE__, 0,
2536                     _("The \"%s\" case file does not seem to\n"
2537                       "indicate a geometry file"),
2538                     nom_fic_case);
2539       }
2540     }
2541 
2542     /* On vérifie que le nom ne contienne pas de caractères "*" */
2543 
2544     for (ind = 0; nom_fic_geo_base[ind] != '\0'; ind++)
2545       if (nom_fic_geo_base[ind] == '*')
2546         ecs_error(__FILE__, __LINE__, 0,
2547                   _("The \"%s\" case file seems to indicate the\n"
2548                     "series of geometric files named:\n"
2549                     "\"%s\".\n"
2550                     "A single file must be chosen."),
2551                   nom_fic_case, nom_fic_geo_base);
2552 
2553   }
2554 
2555   /* On n'a plus besoin du fichier ".case" */
2556 
2557   ecs_file_free(fic);
2558 
2559   /* Maintenant, on extrait le préfixe du nom du fichier ".case" */
2560 
2561   for (ind = strlen(nom_fic_case) - 1;
2562        ind > 0 && nom_fic_case[ind] != ECS_PATH_SEP;
2563        ind--);
2564 
2565   if (nom_fic_case[ind] == ECS_PATH_SEP)
2566     ind++;
2567 
2568   ECS_MALLOC(nom_fic_geo, ind + strlen(nom_fic_geo_base) + 1, char);
2569   strncpy(nom_fic_geo, nom_fic_case, ind);
2570   strcpy(nom_fic_geo + ind, nom_fic_geo_base);
2571 
2572   /* On connaît maintenant le nom du fichier géométrique */
2573 
2574   printf(_("  \"geo\"  file: %s\n\n"), nom_fic_geo);
2575 
2576   /* Lecture du fichier géométrique associé */
2577   /*----------------------------------------*/
2578 
2579   if (fmt_ensight_gold == true)
2580     maillage = ecs_loc_pre_ens__lit_geo_gold(nom_fic_geo,
2581                                              num_maillage);
2582 
2583   else if (fmt_ensight == true)
2584     maillage = ecs_loc_pre_ens__lit_geo_6(nom_fic_geo,
2585                                           num_maillage);
2586 
2587   /* Libération mémoire et retour */
2588 
2589   ECS_FREE(nom_fic_geo);
2590 
2591   return maillage;
2592 }
2593 
2594 /*----------------------------------------------------------------------------*/
2595