11 |
|
#include "sm_flag.h" |
12 |
|
#include "sm_list.h" |
13 |
|
#include "sm_geom.h" |
14 |
– |
#include "sm_qtree.h" |
15 |
– |
#include "sm_stree.h" |
14 |
|
#include "sm.h" |
15 |
|
|
16 |
|
|
17 |
+ |
|
18 |
|
SM *smMesh = NULL; |
19 |
|
double smDist_sum=0; |
21 |
– |
int smNew_tri_cnt=0; |
22 |
– |
double smMinSampDiff = 4.25e-4; /* min edge length in radians */ |
20 |
|
|
21 |
< |
/* Each edge extends .5536 radians - 31.72 degrees */ |
21 |
> |
#ifdef DEBUG |
22 |
> |
int Tcnt=0,Wcnt=0; |
23 |
> |
#endif |
24 |
> |
/* Each edge extends .372 radians */ |
25 |
|
static FVECT icosa_verts[162] = |
26 |
|
{{-0.018096,0.495400,0.868477},{0.018614,-0.554780,0.831789}, |
27 |
|
{0.850436,0.011329,0.525956},{0.850116,0.048016,-0.524402}, |
128 |
|
{34,112,114},{112,33,113},{114,113,1},{112,113,114},{32,111,107},{111,33,112}, |
129 |
|
{107,112,34},{111,112,107},{9,109,116},{109,32,115},{116,115,36},{109,115,116}, |
130 |
|
{32,106,118},{106,8,117},{118,117,35},{106,117,118},{36,119,121},{119,35,120}, |
131 |
< |
{121,120,11},{119,120,121},{32,118,115},{118,35,119},{115,119,36},{118,119,115}, |
132 |
< |
{10,122,124},{122,37,123},{124,123,39},{122,123,124},{37,125,127},{125,11,126}, |
133 |
< |
{127,126,38},{125,126,127},{39,128,130},{128,38,129},{130,129,3},{128,129,130}, |
131 |
> |
{121,120,11},{119,120,121},{32,118,115},{118,35,119},{115,119,36}, |
132 |
> |
{118,119,115},{10,122,124},{122,37,123},{124,123,39},{122,123,124}, |
133 |
> |
{37,125,127},{125,11,126},{127,126,38},{125,126,127},{39,128,130}, |
134 |
> |
{128,38,129},{130,129,3},{128,129,130}, |
135 |
|
{37,127,123},{127,38,128},{123,128,39},{127,128,123},{11,125,132},{125,37,131}, |
136 |
< |
{132,131,41},{125,131,132},{37,122,134},{122,10,133},{134,133,40},{122,133,134}, |
137 |
< |
{41,135,137},{135,40,136},{137,136,5},{135,136,137},{37,134,131},{134,40,135}, |
136 |
> |
{132,131,41},{125,131,132},{37,122,134},{122,10,133},{134,133,40}, |
137 |
> |
{122,133,134},{41,135,137},{135,40,136},{137,136,5},{135,136,137}, |
138 |
> |
{37,134,131},{134,40,135}, |
139 |
|
{131,135,41},{134,135,131},{6,65,94},{65,18,138},{94,138,28},{65,138,94}, |
140 |
< |
{18,62,139},{62,2,49},{139,49,13},{62,49,139},{28,140,97},{140,13,46},{97,46,0}, |
141 |
< |
{140,46,97},{18,139,138},{139,13,140},{138,140,28},{139,140,138},{1,44,114}, |
140 |
> |
{18,62,139},{62,2,49},{139,49,13},{62,49,139},{28,140,97},{140,13,46}, |
141 |
> |
{97,46,0},{140,46,97},{18,139,138},{139,13,140},{138,140,28},{139,140,138}, |
142 |
> |
{1,44,114}, |
143 |
|
{44,14,141},{114,141,34},{44,141,114},{14,50,142},{50,2,68},{142,68,21}, |
144 |
|
{50,68,142},{34,143,108},{143,21,73},{108,73,8},{143,73,108},{14,142,141}, |
145 |
|
{142,21,143},{141,143,34},{142,143,141},{0,52,98},{52,16,144},{98,144,29}, |
155 |
|
{155,38,126},{120,126,11},{155,126,120},{20,154,153},{154,38,155},{153,155,35}, |
156 |
|
{154,155,153},{7,81,101},{81,23,156},{101,156,30},{81,156,101},{23,78,157}, |
157 |
|
{78,5,136},{157,136,40},{78,136,157},{30,158,104},{158,40,133},{104,133,10}, |
158 |
< |
{158,133,104},{23,157,156},{157,40,158},{156,158,30},{157,158,156},{11,132,121}, |
158 |
> |
{158,133,104},{23,157,156},{157,40,158},{156,158,30},{157,158,156},{ |
159 |
> |
11,132,121}, |
160 |
|
{132,41,159},{121,159,36},{132,159,121},{41,137,160},{137,5,84},{160,84,26}, |
161 |
|
{137,84,160},{36,161,116},{161,26,89},{116,89,9},{161,89,116},{41,160,159}, |
162 |
|
{160,26,161},{159,161,36},{160,161,159}}; |
196 |
|
{182,180,181},{187,308,190},{294,187,189},{293,309,187},{186,184,185}, |
197 |
|
{191,177,180},{185,191,182},{184,178,191},{190,188,189},{195,101,42}, |
198 |
|
{204,195,41},{206,102,195},{194,192,193},{199,204,38},{10,199,37},{9,205,199}, |
199 |
< |
{198,196,197},{203,105,206},{6,203,205},{5,106,203},{202,200,201},{207,193,196}, |
200 |
< |
{201,207,198},{200,194,207},{206,204,205},{211,138,0},{220,211,2},{222,136,211}, |
201 |
< |
{210,208,209},{215,220,8},{48,215,10},{50,221,215},{214,212,213},{219,130,222}, |
199 |
> |
{198,196,197},{203,105,206},{6,203,205},{5,106,203},{202,200,201}, |
200 |
> |
{207,193,196},{201,207,198},{200,194,207},{206,204,205},{211,138,0}, |
201 |
> |
{220,211,2}, {222,136,211},{210,208,209},{215,220,8},{48,215,10},{50,221,215}, |
202 |
> |
{214,212,213},{219,130,222}, |
203 |
|
{56,219,221},{58,128,219},{218,216,217},{223,209,212},{217,223,214}, |
204 |
|
{216,210,223},{222,220,221},{227,106,16},{236,227,18},{238,104,227}, |
205 |
< |
{226,224,225},{231,236,24},{64,231,26},{66,237,231},{230,228,229},{235,98,238}, |
205 |
> |
{226,224,225},{231,236,24},{64,231,26},{66,237,231},{230,228,229}, |
206 |
> |
{235,98,238}, |
207 |
|
{72,235,237},{74,96,235},{234,232,233},{239,225,228},{233,239,230}, |
208 |
|
{232,226,239},{238,236,237},{243,133,90},{252,243,89},{254,134,243}, |
209 |
< |
{242,240,241},{247,252,86},{26,247,85},{25,253,247},{246,244,245},{251,137,254}, |
209 |
> |
{242,240,241},{247,252,86},{26,247,85},{25,253,247},{246,244,245}, |
210 |
> |
{251,137,254}, |
211 |
|
{22,251,253},{21,138,251},{250,248,249},{255,241,244},{249,255,246}, |
212 |
|
{248,242,255},{254,252,253},{259,122,160},{268,259,162},{270,120,259}, |
213 |
|
{258,256,257},{263,268,168},{32,263,170},{34,269,263},{262,260,261}, |
237 |
|
double dev_zmin=.01,dev_zmax=1000; |
238 |
|
#endif |
239 |
|
|
240 |
< |
smDir(sm,ps,id) |
241 |
< |
SM *sm; |
242 |
< |
FVECT ps; |
243 |
< |
int id; |
240 |
> |
|
241 |
> |
char * |
242 |
> |
tempbuf(len,resize) /* get a temporary buffer */ |
243 |
> |
unsigned len; |
244 |
> |
int resize; |
245 |
|
{ |
246 |
< |
VSUB(ps,SM_NTH_WV(sm,id),SM_VIEW_CENTER(sm)); |
247 |
< |
normalize(ps); |
246 |
> |
extern char *malloc(), *realloc(); |
247 |
> |
static char *tempbuf = NULL; |
248 |
> |
static unsigned tempbuflen = 0; |
249 |
> |
|
250 |
> |
#ifdef DEBUG |
251 |
> |
static int in_use=FALSE; |
252 |
> |
|
253 |
> |
if(len == -1) |
254 |
> |
{ |
255 |
> |
in_use = FALSE; |
256 |
> |
return(NULL); |
257 |
> |
} |
258 |
> |
if(!resize && in_use) |
259 |
> |
{ |
260 |
> |
eputs("Buffer in use:cannot allocate:tempbuf()\n"); |
261 |
> |
return(NULL); |
262 |
> |
} |
263 |
> |
#endif |
264 |
> |
if (len > tempbuflen) { |
265 |
> |
if (tempbuflen > 0) |
266 |
> |
tempbuf = realloc(tempbuf, len); |
267 |
> |
else |
268 |
> |
tempbuf = malloc(len); |
269 |
> |
tempbuflen = tempbuf==NULL ? 0 : len; |
270 |
> |
} |
271 |
> |
#ifdef DEBUG |
272 |
> |
in_use = TRUE; |
273 |
> |
#endif |
274 |
> |
return(tempbuf); |
275 |
|
} |
276 |
|
|
277 |
< |
smDir_in_cone(sm,ps,id) |
277 |
> |
smDir(sm,ps,id) |
278 |
|
SM *sm; |
279 |
|
FVECT ps; |
280 |
|
int id; |
281 |
|
{ |
247 |
– |
|
282 |
|
VSUB(ps,SM_NTH_WV(sm,id),SM_VIEW_CENTER(sm)); |
283 |
|
normalize(ps); |
284 |
|
} |
302 |
|
{ |
303 |
|
/* Reset the triangle counters */ |
304 |
|
SM_NUM_TRI(sm) = 0; |
271 |
– |
SM_SAMPLE_TRIS(sm) = 0; |
305 |
|
SM_FREE_TRIS(sm) = -1; |
273 |
– |
SM_AVAILABLE_TRIS(sm) = -1; |
306 |
|
smClear_flags(sm,-1); |
307 |
|
} |
308 |
|
|
313 |
|
smClear(sm) |
314 |
|
SM *sm; |
315 |
|
{ |
316 |
< |
smClear_samples(sm); |
317 |
< |
smClear_locator(sm); |
316 |
> |
smDist_sum = 0; |
317 |
> |
smInit_samples(sm); |
318 |
> |
smInit_locator(sm); |
319 |
|
smInit_mesh(sm); |
320 |
|
} |
321 |
|
|
289 |
– |
static int realloc_cnt=0; |
290 |
– |
|
291 |
– |
int |
292 |
– |
smRealloc_mesh(sm) |
293 |
– |
SM *sm; |
294 |
– |
{ |
295 |
– |
int fbytes,i,max_tris,max_verts; |
296 |
– |
|
297 |
– |
if(realloc_cnt <=0) |
298 |
– |
realloc_cnt = SM_MAX_TRIS(sm); |
299 |
– |
|
300 |
– |
max_tris = SM_MAX_TRIS(sm) + realloc_cnt; |
301 |
– |
fbytes = FLAG_BYTES(max_tris); |
302 |
– |
|
303 |
– |
if(!(SM_TRIS(sm) = (TRI *)realloc(SM_TRIS(sm),max_tris*sizeof(TRI)))) |
304 |
– |
goto memerr; |
305 |
– |
|
306 |
– |
for(i=0; i< T_FLAGS; i++) |
307 |
– |
if(!(SM_NTH_FLAGS(sm,i)=(int4 *)realloc((char *)SM_NTH_FLAGS(sm,i),fbytes))) |
308 |
– |
goto memerr; |
309 |
– |
|
310 |
– |
SM_MAX_TRIS(sm) = max_tris; |
311 |
– |
return(max_tris); |
312 |
– |
|
313 |
– |
memerr: |
314 |
– |
error(SYSTEM, "out of memory in smRealloc_mesh()"); |
315 |
– |
} |
316 |
– |
|
322 |
|
/* Allocate and initialize a new mesh with max_verts and max_tris */ |
323 |
|
int |
324 |
|
smAlloc_mesh(sm,max_verts,max_tris) |
329 |
|
|
330 |
|
fbytes = FLAG_BYTES(max_tris); |
331 |
|
|
332 |
< |
if(!(SM_TRIS(sm) = (TRI *)realloc(NULL,max_tris*sizeof(TRI)))) |
332 |
> |
if(!(SM_TRIS(sm) = (TRI *)malloc(max_tris*sizeof(TRI)))) |
333 |
|
goto memerr; |
334 |
|
|
330 |
– |
if(!(SM_VERTS(sm) = (VERT *)realloc(NULL,max_verts*sizeof(VERT)))) |
331 |
– |
goto memerr; |
332 |
– |
|
335 |
|
for(i=0; i< T_FLAGS; i++) |
336 |
< |
if(!(SM_NTH_FLAGS(sm,i)=(int4 *)realloc(NULL,fbytes))) |
336 |
> |
if(!(SM_NTH_FLAGS(sm,i)=(int4 *)malloc(fbytes))) |
337 |
|
goto memerr; |
338 |
|
|
339 |
|
SM_MAX_VERTS(sm) = max_verts; |
340 |
|
SM_MAX_TRIS(sm) = max_tris; |
341 |
|
|
340 |
– |
realloc_cnt = max_verts >> 1; |
341 |
– |
|
342 |
|
smInit_mesh(sm); |
343 |
|
|
344 |
|
return(max_tris); |
347 |
|
} |
348 |
|
|
349 |
|
|
350 |
– |
int |
351 |
– |
compress_set(os) |
352 |
– |
OBJECT *os; |
353 |
– |
{ |
354 |
– |
int i,j; |
355 |
– |
|
356 |
– |
for (i = 1, j = os[0]; i <= j; i++) |
357 |
– |
{ |
358 |
– |
if(SM_T_ID_VALID(smMesh,os[i])) |
359 |
– |
continue; |
360 |
– |
if(i==j) |
361 |
– |
break; |
362 |
– |
while(!SM_T_ID_VALID(smMesh,os[j]) && (i < j)) |
363 |
– |
j--; |
364 |
– |
if(i==j) |
365 |
– |
break; |
366 |
– |
os[i] = os[j--]; |
367 |
– |
} |
368 |
– |
i--; |
369 |
– |
|
370 |
– |
os[0] = i; |
371 |
– |
return(i); |
372 |
– |
|
373 |
– |
} |
374 |
– |
|
350 |
|
int |
351 |
|
smAlloc_tri(sm) |
352 |
|
SM *sm; |
357 |
|
/* Otherwise, have we reached the end of the list yet?*/ |
358 |
|
if(SM_NUM_TRI(sm) < SM_MAX_TRIS(sm)) |
359 |
|
return(SM_NUM_TRI(sm)++); |
385 |
– |
if((id = SM_AVAILABLE_TRIS(sm)) != -1) |
386 |
– |
{ |
387 |
– |
SM_AVAILABLE_TRIS(sm) = T_NEXT_AVAILABLE(SM_NTH_TRI(sm,id)); |
388 |
– |
return(id); |
389 |
– |
} |
360 |
|
if((id = SM_FREE_TRIS(sm)) != -1) |
361 |
|
{ |
362 |
< |
dosets(compress_set); |
393 |
< |
SM_AVAILABLE_TRIS(sm) = T_NEXT_FREE(SM_NTH_TRI(sm,id)); |
394 |
< |
SM_FREE_TRIS(sm) = -1; |
362 |
> |
SM_FREE_TRIS(sm) = T_NEXT_FREE(SM_NTH_TRI(sm,id)); |
363 |
|
return(id); |
364 |
|
} |
365 |
< |
/*Else: realloc */ |
366 |
< |
smRealloc_mesh(sm); |
367 |
< |
return(SM_NUM_TRI(sm)++); |
365 |
> |
|
366 |
> |
error(CONSISTENCY,"smAlloc_tri: no more available triangles\n"); |
367 |
> |
return(INVALID); |
368 |
|
} |
369 |
|
|
370 |
|
smFree_mesh(sm) |
374 |
|
|
375 |
|
if(SM_TRIS(sm)) |
376 |
|
free(SM_TRIS(sm)); |
409 |
– |
if(SM_VERTS(sm)) |
410 |
– |
free(SM_VERTS(sm)); |
377 |
|
for(i=0; i< T_FLAGS; i++) |
378 |
|
if(SM_NTH_FLAGS(sm,i)) |
379 |
|
free(SM_NTH_FLAGS(sm,i)); |
407 |
|
/* First allocate at least n samples + extra points:at least enough |
408 |
|
necessary to form the BASE MESH- Default = 4; |
409 |
|
*/ |
410 |
< |
SM_SAMP(smMesh) = sAlloc(&n,SM_EXTRA_POINTS); |
410 |
> |
SM_SAMP(smMesh) = sAlloc(&n,SM_BASE_POINTS); |
411 |
|
|
412 |
< |
total_points = n + SM_EXTRA_POINTS; |
412 |
> |
total_points = n + SM_BASE_POINTS; |
413 |
|
|
414 |
< |
max_tris = total_points*4; |
414 |
> |
/* Need enough tris for base mesh, + 2 for each sample, plus extra |
415 |
> |
since triangles are not deleted until added and edge flips (max 4) |
416 |
> |
*/ |
417 |
> |
max_tris = n*2 + SM_BASE_TRIS + 10; |
418 |
|
/* Now allocate space for mesh vertices and triangles */ |
419 |
|
max_tris = smAlloc_mesh(smMesh, total_points, max_tris); |
420 |
|
|
430 |
|
FVECT vp; |
431 |
|
{ |
432 |
|
|
464 |
– |
smDist_sum = 0; |
465 |
– |
smNew_tri_cnt = 0; |
466 |
– |
|
433 |
|
VCOPY(SM_VIEW_CENTER(sm),vp); |
434 |
< |
smInit_locator(sm,vp); |
469 |
< |
smInit_samples(sm); |
470 |
< |
smInit_mesh(sm); |
434 |
> |
smClear(sm); |
435 |
|
smCreate_base_mesh(sm,SM_DEFAULT); |
436 |
|
} |
437 |
|
|
452 |
|
{ |
453 |
|
int max_vertices; |
454 |
|
|
491 |
– |
|
455 |
|
/* If n <=0, Just clear the existing structures */ |
456 |
|
if(n <= 0) |
457 |
|
{ |
458 |
+ |
#ifdef DEBUG |
459 |
+ |
fprintf(stderr,"Tcnt=%d Wcnt = %d, avg = %f\n",Tcnt,Wcnt,(float)Wcnt/Tcnt); |
460 |
+ |
#endif |
461 |
|
smClear(smMesh); |
462 |
|
return(0); |
463 |
|
} |
465 |
|
/* Total mesh vertices includes the sample points and the extra vertices |
466 |
|
to form the base mesh |
467 |
|
*/ |
468 |
< |
max_vertices = n + SM_EXTRA_POINTS; |
468 |
> |
max_vertices = n + SM_BASE_POINTS; |
469 |
|
|
470 |
|
/* If the current mesh contains enough room, clear and return */ |
471 |
|
if(smMesh && (max_vertices <= SM_MAX_VERTS(smMesh)) && SM_MAX_SAMP(smMesh) <= |
479 |
|
*/ |
480 |
|
smAlloc(n); |
481 |
|
|
482 |
+ |
#ifdef DEBUG |
483 |
+ |
fprintf(stderr,"smInit: allocating room for %d samples\n", |
484 |
+ |
SM_MAX_SAMP(smMesh)); |
485 |
+ |
#endif |
486 |
|
return(SM_MAX_SAMP(smMesh)); |
487 |
|
} |
488 |
|
|
489 |
|
|
490 |
< |
smLocator_apply(sm,v0,v1,v2,func) |
490 |
> |
smLocator_apply(sm,v0,v1,v2,func,n) |
491 |
|
SM *sm; |
492 |
|
FVECT v0,v1,v2; |
493 |
|
FUNC func; |
494 |
+ |
int n; |
495 |
|
{ |
496 |
|
STREE *st; |
497 |
|
FVECT tri[3]; |
501 |
|
VSUB(tri[0],v0,SM_VIEW_CENTER(sm)); |
502 |
|
VSUB(tri[1],v1,SM_VIEW_CENTER(sm)); |
503 |
|
VSUB(tri[2],v2,SM_VIEW_CENTER(sm)); |
504 |
< |
stVisit(st,tri,func); |
504 |
> |
stVisit(st,tri,func,n); |
505 |
|
|
506 |
|
} |
507 |
|
|
537 |
– |
|
538 |
– |
/* NEW INSERTION!!! ******************************************************/ |
508 |
|
QUADTREE |
509 |
< |
insert_tri(argptr,root,qt,q0,q1,q2,t0,t1,t2,dt10,dt21,dt02,scale, |
541 |
< |
s0,s1,s2,sq0,sq1,sq2,rev,f,n) |
509 |
> |
insert_samp(argptr,root,qt,parent,q0,q1,q2,bc,scale,rev,f,n,doneptr) |
510 |
|
int *argptr; |
511 |
|
int root; |
512 |
< |
QUADTREE qt; |
513 |
< |
BCOORD q0[3],q1[3],q2[3]; |
514 |
< |
BCOORD t0[3],t1[3],t2[3]; |
547 |
< |
BCOORD dt10[3],dt21[3],dt02[3]; |
548 |
< |
unsigned int scale,s0,s1,s2,sq0,sq1,sq2,rev; |
512 |
> |
QUADTREE qt,parent; |
513 |
> |
BCOORD q0[3],q1[3],q2[3],bc[3]; |
514 |
> |
unsigned int scale,rev; |
515 |
|
FUNC f; |
516 |
< |
int n; |
516 |
> |
int n,*doneptr; |
517 |
|
{ |
518 |
< |
OBJECT *optr,*tptr,t_set[QT_MAXSET+1]; |
519 |
< |
int i,t_id; |
520 |
< |
TRI *t; |
521 |
< |
FVECT tri[3]; |
522 |
< |
BCOORD b0[3],b1[3],b2[3]; |
523 |
< |
BCOORD tb0[3],tb1[3],tb2[3]; |
558 |
< |
BCOORD db10[3],db21[3],db02[3]; |
559 |
< |
BCOORD a,b,c,qa,qb,qc; |
560 |
< |
FUNC tfunc; |
518 |
> |
OBJECT *optr,*sptr,s_set[QT_MAXSET+1]; |
519 |
> |
int i,s_id; |
520 |
> |
FVECT p; |
521 |
> |
BCOORD bp[3]; |
522 |
> |
FUNC sfunc; |
523 |
> |
S_ARGS args; |
524 |
|
|
525 |
< |
t_id = *argptr; |
563 |
< |
|
525 |
> |
s_id = ((S_ARGS *)argptr)->s_id; |
526 |
|
/* If the set is empty - just add */ |
527 |
|
if(QT_IS_EMPTY(qt)) |
528 |
< |
return(qtadduelem(qt,t_id)); |
529 |
< |
|
528 |
> |
{ |
529 |
> |
qt = qtadduelem(qt,s_id); |
530 |
> |
SM_S_NTH_QT(smMesh,s_id) = qt; |
531 |
> |
if(((S_ARGS *)argptr)->n_id) |
532 |
> |
*doneptr = FALSE; |
533 |
> |
else |
534 |
> |
*doneptr = TRUE; |
535 |
> |
return(qt); |
536 |
> |
} |
537 |
|
/* If the set size is below expansion threshold,or at maximum |
538 |
|
number of quadtree levels : just add */ |
539 |
|
optr = qtqueryset(qt); |
540 |
|
if(QT_SET_CNT(optr) < QT_SET_THRESHOLD || (n > (QT_MAX_LEVELS-2))) |
541 |
< |
return(qtadduelem(qt,t_id)); |
542 |
< |
/* otherwise: expand node- and insert tri, and reinsert existing tris |
541 |
> |
{ |
542 |
> |
qt = qtadduelem(qt,s_id); |
543 |
> |
|
544 |
> |
SM_S_NTH_QT(smMesh,s_id) = qt; |
545 |
> |
if(((S_ARGS *)argptr)->n_id) |
546 |
> |
if(QT_SET_CNT(qtqueryset(qt)) > 1) |
547 |
> |
{ |
548 |
> |
((S_ARGS *)argptr)->n_id = qtqueryset(qt)[1]; |
549 |
> |
*doneptr = TRUE; |
550 |
> |
} |
551 |
> |
else |
552 |
> |
*doneptr = FALSE; |
553 |
> |
else |
554 |
> |
*doneptr = TRUE; |
555 |
> |
return(qt); |
556 |
> |
} |
557 |
> |
/* otherwise: expand node- and insert sample, and reinsert existing samples |
558 |
|
in set to children of new node |
559 |
|
*/ |
560 |
< |
/* First tri compressing set */ |
561 |
< |
#ifdef NEWSETS0 |
562 |
< |
if(qtcompressuelem(qt,compress_set) < QT_SET_THRESHOLD) |
563 |
< |
/* Get set: If greater than standard size: allocate memory to hold */ |
564 |
< |
return(qtadduelem(qt,t_id)); |
565 |
< |
#endif |
566 |
< |
if(QT_SET_CNT(optr) > QT_MAXSET) |
567 |
< |
{ |
584 |
< |
if(!(tptr = (OBJECT *)malloc((QT_SET_CNT(optr)+1)*sizeof(OBJECT)))) |
585 |
< |
goto memerr; |
586 |
< |
} |
587 |
< |
else |
588 |
< |
tptr = t_set; |
589 |
< |
qtgetset(tptr,qt); |
560 |
> |
if(QT_SET_CNT(optr) > QT_MAXSET) |
561 |
> |
{ |
562 |
> |
if(!(sptr = (OBJECT *)malloc((QT_SET_CNT(optr)+1)*sizeof(OBJECT)))) |
563 |
> |
goto memerr; |
564 |
> |
} |
565 |
> |
else |
566 |
> |
sptr = s_set; |
567 |
> |
qtgetset(sptr,qt); |
568 |
|
|
569 |
|
/* subdivide node */ |
570 |
|
qtfreeleaf(qt); |
571 |
|
qtSubdivide(qt); |
572 |
|
|
595 |
– |
a = q1[0]; b = q0[1]; c = q0[2]; |
596 |
– |
qa = q0[0]; qb = q1[1]; qc = q2[2]; |
597 |
– |
/* First add current tri: have all of the information */ |
598 |
– |
if(rev) |
599 |
– |
qt = qtInsert_tri_rev(root,qt,q0,q1,q2,t0,t1,t2,dt10,dt21,dt02,scale, |
600 |
– |
s0,s1,s2,sq0,sq1,sq2,f,n); |
601 |
– |
else |
602 |
– |
qt = qtInsert_tri(root,qt,q0,q1,q2,t0,t1,t2,dt10,dt21,dt02,scale, |
603 |
– |
s0,s1,s2,sq0,sq1,sq2,f,n); |
604 |
– |
|
573 |
|
/* Now add in all of the rest; */ |
574 |
< |
F_FUNC(tfunc) = F_FUNC(f); |
575 |
< |
for(optr = QT_SET_PTR(tptr),i=QT_SET_CNT(tptr); i > 0; i--) |
574 |
> |
F_FUNC(sfunc) = F_FUNC(f); |
575 |
> |
F_ARGS(sfunc) = (int *) (&args); |
576 |
> |
args.n_id = 0; |
577 |
> |
for(optr = sptr,i=QT_SET_CNT(sptr); i > 0; i--) |
578 |
|
{ |
579 |
< |
t_id = QT_SET_NEXT_ELEM(optr); |
580 |
< |
t = SM_NTH_TRI(smMesh,t_id); |
581 |
< |
if(!T_IS_VALID(t)) |
582 |
< |
continue; |
583 |
< |
F_ARGS(tfunc) = &t_id; |
614 |
< |
VSUB(tri[0],SM_T_NTH_WV(smMesh,t,0),SM_VIEW_CENTER(smMesh)); |
615 |
< |
VSUB(tri[1],SM_T_NTH_WV(smMesh,t,1),SM_VIEW_CENTER(smMesh)); |
616 |
< |
VSUB(tri[2],SM_T_NTH_WV(smMesh,t,2),SM_VIEW_CENTER(smMesh)); |
617 |
< |
convert_tri_to_frame(root,tri,b0,b1,b2,db10,db21,db02); |
618 |
< |
|
619 |
< |
/* Calculate appropriate sidedness values */ |
620 |
< |
SIDES_GTR(b0,b1,b2,s0,s1,s2,a,b,c); |
621 |
< |
SIDES_GTR(b0,b1,b2,sq0,sq1,sq2,qa,qb,qc); |
579 |
> |
s_id = QT_SET_NEXT_ELEM(optr); |
580 |
> |
args.s_id = s_id; |
581 |
> |
VSUB(p,SM_NTH_WV(smMesh,s_id),SM_VIEW_CENTER(smMesh)); |
582 |
> |
normalize(p); |
583 |
> |
vert_to_qt_frame(i,p,bp); |
584 |
|
if(rev) |
585 |
< |
qt = qtInsert_tri_rev(root,qt,q0,q1,q2,b0,b1,b2,db10,db21,db02,scale, |
624 |
< |
s0,s1,s2,sq0,sq1,sq2,tfunc,n); |
585 |
> |
qt= qtInsert_point_rev(root,qt,parent,q0,q1,q2,bp,scale,sfunc,n,doneptr); |
586 |
|
else |
587 |
< |
qt = qtInsert_tri(root,qt,q0,q1,q2,b0,b1,b2,db10,db21,db02,scale, |
627 |
< |
s0,s1,s2,sq0,sq1,sq2,tfunc,n); |
587 |
> |
qt= qtInsert_point(root,qt,parent,q0,q1,q2,bp,scale,sfunc,n,doneptr); |
588 |
|
} |
589 |
+ |
/* Add current sample: have all of the information */ |
590 |
+ |
if(rev) |
591 |
+ |
qt =qtInsert_point_rev(root,qt,parent,q0,q1,q2,bc,scale,f,n,doneptr); |
592 |
+ |
else |
593 |
+ |
qt = qtInsert_point(root,qt,parent,q0,q1,q2,bc,scale,f,n,doneptr); |
594 |
+ |
|
595 |
|
/* If we allocated memory: free it */ |
630 |
– |
if( tptr != t_set) |
631 |
– |
free(tptr); |
596 |
|
|
597 |
+ |
if( sptr != s_set) |
598 |
+ |
free(sptr); |
599 |
+ |
|
600 |
|
return(qt); |
601 |
|
memerr: |
602 |
|
error(SYSTEM,"expand_node():Unable to allocate memory"); |
604 |
|
} |
605 |
|
|
606 |
|
|
607 |
< |
|
608 |
< |
smLocator_add_tri(sm,t_id,v0_id,v1_id,v2_id) |
609 |
< |
SM *sm; |
610 |
< |
int t_id; |
644 |
< |
int v0_id,v1_id,v2_id; |
607 |
> |
double |
608 |
> |
triangle_normal(n,a,b,c) |
609 |
> |
double n[3]; |
610 |
> |
double a[3],b[3],c[3]; |
611 |
|
{ |
612 |
< |
FVECT tri[3]; |
647 |
< |
FUNC f; |
612 |
> |
double ab[3],ac[3]; |
613 |
|
|
614 |
< |
#ifdef DEBUG |
615 |
< |
if(T_NTH_NBR(SM_NTH_TRI(sm,t_id),0)== -1 || |
616 |
< |
T_NTH_NBR(SM_NTH_TRI(sm,t_id),1)== -1 || |
617 |
< |
T_NTH_NBR(SM_NTH_TRI(sm,t_id),2)== -1) |
618 |
< |
error("Invalid tri: smLocator_add_tri()\n"); |
619 |
< |
|
655 |
< |
if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(SM_NTH_TRI(sm,t_id),0))) || |
656 |
< |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(SM_NTH_TRI(sm,t_id),1))) || |
657 |
< |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(SM_NTH_TRI(sm,t_id),2)))) |
658 |
< |
error("Invalid tri: smLocator_add_tri()\n"); |
659 |
< |
#endif |
660 |
< |
|
661 |
< |
VSUB(tri[0],SM_NTH_WV(sm,v0_id),SM_VIEW_CENTER(sm)); |
662 |
< |
VSUB(tri[1],SM_NTH_WV(sm,v1_id),SM_VIEW_CENTER(sm)); |
663 |
< |
VSUB(tri[2],SM_NTH_WV(sm,v2_id),SM_VIEW_CENTER(sm)); |
664 |
< |
|
665 |
< |
F_FUNC(f) = insert_tri; |
666 |
< |
F_ARGS(f) = &t_id; |
667 |
< |
stInsert_tri(SM_LOCATOR(sm),tri,f); |
614 |
> |
VSUB(ab,b,a); |
615 |
> |
normalize(ab); |
616 |
> |
VSUB(ac,c,a); |
617 |
> |
normalize(ac); |
618 |
> |
VCROSS(n,ab,ac); |
619 |
> |
return(normalize(n)); |
620 |
|
} |
621 |
< |
|
621 |
> |
double on0,on1,on2; |
622 |
|
/* Add a triangle to the base array with vertices v1-v2-v3 */ |
623 |
|
int |
624 |
< |
smAdd_tri(sm, v0_id,v1_id,v2_id) |
624 |
> |
smAdd_tri(sm, v0_id,v1_id,v2_id,tptr) |
625 |
|
SM *sm; |
626 |
|
int v0_id,v1_id,v2_id; |
627 |
+ |
TRI **tptr; |
628 |
|
{ |
629 |
|
int t_id; |
630 |
|
TRI *t; |
631 |
|
#ifdef DEBUG |
632 |
|
if(v0_id==v1_id || v0_id==v2_id || v1_id==v2_id) |
633 |
|
error(CONSISTENCY,"smAdd_tri: invalid vertex ids\n"); |
681 |
– |
#endif |
682 |
– |
t_id = smAlloc_tri(sm); |
634 |
|
|
635 |
< |
if(t_id == -1) |
636 |
< |
return(t_id); |
635 |
> |
#endif |
636 |
> |
t_id = smAlloc_tri(sm); |
637 |
> |
#ifdef DEBUG |
638 |
> |
#if DEBUG > 1 |
639 |
> |
{ |
640 |
> |
double v0[3],v1[3],v2[3],n[3]; |
641 |
> |
double area,dp; |
642 |
|
|
643 |
+ |
VSUB(v0,SM_NTH_WV(sm,v0_id),SM_VIEW_CENTER(sm)); |
644 |
+ |
VSUB(v1,SM_NTH_WV(sm,v1_id),SM_VIEW_CENTER(sm)); |
645 |
+ |
VSUB(v2,SM_NTH_WV(sm,v2_id),SM_VIEW_CENTER(sm)); |
646 |
+ |
normalize(v0); |
647 |
+ |
normalize(v1); |
648 |
+ |
normalize(v2); |
649 |
+ |
area = triangle_normal(n,v2,v1,v0); |
650 |
+ |
if((dp=DOT(v0,n)) < 0.0) |
651 |
+ |
{ |
652 |
+ |
fprintf(stderr,"dp = %.10f on0=%.10f on1=%.10f on2=%.10f\n", dp, |
653 |
+ |
on0,on1,on2); |
654 |
+ |
eputs("backwards tri\n"); |
655 |
+ |
} |
656 |
+ |
} |
657 |
+ |
#endif |
658 |
+ |
#endif |
659 |
+ |
|
660 |
+ |
|
661 |
|
t = SM_NTH_TRI(sm,t_id); |
662 |
|
|
663 |
|
T_CLEAR_NBRS(t); |
671 |
|
SM_NTH_VERT(sm,v2_id) = t_id; |
672 |
|
|
673 |
|
if(SM_BASE_ID(sm,v0_id) || SM_BASE_ID(sm,v1_id) || SM_BASE_ID(sm,v2_id)) |
700 |
– |
{ |
701 |
– |
smClear_tri_flags(sm,t_id); |
674 |
|
SM_SET_NTH_T_BASE(sm,t_id); |
703 |
– |
} |
675 |
|
else |
705 |
– |
{ |
676 |
|
SM_CLR_NTH_T_BASE(sm,t_id); |
677 |
< |
SM_SET_NTH_T_ACTIVE(sm,t_id); |
678 |
< |
SM_SET_NTH_T_NEW(sm,t_id); |
679 |
< |
S_SET_FLAG(T_NTH_V(t,0)); |
680 |
< |
S_SET_FLAG(T_NTH_V(t,1)); |
681 |
< |
S_SET_FLAG(T_NTH_V(t,2)); |
682 |
< |
SM_SAMPLE_TRIS(sm)++; |
683 |
< |
smNew_tri_cnt++; |
714 |
< |
} |
677 |
> |
if(SM_DIR_ID(sm,v0_id) || SM_DIR_ID(sm,v1_id) || SM_DIR_ID(sm,v2_id)) |
678 |
> |
SM_SET_NTH_T_BG(sm,t_id); |
679 |
> |
else |
680 |
> |
SM_CLR_NTH_T_BG(sm,t_id); |
681 |
> |
S_SET_FLAG(T_NTH_V(t,0)); |
682 |
> |
S_SET_FLAG(T_NTH_V(t,1)); |
683 |
> |
S_SET_FLAG(T_NTH_V(t,2)); |
684 |
|
|
685 |
+ |
SM_SET_NTH_T_ACTIVE(sm,t_id); |
686 |
+ |
SM_SET_NTH_T_NEW(sm,t_id); |
687 |
+ |
|
688 |
+ |
|
689 |
+ |
*tptr = t; |
690 |
|
/* return initialized triangle */ |
691 |
|
return(t_id); |
692 |
|
} |
693 |
|
|
694 |
|
|
695 |
< |
void |
696 |
< |
smTris_swap_edge(sm,t_id,t1_id,e,e1,tn_id,tn1_id,add_ptr) |
697 |
< |
SM *sm; |
698 |
< |
int t_id,t1_id; |
699 |
< |
int e,e1; |
700 |
< |
int *tn_id,*tn1_id; |
727 |
< |
LIST **add_ptr; |
695 |
> |
/* pt_in_cone: assumed apex at origin, a,b,c are unit vectors defining the |
696 |
> |
triangle which the cone circumscribes. Assumed p is not normalized |
697 |
> |
*/ |
698 |
> |
int |
699 |
> |
pt_in_cone(p,a,b,c) |
700 |
> |
double p[3],a[3],b[3],c[3]; |
701 |
|
{ |
702 |
< |
int verts[3],enext,eprev,e1next,e1prev; |
703 |
< |
TRI *n,*ta,*tb,*t,*t1; |
704 |
< |
FVECT p1,p2,p3; |
705 |
< |
int ta_id,tb_id; |
706 |
< |
/* form new diagonal (e relative to t, and e1 relative to t1) |
734 |
< |
defined by quadrilateral formed by t,t1- swap for the opposite diagonal |
735 |
< |
*/ |
736 |
< |
enext = (e+1)%3; |
737 |
< |
eprev = (e+2)%3; |
738 |
< |
e1next = (e1+1)%3; |
739 |
< |
e1prev = (e1+2)%3; |
740 |
< |
verts[e] = T_NTH_V(SM_NTH_TRI(sm,t_id),e); |
741 |
< |
verts[enext] = T_NTH_V(SM_NTH_TRI(sm,t_id),enext); |
742 |
< |
verts[eprev] = T_NTH_V(SM_NTH_TRI(sm,t1_id),e1); |
743 |
< |
ta_id = smAdd_tri(sm,verts[0],verts[1],verts[2]); |
744 |
< |
*add_ptr = push_data(*add_ptr,ta_id); |
745 |
< |
verts[e1] = T_NTH_V(SM_NTH_TRI(sm,t1_id),e1); |
746 |
< |
verts[e1next] = T_NTH_V(SM_NTH_TRI(sm,t1_id),e1next); |
747 |
< |
verts[e1prev] = T_NTH_V(SM_NTH_TRI(sm,t_id),e); |
748 |
< |
tb_id = smAdd_tri(sm,verts[0],verts[1],verts[2]); |
702 |
> |
double r[3]; |
703 |
> |
double pr,ar; |
704 |
> |
double ab[3],ac[3]; |
705 |
> |
/* r = (B-A)X(C-A) */ |
706 |
> |
/* in = (p.r) > (a.r) */ |
707 |
|
|
750 |
– |
*add_ptr = push_data(*add_ptr,tb_id); |
751 |
– |
ta = SM_NTH_TRI(sm,ta_id); |
752 |
– |
tb = SM_NTH_TRI(sm,tb_id); |
753 |
– |
t = SM_NTH_TRI(sm,t_id); |
754 |
– |
t1 = SM_NTH_TRI(sm,t1_id); |
755 |
– |
/* set the neighbors */ |
756 |
– |
T_NTH_NBR(ta,e) = T_NTH_NBR(t1,e1next); |
757 |
– |
T_NTH_NBR(tb,e1) = T_NTH_NBR(t,enext); |
758 |
– |
T_NTH_NBR(ta,enext)= tb_id; |
759 |
– |
T_NTH_NBR(tb,e1next)= ta_id; |
760 |
– |
T_NTH_NBR(ta,eprev)=T_NTH_NBR(t,eprev); |
761 |
– |
T_NTH_NBR(tb,e1prev)=T_NTH_NBR(t1,e1prev); |
762 |
– |
|
763 |
– |
|
708 |
|
#ifdef DEBUG |
709 |
< |
if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(ta,0))) || |
710 |
< |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(ta,1))) || |
711 |
< |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(ta,2))) || |
712 |
< |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(tb,0))) || |
713 |
< |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(tb,1))) || |
714 |
< |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(tb,2)))) |
715 |
< |
goto Ltri_error; |
716 |
< |
/* |
717 |
< |
if(SM_NTH_TRI(sm,T_NTH_NBR(ta,0))==SM_NTH_TRI(sm,T_NTH_NBR(ta,1)) || |
718 |
< |
SM_NTH_TRI(sm,T_NTH_NBR(ta,0))==SM_NTH_TRI(sm,T_NTH_NBR(ta,2)) || |
719 |
< |
SM_NTH_TRI(sm,T_NTH_NBR(ta,1))==SM_NTH_TRI(sm,T_NTH_NBR(ta,2)) || |
776 |
< |
SM_NTH_TRI(sm,T_NTH_NBR(tb,0))==SM_NTH_TRI(sm,T_NTH_NBR(tb,1)) || |
777 |
< |
SM_NTH_TRI(sm,T_NTH_NBR(tb,0))==SM_NTH_TRI(sm,T_NTH_NBR(tb,2)) || |
778 |
< |
SM_NTH_TRI(sm,T_NTH_NBR(tb,1))==SM_NTH_TRI(sm,T_NTH_NBR(tb,2)) ) |
779 |
< |
goto Ltri_error; |
780 |
< |
*/ |
709 |
> |
#if DEBUG > 1 |
710 |
> |
{ |
711 |
> |
double l; |
712 |
> |
l = triangle_normal(r,a,b,c); |
713 |
> |
/* l = sin@ between ab,ac - if 0 vectors are colinear */ |
714 |
> |
if( l <= COLINEAR_EPS) |
715 |
> |
{ |
716 |
> |
eputs("pt in cone: null triangle:returning FALSE\n"); |
717 |
> |
return(FALSE); |
718 |
> |
} |
719 |
> |
} |
720 |
|
#endif |
782 |
– |
/* Reset neighbor pointers of original neighbors */ |
783 |
– |
n = SM_NTH_TRI(sm,T_NTH_NBR(t,enext)); |
784 |
– |
#ifdef DEBUG |
785 |
– |
if(!T_IS_VALID(n)) |
786 |
– |
goto Ltri_error; |
721 |
|
#endif |
788 |
– |
T_NTH_NBR(n,T_NTH_NBR_PTR(t_id,n)) = tb_id; |
789 |
– |
n = SM_NTH_TRI(sm,T_NTH_NBR(t,eprev)); |
790 |
– |
#ifdef DEBUG |
791 |
– |
if(!T_IS_VALID(n)) |
792 |
– |
goto Ltri_error; |
793 |
– |
#endif |
794 |
– |
T_NTH_NBR(n,T_NTH_NBR_PTR(t_id,n)) = ta_id; |
722 |
|
|
723 |
< |
n = SM_NTH_TRI(sm,T_NTH_NBR(t1,e1next)); |
724 |
< |
#ifdef DEBUG |
725 |
< |
if(!T_IS_VALID(n)) |
799 |
< |
goto Ltri_error; |
800 |
< |
#endif |
801 |
< |
T_NTH_NBR(n,T_NTH_NBR_PTR(t1_id,n)) = ta_id; |
802 |
< |
n = SM_NTH_TRI(sm,T_NTH_NBR(t1,e1prev)); |
803 |
< |
#ifdef DEBUG |
804 |
< |
if(!T_IS_VALID(n)) |
805 |
< |
goto Ltri_error; |
806 |
< |
#endif |
807 |
< |
T_NTH_NBR(n,T_NTH_NBR_PTR(t1_id,n)) = tb_id; |
723 |
> |
VSUB(ab,b,a); |
724 |
> |
VSUB(ac,c,a); |
725 |
> |
VCROSS(r,ab,ac); |
726 |
|
|
727 |
< |
#ifdef DEBUG |
728 |
< |
T_VALID_FLAG(SM_NTH_TRI(sm,t_id))=-1; |
729 |
< |
T_VALID_FLAG(SM_NTH_TRI(sm,t1_id))=-1; |
730 |
< |
#endif |
727 |
> |
pr = DOT(p,r); |
728 |
> |
ar = DOT(a,r); |
729 |
> |
/* Need to check for equality for degeneracy of 4 points on circle */ |
730 |
> |
if( pr > ar *( 1.0 + EQUALITY_EPS)) |
731 |
> |
return(TRUE); |
732 |
> |
else |
733 |
> |
return(FALSE); |
734 |
> |
} |
735 |
|
|
736 |
< |
remove_from_list(t_id,add_ptr); |
737 |
< |
remove_from_list(t1_id,add_ptr); |
738 |
< |
#if 1 |
739 |
< |
smDelete_tri(sm,t_id); |
740 |
< |
smDelete_tri(sm,t1_id); |
741 |
< |
#else |
742 |
< |
*del_ptr = push_data(*del_ptr,t_id); |
743 |
< |
*del_ptr = push_data(*del_ptr,t1_id); |
744 |
< |
#endif |
736 |
> |
smRestore_Delaunay(sm,a,b,c,t,t_id,a_id,b_id,c_id) |
737 |
> |
SM *sm; |
738 |
> |
FVECT a,b,c; |
739 |
> |
TRI *t; |
740 |
> |
int t_id,a_id,b_id,c_id; |
741 |
> |
{ |
742 |
> |
int e1,topp_id,p_id; |
743 |
> |
TRI *topp; |
744 |
> |
FVECT p; |
745 |
|
|
746 |
< |
|
825 |
< |
|
826 |
< |
*tn_id = ta_id; |
827 |
< |
*tn1_id = tb_id; |
828 |
< |
|
746 |
> |
topp_id = T_NTH_NBR(t,0); |
747 |
|
#ifdef DEBUG |
748 |
< |
if(T_NTH_NBR(SM_NTH_TRI(sm,ta_id),0)== -1 || |
749 |
< |
T_NTH_NBR(SM_NTH_TRI(sm,ta_id),1)== -1 || |
750 |
< |
T_NTH_NBR(SM_NTH_TRI(sm,ta_id),2)== -1 || |
751 |
< |
T_NTH_NBR(SM_NTH_TRI(sm,tb_id),0)== -1 || |
752 |
< |
T_NTH_NBR(SM_NTH_TRI(sm,tb_id),1)== -1 || |
835 |
< |
T_NTH_NBR(SM_NTH_TRI(sm,tb_id),2)== -1) |
836 |
< |
goto Ltri_error; |
837 |
< |
if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(SM_NTH_TRI(sm,ta_id),0))) || |
838 |
< |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(SM_NTH_TRI(sm,ta_id),1))) || |
839 |
< |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(SM_NTH_TRI(sm,ta_id),2)))) |
840 |
< |
goto Ltri_error; |
841 |
< |
if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(SM_NTH_TRI(sm,tb_id),0))) || |
842 |
< |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(SM_NTH_TRI(sm,tb_id),1))) || |
843 |
< |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(SM_NTH_TRI(sm,tb_id),2)))) |
844 |
< |
goto Ltri_error; |
748 |
> |
if(topp_id==INVALID) |
749 |
> |
{ |
750 |
> |
eputs("Invalid tri id smRestore_delaunay()\n"); |
751 |
> |
return; |
752 |
> |
} |
753 |
|
#endif |
754 |
+ |
topp = SM_NTH_TRI(sm,topp_id); |
755 |
+ |
#ifdef DEBUG |
756 |
+ |
if(!T_IS_VALID(topp)) |
757 |
+ |
{ |
758 |
+ |
eputs("Invalid tri smRestore_delaunay()\n"); |
759 |
|
return; |
760 |
< |
Ltri_error: |
761 |
< |
error(CONSISTENCY,"Invalid tri: smTris_swap_edge()\n"); |
762 |
< |
} |
760 |
> |
} |
761 |
> |
#endif |
762 |
> |
e1 = T_NTH_NBR_PTR(t_id,topp); |
763 |
> |
p_id = T_NTH_V(topp,e1); |
764 |
|
|
765 |
< |
smUpdate_locator(sm,add_list) |
766 |
< |
SM *sm; |
767 |
< |
LIST *add_list; |
854 |
< |
{ |
855 |
< |
int t_id,i; |
856 |
< |
TRI *t; |
857 |
< |
OBJECT *optr; |
858 |
< |
|
859 |
< |
while(add_list) |
765 |
> |
VSUB(p,SM_NTH_WV(sm,p_id),SM_VIEW_CENTER(sm)); |
766 |
> |
normalize(p); |
767 |
> |
if(pt_in_cone(p,c,b,a)) |
768 |
|
{ |
769 |
< |
t_id = pop_list(&add_list); |
770 |
< |
t = SM_NTH_TRI(sm,t_id); |
771 |
< |
smLocator_add_tri(sm,t_id,T_NTH_V(t,0),T_NTH_V(t,1),T_NTH_V(t,2)); |
772 |
< |
} |
773 |
< |
} |
769 |
> |
int e1next,e1prev; |
770 |
> |
int ta_id,tb_id; |
771 |
> |
TRI *ta,*tb,*n; |
772 |
> |
e1next = (e1 + 1)%3; |
773 |
> |
e1prev = (e1 + 2)%3; |
774 |
> |
ta_id = smAdd_tri(sm,a_id,b_id,p_id,&ta); |
775 |
> |
tb_id = smAdd_tri(sm,a_id,p_id,c_id,&tb); |
776 |
|
|
777 |
< |
int |
778 |
< |
smFix_tris(sm,id,tlist,add_list) |
779 |
< |
SM *sm; |
780 |
< |
int id; |
781 |
< |
LIST *tlist,*add_list; |
782 |
< |
{ |
783 |
< |
TRI *t,*t_opp; |
784 |
< |
FVECT p,p0,p1,p2; |
785 |
< |
int e,e1,swapped = 0; |
786 |
< |
int t_id,t_opp_id; |
787 |
< |
LIST *del_list=NULL; |
777 |
> |
T_NTH_NBR(ta,0) = T_NTH_NBR(topp,e1next); |
778 |
> |
T_NTH_NBR(ta,1) = tb_id; |
779 |
> |
T_NTH_NBR(ta,2) = T_NTH_NBR(t,2); |
780 |
> |
|
781 |
> |
T_NTH_NBR(tb,0) = T_NTH_NBR(topp,e1prev); |
782 |
> |
T_NTH_NBR(tb,1) = T_NTH_NBR(t,1); |
783 |
> |
T_NTH_NBR(tb,2) = ta_id; |
784 |
> |
|
785 |
> |
n = SM_NTH_TRI(sm,T_NTH_NBR(t,1)); |
786 |
> |
T_NTH_NBR(n,T_NTH_NBR_PTR(t_id,n)) = tb_id; |
787 |
> |
n = SM_NTH_TRI(sm,T_NTH_NBR(t,2)); |
788 |
> |
T_NTH_NBR(n,T_NTH_NBR_PTR(t_id,n)) = ta_id; |
789 |
> |
n = SM_NTH_TRI(sm,T_NTH_NBR(topp,e1next)); |
790 |
> |
T_NTH_NBR(n,T_NTH_NBR_PTR(topp_id,n)) = ta_id; |
791 |
> |
n = SM_NTH_TRI(sm,T_NTH_NBR(topp,e1prev)); |
792 |
> |
T_NTH_NBR(n,T_NTH_NBR_PTR(topp_id,n)) = tb_id; |
793 |
> |
|
794 |
> |
smDelete_tri(sm,t_id,t); |
795 |
> |
smDelete_tri(sm,topp_id,topp); |
796 |
|
|
879 |
– |
VSUB(p,SM_NTH_WV(sm,id),SM_VIEW_CENTER(sm)); |
880 |
– |
while(tlist) |
881 |
– |
{ |
882 |
– |
t_id = pop_list(&tlist); |
797 |
|
#ifdef DEBUG |
798 |
< |
if(t_id==INVALID || t_id > smMesh->num_tri) |
799 |
< |
error(CONSISTENCY,"Invalid tri id smFix_tris()\n"); |
800 |
< |
#endif |
801 |
< |
t = SM_NTH_TRI(sm,t_id); |
802 |
< |
e = T_WHICH_V(t,id); |
803 |
< |
t_opp_id = T_NTH_NBR(t,e); |
804 |
< |
#ifdef DEBUG |
805 |
< |
if(t_opp_id==INVALID || t_opp_id > smMesh->num_tri) |
806 |
< |
error(CONSISTENCY,"Invalid tri id smFix_tris()\n"); |
807 |
< |
#endif |
808 |
< |
t_opp = SM_NTH_TRI(sm,t_opp_id); |
809 |
< |
#ifdef DEBUG |
810 |
< |
if(!T_IS_VALID(t_opp)) |
811 |
< |
error(CONSISTENCY,"Invalid trismFix_tris()\n"); |
812 |
< |
#endif |
813 |
< |
smDir_in_cone(sm,p0,T_NTH_V(t_opp,0)); |
814 |
< |
smDir_in_cone(sm,p1,T_NTH_V(t_opp,1)); |
815 |
< |
smDir_in_cone(sm,p2,T_NTH_V(t_opp,2)); |
816 |
< |
if(point_in_cone(p,p0,p1,p2)) |
817 |
< |
{ |
818 |
< |
swapped = 1; |
819 |
< |
e1 = T_NTH_NBR_PTR(t_id,t_opp); |
820 |
< |
/* check list for t_opp and Remove if there */ |
821 |
< |
remove_from_list(t_opp_id,&tlist); |
822 |
< |
smTris_swap_edge(sm,t_id,t_opp_id,e,e1,&t_id,&t_opp_id, |
823 |
< |
&add_list); |
824 |
< |
tlist = push_data(tlist,t_id); |
825 |
< |
tlist = push_data(tlist,t_opp_id); |
826 |
< |
} |
827 |
< |
} |
828 |
< |
#if 0 |
829 |
< |
while(del_list) |
830 |
< |
{ |
831 |
< |
t_id = pop_list(&del_list); |
832 |
< |
smDelete_tri(sm,t_id); |
833 |
< |
} |
834 |
< |
#endif |
835 |
< |
smUpdate_locator(sm,add_list); |
798 |
> |
#if DEBUG > 1 |
799 |
> |
if(T_NTH_NBR(ta,0) == T_NTH_NBR(ta,1) || |
800 |
> |
T_NTH_NBR(ta,1) == T_NTH_NBR(ta,2) || |
801 |
> |
T_NTH_NBR(ta,0) == T_NTH_NBR(ta,2)) |
802 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
803 |
> |
if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(ta,0))) || |
804 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(ta,1))) || |
805 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(ta,2)))) |
806 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
807 |
> |
n = SM_NTH_TRI(sm,T_NTH_NBR(ta,0)); |
808 |
> |
if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1) || |
809 |
> |
T_NTH_NBR(n,1) == T_NTH_NBR(n,2) || |
810 |
> |
T_NTH_NBR(n,0) == T_NTH_NBR(n,2)) |
811 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
812 |
> |
if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) || |
813 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) || |
814 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2)))) |
815 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
816 |
> |
n = SM_NTH_TRI(sm,T_NTH_NBR(ta,1)); |
817 |
> |
if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1) || |
818 |
> |
T_NTH_NBR(n,1) == T_NTH_NBR(n,2) || |
819 |
> |
T_NTH_NBR(n,0) == T_NTH_NBR(n,2)) |
820 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
821 |
> |
if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) || |
822 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) || |
823 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2)))) |
824 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
825 |
> |
n = SM_NTH_TRI(sm,T_NTH_NBR(ta,2)); |
826 |
> |
if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1) || |
827 |
> |
T_NTH_NBR(n,1) == T_NTH_NBR(n,2) || |
828 |
> |
T_NTH_NBR(n,0) == T_NTH_NBR(n,2)) |
829 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
830 |
> |
if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) || |
831 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) || |
832 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2)))) |
833 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
834 |
> |
n = SM_NTH_TRI(sm,T_NTH_NBR(tb,0)); |
835 |
> |
if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1) || |
836 |
> |
T_NTH_NBR(n,1) == T_NTH_NBR(n,2) || |
837 |
> |
T_NTH_NBR(n,0) == T_NTH_NBR(n,2)) |
838 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
839 |
> |
if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) || |
840 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) || |
841 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2)))) |
842 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
843 |
> |
n = SM_NTH_TRI(sm,T_NTH_NBR(tb,1)); |
844 |
> |
if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1) || |
845 |
> |
T_NTH_NBR(n,1) == T_NTH_NBR(n,2) || |
846 |
> |
T_NTH_NBR(n,0) == T_NTH_NBR(n,2)) |
847 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
848 |
> |
if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) || |
849 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) || |
850 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2)))) |
851 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
852 |
> |
n = SM_NTH_TRI(sm,T_NTH_NBR(tb,2)); |
853 |
> |
if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1) || |
854 |
> |
T_NTH_NBR(n,1) == T_NTH_NBR(n,2) || |
855 |
> |
T_NTH_NBR(n,0) == T_NTH_NBR(n,2)) |
856 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
857 |
> |
if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) || |
858 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) || |
859 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2)))) |
860 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
861 |
|
|
862 |
< |
return(swapped); |
862 |
> |
if(T_NTH_NBR(tb,0) == T_NTH_NBR(tb,1) || |
863 |
> |
T_NTH_NBR(tb,1) == T_NTH_NBR(tb,2) || |
864 |
> |
T_NTH_NBR(tb,0) == T_NTH_NBR(tb,2)) |
865 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
866 |
> |
if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(tb,0))) || |
867 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(tb,1))) || |
868 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(tb,2)))) |
869 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
870 |
> |
|
871 |
> |
#endif |
872 |
> |
#endif |
873 |
> |
smRestore_Delaunay(sm,a,b,p,ta,ta_id,a_id,b_id,p_id); |
874 |
> |
smRestore_Delaunay(sm,a,p,c,tb,tb_id,a_id,p_id,c_id); |
875 |
> |
} |
876 |
|
} |
877 |
|
|
878 |
+ |
|
879 |
|
/* Give the vertex "id" and a triangle "t" that it belongs to- return the |
880 |
|
next nbr in a counter clockwise order about vertex "id" |
881 |
|
*/ |
910 |
|
|
911 |
|
/* Locate the point-id in the point location structure: */ |
912 |
|
int |
913 |
< |
smInsert_samp(sm,s_id,tri_id,on,which) |
913 |
> |
smInsert_samp_mesh(sm,s_id,tri_id,a,b,c,d,on,which) |
914 |
|
SM *sm; |
915 |
|
int s_id,tri_id; |
916 |
+ |
FVECT a,b,c,d; |
917 |
|
int on,which; |
918 |
|
{ |
919 |
|
int v_id[3],topp_id,i; |
920 |
< |
int t0_id,t1_id,t2_id,t3_id,replaced; |
921 |
< |
int e0,e1,e2,opp0,opp1,opp2,opp_id; |
922 |
< |
LIST *tlist,*add_list; |
923 |
< |
FVECT npt; |
970 |
< |
TRI *tri,*nbr,*topp; |
920 |
> |
int t0_id,t1_id,t2_id,t3_id; |
921 |
> |
int e0,e1,e2,opp_id,opp0,opp1,opp2; |
922 |
> |
TRI *tri,*nbr,*topp,*t0,*t1,*t2,*t3; |
923 |
> |
FVECT e; |
924 |
|
|
972 |
– |
|
973 |
– |
add_list = NULL; |
925 |
|
for(i=0; i<3;i++) |
926 |
|
v_id[i] = T_NTH_V(SM_NTH_TRI(sm,tri_id),i); |
927 |
|
|
928 |
|
/* If falls on existing edge */ |
929 |
|
if(on == ON_E) |
930 |
|
{ |
931 |
+ |
FVECT n,vopp; |
932 |
+ |
double dp; |
933 |
+ |
|
934 |
|
tri = SM_NTH_TRI(sm,tri_id); |
935 |
|
topp_id = T_NTH_NBR(tri,which); |
936 |
|
e0 = which; |
938 |
|
e2 = (which+2)%3; |
939 |
|
topp = SM_NTH_TRI(sm,topp_id); |
940 |
|
opp0 = T_NTH_NBR_PTR(tri_id,topp); |
987 |
– |
opp_id = T_NTH_V(topp,opp0); |
941 |
|
opp1 = (opp0+1)%3; |
942 |
|
opp2 = (opp0+2)%3; |
943 |
+ |
|
944 |
+ |
opp_id = T_NTH_V(topp,opp0); |
945 |
|
|
946 |
|
/* Create 4 triangles */ |
947 |
|
/* /|\ /|\ |
951 |
|
\ | / \ | / |
952 |
|
\|/ \|/ |
953 |
|
*/ |
954 |
< |
t0_id = smAdd_tri(sm,s_id,v_id[e0],v_id[e1]); |
955 |
< |
add_list = push_data(add_list,t0_id); |
956 |
< |
t1_id = smAdd_tri(sm,s_id,v_id[e2],v_id[e0]); |
957 |
< |
add_list = push_data(add_list,t1_id); |
1003 |
< |
t2_id = smAdd_tri(sm,s_id,v_id[e1],opp_id); |
1004 |
< |
add_list = push_data(add_list,t2_id); |
1005 |
< |
t3_id = smAdd_tri(sm,s_id,opp_id,v_id[e2]); |
1006 |
< |
add_list = push_data(add_list,t3_id); |
1007 |
< |
/* CAUTION: tri must be assigned after Add_tri: pointers may change*/ |
1008 |
< |
tri = SM_NTH_TRI(sm,tri_id); |
1009 |
< |
topp =SM_NTH_TRI(sm,topp_id); |
954 |
> |
t0_id = smAdd_tri(sm,s_id,v_id[e0],v_id[e1],&t0); |
955 |
> |
t1_id = smAdd_tri(sm,s_id,v_id[e2],v_id[e0],&t1); |
956 |
> |
t2_id = smAdd_tri(sm,s_id,v_id[e1],opp_id,&t2); |
957 |
> |
t3_id = smAdd_tri(sm,s_id,opp_id,v_id[e2],&t3); |
958 |
|
|
959 |
< |
/* Set the neighbor pointers for the new tris */ |
960 |
< |
T_NTH_NBR(SM_NTH_TRI(sm,t0_id),0) = T_NTH_NBR(tri,e2); |
961 |
< |
T_NTH_NBR(SM_NTH_TRI(sm,t0_id),1) = t2_id; |
962 |
< |
T_NTH_NBR(SM_NTH_TRI(sm,t0_id),2) = t1_id; |
963 |
< |
T_NTH_NBR(SM_NTH_TRI(sm,t1_id),0) = T_NTH_NBR(tri,e1); |
964 |
< |
T_NTH_NBR(SM_NTH_TRI(sm,t1_id),1) = t0_id; |
965 |
< |
T_NTH_NBR(SM_NTH_TRI(sm,t1_id),2) = t3_id; |
966 |
< |
T_NTH_NBR(SM_NTH_TRI(sm,t2_id),0) = T_NTH_NBR(topp,opp1); |
967 |
< |
T_NTH_NBR(SM_NTH_TRI(sm,t2_id),1) = t3_id; |
968 |
< |
T_NTH_NBR(SM_NTH_TRI(sm,t2_id),2) = t0_id; |
969 |
< |
T_NTH_NBR(SM_NTH_TRI(sm,t3_id),0) = T_NTH_NBR(topp,opp2); |
970 |
< |
T_NTH_NBR(SM_NTH_TRI(sm,t3_id),1) = t1_id; |
971 |
< |
T_NTH_NBR(SM_NTH_TRI(sm,t3_id),2) = t2_id; |
959 |
> |
/* Set the neighbor pointers for the new tris */ |
960 |
> |
T_NTH_NBR(t0,0) = T_NTH_NBR(tri,e2); |
961 |
> |
T_NTH_NBR(t0,1) = t2_id; |
962 |
> |
T_NTH_NBR(t0,2) = t1_id; |
963 |
> |
T_NTH_NBR(t1,0) = T_NTH_NBR(tri,e1); |
964 |
> |
T_NTH_NBR(t1,1) = t0_id; |
965 |
> |
T_NTH_NBR(t1,2) = t3_id; |
966 |
> |
T_NTH_NBR(t2,0) = T_NTH_NBR(topp,opp1); |
967 |
> |
T_NTH_NBR(t2,1) = t3_id; |
968 |
> |
T_NTH_NBR(t2,2) = t0_id; |
969 |
> |
T_NTH_NBR(t3,0) = T_NTH_NBR(topp,opp2); |
970 |
> |
T_NTH_NBR(t3,1) = t1_id; |
971 |
> |
T_NTH_NBR(t3,2) = t2_id; |
972 |
|
|
973 |
|
/* Reset the neigbor pointers for the neighbors of the original */ |
974 |
|
nbr = SM_NTH_TRI(sm,T_NTH_NBR(tri,e1)); |
979 |
|
T_NTH_NBR(nbr,T_NTH_NBR_PTR(topp_id,nbr)) = t2_id; |
980 |
|
nbr = SM_NTH_TRI(sm,T_NTH_NBR(topp,opp2)); |
981 |
|
T_NTH_NBR(nbr,T_NTH_NBR_PTR(topp_id,nbr)) = t3_id; |
982 |
+ |
|
983 |
|
#ifdef DEBUG |
984 |
< |
T_VALID_FLAG(SM_NTH_TRI(sm,tri_id))=-1; |
985 |
< |
T_VALID_FLAG(SM_NTH_TRI(sm,topp_id))=-1; |
986 |
< |
#endif |
987 |
< |
tlist = push_data(NULL,t0_id); |
988 |
< |
tlist = push_data(tlist,t1_id); |
989 |
< |
tlist = push_data(tlist,t2_id); |
990 |
< |
tlist = push_data(tlist,t3_id); |
984 |
> |
#if DEBUG > 1 |
985 |
> |
{ |
986 |
> |
TRI *n; |
987 |
> |
|
988 |
> |
if(T_NTH_NBR(t0,0) == T_NTH_NBR(t0,1) || |
989 |
> |
T_NTH_NBR(t0,1) == T_NTH_NBR(t0,2) || |
990 |
> |
T_NTH_NBR(t0,0) == T_NTH_NBR(t0,2)) |
991 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
992 |
> |
if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t0,0))) || |
993 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t0,1))) || |
994 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t0,2)))) |
995 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
996 |
> |
n = SM_NTH_TRI(sm,T_NTH_NBR(t0,0)); |
997 |
> |
if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1) || |
998 |
> |
T_NTH_NBR(n,1) == T_NTH_NBR(n,2) || |
999 |
> |
T_NTH_NBR(n,0) == T_NTH_NBR(n,2)) |
1000 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
1001 |
> |
if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) || |
1002 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) || |
1003 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2)))) |
1004 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
1005 |
> |
n = SM_NTH_TRI(sm,T_NTH_NBR(t0,1)); |
1006 |
> |
if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1) || |
1007 |
> |
T_NTH_NBR(n,1) == T_NTH_NBR(n,2) || |
1008 |
> |
T_NTH_NBR(n,0) == T_NTH_NBR(n,2)) |
1009 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
1010 |
> |
if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) || |
1011 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) || |
1012 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2)))) |
1013 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
1014 |
> |
n = SM_NTH_TRI(sm,T_NTH_NBR(t0,2)); |
1015 |
> |
if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1) || |
1016 |
> |
T_NTH_NBR(n,1) == T_NTH_NBR(n,2) || |
1017 |
> |
T_NTH_NBR(n,0) == T_NTH_NBR(n,2)) |
1018 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
1019 |
> |
if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) || |
1020 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) || |
1021 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2)))) |
1022 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
1023 |
> |
n = SM_NTH_TRI(sm,T_NTH_NBR(t1,0)); |
1024 |
> |
if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1) || |
1025 |
> |
T_NTH_NBR(n,1) == T_NTH_NBR(n,2) || |
1026 |
> |
T_NTH_NBR(n,0) == T_NTH_NBR(n,2)) |
1027 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
1028 |
> |
if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) || |
1029 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) || |
1030 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2)))) |
1031 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
1032 |
> |
n = SM_NTH_TRI(sm,T_NTH_NBR(t1,1)); |
1033 |
> |
if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1) || |
1034 |
> |
T_NTH_NBR(n,1) == T_NTH_NBR(n,2) || |
1035 |
> |
T_NTH_NBR(n,0) == T_NTH_NBR(n,2)) |
1036 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
1037 |
> |
if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) || |
1038 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) || |
1039 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2)))) |
1040 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
1041 |
> |
n = SM_NTH_TRI(sm,T_NTH_NBR(t1,2)); |
1042 |
> |
if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1) || |
1043 |
> |
T_NTH_NBR(n,1) == T_NTH_NBR(n,2) || |
1044 |
> |
T_NTH_NBR(n,0) == T_NTH_NBR(n,2)) |
1045 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
1046 |
> |
if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) || |
1047 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) || |
1048 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2)))) |
1049 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
1050 |
> |
|
1051 |
> |
if(T_NTH_NBR(t1,0) == T_NTH_NBR(t1,1) || |
1052 |
> |
T_NTH_NBR(t1,1) == T_NTH_NBR(t1,2) || |
1053 |
> |
T_NTH_NBR(t1,0) == T_NTH_NBR(t1,2)) |
1054 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
1055 |
> |
if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t1,0))) || |
1056 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t1,1))) || |
1057 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t1,2)))) |
1058 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
1059 |
> |
|
1060 |
> |
if(T_NTH_NBR(t2,0) == T_NTH_NBR(t2,1) || |
1061 |
> |
T_NTH_NBR(t2,1) == T_NTH_NBR(t2,2) || |
1062 |
> |
T_NTH_NBR(t2,0) == T_NTH_NBR(t2,2)) |
1063 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
1064 |
> |
if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t2,0))) || |
1065 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t2,1))) || |
1066 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t2,2)))) |
1067 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
1068 |
> |
n = SM_NTH_TRI(sm,T_NTH_NBR(t2,0)); |
1069 |
> |
if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1) || |
1070 |
> |
T_NTH_NBR(n,1) == T_NTH_NBR(n,2) || |
1071 |
> |
T_NTH_NBR(n,0) == T_NTH_NBR(n,2)) |
1072 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
1073 |
> |
if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) || |
1074 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) || |
1075 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2)))) |
1076 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
1077 |
> |
n = SM_NTH_TRI(sm,T_NTH_NBR(t2,1)); |
1078 |
> |
if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1) || |
1079 |
> |
T_NTH_NBR(n,1) == T_NTH_NBR(n,2) || |
1080 |
> |
T_NTH_NBR(n,0) == T_NTH_NBR(n,2)) |
1081 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
1082 |
> |
if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) || |
1083 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) || |
1084 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2)))) |
1085 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
1086 |
> |
n = SM_NTH_TRI(sm,T_NTH_NBR(t2,2)); |
1087 |
> |
if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1) || |
1088 |
> |
T_NTH_NBR(n,1) == T_NTH_NBR(n,2) || |
1089 |
> |
T_NTH_NBR(n,0) == T_NTH_NBR(n,2)) |
1090 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
1091 |
> |
if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) || |
1092 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) || |
1093 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2)))) |
1094 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
1095 |
> |
|
1096 |
> |
if(T_NTH_NBR(t3,0) == T_NTH_NBR(t3,1) || |
1097 |
> |
T_NTH_NBR(t3,1) == T_NTH_NBR(t3,2) || |
1098 |
> |
T_NTH_NBR(t3,0) == T_NTH_NBR(t3,2)) |
1099 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
1100 |
> |
if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t3,0))) || |
1101 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t3,1))) || |
1102 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t3,2)))) |
1103 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
1104 |
> |
n = SM_NTH_TRI(sm,T_NTH_NBR(t3,0)); |
1105 |
> |
if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1) || |
1106 |
> |
T_NTH_NBR(n,1) == T_NTH_NBR(n,2) || |
1107 |
> |
T_NTH_NBR(n,0) == T_NTH_NBR(n,2)) |
1108 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
1109 |
> |
if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) || |
1110 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) || |
1111 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2)))) |
1112 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
1113 |
> |
n = SM_NTH_TRI(sm,T_NTH_NBR(t3,1)); |
1114 |
> |
if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1) || |
1115 |
> |
T_NTH_NBR(n,1) == T_NTH_NBR(n,2) || |
1116 |
> |
T_NTH_NBR(n,0) == T_NTH_NBR(n,2)) |
1117 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
1118 |
> |
if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) || |
1119 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) || |
1120 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2)))) |
1121 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
1122 |
> |
n = SM_NTH_TRI(sm,T_NTH_NBR(t3,2)); |
1123 |
> |
if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1) || |
1124 |
> |
T_NTH_NBR(n,1) == T_NTH_NBR(n,2) || |
1125 |
> |
T_NTH_NBR(n,0) == T_NTH_NBR(n,2)) |
1126 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
1127 |
> |
if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) || |
1128 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) || |
1129 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2)))) |
1130 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
1131 |
> |
} |
1132 |
> |
#endif |
1133 |
> |
#endif |
1134 |
> |
smDir(sm,e,opp_id); |
1135 |
> |
if(which == 0) |
1136 |
> |
{ |
1137 |
> |
smRestore_Delaunay(sm,a,b,c,t0,t0_id,s_id,v_id[e0],v_id[e1]); |
1138 |
> |
smRestore_Delaunay(sm,a,d,b,t1,t1_id,s_id,v_id[e2],v_id[e0]); |
1139 |
> |
smRestore_Delaunay(sm,a,c,e,t2,t2_id,s_id,v_id[e1],opp_id); |
1140 |
> |
smRestore_Delaunay(sm,a,e,d,t3,t3_id,s_id,opp_id,v_id[e2]); |
1141 |
> |
} |
1142 |
> |
else |
1143 |
> |
if( which==1 ) |
1144 |
> |
{ |
1145 |
> |
smRestore_Delaunay(sm,a,c,d,t0,t0_id,s_id,v_id[e0],v_id[e1]); |
1146 |
> |
smRestore_Delaunay(sm,a,b,c,t1,t1_id,s_id,v_id[e2],v_id[e0]); |
1147 |
> |
smRestore_Delaunay(sm,a,d,e,t2,t2_id,s_id,v_id[e1],opp_id); |
1148 |
> |
smRestore_Delaunay(sm,a,e,b,t3,t3_id,s_id,opp_id,v_id[e2]); |
1149 |
> |
} |
1150 |
> |
else |
1151 |
> |
{ |
1152 |
> |
smRestore_Delaunay(sm,a,d,b,t0,t0_id,s_id,v_id[e0],v_id[e1]); |
1153 |
> |
smRestore_Delaunay(sm,a,c,d,t1,t1_id,s_id,v_id[e2],v_id[e0]); |
1154 |
> |
smRestore_Delaunay(sm,a,b,e,t2,t2_id,s_id,v_id[e1],opp_id); |
1155 |
> |
smRestore_Delaunay(sm,a,e,c,t3,t3_id,s_id,opp_id,v_id[e2]); |
1156 |
> |
} |
1157 |
> |
smDelete_tri(sm,tri_id,tri); |
1158 |
> |
smDelete_tri(sm,topp_id,topp); |
1159 |
> |
return(TRUE); |
1160 |
|
} |
1161 |
< |
else |
1162 |
< |
{ |
1163 |
< |
/* Create 3 triangles */ |
1164 |
< |
/* / \ /|\ |
1165 |
< |
/ \ / | \ |
1166 |
< |
/ * \ ----> / | \ |
1167 |
< |
/ \ / / \ \ |
1168 |
< |
/ \ / / \ \ |
1169 |
< |
/___________\ //_________\\ |
1170 |
< |
*/ |
1161 |
> |
Linsert_in_tri: |
1162 |
> |
/* Create 3 triangles */ |
1163 |
> |
/* / \ /|\ |
1164 |
> |
/ \ / | \ |
1165 |
> |
/ * \ ----> / | \ |
1166 |
> |
/ \ / / \ \ |
1167 |
> |
/ \ / / \ \ |
1168 |
> |
___________\ //_________\\ |
1169 |
> |
*/ |
1170 |
> |
tri = SM_NTH_TRI(sm,tri_id); |
1171 |
|
|
1172 |
< |
t0_id = smAdd_tri(sm,s_id,v_id[0],v_id[1]); |
1173 |
< |
add_list = push_data(add_list,t0_id); |
1174 |
< |
t1_id = smAdd_tri(sm,s_id,v_id[1],v_id[2]); |
1057 |
< |
add_list = push_data(add_list,t1_id); |
1058 |
< |
t2_id = smAdd_tri(sm,s_id,v_id[2],v_id[0]); |
1059 |
< |
add_list = push_data(add_list,t2_id); |
1172 |
> |
t0_id = smAdd_tri(sm,s_id,v_id[0],v_id[1],&t0); |
1173 |
> |
t1_id = smAdd_tri(sm,s_id,v_id[1],v_id[2],&t1); |
1174 |
> |
t2_id = smAdd_tri(sm,s_id,v_id[2],v_id[0],&t2); |
1175 |
|
|
1176 |
< |
/* CAUTION: tri must be assigned after Add_tri: pointers may change*/ |
1177 |
< |
tri = SM_NTH_TRI(sm,tri_id); |
1178 |
< |
/* Set the neighbor pointers for the new tris */ |
1179 |
< |
T_NTH_NBR(SM_NTH_TRI(sm,t0_id),0) = T_NTH_NBR(tri,2); |
1180 |
< |
T_NTH_NBR(SM_NTH_TRI(sm,t0_id),1) = t1_id; |
1181 |
< |
T_NTH_NBR(SM_NTH_TRI(sm,t0_id),2) = t2_id; |
1182 |
< |
T_NTH_NBR(SM_NTH_TRI(sm,t1_id),0) = T_NTH_NBR(tri,0); |
1183 |
< |
T_NTH_NBR(SM_NTH_TRI(sm,t1_id),1) = t2_id; |
1184 |
< |
T_NTH_NBR(SM_NTH_TRI(sm,t1_id),2) = t0_id; |
1185 |
< |
T_NTH_NBR(SM_NTH_TRI(sm,t2_id),0) = T_NTH_NBR(tri,1); |
1071 |
< |
T_NTH_NBR(SM_NTH_TRI(sm,t2_id),1) = t0_id; |
1072 |
< |
T_NTH_NBR(SM_NTH_TRI(sm,t2_id),2) = t1_id; |
1176 |
> |
/* Set the neighbor pointers for the new tris */ |
1177 |
> |
T_NTH_NBR(t0,0) = T_NTH_NBR(tri,2); |
1178 |
> |
T_NTH_NBR(t0,1) = t1_id; |
1179 |
> |
T_NTH_NBR(t0,2) = t2_id; |
1180 |
> |
T_NTH_NBR(t1,0) = T_NTH_NBR(tri,0); |
1181 |
> |
T_NTH_NBR(t1,1) = t2_id; |
1182 |
> |
T_NTH_NBR(t1,2) = t0_id; |
1183 |
> |
T_NTH_NBR(t2,0) = T_NTH_NBR(tri,1); |
1184 |
> |
T_NTH_NBR(t2,1) = t0_id; |
1185 |
> |
T_NTH_NBR(t2,2) = t1_id; |
1186 |
|
|
1187 |
< |
/* Reset the neigbor pointers for the neighbors of the original */ |
1188 |
< |
nbr = SM_NTH_TRI(sm,T_NTH_NBR(tri,0)); |
1189 |
< |
T_NTH_NBR(nbr,T_NTH_NBR_PTR(tri_id,nbr)) = t1_id; |
1190 |
< |
nbr = SM_NTH_TRI(sm,T_NTH_NBR(tri,1)); |
1191 |
< |
T_NTH_NBR(nbr,T_NTH_NBR_PTR(tri_id,nbr)) = t2_id; |
1192 |
< |
nbr = SM_NTH_TRI(sm,T_NTH_NBR(tri,2)); |
1193 |
< |
T_NTH_NBR(nbr,T_NTH_NBR_PTR(tri_id,nbr)) = t0_id; |
1187 |
> |
/* Reset the neigbor pointers for the neighbors of the original */ |
1188 |
> |
nbr = SM_NTH_TRI(sm,T_NTH_NBR(tri,0)); |
1189 |
> |
T_NTH_NBR(nbr,T_NTH_NBR_PTR(tri_id,nbr)) = t1_id; |
1190 |
> |
nbr = SM_NTH_TRI(sm,T_NTH_NBR(tri,1)); |
1191 |
> |
T_NTH_NBR(nbr,T_NTH_NBR_PTR(tri_id,nbr)) = t2_id; |
1192 |
> |
nbr = SM_NTH_TRI(sm,T_NTH_NBR(tri,2)); |
1193 |
> |
T_NTH_NBR(nbr,T_NTH_NBR_PTR(tri_id,nbr)) = t0_id; |
1194 |
> |
#ifdef DEBUG |
1195 |
> |
#if DEBUG > 1 |
1196 |
> |
{ |
1197 |
> |
TRI *n; |
1198 |
> |
if(T_NTH_NBR(t0,0) == T_NTH_NBR(t0,1) || |
1199 |
> |
T_NTH_NBR(t0,1) == T_NTH_NBR(t0,2) || |
1200 |
> |
T_NTH_NBR(t0,0) == T_NTH_NBR(t0,2)) |
1201 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
1202 |
> |
if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t0,0))) || |
1203 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t0,1))) || |
1204 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t0,2)))) |
1205 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
1206 |
> |
n = SM_NTH_TRI(sm,T_NTH_NBR(t0,0)); |
1207 |
> |
if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1) || |
1208 |
> |
T_NTH_NBR(n,1) == T_NTH_NBR(n,2) || |
1209 |
> |
T_NTH_NBR(n,0) == T_NTH_NBR(n,2)) |
1210 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
1211 |
> |
if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) || |
1212 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) || |
1213 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2)))) |
1214 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
1215 |
> |
n = SM_NTH_TRI(sm,T_NTH_NBR(t0,1)); |
1216 |
> |
if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1) || |
1217 |
> |
T_NTH_NBR(n,1) == T_NTH_NBR(n,2) || |
1218 |
> |
T_NTH_NBR(n,0) == T_NTH_NBR(n,2)) |
1219 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
1220 |
> |
if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) || |
1221 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) || |
1222 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2)))) |
1223 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
1224 |
> |
n = SM_NTH_TRI(sm,T_NTH_NBR(t0,2)); |
1225 |
> |
if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1) || |
1226 |
> |
T_NTH_NBR(n,1) == T_NTH_NBR(n,2) || |
1227 |
> |
T_NTH_NBR(n,0) == T_NTH_NBR(n,2)) |
1228 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
1229 |
> |
if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) || |
1230 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) || |
1231 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2)))) |
1232 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
1233 |
> |
n = SM_NTH_TRI(sm,T_NTH_NBR(t1,0)); |
1234 |
> |
if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1) || |
1235 |
> |
T_NTH_NBR(n,1) == T_NTH_NBR(n,2) || |
1236 |
> |
T_NTH_NBR(n,0) == T_NTH_NBR(n,2)) |
1237 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
1238 |
> |
if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) || |
1239 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) || |
1240 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2)))) |
1241 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
1242 |
> |
n = SM_NTH_TRI(sm,T_NTH_NBR(t1,1)); |
1243 |
> |
if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1) || |
1244 |
> |
T_NTH_NBR(n,1) == T_NTH_NBR(n,2) || |
1245 |
> |
T_NTH_NBR(n,0) == T_NTH_NBR(n,2)) |
1246 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
1247 |
> |
if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) || |
1248 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) || |
1249 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2)))) |
1250 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
1251 |
> |
n = SM_NTH_TRI(sm,T_NTH_NBR(t1,2)); |
1252 |
> |
if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1) || |
1253 |
> |
T_NTH_NBR(n,1) == T_NTH_NBR(n,2) || |
1254 |
> |
T_NTH_NBR(n,0) == T_NTH_NBR(n,2)) |
1255 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
1256 |
> |
if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) || |
1257 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) || |
1258 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2)))) |
1259 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
1260 |
|
|
1261 |
< |
tlist = push_data(NULL,t0_id); |
1262 |
< |
tlist = push_data(tlist,t1_id); |
1263 |
< |
tlist = push_data(tlist,t2_id); |
1264 |
< |
} |
1265 |
< |
/* Fix up the new triangles*/ |
1266 |
< |
smFix_tris(sm,s_id,tlist,add_list); |
1261 |
> |
if(T_NTH_NBR(t1,0) == T_NTH_NBR(t1,1) || |
1262 |
> |
T_NTH_NBR(t1,1) == T_NTH_NBR(t1,2) || |
1263 |
> |
T_NTH_NBR(t1,0) == T_NTH_NBR(t1,2)) |
1264 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
1265 |
> |
if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t1,0))) || |
1266 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t1,1))) || |
1267 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t1,2)))) |
1268 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
1269 |
|
|
1270 |
< |
smDelete_tri(sm,tri_id); |
1271 |
< |
if(on==ON_E) |
1272 |
< |
smDelete_tri(sm,topp_id); |
1270 |
> |
if(T_NTH_NBR(t2,0) == T_NTH_NBR(t2,1) || |
1271 |
> |
T_NTH_NBR(t2,1) == T_NTH_NBR(t2,2) || |
1272 |
> |
T_NTH_NBR(t2,0) == T_NTH_NBR(t2,2)) |
1273 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
1274 |
> |
if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t2,0))) || |
1275 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t2,1))) || |
1276 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(t2,2)))) |
1277 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
1278 |
> |
n = SM_NTH_TRI(sm,T_NTH_NBR(t2,0)); |
1279 |
> |
if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1) || |
1280 |
> |
T_NTH_NBR(n,1) == T_NTH_NBR(n,2) || |
1281 |
> |
T_NTH_NBR(n,0) == T_NTH_NBR(n,2)) |
1282 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
1283 |
> |
if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) || |
1284 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) || |
1285 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2)))) |
1286 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
1287 |
> |
n = SM_NTH_TRI(sm,T_NTH_NBR(t2,1)); |
1288 |
> |
if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1) || |
1289 |
> |
T_NTH_NBR(n,1) == T_NTH_NBR(n,2) || |
1290 |
> |
T_NTH_NBR(n,0) == T_NTH_NBR(n,2)) |
1291 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
1292 |
> |
if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) || |
1293 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) || |
1294 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2)))) |
1295 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
1296 |
> |
n = SM_NTH_TRI(sm,T_NTH_NBR(t2,2)); |
1297 |
> |
if(T_NTH_NBR(n,0) == T_NTH_NBR(n,1) || |
1298 |
> |
T_NTH_NBR(n,1) == T_NTH_NBR(n,2) || |
1299 |
> |
T_NTH_NBR(n,0) == T_NTH_NBR(n,2)) |
1300 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
1301 |
> |
if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,0))) || |
1302 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,1))) || |
1303 |
> |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(n,2)))) |
1304 |
> |
error(CONSISTENCY,"Invalid topology\n"); |
1305 |
> |
} |
1306 |
> |
#endif |
1307 |
> |
#endif |
1308 |
> |
smRestore_Delaunay(sm,a,b,c,t0,t0_id,s_id,v_id[0],v_id[1]); |
1309 |
> |
smRestore_Delaunay(sm,a,c,d,t1,t1_id,s_id,v_id[1],v_id[2]); |
1310 |
> |
smRestore_Delaunay(sm,a,d,b,t2,t2_id,s_id,v_id[2],v_id[0]); |
1311 |
> |
smDelete_tri(sm,tri_id,tri); |
1312 |
> |
return(TRUE); |
1313 |
|
|
1093 |
– |
return(TRUE); |
1094 |
– |
|
1314 |
|
#ifdef DEBUG |
1315 |
|
Ladderror: |
1316 |
< |
error(CONSISTENCY,"Invalid tri: smInsert_samp()\n"); |
1316 |
> |
error(CONSISTENCY,"Invalid tri: smInsert_samp_mesh()\n"); |
1317 |
|
#endif |
1318 |
|
} |
1319 |
|
|
1320 |
+ |
|
1321 |
|
int |
1322 |
< |
smTri_in_set(sm,p,optr,onptr,whichptr) |
1322 |
> |
smWalk(sm,p,t_id,t,onptr,wptr,from,on_edge,a,b) |
1323 |
|
SM *sm; |
1324 |
|
FVECT p; |
1325 |
< |
OBJECT *optr; |
1326 |
< |
int *onptr,*whichptr; |
1325 |
> |
int t_id; |
1326 |
> |
TRI *t; |
1327 |
> |
int *onptr,*wptr; |
1328 |
> |
int from; |
1329 |
> |
double on_edge; |
1330 |
> |
FVECT a,b; |
1331 |
|
{ |
1108 |
– |
int i,t_id,on0,on1,on2; |
1332 |
|
FVECT n,v0,v1,v2; |
1333 |
< |
TRI *t; |
1111 |
< |
double side; |
1333 |
> |
TRI *tn; |
1334 |
|
|
1335 |
< |
for (i = QT_SET_CNT(optr),optr = QT_SET_PTR(optr);i > 0; i--) |
1336 |
< |
{ |
1337 |
< |
/* Find the first triangle that pt falls */ |
1338 |
< |
t_id = QT_SET_NEXT_ELEM(optr); |
1339 |
< |
t = SM_NTH_TRI(sm,t_id); |
1340 |
< |
if(!T_IS_VALID(t)) |
1341 |
< |
continue; |
1335 |
> |
int tn_id; |
1336 |
> |
|
1337 |
> |
#ifdef DEBUG |
1338 |
> |
Wcnt++; |
1339 |
> |
on0 = on1 = on2 = 10; |
1340 |
> |
#endif |
1341 |
> |
switch(from){ |
1342 |
> |
case 0: |
1343 |
> |
on0 = on_edge; |
1344 |
> |
/* Havnt calculate v0 yet: check for equality first */ |
1345 |
|
VSUB(v0,SM_T_NTH_WV(sm,t,0),SM_VIEW_CENTER(sm)); |
1346 |
< |
VSUB(v1,SM_T_NTH_WV(sm,t,1),SM_VIEW_CENTER(sm)); |
1347 |
< |
VSUB(v2,SM_T_NTH_WV(sm,t,2),SM_VIEW_CENTER(sm)); |
1346 |
> |
normalize(v0); |
1347 |
> |
if(EQUAL_VEC3(v0,p)){ *onptr = ON_V; *wptr = 0; return(t_id); } |
1348 |
> |
/* determine what side of edge v0v1 (v0a) point is on*/ |
1349 |
> |
VCROSS(n,v0,a); |
1350 |
> |
normalize(n); |
1351 |
> |
on2 = DOT(n,p); |
1352 |
> |
if(on2 > 0.0) |
1353 |
> |
{ |
1354 |
> |
tn_id = T_NTH_NBR(t,2); |
1355 |
> |
tn = SM_NTH_TRI(sm,tn_id); |
1356 |
> |
return(smWalk(sm,p,tn_id,tn,onptr,wptr,T_NTH_NBR_PTR(t_id,tn), |
1357 |
> |
-on2,a,v0)); |
1358 |
> |
} |
1359 |
> |
else |
1360 |
> |
if(on2 >= -EDGE_EPS) |
1361 |
> |
{ |
1362 |
> |
if(on0 >= -EDGE_EPS) |
1363 |
> |
{ |
1364 |
> |
/* Could either be epsilon of vertex 1*/ |
1365 |
> |
/* dot(p,a) == cos angle between them. Want length of chord x to |
1366 |
> |
be <= EDGE_EPS for test. if the perpendicular bisector of pa |
1367 |
> |
is d, cos@/2 = d/1, with right triangle d^2 + (x/2)^2 = 1 |
1368 |
> |
or x^2 = 4(1-cos^2@/2) = 4(1- (1 + cos@)/2) = 2 -2cos@, |
1369 |
> |
so test is if x^2 <= VERT_EPS*VERT_EPS, |
1370 |
> |
2 - 2cos@ <= VERT_EPS*VERT_EPS, or... */ |
1371 |
> |
if(DOT(p,a) >= 1.0-VERT_EPS*VERT_EPS/2.0) |
1372 |
> |
{*onptr = ON_P; *wptr = 1;} |
1373 |
> |
else |
1374 |
> |
if(on2 > on0) |
1375 |
> |
{*onptr = ON_E; *wptr = 2;} |
1376 |
> |
else |
1377 |
> |
{*onptr = ON_E; *wptr = 0;} |
1378 |
> |
return(t_id); |
1379 |
> |
} |
1380 |
> |
} |
1381 |
|
|
1382 |
< |
if(EQUAL_VEC3(v0,p)) |
1382 |
> |
VCROSS(n,b,v0); |
1383 |
> |
normalize(n); |
1384 |
> |
on1 = DOT(n,p); |
1385 |
> |
if(on1 > 0.0) |
1386 |
|
{ |
1387 |
< |
*onptr = ON_V; |
1388 |
< |
*whichptr = 0; |
1389 |
< |
return(t_id); |
1387 |
> |
tn_id = T_NTH_NBR(t,1); |
1388 |
> |
tn = SM_NTH_TRI(sm,tn_id); |
1389 |
> |
return(smWalk(sm,p,tn_id,tn,onptr,wptr,T_NTH_NBR_PTR(t_id,tn), |
1390 |
> |
-on1,v0,b)); |
1391 |
|
} |
1392 |
< |
if(EQUAL_VEC3(v1,p)) |
1392 |
> |
else |
1393 |
> |
if(on1 >= -EDGE_EPS) |
1394 |
> |
{ /* Either on v0 or on edge 1 */ |
1395 |
> |
if(on0 >= -EDGE_EPS) |
1396 |
> |
{ |
1397 |
> |
if(DOT(p,b) >= 1.0-VERT_EPS*VERT_EPS/2.0) |
1398 |
> |
{*onptr = ON_P; *wptr = 2;} |
1399 |
> |
else |
1400 |
> |
if(on1 > on0) |
1401 |
> |
{*onptr = ON_E; *wptr = 1;} |
1402 |
> |
else |
1403 |
> |
{*onptr = ON_E; *wptr = 0;} |
1404 |
> |
return(t_id); |
1405 |
> |
} |
1406 |
> |
if(on2 >= -EDGE_EPS) |
1407 |
> |
{ |
1408 |
> |
if(DOT(p,v0) >= 1.0-VERT_EPS*VERT_EPS/2.0) |
1409 |
> |
{*onptr = ON_P; *wptr = 0;} |
1410 |
> |
else |
1411 |
> |
if( on1 > on2) |
1412 |
> |
{*onptr = ON_E; *wptr = 1;} |
1413 |
> |
else |
1414 |
> |
{*onptr = ON_E; *wptr = 2;} |
1415 |
> |
return(t_id); |
1416 |
> |
} |
1417 |
> |
*onptr = ON_E; *wptr = 1; |
1418 |
> |
return(t_id); |
1419 |
> |
} |
1420 |
> |
else |
1421 |
> |
if(on2 >= -EDGE_EPS) |
1422 |
> |
{ |
1423 |
> |
*onptr = ON_E; *wptr = 2; |
1424 |
> |
return(t_id); |
1425 |
> |
} |
1426 |
> |
if(on0 >= -EDGE_EPS) |
1427 |
> |
{ |
1428 |
> |
*onptr = ON_E; *wptr = 0; |
1429 |
> |
return(t_id); |
1430 |
> |
} |
1431 |
> |
*onptr = IN_T; |
1432 |
> |
return(t_id); |
1433 |
> |
case 1: |
1434 |
> |
on1 = on_edge; |
1435 |
> |
/* Havnt calculate v1 yet: check for equality first */ |
1436 |
> |
VSUB(v1,SM_T_NTH_WV(sm,t,1),SM_VIEW_CENTER(sm)); |
1437 |
> |
normalize(v1); |
1438 |
> |
if(EQUAL_VEC3(v1,p)){ *onptr = ON_V; *wptr = 1; return(t_id); } |
1439 |
> |
/* determine what side of edge v0v1 (v0a) point is on*/ |
1440 |
> |
VCROSS(n,b,v1); |
1441 |
> |
normalize(n); |
1442 |
> |
on2 = DOT(n,p); |
1443 |
> |
if(on2 > 0.0) |
1444 |
|
{ |
1445 |
< |
*onptr = ON_V; |
1446 |
< |
*whichptr = 1; |
1447 |
< |
return(t_id); |
1445 |
> |
tn_id = T_NTH_NBR(t,2); |
1446 |
> |
tn = SM_NTH_TRI(sm,tn_id); |
1447 |
> |
return(smWalk(sm,p,tn_id,tn,onptr,wptr,T_NTH_NBR_PTR(t_id,tn), |
1448 |
> |
-on2,v1,b)); |
1449 |
|
} |
1450 |
< |
if(EQUAL_VEC3(v2,p)) |
1450 |
> |
if(on2 >= -EDGE_EPS) |
1451 |
|
{ |
1452 |
< |
*onptr = ON_V; |
1453 |
< |
*whichptr = 2; |
1454 |
< |
return(t_id); |
1452 |
> |
if(on1 >= -EDGE_EPS) |
1453 |
> |
{ |
1454 |
> |
if(DOT(p,b) >= 1.0-VERT_EPS*VERT_EPS/2.0) |
1455 |
> |
{ *onptr = ON_P; *wptr = 0;} |
1456 |
> |
else |
1457 |
> |
if(on2 > on1) |
1458 |
> |
{ *onptr = ON_E; *wptr = 2;} |
1459 |
> |
else |
1460 |
> |
{ *onptr = ON_E; *wptr = 1;} |
1461 |
> |
return(t_id); |
1462 |
> |
} |
1463 |
|
} |
1142 |
– |
|
1143 |
– |
on0 = on1 =on2 = 0; |
1144 |
– |
VCROSS(n,v0,v1); |
1145 |
– |
side = DOT(n,p); |
1146 |
– |
if(ZERO(side)) |
1147 |
– |
on2 = TRUE; |
1148 |
– |
else |
1149 |
– |
if(side >0.0) |
1150 |
– |
continue; |
1464 |
|
|
1465 |
< |
VCROSS(n,v1,v2); |
1466 |
< |
side = DOT(n,p); |
1467 |
< |
if(ZERO(side)) |
1468 |
< |
on0 = TRUE; |
1465 |
> |
VCROSS(n,v1,a); |
1466 |
> |
normalize(n); |
1467 |
> |
on0 = DOT(n,p); |
1468 |
> |
if(on0 >0.0) |
1469 |
> |
{ |
1470 |
> |
tn_id = T_NTH_NBR(t,0); |
1471 |
> |
tn = SM_NTH_TRI(sm,tn_id); |
1472 |
> |
return(smWalk(sm,p,tn_id,tn,onptr,wptr,T_NTH_NBR_PTR(t_id,tn), |
1473 |
> |
-on0,a,v1)); |
1474 |
> |
} |
1475 |
> |
else |
1476 |
> |
if(on0 >= -EDGE_EPS) |
1477 |
> |
{ /* Either on v0 or on edge 1 */ |
1478 |
> |
if(on1 >= -EDGE_EPS) |
1479 |
> |
{ |
1480 |
> |
if(DOT(p,a) >= 1.0-VERT_EPS*VERT_EPS/2.0) |
1481 |
> |
{*onptr = ON_P; *wptr = 2;} |
1482 |
> |
else |
1483 |
> |
if(on0 > on1) |
1484 |
> |
{ *onptr = ON_E; *wptr = 0;} |
1485 |
> |
else |
1486 |
> |
{ *onptr = ON_E; *wptr = 1;} |
1487 |
> |
return(t_id); |
1488 |
> |
} |
1489 |
> |
if(on2 >= -EDGE_EPS) |
1490 |
> |
{ |
1491 |
> |
if(DOT(p,v1) >= 1.0-VERT_EPS*VERT_EPS/2.0) |
1492 |
> |
{*onptr = ON_P; *wptr = 1;} |
1493 |
> |
else |
1494 |
> |
if(on0 > on2) |
1495 |
> |
{ *onptr = ON_E; *wptr = 0;} |
1496 |
> |
else |
1497 |
> |
{ *onptr = ON_E; *wptr = 2;} |
1498 |
> |
return(t_id); |
1499 |
> |
} |
1500 |
> |
*onptr = ON_E; *wptr = 0; |
1501 |
> |
return(t_id); |
1502 |
> |
} |
1503 |
|
else |
1504 |
< |
if(side >0.0) |
1505 |
< |
continue; |
1504 |
> |
if(on2 >= -EDGE_EPS) |
1505 |
> |
{ |
1506 |
> |
*onptr = ON_E; *wptr = 2; |
1507 |
> |
return(t_id); |
1508 |
> |
} |
1509 |
> |
if(on1 >= -EDGE_EPS) |
1510 |
> |
{ |
1511 |
> |
*onptr = ON_E; *wptr = 1; |
1512 |
> |
return(t_id); |
1513 |
> |
} |
1514 |
> |
*onptr = IN_T; |
1515 |
> |
return(t_id); |
1516 |
> |
case 2: |
1517 |
> |
on2 = on_edge; |
1518 |
> |
VSUB(v2,SM_T_NTH_WV(sm,t,2),SM_VIEW_CENTER(sm)); |
1519 |
> |
normalize(v2); |
1520 |
> |
if(EQUAL_VEC3(v2,p)){ *onptr = ON_V; *wptr = 2; return(t_id); } |
1521 |
|
|
1522 |
< |
VCROSS(n,v2,v0); |
1523 |
< |
side = DOT(n,p); |
1524 |
< |
if(ZERO(side)) |
1525 |
< |
on1 = TRUE; |
1526 |
< |
else |
1165 |
< |
if(side >0.0) |
1166 |
< |
continue; |
1167 |
< |
if(on0) |
1522 |
> |
/* determine what side of edge v0v1 (v0a) point is on*/ |
1523 |
> |
VCROSS(n,b,v2); |
1524 |
> |
normalize(n); |
1525 |
> |
on0 = DOT(n,p); |
1526 |
> |
if(on0 > 0.0) |
1527 |
|
{ |
1528 |
< |
if(on1) |
1528 |
> |
tn_id = T_NTH_NBR(t,0); |
1529 |
> |
tn = SM_NTH_TRI(sm,tn_id); |
1530 |
> |
return(smWalk(sm,p,tn_id,tn,onptr,wptr,T_NTH_NBR_PTR(t_id,tn), |
1531 |
> |
-on0,v2,b)); |
1532 |
> |
} |
1533 |
> |
else |
1534 |
> |
if(on0 >= -EDGE_EPS) |
1535 |
|
{ |
1536 |
< |
*onptr = ON_P; |
1537 |
< |
*whichptr = 2; |
1536 |
> |
if(on2 >= - EDGE_EPS) |
1537 |
> |
{ |
1538 |
> |
if(DOT(p,b) >= 1.0-VERT_EPS*VERT_EPS/2.0) |
1539 |
> |
{*onptr = ON_P; *wptr = 1;} |
1540 |
> |
else |
1541 |
> |
if(on0 > on2) |
1542 |
> |
{*onptr = ON_E; *wptr = 0;} |
1543 |
> |
else |
1544 |
> |
{*onptr = ON_E; *wptr = 2;} |
1545 |
> |
return(t_id); |
1546 |
> |
} |
1547 |
|
} |
1548 |
< |
else |
1549 |
< |
if(on2) |
1548 |
> |
VCROSS(n,v2,a); |
1549 |
> |
normalize(n); |
1550 |
> |
on1 = DOT(n,p); |
1551 |
> |
if(on1 >0.0) |
1552 |
> |
{ |
1553 |
> |
tn_id = T_NTH_NBR(t,1); |
1554 |
> |
tn = SM_NTH_TRI(sm,tn_id); |
1555 |
> |
return(smWalk(sm,p,tn_id,tn,onptr,wptr,T_NTH_NBR_PTR(t_id,tn), |
1556 |
> |
-on1,a,v2)); |
1557 |
> |
} |
1558 |
> |
else |
1559 |
> |
if(on1 >= -EDGE_EPS) |
1560 |
> |
{ /* Either on v0 or on edge 1 */ |
1561 |
> |
if(on0 >= - EDGE_EPS) |
1562 |
|
{ |
1563 |
< |
*onptr = ON_P; |
1564 |
< |
*whichptr = 1; |
1563 |
> |
if(DOT(p,v2) >= 1.0-VERT_EPS*VERT_EPS/2.0) |
1564 |
> |
{*onptr = ON_P;*wptr = 2;} |
1565 |
> |
else |
1566 |
> |
if(on1 > on0) |
1567 |
> |
{*onptr = ON_E;*wptr = 1;} |
1568 |
> |
else |
1569 |
> |
{*onptr = ON_E;*wptr = 0;} |
1570 |
> |
return(t_id); |
1571 |
|
} |
1572 |
+ |
if(on2 >= -EDGE_EPS) |
1573 |
+ |
{ |
1574 |
+ |
if(DOT(p,a) >= 1.0-VERT_EPS*VERT_EPS/2.0) |
1575 |
+ |
{*onptr = ON_P;*wptr = 0;} |
1576 |
|
else |
1577 |
< |
{ |
1578 |
< |
*onptr = ON_E; |
1579 |
< |
*whichptr = 0; |
1580 |
< |
} |
1581 |
< |
return(t_id); |
1582 |
< |
} |
1583 |
< |
if(on1) |
1584 |
< |
{ |
1585 |
< |
if(on2) |
1577 |
> |
if(on1 > on2) |
1578 |
> |
{*onptr = ON_E;*wptr = 1;} |
1579 |
> |
else |
1580 |
> |
{*onptr = ON_E;*wptr = 2;} |
1581 |
> |
return(t_id); |
1582 |
> |
} |
1583 |
> |
*onptr = ON_E;*wptr = 1; |
1584 |
> |
return(t_id); |
1585 |
> |
} |
1586 |
> |
else |
1587 |
> |
if(on0 >= -EDGE_EPS) |
1588 |
|
{ |
1589 |
< |
*onptr = ON_P; |
1590 |
< |
*whichptr = 0; |
1589 |
> |
*onptr = ON_E;*wptr = 0; |
1590 |
> |
return(t_id); |
1591 |
|
} |
1592 |
< |
else |
1592 |
> |
if(on2 >= -EDGE_EPS) |
1593 |
|
{ |
1594 |
< |
*onptr = ON_E; |
1595 |
< |
*whichptr = 1; |
1594 |
> |
*onptr = ON_E;*wptr = 2; |
1595 |
> |
return(t_id); |
1596 |
|
} |
1597 |
< |
return(t_id); |
1597 |
> |
*onptr = IN_T; |
1598 |
> |
return(t_id); |
1599 |
> |
default: |
1600 |
> |
/* First time called: havnt tested anything */ |
1601 |
> |
/* Check against vertices */ |
1602 |
> |
VSUB(v0,SM_T_NTH_WV(sm,t,0),SM_VIEW_CENTER(sm)); |
1603 |
> |
normalize(v0); |
1604 |
> |
if(EQUAL_VEC3(v0,p)){ *onptr = ON_V; *wptr = 0; return(t_id); } |
1605 |
> |
VSUB(v1,SM_T_NTH_WV(sm,t,1),SM_VIEW_CENTER(sm)); |
1606 |
> |
normalize(v1); |
1607 |
> |
if(EQUAL_VEC3(v1,p)){ *onptr = ON_V; *wptr = 1; return(t_id); } |
1608 |
> |
VSUB(v2,SM_T_NTH_WV(sm,t,2),SM_VIEW_CENTER(sm)); |
1609 |
> |
normalize(v2); |
1610 |
> |
if(EQUAL_VEC3(v2,p)){ *onptr = ON_V; *wptr = 2; return(t_id); } |
1611 |
> |
|
1612 |
> |
VCROSS(n,v0,v1); /* Check against v0v1, or edge 2 */ |
1613 |
> |
normalize(n); |
1614 |
> |
on2 = DOT(n,p); |
1615 |
> |
if(on2 > 0.0) |
1616 |
> |
{ /* Outside edge: traverse to nbr 2 */ |
1617 |
> |
tn_id = T_NTH_NBR(t,2); |
1618 |
> |
tn = SM_NTH_TRI(sm,tn_id); |
1619 |
> |
return(smWalk(sm,p,tn_id,tn,onptr,wptr,T_NTH_NBR_PTR(t_id,tn), |
1620 |
> |
-on2,v1,v0)); |
1621 |
|
} |
1622 |
< |
if(on2) |
1623 |
< |
{ |
1624 |
< |
*onptr = ON_E; |
1625 |
< |
*whichptr = 2; |
1622 |
> |
else |
1623 |
> |
VCROSS(n,v1,v2); /* Check against v1v2 or edge 0 */ |
1624 |
> |
normalize(n); |
1625 |
> |
on0 = DOT(n,p); |
1626 |
> |
if(on0 > 0.0) |
1627 |
> |
{ /* Outside edge: traverse to nbr 0 */ |
1628 |
> |
tn_id = T_NTH_NBR(t,0); |
1629 |
> |
tn = SM_NTH_TRI(sm,tn_id); |
1630 |
> |
return(smWalk(sm,p,tn_id,tn,onptr,wptr,T_NTH_NBR_PTR(t_id,tn), |
1631 |
> |
-on0,v2,v1)); |
1632 |
> |
} |
1633 |
> |
else |
1634 |
> |
if(on0 >= -EDGE_EPS) |
1635 |
> |
{ /* On the line defining edge 0 */ |
1636 |
> |
if(on2 >= -EDGE_EPS) |
1637 |
> |
{ |
1638 |
> |
if(DOT(p,v1) >= 1.0-VERT_EPS*VERT_EPS/2.0) |
1639 |
> |
{*onptr = ON_P;*wptr = 1;} |
1640 |
> |
else |
1641 |
> |
if(on0 > on2) |
1642 |
> |
{*onptr = ON_E;*wptr = 0;} |
1643 |
> |
else |
1644 |
> |
{*onptr = ON_E;*wptr = 2;} |
1645 |
> |
return(t_id); |
1646 |
> |
} |
1647 |
> |
} |
1648 |
> |
VCROSS(n,v2,v0); /* Check against v2v0 or edge 1 */ |
1649 |
> |
normalize(n); |
1650 |
> |
on1 = DOT(n,p); |
1651 |
> |
if(on1 >0.0) |
1652 |
> |
{ /* Outside edge: traverse to nbr 1 */ |
1653 |
> |
tn_id = T_NTH_NBR(t,1); |
1654 |
> |
tn = SM_NTH_TRI(sm,tn_id); |
1655 |
> |
return(smWalk(sm,p,tn_id,tn,onptr,wptr,T_NTH_NBR_PTR(t_id,tn), |
1656 |
> |
-on1,v0,v2)); |
1657 |
> |
} |
1658 |
> |
else |
1659 |
> |
if(on1 >= -EDGE_EPS) |
1660 |
> |
{ /* On the line defining edge 1 */ |
1661 |
> |
if(on2 >= -EDGE_EPS) |
1662 |
> |
{ |
1663 |
> |
if(DOT(p,v0) >= 1.0-VERT_EPS*VERT_EPS/2.0) |
1664 |
> |
{*onptr = ON_P;*wptr = 0;} |
1665 |
> |
else |
1666 |
> |
if(on1 > on2) |
1667 |
> |
{*onptr = ON_E;*wptr = 1;} |
1668 |
> |
else |
1669 |
> |
{*onptr = ON_E;*wptr = 2;} |
1670 |
> |
return(t_id); |
1671 |
> |
} |
1672 |
> |
if(on0 >= -EDGE_EPS) |
1673 |
> |
{ |
1674 |
> |
if(DOT(p,v2) >= 1.0-VERT_EPS*VERT_EPS/2.0) |
1675 |
> |
{*onptr = ON_P;*wptr = 2;} |
1676 |
> |
else |
1677 |
> |
if(on1 > on0) |
1678 |
> |
{*onptr = ON_E;*wptr = 1;} |
1679 |
> |
else |
1680 |
> |
{*onptr = ON_E;*wptr = 0;} |
1681 |
> |
return(t_id); |
1682 |
> |
} |
1683 |
> |
*onptr = ON_E; /* Only on edge 1 */ |
1684 |
> |
*wptr = 1; |
1685 |
> |
return(t_id); |
1686 |
> |
} |
1687 |
> |
else |
1688 |
> |
if(on2 >= -EDGE_EPS) /* Is on edge 2 ? */ |
1689 |
> |
{ |
1690 |
> |
*onptr = ON_E; *wptr = 2; |
1691 |
> |
return(t_id); |
1692 |
> |
} |
1693 |
> |
if(on0 >= -EDGE_EPS) /* Is on edge 0 ? */ |
1694 |
> |
{ |
1695 |
> |
*onptr = ON_E; *wptr = 0; |
1696 |
|
return(t_id); |
1697 |
< |
} |
1698 |
< |
*onptr = IN_T; |
1697 |
> |
} |
1698 |
> |
*onptr = IN_T; /* Must be interior to t */ |
1699 |
|
return(t_id); |
1700 |
|
} |
1210 |
– |
return(INVALID); |
1701 |
|
} |
1702 |
|
|
1703 |
+ |
#define check_edges(on0,on1,on2,o,w,t_id) \ |
1704 |
+ |
if(on0){if(on1){*o = ON_P;*w = 2;} else if(on2){*o = ON_P;*w = 1;} \ |
1705 |
+ |
else {*o = ON_E; *w = 0; } return(t_id); } \ |
1706 |
+ |
if(on1){if(on2){*o = ON_P;*w = 0;} else {*o = ON_E;*w = 1;}return(t_id);}\ |
1707 |
+ |
if(on2){*o = ON_E;*w = 2;return(t_id);} |
1708 |
+ |
|
1709 |
+ |
#define check_verts(p,v0,v1,v2,o,w,t_id) \ |
1710 |
+ |
if(EQUAL_VEC3(v0,p)){ *o = ON_V; *w = 0; return(t_id); } \ |
1711 |
+ |
if(EQUAL_VEC3(v1,p)){ *o = ON_V; *w = 1; return(t_id); } \ |
1712 |
+ |
if(EQUAL_VEC3(v2,p)){ *o = ON_V; *w = 2; return(t_id);} |
1713 |
+ |
|
1714 |
+ |
|
1715 |
|
int |
1716 |
< |
smPointLocateTri(sm,p,onptr,whichptr) |
1716 |
> |
find_neighbor(argptr,qt,f,doneptr) |
1717 |
> |
int *argptr; |
1718 |
> |
QUADTREE qt; |
1719 |
> |
FUNC f; |
1720 |
> |
int *doneptr; |
1721 |
> |
{ |
1722 |
> |
int s_id,i; |
1723 |
> |
OBJECT *optr; |
1724 |
> |
|
1725 |
> |
if(QT_IS_EMPTY(qt)) |
1726 |
> |
return; |
1727 |
> |
else |
1728 |
> |
if(QT_IS_TREE(qt)) |
1729 |
> |
{ |
1730 |
> |
for(i=0;i < 4; i++) |
1731 |
> |
{ |
1732 |
> |
find_neighbor(argptr,QT_NTH_CHILD(qt,i),f,doneptr); |
1733 |
> |
if(*doneptr) |
1734 |
> |
return; |
1735 |
> |
} |
1736 |
> |
} |
1737 |
> |
else |
1738 |
> |
{ |
1739 |
> |
optr = qtqueryset(qt); |
1740 |
> |
for(i = QT_SET_CNT(optr); i > 0; i--) |
1741 |
> |
{ |
1742 |
> |
s_id = QT_SET_NEXT_ELEM(optr); |
1743 |
> |
if(s_id != ((S_ARGS *)argptr)->s_id) |
1744 |
> |
{ |
1745 |
> |
*doneptr = TRUE; |
1746 |
> |
((S_ARGS *)argptr)->n_id = s_id; |
1747 |
> |
return; |
1748 |
> |
} |
1749 |
> |
} |
1750 |
> |
} |
1751 |
> |
} |
1752 |
> |
|
1753 |
> |
smInsert_samp(sm,s_id,p,nptr) |
1754 |
|
SM *sm; |
1755 |
+ |
int s_id; |
1756 |
|
FVECT p; |
1757 |
< |
int *onptr,*whichptr; |
1757 |
> |
int *nptr; |
1758 |
|
{ |
1219 |
– |
QUADTREE qt,*optr; |
1759 |
|
FVECT tpt; |
1760 |
+ |
FUNC f; |
1761 |
+ |
S_ARGS args; |
1762 |
+ |
|
1763 |
+ |
F_FUNC(f) = insert_samp; |
1764 |
+ |
args.s_id = s_id; |
1765 |
+ |
if(nptr) |
1766 |
+ |
{ |
1767 |
+ |
args.n_id = 1; |
1768 |
+ |
F_FUNC2(f) = find_neighbor; |
1769 |
+ |
} |
1770 |
+ |
else |
1771 |
+ |
args.n_id = 0; |
1772 |
+ |
F_ARGS(f) = (int *)(&args); |
1773 |
+ |
stInsert_samp(SM_LOCATOR(sm),p,f); |
1774 |
+ |
|
1775 |
+ |
if(nptr) |
1776 |
+ |
*nptr = args.n_id; |
1777 |
+ |
} |
1778 |
+ |
|
1779 |
+ |
/* Assumed p is normalized to view sphere */ |
1780 |
+ |
int |
1781 |
+ |
smSample_locate_tri(sm,p,s_id,onptr,whichptr,nptr) |
1782 |
+ |
SM *sm; |
1783 |
+ |
FVECT p; |
1784 |
+ |
int s_id; |
1785 |
+ |
int *onptr,*whichptr,*nptr; |
1786 |
+ |
{ |
1787 |
|
int tri_id; |
1788 |
+ |
FVECT tpt; |
1789 |
+ |
TRI *tri; |
1790 |
|
|
1791 |
< |
VSUB(tpt,p,SM_VIEW_CENTER(sm)); |
1792 |
< |
qt = smPointLocateCell(sm,tpt); |
1793 |
< |
if(QT_IS_EMPTY(qt)) |
1794 |
< |
return(INVALID); |
1795 |
< |
|
1796 |
< |
optr = qtqueryset(qt); |
1797 |
< |
tri_id = smTri_in_set(sm,tpt,optr,onptr,whichptr); |
1791 |
> |
if(SM_S_NTH_QT(sm,s_id) == EMPTY) |
1792 |
> |
smInsert_samp(sm,s_id,p,nptr); |
1793 |
> |
#ifdef DEBUG |
1794 |
> |
if(*nptr == INVALID) |
1795 |
> |
error(CONSISTENCY,"smSample_locate_tri: unable to find sample\n"); |
1796 |
> |
#endif |
1797 |
> |
|
1798 |
> |
/* Get the triangle adjacent to a sample in qt, or if there are no other |
1799 |
> |
samples in qt than the one just inserted, look at siblings-from parent |
1800 |
> |
node |
1801 |
> |
*/ |
1802 |
|
|
1803 |
+ |
tri_id = SM_NTH_VERT(sm,*nptr); |
1804 |
|
#ifdef DEBUG |
1805 |
< |
if(!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(SM_NTH_TRI(sm,tri_id),0))) || |
1806 |
< |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(SM_NTH_TRI(sm,tri_id),1))) || |
1234 |
< |
!T_IS_VALID(SM_NTH_TRI(sm,T_NTH_NBR(SM_NTH_TRI(sm,tri_id),2)))) |
1235 |
< |
eputs("Invalid tri nbrs smPointLocateTri()\n"); |
1805 |
> |
if(tri_id == INVALID) |
1806 |
> |
error(CONSISTENCY,"smSample_locate_tri: Invalid tri_id\n"); |
1807 |
|
#endif |
1808 |
< |
return(tri_id); |
1808 |
> |
|
1809 |
> |
tri = SM_NTH_TRI(sm,tri_id); |
1810 |
> |
#ifdef DEBUG |
1811 |
> |
Tcnt++; |
1812 |
> |
if(!T_IS_VALID(tri)) |
1813 |
> |
error(CONSISTENCY,"smSample_locate_tri: Invalid tri\n"); |
1814 |
> |
#endif |
1815 |
> |
tri_id = smWalk(sm,p,tri_id,tri,onptr,whichptr,-1,0.0,NULL,NULL); |
1816 |
> |
#ifdef DEBUG |
1817 |
> |
if(tri_id == INVALID) |
1818 |
> |
error(CONSISTENCY,"smSample_locate_tri: unable to find tri on walk\n"); |
1819 |
> |
#endif |
1820 |
> |
return(tri_id); |
1821 |
|
} |
1822 |
|
|
1240 |
– |
|
1823 |
|
/* |
1824 |
|
Determine whether this sample should: |
1825 |
|
a) be added to the mesh by subdividing the triangle |
1849 |
|
This attempts to throw out points that should be occluded |
1850 |
|
*/ |
1851 |
|
int |
1852 |
< |
smTest_sample(sm,tri_id,dir,p,rptr) |
1852 |
> |
smTest_samp(sm,tri_id,dir,p,rptr,ns,n0,n1,n2,ds,d0,on,which) |
1853 |
|
SM *sm; |
1854 |
|
int tri_id; |
1855 |
|
FVECT dir,p; |
1856 |
|
int *rptr; |
1857 |
+ |
FVECT ns,n0,n1,n2; |
1858 |
+ |
double ds,d0; |
1859 |
+ |
int on,which; |
1860 |
|
{ |
1861 |
|
TRI *tri; |
1862 |
< |
double d,d2,dnear,dspt,d01,d12,d20,s0,s1,s2,ds,dv; |
1862 |
> |
double d,d2,dnear,dspt,d01,d12,d20,s0,s1,s2; |
1863 |
> |
double dp,dp1; |
1864 |
|
int vid[3],i,nearid,norm,dcnt,bcnt; |
1865 |
< |
FVECT diff[3],spt,npt; |
1865 |
> |
FVECT diff[3],spt,npt,n; |
1866 |
> |
FVECT nearpt; |
1867 |
|
|
1868 |
|
*rptr = INVALID; |
1869 |
|
bcnt = dcnt = 0; |
1874 |
|
|
1875 |
|
for(i=0; i<3; i++) |
1876 |
|
{ |
1877 |
< |
if(SM_BASE_ID(sm,vid[i])) |
1878 |
< |
{ |
1879 |
< |
bcnt++; |
1293 |
< |
continue; |
1294 |
< |
} |
1877 |
> |
if(SM_BASE_ID(sm,vid[i])) |
1878 |
> |
bcnt++; |
1879 |
> |
else |
1880 |
|
if(SM_DIR_ID(sm,vid[i])) |
1881 |
< |
dcnt++; |
1297 |
< |
VSUB(diff[i],SM_NTH_WV(sm,vid[i]),p); |
1298 |
< |
/* If same world point: replace */ |
1881 |
> |
dcnt++; |
1882 |
|
} |
1883 |
< |
/* TEST 1: If the new sample is close in ws, and close in the spherical |
1301 |
< |
projection to one of the triangle vertex samples |
1302 |
< |
*/ |
1303 |
< |
norm = FALSE; |
1304 |
< |
if(bcnt + dcnt != 3) |
1883 |
> |
if( on == IN_T) |
1884 |
|
{ |
1885 |
< |
VSUB(spt,p,SM_VIEW_CENTER(sm)); |
1886 |
< |
ds = DOT(spt,spt); |
1887 |
< |
dnear = FHUGE; |
1888 |
< |
for(i=0; i<3; i++) |
1889 |
< |
{ |
1890 |
< |
if(SM_BASE_ID(sm,vid[i]) || SM_DIR_ID(sm,vid[i])) |
1891 |
< |
continue; |
1892 |
< |
d = DOT(diff[i],diff[i])/ds; |
1893 |
< |
if(d < dnear) |
1894 |
< |
{ |
1895 |
< |
dnear = d; |
1896 |
< |
nearid=vid[i]; |
1897 |
< |
} |
1898 |
< |
} |
1885 |
> |
d = DIST_SQ(n0,ns); |
1886 |
> |
dnear = d; |
1887 |
> |
nearid = 0; |
1888 |
> |
d = DIST_SQ(n1,ns); |
1889 |
> |
if(d < dnear) |
1890 |
> |
{ |
1891 |
> |
dnear = d; nearid = 1; |
1892 |
> |
} |
1893 |
> |
d = DIST_SQ(n2,ns); |
1894 |
> |
if(d < dnear) |
1895 |
> |
{ |
1896 |
> |
dnear = d; nearid = 2; |
1897 |
> |
} |
1898 |
> |
} |
1899 |
> |
if(on == ON_P) |
1900 |
> |
nearid = which; |
1901 |
> |
if(on == ON_P || dnear < VERT_EPS*VERT_EPS) |
1902 |
> |
{ |
1903 |
> |
FVECT edir; |
1904 |
> |
/* Pick the point with dir closest to that of the canonical view |
1905 |
> |
if it is the new sample: mark existing point for deletion |
1906 |
> |
*/ |
1907 |
> |
if(SM_BASE_ID(sm,vid[nearid])) |
1908 |
> |
return(FALSE); |
1909 |
> |
if(!dir) |
1910 |
> |
return(FALSE); |
1911 |
> |
if(SM_DIR_ID(sm,vid[nearid])) |
1912 |
> |
{ |
1913 |
> |
*rptr = vid[nearid]; |
1914 |
> |
return(TRUE); |
1915 |
> |
} |
1916 |
> |
decodedir(edir,SM_NTH_W_DIR(sm,vid[nearid])); |
1917 |
> |
if(nearid == 0) |
1918 |
> |
d = DOT(edir,n0); |
1919 |
> |
else |
1920 |
> |
if(nearid == 1) |
1921 |
> |
d = DOT(edir,n1); |
1922 |
> |
else |
1923 |
> |
d = DOT(edir,n2); |
1924 |
> |
d2 = DOT(dir,ns); |
1925 |
> |
/* The existing sample is a better sample:punt */ |
1926 |
> |
if(d2 >= d) |
1927 |
> |
return(FALSE); |
1928 |
> |
else |
1929 |
> |
{ |
1930 |
> |
/* The new sample is better: mark existing one for deletion*/ |
1931 |
> |
*rptr = vid[nearid]; |
1932 |
> |
return(TRUE); |
1933 |
> |
} |
1934 |
> |
} |
1935 |
|
|
1936 |
< |
if(dnear <= smMinSampDiff*smMinSampDiff) |
1936 |
> |
/* Now test if sample epsilon is within circumcircle of enclosing tri |
1937 |
> |
if not punt: |
1938 |
> |
*/ |
1939 |
> |
{ |
1940 |
> |
double ab[3],ac[3],r[3]; |
1941 |
> |
|
1942 |
> |
VSUB(ab,n2,n1); |
1943 |
> |
VSUB(ac,n0,n2); |
1944 |
> |
VCROSS(r,ab,ac); |
1945 |
> |
dp = DOT(r,n1); |
1946 |
> |
dp1 = DOT(r,ns); |
1947 |
> |
if(dp1*dp1 + COS_VERT_EPS*DOT(r,r) < dp*dp) |
1948 |
|
{ |
1949 |
< |
/* Pick the point with dir closest to that of the canonical view |
1950 |
< |
if it is the new sample: mark existing point for deletion |
1951 |
< |
*/ |
1952 |
< |
normalize(spt); |
1327 |
< |
norm = TRUE; |
1328 |
< |
VSUB(npt,SM_NTH_WV(sm,nearid),SM_VIEW_CENTER(sm)); |
1329 |
< |
normalize(npt); |
1330 |
< |
d = fdir2diff(SM_NTH_W_DIR(sm,nearid), npt); |
1331 |
< |
d2 = 2. - 2.*DOT(dir,spt); |
1332 |
< |
/* The existing sample is a better sample:punt */ |
1333 |
< |
if(d2 > d) |
1334 |
< |
return(FALSE); |
1335 |
< |
else |
1336 |
< |
{ |
1337 |
< |
/* The new sample is better: mark the existing one |
1338 |
< |
for deletion after the new one is added*/ |
1339 |
< |
*rptr = nearid; |
1340 |
< |
return(TRUE); |
1341 |
< |
} |
1949 |
> |
#ifdef DEBUG |
1950 |
> |
eputs("smTest_samp:rejecting samp,cant guarantee not within eps\n"); |
1951 |
> |
#endif |
1952 |
> |
return(FALSE); |
1953 |
|
} |
1954 |
|
} |
1955 |
< |
/* TEST 3: If the spherical projection of new is < S_REPLACE_EPS |
1956 |
< |
from a base point: Edge length is constrained to subtend <45 degrees: |
1957 |
< |
original base mesh edges are approx 32 degrees- so have about 13 degrees |
1958 |
< |
to work in: S_REPLACE_EPS is the square of the radian value |
1959 |
< |
*/ |
1960 |
< |
if(bcnt) |
1961 |
< |
{ |
1351 |
< |
dnear = FHUGE; |
1352 |
< |
if(bcnt + dcnt ==3) |
1353 |
< |
VSUB(spt,p,SM_VIEW_CENTER(sm)); |
1354 |
< |
if(!norm) |
1355 |
< |
normalize(spt); |
1955 |
> |
#ifdef DEBUG |
1956 |
> |
#if DEBUG > 1 |
1957 |
> |
if(on == ON_E) |
1958 |
> |
{ |
1959 |
> |
TRI *topp; |
1960 |
> |
int opp_id; |
1961 |
> |
FVECT vopp; |
1962 |
|
|
1963 |
< |
for(i=0; i<3; i++) |
1964 |
< |
{ |
1965 |
< |
if(!SM_BASE_ID(sm,vid[i])) |
1966 |
< |
continue; |
1967 |
< |
VSUB(npt,SM_NTH_WV(sm,vid[i]),SM_VIEW_CENTER(sm)); |
1968 |
< |
d = DIST_SQ(npt,spt); |
1969 |
< |
if(d < S_REPLACE_EPS && d < dnear) |
1970 |
< |
{ |
1971 |
< |
dnear = d; |
1972 |
< |
nearid = vid[i]; |
1973 |
< |
} |
1974 |
< |
} |
1975 |
< |
if(dnear != FHUGE) |
1976 |
< |
{ |
1977 |
< |
/* add new and mark the base for deletion */ |
1978 |
< |
*rptr = nearid; |
1979 |
< |
return(TRUE); |
1980 |
< |
} |
1963 |
> |
topp = SM_NTH_TRI(sm,T_NTH_NBR(tri,which)); |
1964 |
> |
opp_id = T_NTH_V(topp, T_NTH_NBR_PTR(tri_id,topp)); |
1965 |
> |
/* first check if valid tri created*/ |
1966 |
> |
VSUB(vopp,SM_NTH_WV(sm,opp_id),SM_VIEW_CENTER(sm)); |
1967 |
> |
normalize(vopp); |
1968 |
> |
VCROSS(n,ns,vopp); |
1969 |
> |
normalize(n); |
1970 |
> |
if(which==2) |
1971 |
> |
dp = DOT(n,n0) * DOT(n,n1); |
1972 |
> |
else |
1973 |
> |
if(which==0) |
1974 |
> |
dp = DOT(n,n1) * DOT(n,n2); |
1975 |
> |
else |
1976 |
> |
dp = DOT(n,n2) * DOT(n,n0); |
1977 |
> |
if(dp > 0.0) |
1978 |
> |
{ |
1979 |
> |
eputs("smInsert_samp_mesh: couldn't split edge: rejecting\n"); |
1980 |
> |
/* test epsilon for edge */ |
1981 |
> |
return(FALSE); |
1982 |
> |
} |
1983 |
|
} |
1984 |
< |
|
1984 |
> |
#endif |
1985 |
> |
#endif |
1986 |
|
/* TEST 4: |
1987 |
|
If the addition of the new sample point would introduce a "puncture" |
1988 |
|
or cause new triangles with large depth differences:dont add: |
1989 |
|
*/ |
1990 |
|
if(bcnt || dcnt) |
1991 |
|
return(TRUE); |
1992 |
< |
/* If the new point is in front of the existing points- add */ |
1993 |
< |
dv = DIST_SQ(SM_NTH_WV(sm,vid[0]),SM_VIEW_CENTER(sm)); |
1385 |
< |
if(ds < dv) |
1992 |
> |
|
1993 |
> |
if(ds < d0) |
1994 |
|
return(TRUE); |
1995 |
|
|
1996 |
|
d01 = DIST_SQ(SM_NTH_WV(sm,vid[1]),SM_NTH_WV(sm,vid[0])); |
1997 |
+ |
VSUB(diff[0],SM_NTH_WV(sm,vid[0]),p); |
1998 |
|
s0 = DOT(diff[0],diff[0]); |
1999 |
|
if(s0 < S_REPLACE_SCALE*d01) |
2000 |
|
return(TRUE); |
2001 |
+ |
|
2002 |
|
d12 = DIST_SQ(SM_NTH_WV(sm,vid[2]),SM_NTH_WV(sm,vid[1])); |
2003 |
|
if(s0 < S_REPLACE_SCALE*d12) |
2004 |
|
return(TRUE); |
2006 |
|
if(s0 < S_REPLACE_SCALE*d20) |
2007 |
|
return(TRUE); |
2008 |
|
d = MIN3(d01,d12,d20); |
2009 |
< |
s1 = DOT(diff[1],diff[1]); |
2009 |
> |
VSUB(diff[1],SM_NTH_WV(sm,vid[1]),p); |
2010 |
> |
s1 = DOT(diff[1],diff[1]); |
2011 |
|
if(s1 < S_REPLACE_SCALE*d) |
2012 |
|
return(TRUE); |
2013 |
+ |
VSUB(diff[2],SM_NTH_WV(sm,vid[2]),p); |
2014 |
|
s2 = DOT(diff[2],diff[2]); |
2015 |
|
if(s2 < S_REPLACE_SCALE*d) |
2016 |
|
return(TRUE); |
2018 |
|
/* TEST 5: |
2019 |
|
Check to see if triangle is relatively large and should therefore |
2020 |
|
be subdivided anyway. |
2021 |
< |
*/ |
2022 |
< |
dv *= DIST_SQ(SM_NTH_WV(sm,vid[1]),SM_VIEW_CENTER(sm)); |
2023 |
< |
dv *= DIST_SQ(SM_NTH_WV(sm,vid[2]),SM_VIEW_CENTER(sm)); |
2024 |
< |
if (d01*d12*d20/dv > S_REPLACE_TRI) |
2021 |
> |
*/ |
2022 |
> |
d0 = d0*d0*DIST_SQ(SM_NTH_WV(sm,vid[1]),SM_VIEW_CENTER(sm)); |
2023 |
> |
d0 *= DIST_SQ(SM_NTH_WV(sm,vid[2]),SM_VIEW_CENTER(sm)); |
2024 |
> |
if (d01*d12*d20/d0 > S_REPLACE_TRI) |
2025 |
|
return(TRUE); |
2026 |
|
|
2027 |
|
return(FALSE); |
2028 |
|
} |
1417 |
– |
|
1418 |
– |
|
2029 |
|
int |
2030 |
< |
smAlloc_samp(sm) |
1421 |
< |
SM *sm; |
1422 |
< |
{ |
1423 |
< |
int s_id,replaced,cnt; |
1424 |
< |
SAMP *s; |
1425 |
< |
FVECT p; |
1426 |
< |
|
1427 |
< |
s = SM_SAMP(sm); |
1428 |
< |
s_id = sAlloc_samp(s,&replaced); |
1429 |
< |
|
1430 |
< |
cnt=0; |
1431 |
< |
while(replaced) |
1432 |
< |
{ |
1433 |
< |
if(smRemoveVertex(sm,s_id)) |
1434 |
< |
break; |
1435 |
< |
s_id = sAlloc_samp(s,&replaced); |
1436 |
< |
cnt++; |
1437 |
< |
if(cnt > S_MAX_SAMP(s)) |
1438 |
< |
error(CONSISTENCY,"smAlloc_samp():unable to find free samp\n"); |
1439 |
< |
} |
1440 |
< |
return(s_id); |
1441 |
< |
} |
1442 |
< |
|
1443 |
< |
int |
1444 |
< |
smReplace_samp(sm,c,dir,p,s_id,t_id,o_id,on,which) |
2030 |
> |
smReplace_samp(sm,c,dir,p,np,s_id,t_id,o_id,on,which) |
2031 |
|
SM *sm; |
2032 |
|
COLR c; |
2033 |
< |
FVECT dir,p; |
2033 |
> |
FVECT dir,p,np; |
2034 |
|
int s_id,t_id,o_id,on,which; |
2035 |
|
{ |
2036 |
< |
int tonemap,v_id; |
2036 |
> |
int v_id,tri_id; |
2037 |
|
TRI *t,*tri; |
2038 |
|
|
2039 |
|
tri = SM_NTH_TRI(sm,t_id); |
2041 |
|
|
2042 |
|
/* If it is a base id, need new sample */ |
2043 |
|
if(SM_BASE_ID(sm,v_id)) |
2044 |
< |
{ |
2045 |
< |
tonemap = (SM_TONE_MAP(sm) > s_id); |
2046 |
< |
sInit_samp(SM_SAMP(sm),s_id,c,dir,p,o_id,tonemap); |
2047 |
< |
SM_NTH_VERT(sm,s_id) = t_id; |
2048 |
< |
T_NTH_V(tri,which) = s_id; |
2049 |
< |
if(!(SM_BASE_ID(sm,T_NTH_V(tri,(which+1)%3)) || |
2050 |
< |
SM_BASE_ID(sm,T_NTH_V(tri,(which+2)%3)))) |
2051 |
< |
SM_CLR_NTH_T_BASE(sm,t_id); |
2052 |
< |
t_id = smTri_next_ccw_nbr(sm,tri,v_id); |
2053 |
< |
while(t_id != INVALID) |
2044 |
> |
return(v_id); |
2045 |
> |
|
2046 |
> |
if(EQUAL_VEC3(p,SM_NTH_WV(sm,v_id))) |
2047 |
> |
return(INVALID); |
2048 |
> |
|
2049 |
> |
if(dir) |
2050 |
> |
{ /* If world point */ |
2051 |
> |
FVECT odir,no; |
2052 |
> |
double d,d1; |
2053 |
> |
int dir_id; |
2054 |
> |
/* if existing point is a not a dir, compare directions */ |
2055 |
> |
if(!(dir_id = SM_DIR_ID(sm,v_id))) |
2056 |
|
{ |
2057 |
< |
t = SM_NTH_TRI(sm,t_id); |
2058 |
< |
which = T_WHICH_V(t,v_id); |
2059 |
< |
T_NTH_V(t,which) = s_id; |
2060 |
< |
/* Check if still a base triangle */ |
2061 |
< |
if(!(SM_BASE_ID(sm,T_NTH_V(t,(which+1)%3)) || |
1474 |
< |
SM_BASE_ID(sm,T_NTH_V(t,(which+2)%3)))) |
1475 |
< |
SM_CLR_NTH_T_BASE(sm,t_id); |
1476 |
< |
t_id = smTri_next_ccw_nbr(sm,t,v_id); |
2057 |
> |
decodedir(odir, SM_NTH_W_DIR(sm,v_id)); |
2058 |
> |
VSUB(no,SM_NTH_WV(sm,v_id),SM_VIEW_CENTER(sm)); |
2059 |
> |
d = DOT(dir,np); |
2060 |
> |
d1 = DOT(odir,np); |
2061 |
> |
/* The existing sample is a better sample:punt */ |
2062 |
|
} |
2063 |
< |
return(s_id); |
1479 |
< |
} |
1480 |
< |
else |
1481 |
< |
if(on == ON_V || !p) |
2063 |
> |
if(dir_id || (d*d*DOT(no,no) > d1*d1)) |
2064 |
|
{ |
2065 |
< |
tonemap = (SM_TONE_MAP(sm) > v_id); |
2066 |
< |
sInit_samp(SM_SAMP(sm),v_id,c,dir,p,o_id,tonemap); |
2067 |
< |
return(v_id); |
2068 |
< |
} |
2069 |
< |
else /* on == ON_P */ |
2070 |
< |
{ |
1489 |
< |
FVECT spt,npt; |
1490 |
< |
double d,d2; |
1491 |
< |
|
1492 |
< |
/* Need to check which sample is preferable */ |
1493 |
< |
VSUB(spt,p,SM_VIEW_CENTER(sm)); |
1494 |
< |
normalize(spt); |
1495 |
< |
|
1496 |
< |
VSUB(npt,SM_NTH_WV(sm,v_id),SM_VIEW_CENTER(sm)); |
1497 |
< |
normalize(npt); |
1498 |
< |
d = fdir2diff(SM_NTH_W_DIR(sm,v_id), npt); |
1499 |
< |
d2 = 2. - 2.*DOT(dir,spt); |
1500 |
< |
/* The existing sample is a better sample:punt */ |
1501 |
< |
if(d2 < d) |
2065 |
> |
/* The new sample has better information- replace values */ |
2066 |
> |
sInit_samp(SM_SAMP(sm),v_id,c,dir,p,o_id); |
2067 |
> |
if(!SM_IS_NTH_T_NEW(sm,t_id)) |
2068 |
> |
SM_SET_NTH_T_NEW(sm,t_id); |
2069 |
> |
tri_id = smTri_next_ccw_nbr(sm,tri,v_id); |
2070 |
> |
while(tri_id != t_id) |
2071 |
|
{ |
2072 |
< |
/* The new sample has better information- replace values */ |
2073 |
< |
tonemap = (SM_TONE_MAP(sm) > v_id); |
2074 |
< |
sInit_samp(SM_SAMP(sm),v_id,c,dir,p,o_id,tonemap); |
2072 |
> |
t = SM_NTH_TRI(sm,tri_id); |
2073 |
> |
if(!SM_IS_NTH_T_NEW(sm,tri_id)) |
2074 |
> |
SM_SET_NTH_T_NEW(sm,tri_id); |
2075 |
> |
tri_id = smTri_next_ccw_nbr(sm,t,v_id); |
2076 |
|
} |
1507 |
– |
return(v_id); |
2077 |
|
} |
2078 |
+ |
return(v_id); |
2079 |
+ |
} |
2080 |
+ |
else /* New point is a dir */ |
2081 |
+ |
return(INVALID); |
2082 |
+ |
|
2083 |
|
} |
2084 |
|
|
2085 |
+ |
int |
2086 |
+ |
smAlloc_samp(sm) |
2087 |
+ |
SM *sm; |
2088 |
+ |
{ |
2089 |
+ |
int s_id,replaced,cnt; |
2090 |
+ |
SAMP *s; |
2091 |
+ |
FVECT p; |
2092 |
+ |
|
2093 |
+ |
s = SM_SAMP(sm); |
2094 |
+ |
s_id = sAlloc_samp(s,&replaced); |
2095 |
+ |
while(replaced) |
2096 |
+ |
{ |
2097 |
+ |
smRemoveVertex(sm,s_id); |
2098 |
+ |
s_id = sAlloc_samp(s,&replaced); |
2099 |
+ |
} |
2100 |
+ |
return(s_id); |
2101 |
+ |
} |
2102 |
+ |
|
2103 |
+ |
|
2104 |
|
/* Add sample to the mesh: |
2105 |
|
|
2106 |
|
the sample can be a world space or directional point. If o_id !=INVALID, |
2121 |
|
FVECT dir,p; |
2122 |
|
int o_id; |
2123 |
|
{ |
2124 |
< |
int t_id,s_id,r_id,on,which,n_id; |
2125 |
< |
double d; |
2126 |
< |
FVECT wpt; |
2124 |
> |
int t_id,s_id,r_id,on,which,n_id,nbr_id; |
2125 |
> |
double ds,d0; |
2126 |
> |
FVECT wpt,ns,n0,n1,n2; |
2127 |
> |
QUADTREE qt,parent; |
2128 |
> |
TRI *t; |
2129 |
|
|
2130 |
|
r_id = INVALID; |
2131 |
< |
|
2131 |
> |
nbr_id = INVALID; |
2132 |
|
/* Must do this first-as may change mesh */ |
2133 |
|
s_id = smAlloc_samp(sm); |
2134 |
+ |
|
2135 |
+ |
SM_S_NTH_QT(sm,s_id)= EMPTY; |
2136 |
|
/* If sample is a world space point */ |
2137 |
|
if(p) |
2138 |
|
{ |
2139 |
< |
t_id = smPointLocateTri(sm,p,&on,&which); |
2140 |
< |
if(t_id == INVALID) |
2139 |
> |
VSUB(ns,p,SM_VIEW_CENTER(sm)); |
2140 |
> |
ds = normalize(ns); |
2141 |
> |
while(1) |
2142 |
> |
{ |
2143 |
> |
t_id = smSample_locate_tri(sm,ns,s_id,&on,&which,&nbr_id); |
2144 |
> |
qt = SM_S_NTH_QT(sm,s_id); |
2145 |
> |
if(t_id == INVALID) |
2146 |
|
{ |
2147 |
|
#ifdef DEBUG |
2148 |
< |
eputs("smAddSamp(): unable to locate tri containing sample \n"); |
2148 |
> |
eputs("smAddSamp(): unable to locate tri containing sample \n"); |
2149 |
|
#endif |
2150 |
+ |
smUnalloc_samp(sm,s_id); |
2151 |
+ |
qtremovelast(qt,s_id); |
2152 |
+ |
return(INVALID); |
2153 |
+ |
} |
2154 |
+ |
/* If spherical projection coincides with existing sample: replace */ |
2155 |
+ |
if(on == ON_V) |
2156 |
+ |
{ |
2157 |
+ |
n_id = smReplace_samp(sm,c,dir,p,ns,s_id,t_id,o_id,on,which); |
2158 |
+ |
if(n_id != s_id) |
2159 |
+ |
{ |
2160 |
+ |
smUnalloc_samp(sm,s_id); |
2161 |
+ |
#if 0 |
2162 |
+ |
fprintf(stderr,"Unallocating sample %d\n",s_id); |
2163 |
+ |
#endif |
2164 |
+ |
qtremovelast(qt,s_id); |
2165 |
+ |
} |
2166 |
+ |
return(n_id); |
2167 |
+ |
} |
2168 |
+ |
t = SM_NTH_TRI(sm,t_id); |
2169 |
+ |
VSUB(n0,SM_NTH_WV(sm,T_NTH_V(t,0)),SM_VIEW_CENTER(sm)); |
2170 |
+ |
d0 = normalize(n0); |
2171 |
+ |
VSUB(n1,SM_NTH_WV(sm,T_NTH_V(t,1)),SM_VIEW_CENTER(sm)); |
2172 |
+ |
normalize(n1); |
2173 |
+ |
VSUB(n2,SM_NTH_WV(sm,T_NTH_V(t,2)),SM_VIEW_CENTER(sm)); |
2174 |
+ |
normalize(n2); |
2175 |
+ |
if((!(smTest_samp(sm,t_id,dir,p,&r_id,ns,n0,n1,n2,ds,d0,on,which)))) |
2176 |
+ |
{ |
2177 |
|
smUnalloc_samp(sm,s_id); |
2178 |
+ |
#if 0 |
2179 |
+ |
fprintf(stderr,"Unallocating sample %d\n",s_id); |
2180 |
+ |
#endif |
2181 |
+ |
qtremovelast(qt,s_id); |
2182 |
|
return(INVALID); |
2183 |
|
} |
2184 |
< |
/* If spherical projection coincides with existing sample: replace */ |
2185 |
< |
if((on == ON_V || on == ON_P)) |
2186 |
< |
{ |
2187 |
< |
if((n_id = smReplace_samp(sm,c,dir,p,s_id,t_id,o_id,on,which))!= s_id) |
2188 |
< |
smUnalloc_samp(sm,s_id); |
2189 |
< |
return(n_id); |
2184 |
> |
if(r_id != INVALID) |
2185 |
> |
{ |
2186 |
> |
smRemoveVertex(sm,r_id); |
2187 |
> |
if(nbr_id == r_id) |
2188 |
> |
{ |
2189 |
> |
qtremovelast(qt,s_id); |
2190 |
> |
SM_S_NTH_QT(sm,s_id) = EMPTY; |
2191 |
> |
} |
2192 |
> |
} |
2193 |
> |
else |
2194 |
> |
break; |
2195 |
|
} |
1558 |
– |
if((!(smTest_sample(sm,t_id,dir,p,&r_id)))) |
1559 |
– |
{ |
1560 |
– |
smUnalloc_samp(sm,s_id); |
1561 |
– |
return(INVALID); |
1562 |
– |
} |
2196 |
|
/* If sample is being added in the middle of the sample array: tone |
2197 |
|
map individually |
2198 |
|
*/ |
2199 |
|
/* Initialize sample */ |
2200 |
< |
sInit_samp(SM_SAMP(sm),s_id,c,dir,p,o_id,(SM_TONE_MAP(sm)>s_id)); |
2201 |
< |
|
2200 |
> |
sInit_samp(SM_SAMP(sm),s_id,c,dir,p,o_id); |
2201 |
> |
/* If not base or sky point, add distance from center to average*/ |
2202 |
> |
smDist_sum += 1.0/ds; |
2203 |
> |
smInsert_samp_mesh(sm,s_id,t_id,ns,n0,n1,n2,on,which); |
2204 |
|
} |
2205 |
|
/* If sample is a direction vector */ |
2206 |
|
else |
2207 |
|
{ |
2208 |
|
VADD(wpt,dir,SM_VIEW_CENTER(sm)); |
2209 |
< |
t_id = smPointLocateTri(sm,wpt,&on,&which); |
2210 |
< |
if(t_id == INVALID) |
2211 |
< |
{ |
2209 |
> |
while(1) |
2210 |
> |
{ |
2211 |
> |
t_id = smSample_locate_tri(sm,dir,s_id,&on,&which,&nbr_id); |
2212 |
> |
qt = SM_S_NTH_QT(sm,s_id); |
2213 |
|
#ifdef DEBUG |
2214 |
< |
eputs("smAddSamp(): unable to locate tri containing sample \n"); |
2214 |
> |
if(t_id == INVALID) |
2215 |
> |
{ |
2216 |
> |
eputs("smAddSamp():can't locate tri containing samp\n"); |
2217 |
> |
smUnalloc_samp(sm,s_id); |
2218 |
> |
qtremovelast(qt,s_id); |
2219 |
> |
return(INVALID); |
2220 |
> |
} |
2221 |
|
#endif |
2222 |
+ |
if(on == ON_V) |
2223 |
+ |
{ |
2224 |
|
smUnalloc_samp(sm,s_id); |
2225 |
+ |
qtremovelast(qt,s_id); |
2226 |
|
return(INVALID); |
2227 |
|
} |
2228 |
< |
if(on == ON_V || on == ON_P) |
2229 |
< |
{ |
2230 |
< |
if((n_id = smReplace_samp(sm,c,wpt,NULL,s_id,t_id,o_id,on,which))!= s_id) |
2231 |
< |
smUnalloc_samp(sm,s_id); |
2232 |
< |
return(n_id); |
2233 |
< |
} |
2228 |
> |
t = SM_NTH_TRI(sm,t_id); |
2229 |
> |
VSUB(n0,SM_NTH_WV(sm,T_NTH_V(t,0)),SM_VIEW_CENTER(sm)); |
2230 |
> |
d0 = normalize(n0); |
2231 |
> |
VSUB(n1,SM_NTH_WV(sm,T_NTH_V(t,1)),SM_VIEW_CENTER(sm)); |
2232 |
> |
normalize(n1); |
2233 |
> |
VSUB(n2,SM_NTH_WV(sm,T_NTH_V(t,2)),SM_VIEW_CENTER(sm)); |
2234 |
> |
normalize(n2); |
2235 |
> |
if(!smTest_samp(sm,t_id,NULL,wpt,&r_id,dir,n0,n1,n2,1.0,d0,on,which)) |
2236 |
> |
{ |
2237 |
> |
smUnalloc_samp(sm,s_id); |
2238 |
> |
qtremovelast(qt,s_id); |
2239 |
> |
return(INVALID); |
2240 |
> |
} |
2241 |
> |
if(r_id != INVALID) |
2242 |
> |
{ |
2243 |
> |
smRemoveVertex(sm,r_id); |
2244 |
> |
if(nbr_id == r_id) |
2245 |
> |
{ |
2246 |
> |
qtremovelast(qt,s_id); |
2247 |
> |
SM_S_NTH_QT(sm,s_id) = EMPTY; |
2248 |
> |
} |
2249 |
> |
} |
2250 |
> |
else |
2251 |
> |
break; |
2252 |
> |
} |
2253 |
|
/* Allocate space for a sample and initialize */ |
2254 |
< |
sInit_samp(SM_SAMP(sm),s_id,c,wpt,NULL,o_id,(SM_TONE_MAP(sm)>s_id)); |
2254 |
> |
sInit_samp(SM_SAMP(sm),s_id,c,NULL,wpt,o_id); |
2255 |
> |
smInsert_samp_mesh(sm,s_id,t_id,dir,n0,n1,n2,on,which); |
2256 |
|
} |
1592 |
– |
if(!SM_DIR_ID(sm,s_id)) |
1593 |
– |
{ |
1594 |
– |
/* If not a base or sky point, add distance from the |
1595 |
– |
viewcenter to average*/ |
1596 |
– |
d = DIST(SM_NTH_WV(sm,s_id),SM_VIEW_CENTER(sm)); |
1597 |
– |
smDist_sum += 1.0/d; |
1598 |
– |
} |
1599 |
– |
smInsert_samp(sm,s_id,t_id,on,which); |
1600 |
– |
|
1601 |
– |
/* If new sample replaces existing one- remove that vertex now */ |
1602 |
– |
if(r_id != INVALID) |
1603 |
– |
{ |
1604 |
– |
smRemoveVertex(sm,r_id); |
1605 |
– |
sDelete_samp(SM_SAMP(sm),r_id); |
1606 |
– |
} |
2257 |
|
return(s_id); |
2258 |
|
} |
2259 |
|
|
2275 |
|
FVECT p; |
2276 |
|
{ |
2277 |
|
int s_id; |
1628 |
– |
|
1629 |
– |
|
2278 |
|
/* First check if this the first sample: if so initialize mesh */ |
1631 |
– |
|
2279 |
|
if(SM_NUM_SAMP(smMesh) == 0) |
2280 |
|
{ |
2281 |
|
smInit_sm(smMesh,odev.v.vp); |
2284 |
|
/* Add the sample to the mesh */ |
2285 |
|
s_id = smAdd_samp(smMesh,c,dir,p,INVALID); |
2286 |
|
|
2287 |
+ |
#if 0 |
2288 |
+ |
{ |
2289 |
+ |
int i; |
2290 |
+ |
FILE *fp; |
2291 |
+ |
if(s_id == 10000) |
2292 |
+ |
{ |
2293 |
+ |
fp = fopen("test.xyz","w"); |
2294 |
+ |
for(i=0; i < s_id; i++) |
2295 |
+ |
if(!SM_DIR_ID(smMesh,i)) |
2296 |
+ |
fprintf(fp,"%f %f %f %d %d %d \n",SM_NTH_WV(smMesh,i)[0], |
2297 |
+ |
SM_NTH_WV(smMesh,i)[1],SM_NTH_WV(smMesh,i)[2], |
2298 |
+ |
SM_NTH_RGB(smMesh,i)[0],SM_NTH_RGB(smMesh,i)[1], |
2299 |
+ |
SM_NTH_RGB(smMesh,i)[2]); |
2300 |
+ |
fclose(fp); |
2301 |
+ |
} |
2302 |
+ |
} |
2303 |
+ |
#endif |
2304 |
|
return(s_id); |
2305 |
|
|
2306 |
|
} |
2333 |
|
int type; |
2334 |
|
{ |
2335 |
|
int i,s_id,tri_id,nbr_id; |
2336 |
< |
int p[SM_EXTRA_POINTS],ids[SM_BASE_TRIS]; |
2336 |
> |
int p[SM_BASE_POINTS],ids[SM_BASE_TRIS]; |
2337 |
|
int v0_id,v1_id,v2_id; |
2338 |
|
FVECT d,pt,cntr,v0,v1,v2; |
2339 |
|
TRI *t; |
2340 |
|
|
2341 |
|
/* First insert the base vertices into the sample point array */ |
2342 |
|
|
2343 |
< |
for(i=0; i < SM_EXTRA_POINTS; i++) |
2343 |
> |
for(i=0; i < SM_BASE_POINTS; i++) |
2344 |
|
{ |
2345 |
|
VADD(cntr,icosa_verts[i],SM_VIEW_CENTER(sm)); |
2346 |
|
p[i] = smAdd_base_vertex(sm,cntr); |
2347 |
+ |
smInsert_samp(sm,p[i],icosa_verts[i],NULL); |
2348 |
|
} |
2349 |
|
/* Create the base triangles */ |
2350 |
|
for(i=0;i < SM_BASE_TRIS; i++) |
2352 |
|
v0_id = p[icosa_tris[i][0]]; |
2353 |
|
v1_id = p[icosa_tris[i][1]]; |
2354 |
|
v2_id = p[icosa_tris[i][2]]; |
2355 |
< |
ids[i] = smAdd_tri(sm, v0_id,v1_id,v2_id); |
2355 |
> |
ids[i] = smAdd_tri(sm, v0_id,v1_id,v2_id,&t); |
2356 |
|
/* Set neighbors */ |
2357 |
|
for(nbr_id=0; nbr_id < 3; nbr_id++) |
2358 |
|
T_NTH_NBR(SM_NTH_TRI(sm,ids[i]),nbr_id) = icosa_nbrs[i][nbr_id]; |
2359 |
|
|
2360 |
|
} |
1696 |
– |
for(i=0;i < SM_BASE_TRIS; i++) |
1697 |
– |
{ |
1698 |
– |
t = SM_NTH_TRI(sm,ids[i]); |
1699 |
– |
smLocator_add_tri(sm,ids[i],T_NTH_V(t,0),T_NTH_V(t,1),T_NTH_V(t,2)); |
1700 |
– |
} |
2361 |
|
return(1); |
2362 |
|
|
2363 |
|
} |
2364 |
|
|
2365 |
< |
|
1706 |
< |
int |
1707 |
< |
smNext_tri_flag_set(sm,i,which,b) |
1708 |
< |
SM *sm; |
1709 |
< |
int i,which; |
1710 |
< |
int b; |
1711 |
< |
{ |
1712 |
< |
|
1713 |
< |
for(; i < SM_NUM_TRI(sm);i++) |
1714 |
< |
{ |
1715 |
< |
|
1716 |
< |
if(!T_IS_VALID(SM_NTH_TRI(sm,i))) |
1717 |
< |
continue; |
1718 |
< |
if(!SM_IS_NTH_T_FLAG(sm,i,which)) |
1719 |
< |
continue; |
1720 |
< |
if(!b) |
1721 |
< |
break; |
1722 |
< |
if((b==1) && !SM_BG_TRI(sm,i)) |
1723 |
< |
break; |
1724 |
< |
if((b==2) && SM_BG_TRI(sm,i)) |
1725 |
< |
break; |
1726 |
< |
} |
1727 |
< |
|
1728 |
< |
return(i); |
1729 |
< |
} |
1730 |
< |
|
1731 |
< |
|
1732 |
< |
int |
1733 |
< |
smNext_valid_tri(sm,i) |
1734 |
< |
SM *sm; |
1735 |
< |
int i; |
1736 |
< |
{ |
1737 |
< |
|
1738 |
< |
while( i < SM_NUM_TRI(sm) && !T_IS_VALID(SM_NTH_TRI(sm,i))) |
1739 |
< |
i++; |
1740 |
< |
|
1741 |
< |
return(i); |
1742 |
< |
} |
1743 |
< |
|
1744 |
< |
|
1745 |
< |
|
1746 |
< |
qtTri_from_id(t_id,v0,v1,v2) |
1747 |
< |
int t_id; |
1748 |
< |
FVECT v0,v1,v2; |
1749 |
< |
{ |
1750 |
< |
TRI *t; |
1751 |
< |
|
1752 |
< |
t = SM_NTH_TRI(smMesh,t_id); |
1753 |
< |
if(!T_IS_VALID(t)) |
1754 |
< |
return(0); |
1755 |
< |
VSUB(v0,SM_T_NTH_WV(smMesh,t,0),SM_VIEW_CENTER(smMesh)); |
1756 |
< |
VSUB(v1,SM_T_NTH_WV(smMesh,t,1),SM_VIEW_CENTER(smMesh)); |
1757 |
< |
VSUB(v2,SM_T_NTH_WV(smMesh,t,2),SM_VIEW_CENTER(smMesh)); |
1758 |
< |
return(1); |
1759 |
< |
} |
1760 |
< |
|
1761 |
< |
|
1762 |
< |
smRebuild_mesh(sm,v) |
2365 |
> |
smRebuild(sm,v) |
2366 |
|
SM *sm; |
2367 |
|
VIEW *v; |
2368 |
|
{ |
2371 |
|
double d; |
2372 |
|
|
2373 |
|
#ifdef DEBUG |
2374 |
< |
fprintf(stderr,"smRebuild_mesh(): rebuilding...."); |
2374 |
> |
fprintf(stderr,"smRebuild(): rebuilding...."); |
2375 |
|
#endif |
2376 |
+ |
smCull(sm,v,SM_ALL_LEVELS); |
2377 |
|
/* Clear the mesh- and rebuild using the current sample array */ |
2378 |
|
/* Remember the current number of samples */ |
2379 |
|
cnt = SM_NUM_SAMP(sm); |
2380 |
|
/* Calculate the difference between the current and new viewpoint*/ |
2381 |
|
/* Will need to subtract this off of sky points */ |
2382 |
|
VCOPY(ov,SM_VIEW_CENTER(sm)); |
1779 |
– |
/* Initialize the mesh to 0 samples and the base triangles */ |
2383 |
|
|
2384 |
+ |
/* Initialize the mesh to 0 samples and the base triangles */ |
2385 |
+ |
smInit_sm(sm,v->vp); |
2386 |
|
/* Go through all samples and add in if in the new view frustum, and |
2387 |
|
the dir is <= 30 degrees from new view |
2388 |
|
*/ |
1784 |
– |
smInit_sm(sm,v->vp); |
2389 |
|
for(i=0; i < cnt; i++) |
2390 |
|
{ |
2391 |
|
/* First check if sample visible(conservative approx: if one of tris |
2392 |
|
attached to sample is in frustum) */ |
2393 |
|
if(!S_IS_FLAG(i)) |
2394 |
|
continue; |
2395 |
< |
|
2396 |
< |
/* Next test if direction > 30 from current direction */ |
2395 |
> |
|
2396 |
> |
/* Next test if direction > 30 degrees from current direction */ |
2397 |
|
if(SM_NTH_W_DIR(sm,i)!=-1) |
2398 |
|
{ |
2399 |
|
VSUB(p,SM_NTH_WV(sm,i),v->vp); |
1796 |
– |
normalize(p); |
2400 |
|
decodedir(dir,SM_NTH_W_DIR(sm,i)); |
2401 |
< |
d = 2. - 2.*DOT(dir,p); |
2402 |
< |
if (d > MAXDIFF2) |
2401 |
> |
d = DOT(dir,p); |
2402 |
> |
if (d*d < MAXDIFF2*DOT(p,p)) |
2403 |
|
continue; |
2404 |
|
VCOPY(p,SM_NTH_WV(sm,i)); |
2405 |
|
smAdd_samp(sm,NULL,dir,p,i); |
2406 |
|
} |
2407 |
|
else |
2408 |
|
{ |
2409 |
+ |
/* If the direction is > 45 degrees from current view direction: |
2410 |
+ |
throw out |
2411 |
+ |
*/ |
2412 |
|
VSUB(dir,SM_NTH_WV(sm,i),ov); |
2413 |
+ |
if(DOT(dir,v->vdir) < MAXDIR) |
2414 |
+ |
continue; |
2415 |
+ |
|
2416 |
|
VADD(SM_NTH_WV(sm,i),dir,SM_VIEW_CENTER(sm)); |
2417 |
|
smAdd_samp(sm,NULL,dir,NULL,i); |
2418 |
|
} |
2419 |
|
|
2420 |
|
} |
1812 |
– |
|
1813 |
– |
smNew_tri_cnt = SM_SAMPLE_TRIS(sm); |
2421 |
|
#ifdef DEBUG |
2422 |
< |
fprintf(stderr,"smRebuild_mesh():done\n"); |
2422 |
> |
fprintf(stderr,"smRebuild():done\n"); |
2423 |
|
#endif |
2424 |
|
} |
2425 |
|
|
2435 |
|
TRI *t; |
2436 |
|
double d,d1; |
2437 |
|
|
2438 |
< |
optr = QT_SET_PTR(t_set); |
2438 |
> |
optr = t_set; |
2439 |
|
for(i = QT_SET_CNT(t_set); i > 0; i--) |
2440 |
|
{ |
2441 |
|
t_id = QT_SET_NEXT_ELEM(optr); |
2442 |
|
t = SM_NTH_TRI(smMesh,t_id); |
2443 |
< |
if(!T_IS_VALID(t)) |
2443 |
> |
if(!T_IS_VALID(t) || SM_IS_NTH_T_BASE(smMesh,t_id)|| |
2444 |
> |
SM_IS_NTH_T_BG(smMesh,t_id)) |
2445 |
|
continue; |
2446 |
|
pid0 = T_NTH_V(t,0); |
2447 |
|
pid1 = T_NTH_V(t,1); |
2448 |
|
pid2 = T_NTH_V(t,2); |
1841 |
– |
if(base = SM_IS_NTH_T_BASE(smMesh,t_id)) |
1842 |
– |
if(SM_BASE_ID(smMesh,pid0) && SM_BASE_ID(smMesh,pid1) && |
1843 |
– |
SM_BASE_ID(smMesh,pid2)) |
1844 |
– |
continue; |
2449 |
|
VCOPY(p0,SM_NTH_WV(smMesh,pid0)); |
2450 |
|
VCOPY(p1,SM_NTH_WV(smMesh,pid1)); |
2451 |
|
VCOPY(p2,SM_NTH_WV(smMesh,pid2)); |
2452 |
|
if(ray_intersect_tri(orig,dir,p0,p1,p2,p)) |
2453 |
|
{ |
2454 |
< |
if(!base) |
2455 |
< |
{ |
2456 |
< |
d = DIST_SQ(p,p0); |
2457 |
< |
d1 = DIST_SQ(p,p1); |
2458 |
< |
if(d < d1) |
2459 |
< |
{ |
2460 |
< |
d1 = DIST_SQ(p,p2); |
1857 |
< |
id = (d1 < d)?pid2:pid0; |
1858 |
< |
} |
1859 |
< |
else |
1860 |
< |
{ |
1861 |
< |
d = DIST_SQ(p,p2); |
1862 |
< |
id = (d < d1)? pid2:pid1; |
1863 |
< |
} |
1864 |
< |
} |
2454 |
> |
d = DIST_SQ(p,p0); |
2455 |
> |
d1 = DIST_SQ(p,p1); |
2456 |
> |
if(d < d1) |
2457 |
> |
{ |
2458 |
> |
d1 = DIST_SQ(p,p2); |
2459 |
> |
id = (d1 < d)?pid2:pid0; |
2460 |
> |
} |
2461 |
|
else |
2462 |
|
{ |
2463 |
< |
if(SM_BASE_ID(smMesh,pid0)) |
2464 |
< |
{ |
1869 |
< |
if(SM_BASE_ID(smMesh,pid1)) |
1870 |
< |
id = pid2; |
1871 |
< |
else |
1872 |
< |
if(SM_BASE_ID(smMesh,pid2)) |
1873 |
< |
id = pid1; |
1874 |
< |
else |
1875 |
< |
{ |
1876 |
< |
d = DIST_SQ(p,p1); |
1877 |
< |
d1 = DIST_SQ(p,p2); |
1878 |
< |
if(d < d1) |
1879 |
< |
id = pid1; |
1880 |
< |
else |
1881 |
< |
id = pid2; |
1882 |
< |
} |
1883 |
< |
} |
1884 |
< |
else |
1885 |
< |
{ |
1886 |
< |
if(SM_BASE_ID(smMesh,pid1)) |
1887 |
< |
{ |
1888 |
< |
if(SM_BASE_ID(smMesh,pid2)) |
1889 |
< |
id = pid0; |
1890 |
< |
else |
1891 |
< |
{ |
1892 |
< |
d = DIST_SQ(p,p0); |
1893 |
< |
d1 = DIST_SQ(p,p2); |
1894 |
< |
if(d < d1) |
1895 |
< |
id = pid0; |
1896 |
< |
else |
1897 |
< |
id = pid2; |
1898 |
< |
} |
1899 |
< |
} |
1900 |
< |
else |
1901 |
< |
{ |
1902 |
< |
d = DIST_SQ(p,p0); |
1903 |
< |
d1 = DIST_SQ(p,p1); |
1904 |
< |
if(d < d1) |
1905 |
< |
id = pid0; |
1906 |
< |
else |
1907 |
< |
id = pid1; |
1908 |
< |
} |
1909 |
< |
} |
2463 |
> |
d = DIST_SQ(p,p2); |
2464 |
> |
id = (d < d1)? pid2:pid1; |
2465 |
|
} |
2466 |
|
if(pt) |
2467 |
|
VCOPY(pt,p); |
2584 |
|
/* orig will be updated-so preserve original value */ |
2585 |
|
if(!smMesh) |
2586 |
|
return; |
2032 |
– |
#ifdef TEST_DRIVER |
2033 |
– |
Picking= TRUE; |
2034 |
– |
#endif |
2587 |
|
|
2588 |
|
if(EQUAL_VEC3(orig,SM_VIEW_CENTER(smMesh))) |
2589 |
|
{ |
2590 |
< |
qt = smPointLocateCell(smMesh,dir); |
2590 |
> |
qt = smPoint_locate_cell(smMesh,dir); |
2591 |
|
if(QT_IS_EMPTY(qt)) |
2592 |
|
goto Lerror; |
2593 |
|
ts = qtqueryset(qt); |
2594 |
|
s_id = intersect_tri_set(ts,orig,dir,p); |
2043 |
– |
#ifdef DEBUG_TEST_DRIVER |
2044 |
– |
VCOPY(Pick_point[0],p); |
2045 |
– |
#endif |
2046 |
– |
#ifdef DEBUG |
2047 |
– |
fprintf(stderr,"Simple pick returning %d\n",s_id); |
2048 |
– |
#endif |
2049 |
– |
|
2595 |
|
return(s_id); |
2596 |
|
} |
2597 |
|
d = point_on_sphere(b,orig,SM_VIEW_CENTER(smMesh)); |
2598 |
|
if(EQUAL_VEC3(b,dir)) |
2599 |
|
{ |
2600 |
< |
qt = smPointLocateCell(smMesh,dir); |
2600 |
> |
qt = smPoint_locate_cell(smMesh,dir); |
2601 |
|
if(QT_IS_EMPTY(qt)) |
2602 |
|
goto Lerror; |
2603 |
|
ts = qtqueryset(qt); |
2604 |
|
s_id = intersect_tri_set(ts,orig,dir,p); |
2605 |
< |
#ifdef DEBUG_TEST_DRIVER |
2061 |
< |
VCOPY(Pick_point[0],p); |
2062 |
< |
#endif |
2063 |
< |
#ifdef DEBUG |
2064 |
< |
fprintf(stderr,"Simple pick2 returning %d\n",s_id); |
2065 |
< |
#endif |
2066 |
< |
return(s_id); |
2605 |
> |
return(s_id); |
2606 |
|
} |
2607 |
|
if(OPP_EQUAL_VEC3(b,dir)) |
2608 |
|
{ |
2609 |
< |
qt = smPointLocateCell(smMesh,orig); |
2609 |
> |
qt = smPoint_locate_cell(smMesh,orig); |
2610 |
|
if(QT_IS_EMPTY(qt)) |
2611 |
|
goto Lerror; |
2612 |
|
ts = qtqueryset(qt); |
2613 |
|
s_id = intersect_tri_set(ts,orig,dir,p); |
2614 |
< |
#ifdef DEBUG_TEST_DRIVER |
2615 |
< |
VCOPY(Pick_point[0],p); |
2077 |
< |
#endif |
2078 |
< |
if(s_id != INVALID) |
2079 |
< |
{ |
2614 |
> |
if(s_id != INVALID) |
2615 |
> |
{ |
2616 |
|
#ifdef DEBUG |
2617 |
|
fprintf(stderr,"Front pick returning %d\n",s_id); |
2618 |
|
#endif |
2619 |
|
return(s_id); |
2620 |
< |
} |
2621 |
< |
qt = smPointLocateCell(smMesh,dir); |
2622 |
< |
if(QT_IS_EMPTY(qt)) |
2623 |
< |
goto Lerror; |
2624 |
< |
ts = qtqueryset(qt); |
2625 |
< |
s_id = intersect_tri_set(ts,orig,dir,p); |
2090 |
< |
#ifdef DEBUG_TEST_DRIVER |
2091 |
< |
VCOPY(Pick_point[0],p); |
2092 |
< |
#endif |
2620 |
> |
} |
2621 |
> |
qt = smPoint_locate_cell(smMesh,dir); |
2622 |
> |
if(QT_IS_EMPTY(qt)) |
2623 |
> |
goto Lerror; |
2624 |
> |
ts = qtqueryset(qt); |
2625 |
> |
s_id = intersect_tri_set(ts,orig,dir,p); |
2626 |
|
#ifdef DEBUG |
2627 |
|
fprintf(stderr,"Back pick returning %d\n",s_id); |
2628 |
|
#endif |
2629 |
< |
return(s_id); |
2629 |
> |
return(s_id); |
2630 |
|
} |
2631 |
|
{ |
2632 |
|
OBJECT t_set[QT_MAXCSET + 1]; |
2645 |
|
F_ARGS(func) = (int *)(&rt); |
2646 |
|
stTrace_ray(SM_LOCATOR(smMesh),o,dir,func); |
2647 |
|
s_id = rt.t_id; |
2648 |
+ |
|
2649 |
|
} |
2116 |
– |
#ifdef DEBUG |
2117 |
– |
fprintf(stderr,"Trace pick returning %d\n",s_id); |
2118 |
– |
#endif |
2650 |
|
return(s_id); |
2651 |
|
|
2652 |
|
Lerror: |
2657 |
|
|
2658 |
|
} |
2659 |
|
|
2660 |
+ |
null_func(argptr,root,qt,n) |
2661 |
+ |
int *argptr; |
2662 |
+ |
int root; |
2663 |
+ |
QUADTREE qt; |
2664 |
+ |
int n; |
2665 |
+ |
{ |
2666 |
+ |
/* do nothing */ |
2667 |
+ |
} |
2668 |
|
|
2669 |
< |
mark_active_tris(argptr,root,qt) |
2669 |
> |
mark_active_samples(argptr,root,qt,n) |
2670 |
|
int *argptr; |
2671 |
|
int root; |
2672 |
|
QUADTREE qt; |
2673 |
+ |
int n; |
2674 |
|
{ |
2675 |
< |
OBJECT *os,*optr; |
2676 |
< |
register int i,t_id; |
2675 |
> |
OBJECT *os; |
2676 |
> |
register int i,s_id,t_id,tri_id; |
2677 |
|
TRI *tri; |
2678 |
|
|
2679 |
|
if(QT_IS_EMPTY(qt) || QT_LEAF_IS_FLAG(qt)) |
2682 |
|
/* For each triangle in the set, set the which flag*/ |
2683 |
|
os = qtqueryset(qt); |
2684 |
|
|
2685 |
< |
for (i = QT_SET_CNT(os), optr = QT_SET_PTR(os); i > 0; i--) |
2685 |
> |
for (i = QT_SET_CNT(os); i > 0; i--) |
2686 |
|
{ |
2687 |
< |
t_id = QT_SET_NEXT_ELEM(optr); |
2688 |
< |
/* Set the render flag */ |
2149 |
< |
tri = SM_NTH_TRI(smMesh,t_id); |
2150 |
< |
if(!T_IS_VALID(tri) || SM_IS_NTH_T_BASE(smMesh,t_id)) |
2151 |
< |
continue; |
2152 |
< |
SM_SET_NTH_T_ACTIVE(smMesh,t_id); |
2153 |
< |
/* Set the Active bits of the Vertices */ |
2154 |
< |
S_SET_FLAG(T_NTH_V(tri,0)); |
2155 |
< |
S_SET_FLAG(T_NTH_V(tri,1)); |
2156 |
< |
S_SET_FLAG(T_NTH_V(tri,2)); |
2157 |
< |
} |
2158 |
< |
} |
2687 |
> |
s_id = QT_SET_NEXT_ELEM(os); |
2688 |
> |
S_SET_FLAG(s_id); |
2689 |
|
|
2690 |
+ |
tri_id = SM_NTH_VERT(smMesh,s_id); |
2691 |
+ |
/* Set the active flag for all adjacent triangles */ |
2692 |
+ |
tri = SM_NTH_TRI(smMesh,tri_id); |
2693 |
+ |
SM_SET_NTH_T_ACTIVE(smMesh,tri_id); |
2694 |
+ |
while((t_id = smTri_next_ccw_nbr(smMesh,tri,s_id)) != tri_id) |
2695 |
+ |
{ |
2696 |
+ |
tri = SM_NTH_TRI(smMesh,t_id); |
2697 |
+ |
SM_SET_NTH_T_ACTIVE(smMesh,t_id); |
2698 |
+ |
} |
2699 |
+ |
} |
2700 |
+ |
} |
2701 |
|
|
2702 |
< |
mark_tris_in_frustum(view) |
2702 |
> |
smCull(sm,view,n) |
2703 |
> |
SM *sm; |
2704 |
|
VIEW *view; |
2705 |
+ |
int n; |
2706 |
|
{ |
2707 |
|
FVECT nr[4],far[4]; |
2708 |
|
FPEQ peq; |
2709 |
|
int debug=0; |
2710 |
|
FUNC f; |
2711 |
|
|
2712 |
< |
F_FUNC(f) = mark_active_tris; |
2713 |
< |
F_ARGS(f) = NULL; |
2712 |
> |
/* First clear all the quadtree node flags */ |
2713 |
> |
qtClearAllFlags(); |
2714 |
|
|
2715 |
+ |
F_ARGS(f) = NULL; |
2716 |
+ |
/* If marking samples down to leaves */ |
2717 |
+ |
if(n == SM_ALL_LEVELS) |
2718 |
+ |
{ |
2719 |
|
/* Mark triangles in approx. view frustum as being active:set |
2720 |
|
LRU counter: for use in discarding samples when out |
2721 |
|
of space |
2722 |
+ |
*/ |
2723 |
+ |
F_FUNC(f) = mark_active_samples; |
2724 |
+ |
smClear_flags(sm,T_ACTIVE_FLAG); |
2725 |
+ |
/* Clear all of the active sample flags*/ |
2726 |
+ |
sClear_all_flags(SM_SAMP(sm)); |
2727 |
+ |
} |
2728 |
+ |
else |
2729 |
+ |
/* Just mark qtree flags */ |
2730 |
+ |
F_FUNC(f) = null_func; |
2731 |
+ |
|
2732 |
+ |
/* calculate the world space coordinates of the view frustum: |
2733 |
|
Radiance often has no far clipping plane: but driver will set |
2734 |
|
dev_zmin,dev_zmax to satisfy OGL |
2735 |
< |
*/ |
2178 |
< |
|
2179 |
< |
/* First clear all the quadtree node and triangle active flags */ |
2180 |
< |
qtClearAllFlags(); |
2181 |
< |
smClear_flags(smMesh,T_ACTIVE_FLAG); |
2182 |
< |
/* Clear all of the active sample flags*/ |
2183 |
< |
sClear_all_flags(SM_SAMP(smMesh)); |
2184 |
< |
|
2185 |
< |
|
2186 |
< |
/* calculate the world space coordinates of the view frustum */ |
2735 |
> |
*/ |
2736 |
|
calculate_view_frustum(view->vp,view->hvec,view->vvec,view->horiz, |
2737 |
|
view->vert, dev_zmin,dev_zmax,nr,far); |
2738 |
|
|
2753 |
|
Also set the triangles LRU clock counter |
2754 |
|
*/ |
2755 |
|
|
2756 |
< |
if(EQUAL_VEC3(view->vp,SM_VIEW_CENTER(smMesh))) |
2756 |
> |
if(EQUAL_VEC3(view->vp,SM_VIEW_CENTER(sm))) |
2757 |
|
{/* Near face triangles */ |
2758 |
|
|
2759 |
< |
smLocator_apply(smMesh,nr[0],nr[2],nr[3],f); |
2760 |
< |
smLocator_apply(smMesh,nr[2],nr[0],nr[1],f); |
2759 |
> |
smLocator_apply(sm,nr[0],nr[2],nr[3],f,n); |
2760 |
> |
smLocator_apply(sm,nr[2],nr[0],nr[1],f,n); |
2761 |
|
return; |
2762 |
|
} |
2763 |
|
/* Test the view against the planes: and swap orientation if inside:*/ |
2764 |
|
tri_plane_equation(nr[0],nr[2],nr[3], &peq,FALSE); |
2765 |
< |
if(PT_ON_PLANE(SM_VIEW_CENTER(smMesh),peq) < 0.0) |
2765 |
> |
if(PT_ON_PLANE(SM_VIEW_CENTER(sm),peq) < 0.0) |
2766 |
|
{/* Near face triangles */ |
2767 |
< |
smLocator_apply(smMesh,nr[3],nr[2],nr[0],f); |
2768 |
< |
smLocator_apply(smMesh,nr[1],nr[0],nr[2],f); |
2767 |
> |
smLocator_apply(sm,nr[3],nr[2],nr[0],f,n); |
2768 |
> |
smLocator_apply(sm,nr[1],nr[0],nr[2],f,n); |
2769 |
|
} |
2770 |
|
else |
2771 |
|
{/* Near face triangles */ |
2772 |
< |
smLocator_apply(smMesh,nr[0],nr[2],nr[3],f); |
2773 |
< |
smLocator_apply(smMesh,nr[2],nr[0],nr[1],f); |
2772 |
> |
smLocator_apply(sm,nr[0],nr[2],nr[3],f,n); |
2773 |
> |
smLocator_apply(sm,nr[2],nr[0],nr[1],f,n); |
2774 |
|
} |
2775 |
|
tri_plane_equation(nr[0],far[3],far[0], &peq,FALSE); |
2776 |
< |
if(PT_ON_PLANE(SM_VIEW_CENTER(smMesh),peq) < 0.0) |
2776 |
> |
if(PT_ON_PLANE(SM_VIEW_CENTER(sm),peq) < 0.0) |
2777 |
|
{ /* Right face triangles */ |
2778 |
< |
smLocator_apply(smMesh,far[0],far[3],nr[0],f); |
2779 |
< |
smLocator_apply(smMesh,nr[3],nr[0],far[3],f); |
2778 |
> |
smLocator_apply(sm,far[0],far[3],nr[0],f,n); |
2779 |
> |
smLocator_apply(sm,nr[3],nr[0],far[3],f,n); |
2780 |
|
} |
2781 |
|
else |
2782 |
|
{/* Right face triangles */ |
2783 |
< |
smLocator_apply(smMesh,nr[0],far[3],far[0],f); |
2784 |
< |
smLocator_apply(smMesh,far[3],nr[0],nr[3],f); |
2783 |
> |
smLocator_apply(sm,nr[0],far[3],far[0],f,n); |
2784 |
> |
smLocator_apply(sm,far[3],nr[0],nr[3],f,n); |
2785 |
|
} |
2786 |
|
|
2787 |
|
tri_plane_equation(nr[1],far[2],nr[2], &peq,FALSE); |
2788 |
|
if(PT_ON_PLANE(SM_VIEW_CENTER(smMesh),peq) < 0.0) |
2789 |
|
{ /* Left face triangles */ |
2790 |
< |
smLocator_apply(smMesh,nr[2],far[2],nr[1],f); |
2791 |
< |
smLocator_apply(smMesh,far[1],nr[1],far[2],f); |
2790 |
> |
smLocator_apply(sm,nr[2],far[2],nr[1],f,n); |
2791 |
> |
smLocator_apply(sm,far[1],nr[1],far[2],f,n); |
2792 |
|
} |
2793 |
|
else |
2794 |
|
{ /* Left face triangles */ |
2795 |
< |
smLocator_apply(smMesh,nr[1],far[2],nr[2],f); |
2796 |
< |
smLocator_apply(smMesh,far[2],nr[1],far[1],f); |
2795 |
> |
smLocator_apply(sm,nr[1],far[2],nr[2],f,n); |
2796 |
> |
smLocator_apply(sm,far[2],nr[1],far[1],f,n); |
2797 |
|
} |
2798 |
|
tri_plane_equation(nr[0],far[0],nr[1], &peq,FALSE); |
2799 |
< |
if(PT_ON_PLANE(SM_VIEW_CENTER(smMesh),peq) < 0.0) |
2799 |
> |
if(PT_ON_PLANE(SM_VIEW_CENTER(sm),peq) < 0.0) |
2800 |
|
{/* Top face triangles */ |
2801 |
< |
smLocator_apply(smMesh,nr[1],far[0],nr[0],f); |
2802 |
< |
smLocator_apply(smMesh,far[1],far[0],nr[1],f); |
2801 |
> |
smLocator_apply(sm,nr[1],far[0],nr[0],f,n); |
2802 |
> |
smLocator_apply(sm,far[1],far[0],nr[1],f,n); |
2803 |
|
} |
2804 |
|
else |
2805 |
|
{/* Top face triangles */ |
2806 |
< |
smLocator_apply(smMesh,nr[0],far[0],nr[1],f); |
2807 |
< |
smLocator_apply(smMesh,nr[1],far[0],far[1],f); |
2806 |
> |
smLocator_apply(sm,nr[0],far[0],nr[1],f,n); |
2807 |
> |
smLocator_apply(sm,nr[1],far[0],far[1],f,n); |
2808 |
|
} |
2809 |
|
tri_plane_equation(nr[3],nr[2],far[3], &peq,FALSE); |
2810 |
< |
if(PT_ON_PLANE(SM_VIEW_CENTER(smMesh),peq) < 0.0) |
2810 |
> |
if(PT_ON_PLANE(SM_VIEW_CENTER(sm),peq) < 0.0) |
2811 |
|
{/* Bottom face triangles */ |
2812 |
< |
smLocator_apply(smMesh,far[3],nr[2],nr[3],f); |
2813 |
< |
smLocator_apply(smMesh,far[3],far[2],nr[2],f); |
2812 |
> |
smLocator_apply(sm,far[3],nr[2],nr[3],f,n); |
2813 |
> |
smLocator_apply(sm,far[3],far[2],nr[2],f,n); |
2814 |
|
} |
2815 |
|
else |
2816 |
|
{ /* Bottom face triangles */ |
2817 |
< |
smLocator_apply(smMesh,nr[3],nr[2],far[3],f); |
2818 |
< |
smLocator_apply(smMesh,nr[2],far[2],far[3],f); |
2817 |
> |
smLocator_apply(sm,nr[3],nr[2],far[3],f,n); |
2818 |
> |
smLocator_apply(sm,nr[2],far[2],far[3],f,n); |
2819 |
|
} |
2820 |
|
tri_plane_equation(far[2],far[0],far[1], &peq,FALSE); |
2821 |
< |
if(PT_ON_PLANE(SM_VIEW_CENTER(smMesh),peq) < 0.0) |
2821 |
> |
if(PT_ON_PLANE(SM_VIEW_CENTER(sm),peq) < 0.0) |
2822 |
|
{/* Far face triangles */ |
2823 |
< |
smLocator_apply(smMesh,far[0],far[2],far[1],f); |
2824 |
< |
smLocator_apply(smMesh,far[2],far[0],far[3],f); |
2823 |
> |
smLocator_apply(sm,far[0],far[2],far[1],f,n); |
2824 |
> |
smLocator_apply(sm,far[2],far[0],far[3],f,n); |
2825 |
|
} |
2826 |
|
else |
2827 |
|
{/* Far face triangles */ |
2828 |
< |
smLocator_apply(smMesh,far[1],far[2],far[0],f); |
2829 |
< |
smLocator_apply(smMesh,far[3],far[0],far[2],f); |
2828 |
> |
smLocator_apply(sm,far[1],far[2],far[0],f,n); |
2829 |
> |
smLocator_apply(sm,far[3],far[0],far[2],f,n); |
2830 |
|
} |
2831 |
|
|
2832 |
|
} |
2833 |
+ |
|
2834 |
+ |
|
2835 |
+ |
|
2836 |
+ |
|
2837 |
+ |
|
2838 |
+ |
|
2839 |
+ |
|
2840 |
+ |
|
2841 |
+ |
|
2842 |
+ |
|
2843 |
|
|
2844 |
|
|
2845 |
|
|