Mmg
Simplicial remeshers (mesh adaptation, isovalue discretization, lagrangian movement)
isosiz_2d.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*/
34#include "libmmg2d_private.h"
35#include "libmmg2d.h"
37#include "mmgexterns_private.h"
38
53 MMG5_int ip0,ip1;
54
55 ip0 = pt->v[MMG5_iprv2[i]];
56 ip1 = pt->v[MMG5_inxt2[i]];
57
58 if ( !MMG5_sum_reqEdgeLengthsAtPoint(mesh,met,ip0,ip1) )
59 return 0;
60
61 return 1;
62}
63
64
78 MMG5_pTria pt;
79 MMG5_int k,iadj;
80 int i;
81
82 /* Reset the tria flag */
83 for ( k=1; k<=mesh->nt; k++ ) {
84 mesh->tria[k].flag = 0;
85 }
86
87 /* Reset the input metric at required edges extremities */
88 if ( !MMG5_reset_metricAtReqEdges_surf (mesh, met, ismet ) ) {
89 return 0;
90 }
91
92 /* Process the required edges and add the edge length to the metric of the
93 * edge extremities */
94 for ( k=1; k<=mesh->nt; k++ ) {
95 pt = &mesh->tria[k];
96 if ( !MG_EOK(pt) ) continue;
97
98 /* Mark the tria as proceeded */
99 pt->flag = 1;
100 for ( i=0; i<3; i++ ) {
101 if ( (pt->tag[i] & MG_REQ) || (pt->tag[i] & MG_NOSURF) ||
102 (pt->tag[i] & MG_PARBDY) ) {
103 /* Check if the edge has been proceeded by the neighbour triangle */
104 iadj = mesh->adja[3*(k-1)+i+1];
105 if ( iadj && mesh->tria[iadj/3].flag ) continue;
106
107 if ( !MMG2D_sum_reqEdgeLengthsAtPoint(mesh,met,pt,i) ) {
108 return 0;
109 }
110 }
111 }
112 }
113
114 /* Travel the points and compute the metric of the points belonging to
115 * required edges as the mean of the required edges length */
116 if ( !MMG5_compute_meanMetricAtMarkedPoints ( mesh,met ) ) {
117 return 0;
118 }
119
120return 1;
121}
122
134 MMG5_pTria pt;
135 MMG5_pPoint p0,p1,p2;
136 MMG5_pPar ppa;
137 double t1[2],t2[2],b1[2],b2[2],gpp1[2],gpp2[2],pv,M1,M2;
138 double ps1,ps2,ux,uy,ll,li,lm,hmax,hausd,hmin,lhmax,lhausd;
139 MMG5_int k,ip,ip1,ip2;
140 int l;
141 int8_t ismet;
142 uint8_t i,i1,i2;
143
144 if ( !MMG5_defsiz_startingMessage (mesh,met,__func__) ) {
145 return 0;
146 }
147
148 /* Reset the s and flag field : s is used to count the number of req edges to
149 * which a req point belongs and flag is used to differenciate the point not
150 * yet treated, the points with a required metric and the classical points */
151 for (k=1; k<=mesh->np; k++) {
152 p0 = &mesh->point[k];
153 p0->flag = 0;
154 p0->s = 0;
155 }
156
158 hmax = mesh->info.hmax;
159 hausd = mesh->info.hausd;
160 hmin = mesh->info.hmin;
161
162 /* Allocate the structure */
163 if ( !met->np ) {
164 ismet = 0;
165
166 /* Allocate and store the header informations for each solution */
168 return 0;
169 }
170 }
171 else {
172 ismet = 1;
173 assert ( met->m );
174 }
175
179 if ( !mesh->info.nosizreq ) {
180 if ( !MMG2D_set_metricAtPointsOnReqEdges ( mesh,met,ismet ) ) {
181 return 0;
182 }
183 }
184
186 if ( !ismet ) {
187 /* Initialize metric with a constant size */
188 for ( k=1; k<=mesh->np; k++ ) {
189 if ( mesh->point[k].flag ) {
190 continue;
191 }
192 met->m[k] = hmax;
193 mesh->point[k].flag = 1;
194 }
195 }
196
198 for ( k=1; k<=mesh->nt; k++ ) {
199 pt = &mesh->tria[k];
200 if ( !MG_EOK(pt) ) continue;
201
202 for ( i=0; i<3; i++ ) {
203
204 if ( !MG_EDG(pt->tag[i]) ) continue;
205
206 i1 = MMG5_inxt2[i];
207 i2 = MMG5_iprv2[i];
208 ip1 = pt->v[i1];
209 ip2 = pt->v[i2];
210
211 p1 = &mesh->point[ip1];
212 p2 = &mesh->point[ip2];
213
214 if ( p1->flag>1 && p2->flag>1 ) continue;
215
216 lhmax = hmax;
217 lhausd = hausd;
218
219 /* Retrieve local parameters associated to edge i */
220 if ( mesh->info.npar ) {
221 for (l=0; l<mesh->info.npar; l++) {
222 ppa = &mesh->info.par[l];
223 if ( ppa->elt == MMG5_Edg && ppa->ref == pt->edg[i] ) {
224 lhmax = ppa->hmax;
225 lhausd = ppa->hausd;
226 break;
227 }
228 }
229 }
230
231
232 ux = p2->c[0] - p1->c[0];
233 uy = p2->c[1] - p1->c[1];
234 ll = ux*ux + uy*uy;
235 if ( ll < MMG5_EPSD ) continue;
236 li = 1.0 / sqrt(ll);
237
238 /* Recovery of the two tangent vectors associated to points p1,p2; they
239 * need not be oriented in the same fashion */
240 if ( MG_CRN & p1->tag || (p1->tag & MG_NOM) ) {
241 t1[0] = li*ux;
242 t1[1] = li*uy;
243 }
244 else {
245 t1[0] = -p1->n[1];
246 t1[1] = p1->n[0];
247 }
248
249 if ( MG_CRN & p2->tag || (p2->tag & MG_NOM) ) {
250 li = 1.0 / sqrt(ll);
251 t2[0] = li*ux;
252 t2[1] = li*uy;
253 }
254 else {
255 t2[0] = -p2->n[1];
256 t2[1] = p2->n[0];
257 }
258
259 /* Calculation of the two Bezier coefficients along the curve */
260 ps1 = ux*t1[0] + uy*t1[1];
261 b1[0] = p1->c[0] + MMG5_ATHIRD*ps1*t1[0];
262 b1[1] = p1->c[1] + MMG5_ATHIRD*ps1*t1[1];
263
264 ps2 = ux*t2[0]+uy*t2[1];
265 b2[0] = p2->c[0] - MMG5_ATHIRD*ps2*t2[0];
266 b2[1] = p2->c[1] - MMG5_ATHIRD*ps2*t2[1];
267
268 ps1 *= ps1;
269 ps2 *= ps2;
270
271 if ( ps1 < MMG5_EPSD || ps2 < MMG5_EPSD ) continue;
272
273 /* \gamma^{\prime\prime}(0); \gamma^\prime(0) = ps*t1 by construction */
274 gpp1[0] = 6.0*(p1->c[0] - 2.0*b1[0] + b2[0]);
275 gpp1[1] = 6.0*(p1->c[1] - 2.0*b1[1] + b2[1]);
276
277 /* Vector product gpp1 ^ t1 */
278 pv = gpp1[0]*t1[1] - gpp1[1]*t1[0];
279 M1 = fabs(pv)/ps1;
280
281 /* \gamma^{\prime\prime}(1); \gamma^\prime(1) = -ps*t2 by construction */
282 gpp2[0] = 6.0*(p2->c[0] - 2.0*b2[0] + b1[0]);
283 gpp2[1] = 6.0*(p2->c[1] - 2.0*b2[1] + b1[1]);
284
285 /* Vector product gpp2 ^ t2 */
286 pv = gpp2[0]*t2[1] - gpp2[1]*t2[0];
287 M2 = fabs(pv)/ps2;
288
289 M1 = MG_MAX(M1,M2);
290 if ( M1 < MMG5_EPSD )
291 lm = lhmax;
292 else {
293 lm = 8.0*lhausd / M1;
294 lm = MG_MIN(lhmax,sqrt(lm));
295 }
296
297 if ( p1->flag < 3 ) {
298 met->m[ip1] = MG_MAX(hmin,MG_MIN(met->m[ip1],lm));
299 }
300 if ( p2->flag < 3 ) {
301 met->m[ip2] = MG_MAX(hmin,MG_MIN(met->m[ip2],lm));
302 }
303 }
304 }
305
307 /* Without local parameters information, only the boundary edges impose a
308 * minimum size feature */
309 if ( mesh->info.npar ) {
310 /* Minimum size feature imposed by triangles */
311 for (k=1; k<=mesh->nt; k++) {
312 pt = &mesh->tria[k];
313 if ( !MG_EOK(pt) ) continue;
314
315 /* Retrieve local parameters associated to triangle k */
316 for (l=0; l<mesh->info.npar; l++) {
317 ppa = &mesh->info.par[l];
318 if ( ppa->elt == MMG5_Triangle && ppa->ref == pt->ref ) {
319 for (i=0; i<3; i++) {
320 ip = pt->v[i];
321 if ( mesh->point[ip].flag < 3 ) {
322 met->m[ip] = MG_MAX(hmin,MG_MIN(met->m[ip],ppa->hmax));
323 }
324 }
325 break;
326 }
327 }
328 }
329 /* Minimum size feature imposed by vertices */
330 for (k=1; k<=mesh->np; k++) {
331 p0 = &mesh->point[k];
332 if ( (!MG_VOK(p0)) || p0->flag == 3 ) continue;
333
334 /* Retrieve local parameters associated to vertex k */
335 for (l=0; l<mesh->info.npar; l++) {
336 ppa = &mesh->info.par[l];
337 if ( ppa->elt == MMG5_Vertex && ppa->ref == p0->ref ) {
338 met->m[k] = MG_MAX(hmin,MG_MIN(met->m[k],ppa->hmax));
339 break;
340 }
341 }
342 }
343 }
344
345 return 1;
346}
int MMG2D_Set_solSize(MMG5_pMesh mesh, MMG5_pSol sol, int typEntity, MMG5_int np, int typSol)
MMG5_pMesh * mesh
#define MMG5_EPSD
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 MMG2D_sum_reqEdgeLengthsAtPoint(MMG5_pMesh mesh, MMG5_pSol met, MMG5_pTria pt, int8_t i)
Definition: isosiz_2d.c:52
int MMG2D_defsiz_iso(MMG5_pMesh mesh, MMG5_pSol met)
Definition: isosiz_2d.c:133
int MMG2D_set_metricAtPointsOnReqEdges(MMG5_pMesh mesh, MMG5_pSol met, int8_t ismet)
Definition: isosiz_2d.c:77
API headers for the mmg2d library.
@ MMG5_Scalar
Definition: libmmgtypes.h:213
@ MMG5_Vertex
Definition: libmmgtypes.h:224
@ MMG5_Edg
Definition: libmmgtypes.h:225
@ 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]
#define MMG5_ATHIRD
static const uint8_t MMG5_inxt2[6]
#define MG_VOK(ppt)
#define MG_CRN
#define MG_NOSURF
#define MG_NOM
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_int * adja
Definition: libmmgtypes.h:624
MMG5_int nt
Definition: libmmgtypes.h:612
MMG5_pTria tria
Definition: libmmgtypes.h:647
MMG5_int np
Definition: libmmgtypes.h:612
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 n[3]
Definition: libmmgtypes.h:272
int16_t tag
Definition: libmmgtypes.h:284
double c[3]
Definition: libmmgtypes.h:271
MMG5_int s
Definition: libmmgtypes.h:283
MMG5_int ref
Definition: libmmgtypes.h:278
MMG5_int flag
Definition: libmmgtypes.h:282
double * m
Definition: libmmgtypes.h:671
MMG5_int np
Definition: libmmgtypes.h:665
MMG5_int edg[3]
Definition: libmmgtypes.h:339
int16_t tag[3]
Definition: libmmgtypes.h:342
MMG5_int ref
Definition: libmmgtypes.h:335
MMG5_int flag
Definition: libmmgtypes.h:341
MMG5_int v[3]
Definition: libmmgtypes.h:334