Mmg
Simplicial remeshers (mesh adaptation, isovalue discretization, lagrangian movement)
isosiz_s.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 free software: you can redistribute it and/or modify it
7** under the terms of the GNU Lesser General Public License as published
8** by the Free Software Foundation, either version 3 of the License, or
9** (at your option) any later version.
10**
11** mmg is distributed in the hope that it will be useful, but WITHOUT
12** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13** FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14** License for more details.
15**
16** You should have received a copy of the GNU Lesser General Public
17** License and of the GNU General Public License along with mmg (in
18** files COPYING.LESSER and COPYING). If not, see
19** <http://www.gnu.org/licenses/>. Please read their terms carefully and
20** use this copy of the mmg distribution only if you accept them.
21** =============================================================================
22*/
23
36#include "libmmgs_private.h"
37#include "libmmgs.h"
38#include <math.h>
39#include "mmgsexterns_private.h"
40#include "mmgexterns_private.h"
41
42#define MAXLEN 1.0e+3
43
58static inline
60 MMG5_pTria pt,int8_t i) {
61 MMG5_int ip0,ip1;
62
63 ip0 = pt->v[MMG5_inxt2[i]];
64 ip1 = pt->v[MMG5_iprv2[i]];
65
66 /* Check if the edge is already treated */
67 if ( MMG5_hashGet(hash,ip0,ip1) ) return 1;
68
69 /* Mark the edge as treated */
70 if ( !MMG5_hashEdge(mesh,hash,ip0,ip1,1) ) return 0;
71
72 if ( !MMG5_sum_reqEdgeLengthsAtPoint(mesh,met,ip0,ip1) )
73 return 0;
74
75 return 1;
76}
77
91 MMG5_pTria pt;
92 MMG5_Hash hash;
93 int i;
94 MMG5_int k;
95
96 /* Reset the input metric at required edges extremities */
97 if ( !MMG5_reset_metricAtReqEdges_surf (mesh, met,ismet ) ) {
98 return 0;
99 }
100
101 /* Process the required edges and add the edge length to the metric of the
102 * edge extremities */
103 if ( !MMG5_hashNew(mesh,&hash,mesh->np,7*mesh->np) ) return 0;
104
105 for ( k=1; k<=mesh->nt; k++ ) {
106 pt = &mesh->tria[k];
107 if ( !MG_EOK(pt) ) continue;
108
109 for ( i=0; i<3; i++ ) {
110 if ( (pt->tag[i] & MG_REQ) || (pt->tag[i] & MG_NOSURF) ||
111 (pt->tag[i] & MG_PARBDY) ) {
112
113 /* Check if the edge has been proceeded by the neighbour triangle */
114 if ( !MMGS_sum_reqEdgeLengthsAtPoint(mesh,met,&hash,pt,i) ) {
115 MMG5_DEL_MEM(mesh,hash.item);
116 return 0;
117 }
118 }
119 }
120 }
121 MMG5_DEL_MEM(mesh,hash.item);
122
123 /* Travel the points and compute the metric of the points belonging to
124 * required edges as the mean of the required edges length */
125 if ( !MMG5_compute_meanMetricAtMarkedPoints ( mesh,met ) ) {
126 return 0;
127 }
128
129 return 1;
130}
131
143 MMG5_pTria pt;
144 MMG5_pPoint p[3],p0;
145 MMG5_pPar par;
146 double n[3][3],t[3][3],nt[3],c1[3],c2[3],*n1,*n2,*t1,*t2;
147 double ps,ps2,ux,uy,uz,ll,l,lm,dd,M1,M2,hausd,hmin,hmax;
148 int j,isloc;
149 MMG5_int k,ip1,ip2;
150 int8_t ismet;
151 int8_t i,i1,i2;
152
153 if ( !MMG5_defsiz_startingMessage (mesh,met,__func__) ) {
154 return 0;
155 }
156
157 for (k=1; k<=mesh->np; k++) {
158 p0 = &mesh->point[k];
159 p0->flag = 0;
160 p0->s = 0;
161 }
162
163 /* alloc structure */
164 if ( !met->m ) {
165 ismet = 0;
166
167 /* Allocate and store the header informations for each solution */
169 return 0;
170 }
171 }
172 else {
173 ismet = 1;
174 assert ( met->m );
175 }
176
180 if ( !mesh->info.nosizreq ) {
181 if ( !MMGS_set_metricAtPointsOnReqEdges ( mesh,met,ismet ) ) {
182 return 0;
183 }
184 }
185
187 if ( !ismet ) {
188
189 /* init constant size */
190 for (k=1; k<=mesh->np; k++) {
191 if ( mesh->point[k].flag ) {
192 continue;
193 }
194 met->m[k] = mesh->info.hmax;
195 mesh->point[k].flag = 1;
196 }
197 }
198
200 for (k=1; k<=mesh->nt; k++) {
201 pt = &mesh->tria[k];
202 if ( !MG_EOK(pt) ) continue;
203
204 p[0] = &mesh->point[pt->v[0]];
205 p[1] = &mesh->point[pt->v[1]];
206 p[2] = &mesh->point[pt->v[2]];
207
208 /* normal recovery */
209 for (i=0; i<3; i++) {
210 if ( MS_SIN(p[i]->tag) ) {
211 MMG5_nortri(mesh,pt,n[i]);
212 }
213 else if ( MG_EDG(p[i]->tag) ) {
214 MMG5_nortri(mesh,pt,nt);
215 n1 = &mesh->xpoint[p[i]->xp].n1[0];
216 n2 = &mesh->xpoint[p[i]->xp].n2[0];
217 ps = n1[0]*nt[0] + n1[1]*nt[1] + n1[2]*nt[2];
218 ps2 = n2[0]*nt[0] + n2[1]*nt[1] + n2[2]*nt[2];
219 if ( fabs(ps) > fabs(ps2) )
220 memcpy(&n[i],n1,3*sizeof(double));
221 else
222 memcpy(&n[i],n2,3*sizeof(double));
223 memcpy(&t[i],p[i]->n,3*sizeof(double));
224 }
225 else
226 memcpy(&n[i],p[i]->n,3*sizeof(double));
227 }
228
229 for (i=0; i<3; i++) {
230 i1 = MMG5_inxt2[i];
231 i2 = MMG5_iprv2[i];
232 ip1 = pt->v[i1];
233 ip2 = pt->v[i2];
234
235 /* local parameters */
236 hausd = mesh->info.hausd;
237 hmin = mesh->info.hmin;
238 hmax = mesh->info.hmax;
239 isloc = 0;
240 for (j=0; j<mesh->info.npar; j++) {
241 par = &mesh->info.par[j];
242 if ( (par->elt == MMG5_Triangle) && (pt->ref == par->ref ) ) {
243 if ( !isloc ) {
244 hausd = par->hausd;
245 hmin = par->hmin;
246 hmax = par->hmax;
247 isloc = 1;
248 }
249 else {
250 hausd = MG_MIN(par->hausd,hausd);
251 hmin = MG_MAX(par->hmin,hmin);
252 hmax = MG_MIN(par->hmax,hmax);
253 }
254 }
255 }
256
257 ux = p[i2]->c[0] - p[i1]->c[0];
258 uy = p[i2]->c[1] - p[i1]->c[1];
259 uz = p[i2]->c[2] - p[i1]->c[2];
260 ll = ux*ux + uy*uy + uz*uz;
261
262 if ( ll < MMG5_EPSD ) continue;
263
264 if ( MG_EDG(pt->tag[i]) ) {
265 if ( MS_SIN(p[i1]->tag) ) {
266 t[i1][0] = ux;
267 t[i1][1] = uy;
268 t[i1][2] = uz;
269 l = 1.0 / sqrt(ll);
270 t[i1][0] *= l;
271 t[i1][1] *= l;
272 t[i1][2] *= l;
273 }
274 if ( MS_SIN(p[i2]->tag) ) {
275 t[i2][0] = -ux;
276 t[i2][1] = -uy;
277 t[i2][2] = -uz;
278 l = 1.0/sqrt(ll);
279 t[i2][0] *= l;
280 t[i2][1] *= l;
281 t[i2][2] *= l;
282 }
283 t1 = t[i1];
284 t2 = t[i2];
285
286 /* The two Bezier coefficients along curve */
287 dd = (t1[0]*ux + t1[1]*uy + t1[2]*uz)/3.0;
288 c1[0] = p[i1]->c[0] + dd * t1[0];
289 c1[1] = p[i1]->c[1] + dd * t1[1];
290 c1[2] = p[i1]->c[2] + dd * t1[2];
291
292 dd = -(t2[0]*ux + t2[1]*uy + t2[2]*uz)/3.0;
293 c2[0] = p[i2]->c[0] + dd * t2[0];
294 c2[1] = p[i2]->c[1] + dd * t2[1];
295 c2[2] = p[i2]->c[2] + dd * t2[2];
296
297 M1 = (c2[0]-2.0*c1[0]+p[i1]->c[0])*(c2[0]-2.0*c1[0]+p[i1]->c[0]) \
298 + (c2[1]-2.0*c1[1]+p[i1]->c[1])*(c2[1]-2.0*c1[1]+p[i1]->c[1]) \
299 + (c2[2]-2.0*c1[2]+p[i1]->c[2])*(c2[2]-2.0*c1[2]+p[i1]->c[2]);
300
301 M2 = (p[i2]->c[0]-2.0*c2[0]+c1[0])*(p[i2]->c[0]-2.0*c2[0]+c1[0]) \
302 + (p[i2]->c[1]-2.0*c2[1]+c1[1])*(p[i2]->c[1]-2.0*c2[1]+c1[1])\
303 + (p[i2]->c[2]-2.0*c2[2]+c1[2])*(p[i2]->c[2]-2.0*c2[2]+c1[2]);
304
305 M1 = 6.0 * sqrt(M1);
306 M2 = 6.0 * sqrt(M2);
307 M1 = MG_MAX(M1,M2);
308
309 if ( M1 < MMG5_EPSD )
310 lm = MAXLEN;
311 else {
312 lm = (16.0*ll*hausd) / (3.0*M1);
313 lm = sqrt(lm);
314 }
315 if ( mesh->point[ip1].flag < 3 ) {
316 met->m[ip1] = MG_MAX(hmin,MG_MIN(met->m[ip1],lm));
317 }
318 if ( mesh->point[ip2].flag < 3 ) {
319 met->m[ip2] = MG_MAX(hmin,MG_MIN(met->m[ip2],lm));
320 }
321 }
322 else {
323 n1 = n[i1];
324 n2 = n[i2];
325
326 ps = ux*n1[0] + uy*n1[1] + uz*n1[2];
327 c1[0] = (2.0*p[i1]->c[0] + p[i2]->c[0] - ps*n1[0]) / 3.0;
328 c1[1] = (2.0*p[i1]->c[1] + p[i2]->c[1] - ps*n1[1]) / 3.0;
329 c1[2] = (2.0*p[i1]->c[2] + p[i2]->c[2] - ps*n1[2]) / 3.0;
330
331 ps = -(ux*n2[0] + uy*n2[1] + uz*n2[2]);
332 c2[0] = (2.0*p[i2]->c[0] + p[i1]->c[0] - ps*n2[0]) / 3.0;
333 c2[1] = (2.0*p[i2]->c[1] + p[i1]->c[1] - ps*n2[1]) / 3.0;
334 c2[2] = (2.0*p[i2]->c[2] + p[i1]->c[2] - ps*n2[2]) / 3.0;
335
336 M1 = (c2[0]-2.0*c1[0]+p[i1]->c[0])*(c2[0]-2.0*c1[0]+p[i1]->c[0]) \
337 + (c2[1]-2.0*c1[1]+p[i1]->c[1])*(c2[1]-2.0*c1[1]+p[i1]->c[1]) \
338 + (c2[2]-2.0*c1[2]+p[i1]->c[2])*(c2[2]-2.0*c1[2]+p[i1]->c[2]);
339
340 M2 = (p[i2]->c[0]-2.0*c2[0]+c1[0])*(p[i2]->c[0]-2.0*c2[0]+c1[0]) \
341 + (p[i2]->c[1]-2.0*c2[1]+c1[1])*(p[i2]->c[1]-2.0*c2[1]+c1[1])\
342 + (p[i2]->c[2]-2.0*c2[2]+c1[2])*(p[i2]->c[2]-2.0*c2[2]+c1[2]);
343
344 M1 = 6.0 * sqrt(M1);
345 M2 = 6.0 * sqrt(M2);
346 M1 = MG_MAX(M1,M2);
347
348 if ( M1 < MMG5_EPSD )
349 lm = MAXLEN;
350 else {
351 lm = (16.0*ll*hausd) / (3.0*M1);
352 lm = sqrt(lm);
353 }
354 if ( mesh->point[ip1].flag < 3 ) {
355 met->m[ip1] = MG_MAX(hmin,MG_MIN(met->m[ip1],lm));
356 }
357 if ( mesh->point[ip2].flag < 3 ) {
358 met->m[ip2] = MG_MAX(hmin,MG_MIN(met->m[ip2],lm));
359 }
360 }
361 }
362 }
363
364 /* take local parameters */
365 for (j=0; j<mesh->info.npar; j++) {
366 par = &mesh->info.par[j];
367 if ( par->elt == MMG5_Triangle ) {
368 for (k=1; k<=mesh->nt; k++) {
369 pt = &mesh->tria[k];
370 if ( !MG_EOK(pt) || pt->ref != par->ref ) continue;
371 if ( mesh->point[pt->v[0]].flag < 3 ) {
372 met->m[pt->v[0]] = MG_MAX(par->hmin,MG_MIN(met->m[pt->v[0]],par->hmax));
373 }
374 if ( mesh->point[pt->v[1]].flag < 3 ) {
375 met->m[pt->v[1]] = MG_MAX(par->hmin,MG_MIN(met->m[pt->v[1]],par->hmax));
376 }
377 if ( mesh->point[pt->v[2]].flag < 3 ) {
378 met->m[pt->v[2]] = MG_MAX(par->hmin,MG_MIN(met->m[pt->v[2]],par->hmax));
379 }
380 }
381 }
382 }
383 return 1;
384}
int MMGS_Set_solSize(MMG5_pMesh mesh, MMG5_pSol sol, int typEntity, MMG5_int np, int typSol)
MMG5_pMesh * mesh
#define MMG5_EPSD
int MMG5_hashNew(MMG5_pMesh mesh, MMG5_Hash *hash, MMG5_int hsiz, MMG5_int hmax)
Definition: hash.c:526
MMG5_int MMG5_hashGet(MMG5_Hash *hash, MMG5_int a, MMG5_int b)
Definition: hash.c:495
int MMG5_hashEdge(MMG5_pMesh mesh, MMG5_Hash *hash, MMG5_int a, MMG5_int b, MMG5_int k)
Definition: hash.c:345
int MMG5_sum_reqEdgeLengthsAtPoint(MMG5_pMesh mesh, MMG5_pSol met, MMG5_int ip0, MMG5_int ip1)
Definition: isosiz.c:129
int MMG5_reset_metricAtReqEdges_surf(MMG5_pMesh mesh, MMG5_pSol met, int8_t ismet)
Definition: isosiz.c:204
int MMG5_defsiz_startingMessage(MMG5_pMesh mesh, MMG5_pSol met, const char *funcname)
Definition: isosiz.c:77
int MMGS_set_metricAtPointsOnReqEdges(MMG5_pMesh mesh, MMG5_pSol met, int8_t ismet)
Definition: isosiz_s.c:90
int MMGS_defsiz_iso(MMG5_pMesh mesh, MMG5_pSol met)
Definition: isosiz_s.c:142
static int MMGS_sum_reqEdgeLengthsAtPoint(MMG5_pMesh mesh, MMG5_pSol met, MMG5_Hash *hash, MMG5_pTria pt, int8_t i)
Definition: isosiz_s.c:59
#define MAXLEN
Definition: isosiz_s.c:42
API headers for the mmgs library.
#define MS_SIN(tag)
@ MMG5_Scalar
Definition: libmmgtypes.h:213
@ MMG5_Vertex
Definition: libmmgtypes.h:224
@ MMG5_Triangle
Definition: libmmgtypes.h:226
#define MG_REQ
#define MG_EOK(pt)
#define MG_PARBDY
#define MG_MIN(a, b)
#define MG_MAX(a, b)
#define MG_EDG(tag)
static const uint8_t MMG5_iprv2[3]
static const uint8_t MMG5_inxt2[6]
int MMG5_nortri(MMG5_pMesh mesh, MMG5_pTria pt, double *n)
Definition: tools.c:209
#define MG_NOSURF
#define MMG5_DEL_MEM(mesh, ptr)
Identic as MMG5_HGeom but use MMG5_hedge to store edges instead of MMG5_hgeom (memory economy).
Definition: libmmgtypes.h:595
MMG5_hedge * item
Definition: libmmgtypes.h:597
double hmin
Definition: libmmgtypes.h:518
double hmax
Definition: libmmgtypes.h:518
uint8_t nosizreq
Definition: libmmgtypes.h:546
MMG5_pPar par
Definition: libmmgtypes.h:517
double hausd
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_pxPoint xpoint
Definition: libmmgtypes.h:642
MMG5_int nt
Definition: libmmgtypes.h:612
MMG5_pTria tria
Definition: libmmgtypes.h:647
MMG5_int np
Definition: libmmgtypes.h:612
double hmin
Definition: libmmgtypes.h:258
double hmax
Definition: libmmgtypes.h:259
double hausd
Definition: libmmgtypes.h:260
MMG5_int ref
Definition: libmmgtypes.h:261
int8_t elt
Definition: libmmgtypes.h:262
Structure to store points of a MMG mesh.
Definition: libmmgtypes.h:270
double c[3]
Definition: libmmgtypes.h:271
MMG5_int xp
Definition: libmmgtypes.h:279
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 ref
Definition: libmmgtypes.h:335
MMG5_int v[3]
Definition: libmmgtypes.h:334
double n2[3]
Definition: libmmgtypes.h:295
double n1[3]
Definition: libmmgtypes.h:295