Mmg
Simplicial remeshers (mesh adaptation, isovalue discretization, lagrangian movement)
isosiz.c
Go to the documentation of this file.
1/* =============================================================================
2** This file is part of the mmg software package for the tetrahedral
3** mesh modification.
4** Copyright (c) Bx INP/CNRS/Inria/UBordeaux/UPMC, 2004-
5**
6** mmg is distributed in the hope that it will be useful, but WITHOUT
7** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
8** FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
9** License for more details.
10**
11** You should have received a copy of the GNU Lesser General Public
12** License and of the GNU General Public License along with mmg (in
13** files COPYING.LESSER and COPYING). If not, see
14** <http://www.gnu.org/licenses/>. Please read their terms carefully and
15** use this copy of the mmg distribution only if you accept them.
16** =============================================================================
17*/
18
30#include "mmgcommon_private.h"
31
43 double *a,*b,*c,abx,aby,abz,acx,acy,acz,det,n[3];
44
45 a = mesh->point[ptt->v[0]].c;
46 b = mesh->point[ptt->v[1]].c;
47 c = mesh->point[ptt->v[2]].c;
48
49 /* area */
50 abx = b[0] - a[0];
51 aby = b[1] - a[1];
52 abz = b[2] - a[2];
53
54 acx = c[0] - a[0];
55 acy = c[1] - a[1];
56 acz = c[2] - a[2];
57
58 n[0] = aby*acz - abz*acy;
59 n[1] = abz*acx - abx*acz;
60 n[2] = abx*acy - aby*acx;
61 det = n[0]*n[0] + n[1]*n[1] + n[2]*n[2];
62
63 return 0.5*sqrt(det) ;
64}
65
77int MMG5_defsiz_startingMessage (MMG5_pMesh mesh,MMG5_pSol met,const char * funcname ) {
78
79 if ( abs(mesh->info.imprim) > 5 || mesh->info.ddebug )
80 fprintf(stdout," ** Defining %stropic map\n",(met->size==1)?"iso":"aniso");
81
82 if ( mesh->info.hmax < 0.0 ) {
83 fprintf(stderr,"\n ## Error: %s: negative hmax value.\n",funcname);
84 return 0;
85 }
86
87 return 1;
88}
89
97
98 if ( mesh->info.imprim > 0 ) {
99 if ( mesh->info.hgrad > 0. ) {
100 fprintf(stdout,"\n -- GRADATION : %8f ",
101 exp(mesh->info.hgrad) );
102 if ( mesh->info.hgradreq > 0. ) {
103 fprintf(stdout,"(%8f)",exp(mesh->info.hgradreq));
104 }
105 fprintf(stdout,"\n");
106 }
107 else {
108 if ( mesh->info.hgradreq > 0. ) {
109 fprintf(stdout,"\n -- GRADATION : DISABLED (%8f)\n",exp(mesh->info.hgradreq));
110 }
111 }
112 }
113 return;
114}
115
129int MMG5_sum_reqEdgeLengthsAtPoint ( MMG5_pMesh mesh,MMG5_pSol met,MMG5_int ip0,MMG5_int ip1 ) {
130 MMG5_pPoint p0,p1;
131 int j;
132 double len,dist;
133
134 /* Compute the euclidean edge length */
135 p0 = &mesh->point[ip0];
136 p1 = &mesh->point[ip1];
137
138 len = 0.;
139 for ( j=0; j<mesh->dim; ++j ) {
140 dist = p1->c[j]-p0->c[j];
141 len += dist*dist;
142 }
143 len = sqrt(len);
144
145 /* Add the length to the point's metric and increment the number of
146 * times the point has been seen */
147 met->m[met->size*ip0] += len;
148 met->m[met->size*ip1] += len;
149 ++p0->s;
150 ++p1->s;
151
152 return 1;
153}
154
168 MMG5_pPoint p0;
169 MMG5_int k;
170 int mmgWarn = 0;
171
172 for ( k=1; k<=mesh->np; k++ ) {
173 p0 = &mesh->point[k];
174 if ( !MG_VOK(p0) ) continue;
175
176 if ( !p0->s ) continue;
177
178 met->m[k] /= p0->s;
179 p0->flag = 3;
180
181 /* Warn the user that edge size is erased */
182 if ( !mmgWarn ) {
183 mmgWarn = 1;
184 if ( mesh->info.ddebug || (mesh->info.imprim > 4) ) {
185 printf("\n -- SIZEMAP CORRECTION : overwritten of sizes at required vertices\n");
186 }
187 }
188 }
189
190 return 1;
191}
192
205 MMG5_pTria pt;
206 int i,j;
207 MMG5_int k,ip0,ip1,iad0,iad1;
208
209 if ( ismet ) {
210 for ( k=1; k<=mesh->nt; k++ ) {
211 pt = &mesh->tria[k];
212 if ( !MG_EOK(pt) ) continue;
213
214 for ( i=0; i<3; ++i ) {
215 if ( (pt->tag[i] & MG_REQ) || (pt->tag[i] & MG_NOSURF) ||
216 (pt->tag[i] & MG_PARBDY) ) {
217
218 ip0 = pt->v[MMG5_iprv2[i]];
219 ip1 = pt->v[MMG5_inxt2[i]];
220 iad0 = met->size*ip0;
221 iad1 = met->size*ip1;
222
223 for ( j=0; j<met->size; ++j ) {
224
225 met->m[ iad0 + j ] = 0.;
226 met->m[ iad1 + j ] = 0.;
227 }
228 }
229 }
230 }
231 }
232
233 return 1;
234}
235
244 MMG5_pTria pt;
245 MMG5_pPoint ppt;
246 MMG5_int k;
247 int8_t i;
248
249 for ( k=1; k<=mesh->np; k++ ) {
250 ppt = &mesh->point[k];
251 ppt->s = 0;
252 }
253
254 /* Mark the points that belongs to a required edge */
255 for ( k=1; k<=mesh->nt; k++ ) {
256 pt = &mesh->tria[k];
257 if ( !MG_EOK(pt) ) { continue; }
258
259 for ( i=0; i<3; ++i ) {
260 if ( pt->tag[i] & MG_REQ ) {
261 mesh->point[pt->v[MMG5_inxt2[i]]].s = 3*mesh->nt+2;
262 mesh->point[pt->v[MMG5_iprv2[i]]].s = 3*mesh->nt+2;
263 }
264 }
265 }
266}
267
279 MMG5_pTria pt;
280 MMG5_pPoint p1,p2;
281 double hgrad,ll,h1,h2,hn,val;
282 int it,maxit;
283 MMG5_int nup,nu;
284 MMG5_int ip1,ip2,k;
285 int8_t i,j,i1,i2;
286
287 if ( abs(mesh->info.imprim) > 5 || mesh->info.ddebug ) {
288 fprintf(stdout," ** Grading mesh\n");
289 }
290
292
293 for ( k=1; k<=mesh->np; k++ ) {
294 mesh->point[k].flag = mesh->base;
295 }
296
297
298 hgrad = mesh->info.hgrad;
299 it = 0;
300 nup = 0;
301 maxit = 100;
302
303 do {
304 mesh->base++;
305 nu = 0;
306 for (k=1; k<=mesh->nt; k++) {
307 pt = &mesh->tria[k];
308 if ( !MG_EOK(pt) ) continue;
309
310 for (i=0; i<3; i++) {
311 i1 = MMG5_inxt2[i];
312 i2 = MMG5_iprv2[i];
313 ip1 = pt->v[i1];
314 ip2 = pt->v[i2];
315 p1 = &mesh->point[ip1];
316 p2 = &mesh->point[ip2];
317 if ( p1->flag < mesh->base-1 && p2->flag < mesh->base-1 ) continue;
318
319 /* Skip points belonging to a required edge */
320 if ( p1->s || p2->s ) continue;
321
322 ll = 0.;
323 for ( j=0; j<mesh->dim; ++j ) {
324 val = p2->c[j]-p1->c[j];
325 ll += val * val;
326 }
327 ll = sqrt(ll);
328
329 h1 = met->m[ip1];
330 h2 = met->m[ip2];
331 if ( h1 < h2 ) {
332 if ( h1 < MMG5_EPSD ) continue;
333 hn = h1 + hgrad*ll;
334 if ( h2 > hn ) {
335 met->m[ip2] = hn;
336 p2->flag = mesh->base;
337 nu++;
338 }
339 }
340 else {
341 if ( h2 < MMG5_EPSD ) continue;
342 hn = h2 + hgrad*ll;
343 if ( h1 > hn ) {
344 met->m[ip1] = hn;
345 p1->flag = mesh->base;
346 nu++;
347 }
348 }
349 }
350 }
351 nup += nu;
352 }
353 while ( ++it < maxit && nu > 0 );
354
355 if ( abs(mesh->info.imprim) > 4 ) {
356 fprintf(stdout," gradation: %7"MMG5_PRId" updated, %d iter.\n",nup,it);
357 }
358
359 return 1;
360}
361
373 MMG5_pTria pt;
374 MMG5_pPoint p1,p2;
375 double hgrad,ll,h1,h2,hn,ux,uy;
376 int it,maxit,nup,nu;
377 MMG5_int k,ip1,ip2,ipmaster,ipslave;
378 uint8_t i,i1,i2;
379
380
381 if ( abs(mesh->info.imprim) > 5 || mesh->info.ddebug ) {
382 fprintf(stdout," ** Grading required points.\n");
383 }
384
385 if ( mesh->info.hgrad < 0. ) {
388 }
389
391 hgrad = mesh->info.hgradreq;
392 it = nup = 0;
393 maxit = 100;
394
395 do {
396 nu = 0;
397 for (k=1; k<=mesh->nt; k++) {
398 pt = &mesh->tria[k];
399 if ( !MG_EOK(pt) ) {
400 continue;
401 }
402
403 for (i=0; i<3; i++) {
404 i1 = MMG5_inxt2[i];
405 i2 = MMG5_iprv2[i];
406 ip1 = pt->v[i1];
407 ip2 = pt->v[i2];
408 p1 = &mesh->point[ip1];
409 p2 = &mesh->point[ip2];
410
411 if ( MMG5_abs ( p1->s - p2->s ) < 2 ) {
412 /* No size to propagate */
413 continue;
414 }
415 else if ( p1->s > p2->s ) {
416 ipmaster = ip1;
417 ipslave = ip2;
418 }
419 else {
420 assert ( p2->s > p1->s );
421 ipmaster = ip2;
422 ipslave = ip1;
423 }
424
425 ux = p2->c[0]-p1->c[0];
426 uy = p2->c[1]-p1->c[1];
427 ll = ux*ux + uy*uy;
428 ll = sqrt(ll);
429
430 h1 = met->m[ipmaster];
431 h2 = met->m[ipslave];
432 if ( h1 < h2 ) {
433 if ( h1 < MMG5_EPSD ) {
434 continue;
435 }
436 hn = h1 + hgrad*ll;
437 if ( h2 <= hn ) {
438 continue;
439 }
440 }
441 else {
442 hn = h1 - hgrad*ll;
443 if ( h2 >= hn ) {
444 continue;
445 }
446 }
447 met->m[ipslave] = hn;
448 mesh->point[ipslave].s = mesh->point[ipmaster].s - 1;
449 nu++;
450 }
451 }
452 nup += nu;
453 }
454 while ( ++it < maxit && nu > 0 );
455
456 if ( abs(mesh->info.imprim) > 4 && nup ) {
457 fprintf(stdout," gradation (required): %7d updated, %d iter.\n",nup,it);
458 }
459
460 return nup;
461}
MMG5_pMesh * mesh
#define MMG5_EPSD
void MMG5_gradation_info(MMG5_pMesh mesh)
Definition: isosiz.c:96
double MMG5_surftri_iso(MMG5_pMesh mesh, MMG5_pSol met, MMG5_pTria ptt)
Definition: isosiz.c:42
int MMG5_sum_reqEdgeLengthsAtPoint(MMG5_pMesh mesh, MMG5_pSol met, MMG5_int ip0, MMG5_int ip1)
Definition: isosiz.c:129
void MMG5_mark_pointsOnReqEdge_fromTria(MMG5_pMesh mesh)
Definition: isosiz.c:243
int MMG5_reset_metricAtReqEdges_surf(MMG5_pMesh mesh, MMG5_pSol met, int8_t ismet)
Definition: isosiz.c:204
int MMG5_gradsiz_iso(MMG5_pMesh mesh, MMG5_pSol met)
Definition: isosiz.c:278
int MMG5_compute_meanMetricAtMarkedPoints_iso(MMG5_pMesh mesh, MMG5_pSol met)
Definition: isosiz.c:167
int MMG5_defsiz_startingMessage(MMG5_pMesh mesh, MMG5_pSol met, const char *funcname)
Definition: isosiz.c:77
int MMG5_gradsizreq_iso(MMG5_pMesh mesh, MMG5_pSol met)
Definition: isosiz.c:372
#define MG_REQ
#define MG_EOK(pt)
#define MG_PARBDY
static const uint8_t MMG5_iprv2[3]
static const uint8_t MMG5_inxt2[6]
#define MG_VOK(ppt)
#define MG_NOSURF
int8_t ddebug
Definition: libmmgtypes.h:532
double hgrad
Definition: libmmgtypes.h:518
double hmax
Definition: libmmgtypes.h:518
double hgradreq
Definition: libmmgtypes.h:518
MMG mesh structure.
Definition: libmmgtypes.h:605
MMG5_Info info
Definition: libmmgtypes.h:651
MMG5_pPoint point
Definition: libmmgtypes.h:641
MMG5_int base
Definition: libmmgtypes.h:616
MMG5_int nt
Definition: libmmgtypes.h:612
MMG5_pTria tria
Definition: libmmgtypes.h:647
MMG5_int np
Definition: libmmgtypes.h:612
Structure to store points of a MMG mesh.
Definition: libmmgtypes.h:270
double c[3]
Definition: libmmgtypes.h:271
MMG5_int s
Definition: libmmgtypes.h:283
MMG5_int flag
Definition: libmmgtypes.h:282
double * m
Definition: libmmgtypes.h:671
int16_t tag[3]
Definition: libmmgtypes.h:342
MMG5_int v[3]
Definition: libmmgtypes.h:334