Mmg
Simplicial remeshers (mesh adaptation, isovalue discretization, lagrangian movement)
bezier_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
38extern int8_t ddb;
39
55 int8_t ori) {
56 MMG5_pPoint p[3];
57 double *n1,*n2,nt[3],ps,ps2,dd,ux,uy,uz,ll;
58 MMG5_int ia,ib,ic;
59 int8_t i,i1,i2;
60
61 ia = pt->v[0];
62 ib = pt->v[1];
63 ic = pt->v[2];
64 p[0] = &mesh->point[ia];
65 p[1] = &mesh->point[ib];
66 p[2] = &mesh->point[ic];
67
68 memset(pb,0,sizeof(MMG5_Bezier));
69
70 /* first 3 CP = vertices, normals */
71 for (i=0; i<3; i++) {
72 memcpy(&pb->b[i],p[i]->c,3*sizeof(double));
73 pb->p[i] = p[i];
74
75 if ( MS_SIN(p[i]->tag) ) {
76 MMG5_nortri(mesh,pt,pb->n[i]);
77 }
78 else if ( MG_EDG(p[i]->tag) ) {
79 MMG5_nortri(mesh,pt,nt);
80
81 n1 = &mesh->xpoint[p[i]->xp].n1[0];
82 n2 = &mesh->xpoint[p[i]->xp].n2[0];
83
84 ps = n1[0]*nt[0] + n1[1]*nt[1] + n1[2]*nt[2];
85 ps2 = n2[0]*nt[0] + n2[1]*nt[1] + n2[2]*nt[2];
86 if ( fabs(ps) > fabs(ps2) )
87 memcpy(&pb->n[i],n1,3*sizeof(double));
88 else
89 memcpy(&pb->n[i],n2,3*sizeof(double));
90 memcpy(&pb->t[i],p[i]->n,3*sizeof(double));
91 }
92 else
93 memcpy(&pb->n[i],p[i]->n,3*sizeof(double));
94 }
95
96 /* compute control points along edges */
97 for (i=0; i<3; i++) {
98 i1 = MMG5_inxt2[i];
99 i2 = MMG5_iprv2[i];
100
101 ux = p[i2]->c[0] - p[i1]->c[0];
102 uy = p[i2]->c[1] - p[i1]->c[1];
103 uz = p[i2]->c[2] - p[i1]->c[2];
104
105 ll = ux*ux + uy*uy + uz*uz; // A PROTEGER !!!!
106
107 /* choose normals */
108 n1 = pb->n[i1];
109 n2 = pb->n[i2];
110
111 /* check for boundary curve */
112 if ( MG_EDG(pt->tag[i]) ) {
113 if ( MS_SIN(p[i1]->tag) ) {
114 dd = 1.0 / 3.0;
115 pb->b[2*i+3][0] = p[i1]->c[0] + dd * ux;
116 pb->b[2*i+3][1] = p[i1]->c[1] + dd * uy;
117 pb->b[2*i+3][2] = p[i1]->c[2] + dd * uz;
118 }
119 else {
120 dd = (ux*pb->t[i1][0] + uy*pb->t[i1][1] + uz*pb->t[i1][2]) / 3.0;
121 pb->b[2*i+3][0] = p[i1]->c[0] + dd * pb->t[i1][0];
122 pb->b[2*i+3][1] = p[i1]->c[1] + dd * pb->t[i1][1];
123 pb->b[2*i+3][2] = p[i1]->c[2] + dd * pb->t[i1][2];
124 }
125 if ( MS_SIN(p[i2]->tag) ) {
126 dd = 1.0 / 3.0;
127 pb->b[2*i+4][0] = p[i2]->c[0] - dd * ux;
128 pb->b[2*i+4][1] = p[i2]->c[1] - dd * uy;
129 pb->b[2*i+4][2] = p[i2]->c[2] - dd * uz;
130 }
131 else {
132 dd = -(ux*pb->t[i2][0] + uy*pb->t[i2][1] + uz*pb->t[i2][2]) / 3.0;
133 pb->b[2*i+4][0] = p[i2]->c[0] + dd * pb->t[i2][0];
134 pb->b[2*i+4][1] = p[i2]->c[1] + dd * pb->t[i2][1];
135 pb->b[2*i+4][2] = p[i2]->c[2] + dd * pb->t[i2][2];
136 }
137
138 /* tangent evaluation */
139 ps = ux*(pb->t[i1][0]+pb->t[i2][0]) + uy*(pb->t[i1][1]+pb->t[i2][1]) + uz*(pb->t[i1][2]+pb->t[i2][2]);
140 ps = 2.0 * ps / ll;
141 pb->t[i+3][0] = pb->t[i1][0] + pb->t[i2][0] - ps*ux;
142 pb->t[i+3][1] = pb->t[i1][1] + pb->t[i2][1] - ps*uy;
143 pb->t[i+3][2] = pb->t[i1][2] + pb->t[i2][2] - ps*uz;
144 dd = pb->t[i+3][0]*pb->t[i+3][0] + pb->t[i+3][1]*pb->t[i+3][1] + pb->t[i+3][2]*pb->t[i+3][2];
145 if ( dd > MMG5_EPSD2 ) {
146 dd = 1.0 / sqrt(dd);
147 pb->t[i+3][0] *= dd;
148 pb->t[i+3][1] *= dd;
149 pb->t[i+3][2] *= dd;
150 }
151 }
152
153 else { /* internal edge */
154 ps = ux*n1[0] + uy*n1[1] + uz*n1[2];
155 pb->b[2*i+3][0] = (2.0*p[i1]->c[0] + p[i2]->c[0] - ps*n1[0]) / 3.0;
156 pb->b[2*i+3][1] = (2.0*p[i1]->c[1] + p[i2]->c[1] - ps*n1[1]) / 3.0;
157 pb->b[2*i+3][2] = (2.0*p[i1]->c[2] + p[i2]->c[2] - ps*n1[2]) / 3.0;
158
159 ps = -(ux*n2[0] + uy*n2[1] + uz*n2[2]);
160 pb->b[2*i+4][0] = (2.0*p[i2]->c[0] + p[i1]->c[0] - ps*n2[0]) / 3.0;
161 pb->b[2*i+4][1] = (2.0*p[i2]->c[1] + p[i1]->c[1] - ps*n2[1]) / 3.0;
162 pb->b[2*i+4][2] = (2.0*p[i2]->c[2] + p[i1]->c[2] - ps*n2[2]) / 3.0;
163 }
164
165 /* normal evaluation */
166 ps = ux*(n1[0]+n2[0]) + uy*(n1[1]+n2[1]) + uz*(n1[2]+n2[2]);
167 ps = 2.0*ps / ll;
168 pb->n[i+3][0] = n1[0] + n2[0] - ps*ux;
169 pb->n[i+3][1] = n1[1] + n2[1] - ps*uy;
170 pb->n[i+3][2] = n1[2] + n2[2] - ps*uz;
171 dd = pb->n[i+3][0]*pb->n[i+3][0] + pb->n[i+3][1]*pb->n[i+3][1] + pb->n[i+3][2]*pb->n[i+3][2];
172 if ( dd > MMG5_EPSD2 ) {
173 dd = 1.0 / sqrt(dd);
174 pb->n[i+3][0] *= dd;
175 pb->n[i+3][1] *= dd;
176 pb->n[i+3][2] *= dd;
177 }
178 }
179
180 /* Central Bezier coefficient */
181 for (i=0; i<3; i++) {
182 dd = 0.5 / 3.0;
183 pb->b[9][0] -= dd * pb->b[i][0];
184 pb->b[9][1] -= dd * pb->b[i][1];
185 pb->b[9][2] -= dd * pb->b[i][2];
186 }
187 for (i=0; i<3; i++) {
188 pb->b[9][0] += 0.25 * (pb->b[2*i+3][0] + pb->b[2*i+4][0]);
189 pb->b[9][1] += 0.25 * (pb->b[2*i+3][1] + pb->b[2*i+4][1]);
190 pb->b[9][2] += 0.25 * (pb->b[2*i+3][2] + pb->b[2*i+4][2]);
191 }
192
193 return 1;
194}
195
207int MMGS_bezierInt(MMG5_pBezier pb,double uv[2],double o[3],double no[3],double to[3]) {
208 double dd,u,v,w,ps,ux,uy,uz;
209 int8_t i;
210
211 memset(to,0,3*sizeof(double));
212 u = uv[0];
213 v = uv[1];
214 w = 1 - u - v;
215
216 /* coordinates + normals */
217 for (i=0; i<3; i++) {
218 o[i] = pb->b[0][i]*w*w*w + pb->b[1][i]*u*u*u + pb->b[2][i]*v*v*v \
219 + 3.0 * (pb->b[3][i]*u*u*v + pb->b[4][i]*u*v*v + pb->b[5][i]*w*v*v \
220 + pb->b[6][i]*w*w*v + pb->b[7][i]*w*w*u + pb->b[8][i]*w*u*u)\
221 + 6.0 * pb->b[9][i]*u*v*w;
222
223 /* quadratic interpolation of normals */
224 no[i] = pb->n[0][i]*w*w + pb->n[1][i]*u*u + pb->n[2][i]*v*v \
225 + 2.0 * (pb->n[3][i]*u*v + pb->n[4][i]*v*w + pb->n[5][i]*u*w);
226
227 /* linear interpolation, not used here
228 no[i] = pb->n[0][i]*w + pb->n[1][i]*u + pb->n[2][i]*v; */
229 }
230
231 /* tangent */
232 if ( w < MMG5_EPSD2 ) {
233 ux = pb->b[2][0] - pb->b[1][0];
234 uy = pb->b[2][1] - pb->b[1][1];
235 uz = pb->b[2][2] - pb->b[1][2];
236 dd = ux*ux + uy*uy + uz*uz;
237 if ( dd > MMG5_EPSD2 ) {
238 dd = 1.0 / sqrt(dd);
239 ux *= dd;
240 uy *= dd;
241 uz *= dd;
242 }
243
244 /* corners */
245 if ( MG_SIN(pb->p[1]->tag) ) {
246 pb->t[1][0] = ux;
247 pb->t[1][1] = uy;
248 pb->t[1][2] = uz;
249 }
250 if ( MG_SIN(pb->p[2]->tag) ) {
251 pb->t[2][0] = ux;
252 pb->t[2][1] = uy;
253 pb->t[2][2] = uz;
254 }
255
256 ps = pb->t[1][0]* pb->t[2][0] + pb->t[1][1]* pb->t[2][1] + pb->t[1][2]* pb->t[2][2];
257 if ( ps > 0.0 ) {
258 to[0] = pb->t[1][0]*u + pb->t[2][0]*v;
259 to[1] = pb->t[1][1]*u + pb->t[2][1]*v;
260 to[2] = pb->t[1][2]*u + pb->t[2][2]*v;
261 }
262 else {
263 to[0] = -pb->t[1][0]*u + pb->t[2][0]*v;
264 to[1] = -pb->t[1][1]*u + pb->t[2][1]*v;
265 to[2] = -pb->t[1][2]*u + pb->t[2][2]*v;
266 }
267 }
268
269 if ( u < MMG5_EPSD2 ) {
270 ux = pb->b[2][0] - pb->b[0][0];
271 uy = pb->b[2][1] - pb->b[0][1];
272 uz = pb->b[2][2] - pb->b[0][2];
273 dd = ux*ux + uy*uy + uz*uz;
274 if ( dd > MMG5_EPSD2 ) {
275 dd = 1.0 / sqrt(dd);
276 ux *= dd;
277 uy *= dd;
278 uz *= dd;
279 }
280
281 /* corners */
282 if ( MG_SIN(pb->p[0]->tag) ) {
283 pb->t[0][0] = ux;
284 pb->t[0][1] = uy;
285 pb->t[0][2] = uz;
286 }
287 if ( MG_SIN(pb->p[2]->tag) ) {
288 pb->t[2][0] = ux;
289 pb->t[2][1] = uy;
290 pb->t[2][2] = uz;
291 }
292
293 ps = pb->t[0][0]* pb->t[2][0] + pb->t[0][1]* pb->t[2][1] + pb->t[0][2]* pb->t[2][2];
294 if ( ps > 0.0 ) {
295 to[0] = pb->t[0][0]*w + pb->t[2][0]*v;
296 to[1] = pb->t[0][1]*w + pb->t[2][1]*v;
297 to[2] = pb->t[0][2]*w + pb->t[2][2]*v;
298 }
299 else {
300 to[0] = -pb->t[0][0]*w + pb->t[2][0]*v;
301 to[1] = -pb->t[0][1]*w + pb->t[2][1]*v;
302 to[2] = -pb->t[0][2]*w + pb->t[2][2]*v;
303 }
304 }
305
306 if ( v < MMG5_EPSD2 ) {
307 ux = pb->b[1][0] - pb->b[0][0];
308 uy = pb->b[1][1] - pb->b[0][1];
309 uz = pb->b[1][2] - pb->b[0][2];
310 dd = ux*ux + uy*uy + uz*uz;
311 if ( dd > MMG5_EPSD2 ) {
312 dd = 1.0 / sqrt(dd);
313 ux *= dd;
314 uy *= dd;
315 uz *= dd;
316 }
317
318 /* corners */
319 if ( MG_SIN(pb->p[0]->tag) ) {
320 pb->t[0][0] = ux;
321 pb->t[0][1] = uy;
322 pb->t[0][2] = uz;
323 }
324 if ( MG_SIN(pb->p[1]->tag) ) {
325 pb->t[1][0] = ux;
326 pb->t[1][1] = uy;
327 pb->t[1][2] = uz;
328 }
329
330 ps = pb->t[0][0]* pb->t[1][0] + pb->t[0][1]* pb->t[1][1] + pb->t[0][2]* pb->t[1][2];
331 if ( ps > 0.0 ) {
332 to[0] = pb->t[0][0]*w + pb->t[1][0]*u;
333 to[1] = pb->t[0][1]*w + pb->t[1][1]*u;
334 to[2] = pb->t[0][2]*w + pb->t[1][2]*u;
335 }
336 else {
337 to[0] = -pb->t[0][0]*w + pb->t[1][0]*u;
338 to[1] = -pb->t[0][1]*w + pb->t[1][1]*u;
339 to[2] = -pb->t[0][2]*w + pb->t[1][2]*u;
340 }
341 }
342
343 dd = no[0]*no[0] + no[1]*no[1] + no[2]*no[2];
344 if ( dd > MMG5_EPSD2 ) {
345 dd = 1.0 / sqrt(dd);
346 no[0] *= dd;
347 no[1] *= dd;
348 no[2] *= dd;
349 }
350
351 dd = to[0]*to[0] + to[1]*to[1] + to[2]*to[2];
352 if ( dd > MMG5_EPSD2 ) {
353 dd = 1.0 / sqrt(dd);
354 to[0] *= dd;
355 to[1] *= dd;
356 to[2] *= dd;
357 }
358
359 return 1;
360}
MMG5_pMesh * mesh
int MMG5_mmgsBezierCP(MMG5_pMesh mesh, MMG5_Tria *pt, MMG5_pBezier pb, int8_t ori)
Definition: bezier_s.c:54
int8_t ddb
Definition: mmg3d1_delone.c:42
int MMGS_bezierInt(MMG5_pBezier pb, double uv[2], double o[3], double no[3], double to[3])
Definition: bezier_s.c:207
#define MS_SIN(tag)
#define MG_EDG(tag)
static const uint8_t MMG5_iprv2[3]
#define MG_SIN(tag)
static const uint8_t MMG5_inxt2[6]
int MMG5_nortri(MMG5_pMesh mesh, MMG5_pTria pt, double *n)
Definition: tools.c:209
#define MMG5_EPSD2
double b[10][3]
MMG5_pPoint p[3]
double n[6][3]
double t[6][3]
MMG mesh structure.
Definition: libmmgtypes.h:605
MMG5_pPoint point
Definition: libmmgtypes.h:641
MMG5_pxPoint xpoint
Definition: libmmgtypes.h:642
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 xp
Definition: libmmgtypes.h:279
int16_t tag[3]
Definition: libmmgtypes.h:342
MMG5_int v[3]
Definition: libmmgtypes.h:334
double n2[3]
Definition: libmmgtypes.h:295
double n1[3]
Definition: libmmgtypes.h:295