1 // MEFISTO2: a library to compute 2D triangulation from segmented boundaries
4 // Copyright (C) 2006-2013 CEA/DEN, EDF R&D, OPEN CASCADE
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : aptrte.cxx le C++ de l'appel du trianguleur plan
24 // Author : Alain PERRONNET
25 // Date : 13 novembre 2006
29 #include "utilities.h"
44 areteideale()//( R3 xyz, R3 direction )
49 //calcul de la longueur ideale de l'arete au sommet xyz (z ici inactif)
50 //dans la direction donnee
51 //a ajuster pour chaque surface plane et selon l'entier notysu (voir plus bas)
54 static double cpunew, cpuold=0;
63 tempscpu_( double & tempsec )
64 //Retourne le temps CPU utilise en secondes
66 tempsec = ( (double) clock() ) / CLOCKS_PER_SEC;
67 //MESSAGE( "temps cpu=" << tempsec );
78 deltacpu_( R & dtcpu )
79 //Retourne le temps CPU utilise en secondes depuis le precedent appel
82 dtcpu = R( cpunew - cpuold );
84 //MESSAGE( "delta temps cpu=" << dtcpu );
89 void aptrte( Z nutysu, R aretmx,
90 Z nblf, Z * nudslf, R2 * uvslf,
92 Z & nbst, R2 * & uvst,
95 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
96 // but : appel de la triangulation par un arbre-4 recouvrant
97 // ----- de triangles equilateraux
98 // le contour du domaine plan est defini par des lignes fermees
99 // la premiere ligne etant l'enveloppe de toutes les autres
100 // la fonction areteideale(s,d) donne la taille d'arete
101 // au point s dans la direction (actuellement inactive) d
102 // des lors toute arete issue d'un sommet s devrait avoir une longueur
103 // comprise entre 0.65 areteideale_(s,d) et 1.3 areteideale_(s,d)
106 // Les tableaux uvslf et uvpti sont supposes ne pas avoir de sommets identiques!
107 // De meme, un sommet d'une ligne fermee ne peut appartenir a une autre ligne fermee
111 // nutysu : numero de traitement de areteideale_(s,d) selon le type de surface
112 // 0 pas d'emploi de la fonction areteideale_() et aretmx est active
113 // 1 il existe une fonction areteideale_(s,d)
114 // dont seules les 2 premieres composantes de uv sont actives
115 // ... autres options a definir ...
116 // aretmx : longueur maximale des aretes de la future triangulation
117 // nblf : nombre de lignes fermees de la surface
118 // nudslf : numero du dernier sommet de chacune des nblf lignes fermees
119 // nudslf(0)=0 pour permettre la difference sans test
120 // Attention le dernier sommet de chaque ligne est raccorde au premier
121 // tous les sommets et les points internes ont des coordonnees
122 // UV differentes <=> Pas de point double!
123 // uvslf : uv des nudslf(nblf) sommets des lignes fermees
124 // nbpti : nombre de points internes futurs sommets de la triangulation
125 // uvpti : uv des points internes futurs sommets de la triangulation
129 // nbst : nombre de sommets de la triangulation finale
130 // uvst : coordonnees uv des nbst sommets de la triangulation
131 // nbt : nombre de triangles de la triangulation finale
132 // nust : 4 numeros dans uvst des sommets des nbt triangles
133 // s1, s2, s3, 0: no dans uvst des 3 sommets et 0 car quadrangle!
134 // ierr : 0 si pas d'erreur
136 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
137 // auteur : Alain Perronnet Laboratoire J.-L. LIONS Paris UPMC mars 2006
138 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
140 Z nbsttria=4; //Attention: 4 sommets stockes par triangle
141 //no st1, st2, st3, 0 (non quadrangle)
144 // R3 direction=R3(0,0,0); //direction pour areteideale() inactive ici!
145 Z nbarfr=nudslf[nblf]; //nombre total d'aretes des lignes fermees
146 Z mxtrou = Max( 1024, nblf ); //nombre maximal de trous dans la surface
149 Z *mnsoar=NULL, mosoar=7, mxsoar, n1soar; //le hachage des aretes
150 Z *mnartr=NULL, moartr=3, mxartr, n1artr; //le no des 3 aretes des triangles
151 Z *mntree=NULL, motree=9, mxtree; //L'arbre 4 de TE et nombre d'entiers par TE
152 Z *mnqueu=NULL, mxqueu;
154 Z *mnarcf=NULL, mxarcf;
163 R3 comxmi[2]; //coordonnees UV Min et Maximales
164 R aremin, aremax; //longueur minimale et maximale des aretes
165 R airemx; //aire maximale souhaitee d'un triangle
169 Z i, l, n, ns, ns0, ns1, ns2, nosotr[3], nt;
170 Z mxsomm, nbsomm, nbarpi, nbarli, ndtri0, mn;
174 // initialisation du temps cpu
178 // quelques reservations de tableaux pour faire les calculs
179 // ========================================================
180 // declaration du tableau des coordonnees des sommets de la frontiere
181 // puis des sommets internes ajoutes
182 // majoration empirique du nombre de sommets de la triangulation
184 mxsomm = Max( 20000, 64*nbpti+i*i );
185 MESSAGE( "APTRTE: Debut de la triangulation plane avec " );
186 MESSAGE( "nutysu=" << nutysu << " aretmx=" << aretmx
187 << " mxsomm=" << mxsomm );
188 MESSAGE( nbarfr << " sommets sur la frontiere et " << nbpti << " points internes");
191 //mnpxyd( 3, mxsomm ) les coordonnees UV des sommets et la taille d'arete aux sommets
192 if( mnpxyd!=NULL ) delete [] mnpxyd;
193 mnpxyd = new R3[mxsomm];
194 if( mnpxyd==NULL ) goto ERREUR;
196 // le tableau mnsoar des aretes des triangles
197 // 1: sommet 1 dans pxyd,
198 // 2: sommet 2 dans pxyd,
199 // 3: numero de 1 a nblf de la ligne qui supporte l'arete
200 // 4: numero dans mnartr du triangle 1 partageant cette arete,
201 // 5: numero dans mnartr du triangle 2 partageant cette arete,
202 // 6: chainage des aretes frontalieres ou internes ou
203 // des aretes simples des etoiles de triangles,
204 // 7: chainage du hachage des aretes
205 // nombre d'aretes = 3 ( nombre de sommets - 1 + nombre de trous )
206 // pour le hachage des aretes mxsoar doit etre > 3*mxsomm!
207 // h(ns1,ns2) = min( ns1, ns2 )
208 if( mnsoar!=NULL ) delete [] mnsoar;
209 mxsoar = 3 * ( mxsomm + mxtrou );
210 mnsoar = new Z[mosoar*mxsoar];
211 if( mnsoar==NULL ) goto ERREUR;
212 //initialiser le tableau mnsoar pour le hachage des aretes
213 insoar( mxsomm, mosoar, mxsoar, n1soar, mnsoar );
215 // mnarst( mxsomm ) numero mnsoar d'une arete pour chacun des sommets
216 if( mnarst!=NULL ) delete [] mnarst;
217 mnarst = new Z[1+mxsomm];
218 if( mnarst==NULL ) goto ERREUR;
222 // mnslig( mxsomm ) no de sommet dans sa ligne pour chaque sommet frontalier
223 // ou no du point si interne forc'e par l'utilisateur
224 // ou 0 si interne cree par le module
225 if( mnslig!=NULL ) delete [] mnslig;
226 mnslig = new Z[mxsomm];
227 if( mnslig==NULL ) goto ERREUR;
228 azeroi( mxsomm, mnslig );
230 // initialisation des aretes frontalieres de la triangulation future
231 // renumerotation des sommets des aretes des lignes pour la triangulation
232 // mise a l'echelle des coordonnees des sommets pour obtenir une
233 // meilleure precision lors des calculs + quelques verifications
234 // boucle sur les lignes fermees qui forment la frontiere
235 // ======================================================================
240 for (n=1; n<=nblf; n++)
242 //l'initialisation de la premiere arete de la ligne n dans la triangulation
243 //-------------------------------------------------------------------------
244 //le sommet ns0 est le numero de l'origine de la ligne
246 mnpxyd[ns0].x = uvslf[ns0].x;
247 mnpxyd[ns0].y = uvslf[ns0].y;
248 mnpxyd[ns0].z = areteideale();//( mnpxyd[ns0], direction );
249 // MESSAGE("Sommet " << ns0 << ": " << mnpxyd[ns0].x
250 // << " " << mnpxyd[ns0].y << " longueur arete=" << mnpxyd[ns0].z);
252 //carre de la longueur de l'arete 1 de la ligne fermee n
253 d = pow( uvslf[ns0+1].x - uvslf[ns0].x, 2 )
254 + pow( uvslf[ns0+1].y - uvslf[ns0].y, 2 ) ;
255 aremin = Min( aremin, d );
256 aremax = Max( aremax, d );
258 //le numero des 2 sommets (ns1,ns2) de la premiere arete de la ligne
259 //initialisation de la 1-ere arete ns1-ns1+1 de cette ligne fermee n
260 //le numero des 2 sommets ns1 ns2 de la 1-ere arete
261 //Attention: les numeros ns debutent a 1 (ils ont >0)
262 // les tableaux c++ demarrent a zero!
263 // les tableaux fortran demarrent ou l'on veut!
268 //le numero n de la ligne du sommet et son numero ns1 dans la ligne
269 mnslig[ns0-1] = 1000000 * n + ns1-nudslf[n-1];
270 fasoar( ns1, ns2, moins1, moins1, n,
271 mosoar, mxsoar, n1soar, mnsoar, mnarst,
273 //pas de test sur ierr car pas de saturation possible a ce niveau
275 //le pointeur dans le hachage sur la premiere arete de la ligne fermee n
278 //la nouvelle arete est la suivante de l'arete definie juste avant
280 mnsoar[mosoar * noar - mosoar + 5] = noar0;
282 //l'initialisation des aretes suivantes de la ligne dans la triangulation
283 //-----------------------------------------------------------------------
284 nbarli = nudslf[n] - nudslf[n-1]; //nombre d'aretes=sommets de la ligne n
285 for (i=2; i<=nbarli; i++)
287 ns1 = ns2; //le numero de l'arete et le numero du premier sommet de l'arete
289 //nbs+1 est le 2-eme sommet de l'arete i de la ligne fermee n
292 //le 2-eme sommet de la derniere arete est le premier sommet de la ligne
295 //l'arete precedente est dotee de sa suivante:celle cree ensuite
296 //les 2 coordonnees du sommet ns2 de la ligne
298 //debut ajout 5/10/2006 ................................................
299 nuds = Max( nuds, ns ); //le numero du dernier sommet traite
300 //fin ajout 5/10/2006 ................................................
301 mnpxyd[ns].x = uvslf[ns].x;
302 mnpxyd[ns].y = uvslf[ns].y;
303 mnpxyd[ns].z = areteideale();//( mnpxyd[ns], direction );
304 // MESSAGE("Sommet " << ns << ": " << mnpxyd[ns].x
305 // << " " << mnpxyd[ns].y << " longueur arete=" << mnpxyd[ns].z);
307 //carre de la longueur de l'arete
308 d = pow( uvslf[ns2-1].x - uvslf[ns1-1].x, 2)
309 + pow( uvslf[ns2-1].y - uvslf[ns1-1].y, 2);
310 aremin = Min( aremin, d );
311 aremax = Max( aremax, d );
313 //debut ajout du 5/10/2006 .............................................
314 //la longueur de l'arete ns1-ns2
316 //longueur arete = Min ( aretmx, aretes incidentes )
317 mnpxyd[ns ].z = Min( mnpxyd[ns ].z, d );
318 mnpxyd[ns2-1].z = Min( mnpxyd[ns2-1].z, d );
319 //fin ajout du 5/10/2006 ...............................................
321 //le numero n de la ligne du sommet et son numero ns1 dans la ligne
322 mnslig[ns] = 1000000 * n + ns1-nudslf[n-1];
324 //ajout de l'arete dans la liste
325 fasoar( ns1, ns2, moins1, moins1, n,
326 mosoar, mxsoar, n1soar, mnsoar,
327 mnarst, noar, ierr );
328 //pas de test sur ierr car pas de saturation possible a ce niveau
330 //chainage des aretes frontalieres en position 6 du tableau mnsoar
331 //la nouvelle arete est la suivante de l'arete definie juste avant
332 mnsoar[ mosoar * noar0 - mosoar + 5 ] = noar;
335 //attention: la derniere arete de la ligne fermee enveloppe
336 // devient en fait la premiere arete de cette ligne
337 // dans le chainage des aretes de la frontiere!
339 if( ierr != 0 ) goto ERREUR;
341 aremin = sqrt( aremin ); //longueur minimale d'une arete des lignes fermees
342 aremax = sqrt( aremax ); //longueur maximale d'une arete
344 //debut ajout 9/11/2006 ................................................
345 // devenu un commentaire aretmx = Min( aretmx, aremax ); //pour homogeneiser
347 // protection contre une arete max desiree trop grande ou trop petite
348 if( aretmx > aremax*2.05 ) aretmx = aremax;
350 // protection contre une arete max desiree trop petite
351 if( (aremax-aremin) > (aremin+aremax)*0.05 && aretmx < aremin*0.5 )
352 aretmx =(aremin+aremax*2)/3.0;
354 if( aretmx < aremin && aremin > 0 )
357 //sauvegarde pour la fonction areteideale_
358 aretemaxface_ = aretmx;
360 //aire maximale souhaitee des triangles
361 airemx = aretmx * aretmx * sqrt(3.0) / 2.0; //Aire triangle equilateral
363 for(i=0; i<=nuds; i++ )
364 mnpxyd[i].z = Min( mnpxyd[i].z, aretmx );
365 //MESSAGE("Numero du dernier sommet frontalier=" << nuds+1);
366 //fin ajout 9/11/2006 .................................................
369 MESSAGE("Sur le bord: arete min=" << aremin << " arete max=" << aremax );
370 MESSAGE("Triangulation: arete mx=" << aretmx
371 << " triangle aire mx=" << airemx );
373 //chainage des aretes frontalieres : la derniere arete frontaliere
374 mnsoar[ mosoar * noar - mosoar + 5 ] = 0;
376 //tous les sommets et aretes frontaliers sont numerotes de 1 a nbarfr
377 //reservation du tableau des numeros des 3 aretes de chaque triangle
378 //mnartr( moartr, mxartr )
379 //En nombre: Triangles = Aretes Internes + Aretes Frontalieres - Sommets + 1-Trous
380 // 3Triangles = 2 Aretes internes + Aretes frontalieres
381 // d'ou 3T/2 < AI + AF => T < 3T/2 - Sommets + 1-Trous
382 //nombre de triangles < 2 ( nombre de sommets - 1 + nombre de trous )
383 if( mnartr!=NULL ) delete [] mnartr;
384 mxartr = 2 * ( mxsomm + mxtrou );
385 mnartr = new Z[moartr*mxartr];
386 if( mnartr==NULL ) goto ERREUR;
388 //Ajout des points internes
389 ns1 = nudslf[ nblf ];
390 for (i=0; i<nbpti; i++)
392 //les 2 coordonnees du point i de sommet nbs
393 mnpxyd[ns1].x = uvpti[i].x;
394 mnpxyd[ns1].y = uvpti[i].y;
395 mnpxyd[ns1].z = areteideale();//( mnpxyd[ns1], direction );
396 //le numero i du point interne
401 //nombre de sommets de la frontiere et internes
404 // creation de l'arbre-4 des te (tableau letree)
405 // ajout dans les te des sommets des lignes et des points internes imposes
406 // =======================================================================
407 // premiere estimation de mxtree
410 NEWTREE: //en cas de saturation de l'un des tableaux, on boucle
411 MESSAGE( "Debut triangulation avec mxsomm=" << mxsomm );
412 if( mntree != NULL ) delete [] mntree;
414 mntree = new Z[motree*(1+mxtree)];
415 if( mntree==NULL ) goto ERREUR;
417 //initialisation du tableau letree et ajout dans letree des sommets 1 a nbsomm
418 comxmi[0].x = comxmi[1].x = uvslf[0].x;
419 comxmi[0].y = comxmi[1].y = uvslf[0].y;
420 teajte( mxsomm, nbsomm, mnpxyd, comxmi, aretmx, mxtree, mntree, ierr );
426 //saturation de letree => sa taille est augmentee et relance
429 MESSAGE( "Nouvelle valeur de mxtree=" << mxtree );
435 MESSAGE( "Temps de l'ajout arbre-4 des Triangles Equilateraux=" << d << " secondes" );
436 if( ierr != 0 ) goto ERREUR;
437 //ici le tableau mnpxyd contient les sommets des te et les points frontaliers et internes
439 // homogeneisation de l'arbre des te a un saut de taille au plus
440 // prise en compte des tailles d'aretes souhaitees autour des sommets initiaux
441 // ===========================================================================
442 // reservation de la queue pour parcourir les te de l'arbre
443 if( mnqueu != NULL ) delete [] mnqueu;
445 mnqueu = new Z[mxqueu];
446 if( mnqueu==NULL) goto ERREUR;
448 tehote( nutysu, nbarpi, mxsomm, nbsomm, mnpxyd,
450 mntree, mxqueu, mnqueu,
455 MESSAGE("Temps de l'adaptation et l'homogeneisation de l'arbre-4 des TE="
456 << d << " secondes");
459 //destruction du tableau auxiliaire et de l'arbre
464 MESSAGE( "Redemarrage avec la valeur de mxtree=" << mxtree );
472 // trianguler les triangles equilateraux feuilles a partir de leurs 3 sommets
473 // et des points de la frontiere, des points internes imposes interieurs
474 // ==========================================================================
475 tetrte( comxmi, aretmx, nbarpi, mxsomm, mnpxyd,
476 mxqueu, mnqueu, mntree, mosoar, mxsoar, n1soar, mnsoar,
477 moartr, mxartr, n1artr, mnartr, mnarst,
480 // destruction de la queue et de l'arbre devenus inutiles
481 delete [] mnqueu; mnqueu=NULL;
482 delete [] mntree; mntree=NULL;
487 MESSAGE( "Temps de la triangulation des TE=" << d << " secondes" );
489 // ierr =0 si pas d'erreur
490 // =1 si le tableau mnsoar est sature
491 // =2 si le tableau mnartr est sature
492 // =3 si aucun des triangles ne contient l'un des points internes
493 // =5 si saturation de la queue de parcours de l'arbre des te
494 if( ierr != 0 ) goto ERREUR;
496 //qualites de la triangulation actuelle
497 qualitetrte( mnpxyd, mosoar, mxsoar, mnsoar, moartr, mxartr, mnartr,
498 nbt, quamoy, quamin );
500 // boucle sur les aretes internes (non sur une ligne de la frontiere)
501 // avec echange des 2 diagonales afin de rendre la triangulation delaunay
502 // ======================================================================
503 // formation du chainage 6 des aretes internes a echanger eventuellement
504 aisoar( mosoar, mxsoar, mnsoar, na );
505 tedela( mnpxyd, mnarst,
506 mosoar, mxsoar, n1soar, mnsoar, na,
507 moartr, mxartr, n1artr, mnartr, n );
509 MESSAGE( "Nombre d'echanges des diagonales de 2 triangles=" << n );
512 MESSAGE("Temps de la triangulation Delaunay par echange des diagonales="
513 << d << " secondes");
515 //qualites de la triangulation actuelle
516 qualitetrte( mnpxyd, mosoar, mxsoar, mnsoar, moartr, mxartr, mnartr,
517 nbt, quamoy, quamin );
519 // detection des aretes frontalieres initiales perdues
520 // triangulation frontale pour les restaurer
521 // ===================================================
523 if( mn1arcf != NULL ) delete [] mn1arcf;
524 if( mnarcf != NULL ) delete [] mnarcf;
525 if( mnarcf1 != NULL ) delete [] mnarcf1;
526 if( mnarcf2 != NULL ) delete [] mnarcf2;
527 mn1arcf = new Z[1+mxarcf];
528 if( mn1arcf == NULL ) goto ERREUR;
529 mnarcf = new Z[3*mxarcf];
530 if( mnarcf == NULL ) goto ERREUR;
531 mnarcf1 = new Z[mxarcf];
532 if( mnarcf1 == NULL ) goto ERREUR;
533 mnarcf2 = new Z[mxarcf];
534 if( mnarcf2 == NULL ) goto ERREUR;
536 terefr( nbarpi, mnpxyd,
537 mosoar, mxsoar, n1soar, mnsoar,
538 moartr, mxartr, n1artr, mnartr, mnarst,
539 mxarcf, mn1arcf, mnarcf, mnarcf1, mnarcf2,
542 MESSAGE( "Restauration de " << n << " aretes perdues de la frontiere ierr=" << ierr );
545 MESSAGE("Temps de la recuperation des aretes perdues de la frontiere="
546 << d << " secondes");
548 if( ierr != 0 ) goto ERREUR;
550 //qualites de la triangulation actuelle
551 qualitetrte( mnpxyd, mosoar, mxsoar, mnsoar, moartr, mxartr, mnartr,
552 nbt, quamoy, quamin );
554 // fin de la triangulation avec respect des aretes initiales frontalieres
556 // suppression des triangles externes a la surface
557 // ===============================================
558 // recherche du dernier triangle utilise
559 mn = mxartr * moartr;
560 for ( ndtri0=mxartr; ndtri0<=1; ndtri0-- )
563 if( mnartr[mn] != 0 ) break;
566 if( mntrsu != NULL ) delete [] mntrsu;
567 mntrsu = new Z[ndtri0];
568 if( mntrsu == NULL ) goto ERREUR;
570 if( mnlftr != NULL ) delete [] mnlftr;
571 mnlftr = new Z[nblf];
572 if( mnlftr == NULL ) goto ERREUR;
574 for (n=0; n<nblf; n++) //numero de la ligne fermee de 1 a nblf
577 tesuex( nblf, mnlftr,
578 ndtri0, nbsomm, mnpxyd, mnslig,
579 mosoar, mxsoar, mnsoar,
580 moartr, mxartr, n1artr, mnartr, mnarst,
583 delete [] mnlftr; mnlftr=NULL;
584 delete [] mntrsu; mntrsu=NULL;
588 MESSAGE( "Temps de la suppression des triangles externes=" << d << "ierr=" << ierr );
589 if( ierr != 0 ) goto ERREUR;
591 //qualites de la triangulation actuelle
592 qualitetrte( mnpxyd, mosoar, mxsoar, mnsoar, moartr, mxartr, mnartr,
593 nbt, quamoy, quamin );
595 // amelioration de la qualite de la triangulation par
596 // barycentrage des sommets internes a la triangulation
597 // suppression des aretes trop longues ou trop courtes
598 // modification de la topologie des groupes de triangles
599 // mise en delaunay de la triangulation
600 // =====================================================
601 mnarcf3 = new Z[mxarcf];
602 if( mnarcf3 == NULL )
604 MESSAGE ( "aptrte: MC saturee mnarcf3=" << mnarcf3 );
607 teamqt( nutysu, aretmx, airemx,
608 mnarst, mosoar, mxsoar, n1soar, mnsoar,
609 moartr, mxartr, n1artr, mnartr,
610 mxarcf, mnarcf2, mnarcf3,
611 mn1arcf, mnarcf, mnarcf1,
612 nbarpi, nbsomm, mxsomm, mnpxyd, mnslig,
614 if( mnarcf3 != NULL ) {delete [] mnarcf3; mnarcf3=NULL;}
615 if( mn1arcf != NULL ) {delete [] mn1arcf; mn1arcf=NULL;}
616 if( mnarcf != NULL ) {delete [] mnarcf; mnarcf =NULL;}
617 if( mnarcf1 != NULL ) {delete [] mnarcf1; mnarcf1=NULL;}
618 if( mnarcf2 != NULL ) {delete [] mnarcf2; mnarcf2=NULL;}
622 MESSAGE( "Temps de l'amelioration de la qualite de la triangulation=" << d );
623 if( ierr == -13 ) ierr=0; //6/10/2006 arret de l'amelioration apres boucle infinie dans caetoi
624 if( ierr != 0 ) goto ERREUR;
626 //qualites de la triangulation finale
627 qualitetrte( mnpxyd, mosoar, mxsoar, mnsoar, moartr, mxartr, mnartr,
628 nbt, quamoy, quamin );
630 // renumerotation des sommets internes: mnarst(i)=numero final du sommet
631 // ===================================
632 for (i=0; i<=nbsomm; i++)
635 for (nt=1; nt<=mxartr; nt++)
637 if( mnartr[nt*moartr-moartr] != 0 )
639 //le numero des 3 sommets du triangle nt
640 nusotr( nt, mosoar, mnsoar, moartr, mnartr, nosotr );
641 //les 3 sommets du triangle sont actifs
642 mnarst[ nosotr[0] ] = 1;
643 mnarst[ nosotr[1] ] = 1;
644 mnarst[ nosotr[2] ] = 1;
648 for (i=1; i<=nbsomm; i++)
654 // generation du tableau uvst de la surface triangulee
655 // ---------------------------------------------------
656 if( uvst != NULL ) delete [] uvst;
658 if( uvst == NULL ) goto ERREUR;
661 for (i=0; i<nbsomm; i++ )
666 uvst[nbst].x = mnpxyd[i].x;
667 uvst[nbst].y = mnpxyd[i].y;
669 //si le sommet est un point ou appartient a une ligne
670 //ses coordonnees initiales sont restaurees
677 //retour aux coordonnees initiales dans uvslf
679 n = n - 1000000 * l + nudslf[l-1] - 1;
680 uvst[nbst].x = uvslf[n].x;
681 uvst[nbst].y = uvslf[n].y;
685 //point utilisateur n interne impose
686 //retour aux coordonnees initiales dans uvpti
687 uvst[nbst].x = uvpti[n-1].x;
688 uvst[nbst].y = uvpti[n-1].y;
695 // generation du tableau 'nsef' de la surface triangulee
696 // -----------------------------------------------------
697 // boucle sur les triangles occupes (internes et externes)
698 if( nust != NULL ) delete [] nust;
699 nust = new Z[nbsttria*nbt];
700 if( nust == NULL ) goto ERREUR;
702 for (i=1; i<=mxartr; i++)
704 //le triangle i de mnartr
705 if( mnartr[i*moartr-moartr] != 0 )
707 //le triangle i est interne => nosotr numero de ses 3 sommets
708 nusotr( i, mosoar, mnsoar, moartr, mnartr, nosotr );
709 nust[nbt++] = mnarst[ nosotr[0] ];
710 nust[nbt++] = mnarst[ nosotr[1] ];
711 nust[nbt++] = mnarst[ nosotr[2] ];
715 nbt /= nbsttria; //le nombre final de triangles de la surface
716 MESSAGE( "APTRTE: Fin de la triangulation plane avec "<<nbst<<" sommets et "
717 << nbt << " triangles" );
720 MESSAGE( "APTRTE: Temps total de la triangulation plane=" << tcpu << " secondes" );
722 // destruction des tableaux auxiliaires
723 // ------------------------------------
725 if( mnarst != NULL ) delete [] mnarst;
726 if( mnartr != NULL ) delete [] mnartr;
727 if( mnslig != NULL ) delete [] mnslig;
728 if( mnsoar != NULL ) delete [] mnsoar;
729 if( mnpxyd != NULL ) delete [] mnpxyd;
730 if( mntree != NULL ) delete [] mntree;
731 if( mnqueu != NULL ) delete [] mnqueu;
732 if( mntrsu != NULL ) delete [] mntrsu;
733 if( mnlftr != NULL ) delete [] mnlftr;
734 if( mn1arcf != NULL ) delete [] mn1arcf;
735 if( mnarcf != NULL ) delete [] mnarcf;
736 if( mnarcf1 != NULL ) delete [] mnarcf1;
737 if( mnarcf2 != NULL ) delete [] mnarcf2;
738 if( mnarcf3 != NULL ) delete [] mnarcf3;
742 if( ierr == 51 || ierr == 52 )
744 //saturation des sommets => redepart avec 2 fois plus de sommets
751 MESSAGE( "APTRTE: Triangulation NON REALISEE avec erreur=" << ierr );
752 if( ierr == 0 ) ierr=1;
763 qualitetrte( R3 *mnpxyd,
764 Z & mosoar, Z & mxsoar, Z *mnsoar,
765 Z & moartr, Z & mxartr, Z *mnartr,
766 Z & nbtria, R & quamoy, R & quamin )
767 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
768 // but : calculer la qualite moyenne et minimale de la triangulation
769 // ----- actuelle definie par les tableaux mnsoar et mnartr
772 // mnpxyd : tableau des coordonnees 2d des points
773 // par point : x y distance_souhaitee
774 // mosoar : nombre maximal d'entiers par arete et
775 // indice dans mnsoar de l'arete suivante dans le hachage
776 // mxsoar : nombre maximal d'aretes stockables dans le tableau mnsoar
777 // attention: mxsoar>3*mxsomm obligatoire!
778 // mnsoar : numero des 2 sommets , no ligne, 2 triangles de l'arete,
779 // chainage des aretes frontalieres, chainage du hachage des aretes
780 // hachage des aretes = mnsoar(1)+mnsoar(2)*2
781 // avec mxsoar>=3*mxsomm
782 // une arete i de mnsoar est vide <=> mnsoar(1,i)=0 et
783 // mnsoar(2,arete vide)=l'arete vide qui precede
784 // mnsoar(3,arete vide)=l'arete vide qui suit
785 // moartr : nombre maximal d'entiers par arete du tableau mnartr
786 // mxartr : nombre maximal de triangles declarables
787 // mnartr : les 3 aretes des triangles +-arete1, +-arete2, +-arete3
788 // arete1 = 0 si triangle vide => arete2 = triangle vide suivant
791 // nbtria : nombre de triangles internes au domaine
792 // quamoy : qualite moyenne des triangles actuels
793 // quamin : qualite minimale des triangles actuels
794 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
797 Z nosotr[3], mn, nbtrianeg, nt, ntqmin;
807 for ( nt=1; nt<=mxartr; nt++ )
812 //un triangle occupe de plus
815 //le numero des 3 sommets du triangle nt
816 nusotr( nt, mosoar, mnsoar, moartr, mnartr, nosotr );
818 //la qualite du triangle ns1 ns2 ns3
819 qutr2d( mnpxyd[nosotr[0]-1], mnpxyd[nosotr[1]-1], mnpxyd[nosotr[2]-1],
825 //la qualite minimale
826 if( qualite < quamin )
832 //aire signee du triangle nt
833 d = surtd2( mnpxyd[nosotr[0]-1], mnpxyd[nosotr[1]-1], mnpxyd[nosotr[2]-1] );
836 //un triangle d'aire negative de plus
838 MESSAGE("ATTENTION: le triangle " << nt << " de sommets:"
839 << nosotr[0] << " " << nosotr[1] << " " << nosotr[2]
840 << " a une aire " << d <<"<=0");
843 //aire des triangles actuels
850 MESSAGE("Qualite moyenne=" << quamoy
851 << " Qualite minimale=" << quamin
852 << " des " << nbtria << " triangles de surface plane totale="
857 //le numero des 3 sommets du triangle ntqmin de qualite minimale
858 nusotr(ntqmin, mosoar, mnsoar, moartr, mnartr, nosotr );
859 MESSAGE("Triangle de qualite minimale "<<quamin<<" de sommets:"
860 <<nosotr[0]<<" "<<nosotr[1]<<" "<<nosotr[2]<<" ");
861 for (int i=0;i<3;i++)
862 MESSAGE("Sommet "<<nosotr[i]<<": x="<< mnpxyd[nosotr[i]-1].x
863 <<" y="<< mnpxyd[nosotr[i]-1].y);
867 MESSAGE( "ATTENTION: "<< nbtrianeg << " TRIANGLES d'AIRE NEGATIVE" );