40 |
|
VCOPY(p,SM_NTH_WV(sm,id)); |
41 |
|
point_on_sphere(ps,p,SM_VIEW_CENTER(sm)); |
42 |
|
} |
43 |
+ |
smDir_in_cone(sm,ps,id) |
44 |
+ |
SM *sm; |
45 |
+ |
FVECT ps; |
46 |
+ |
int id; |
47 |
+ |
{ |
48 |
+ |
FVECT p; |
49 |
+ |
|
50 |
+ |
VCOPY(p,SM_NTH_WV(sm,id)); |
51 |
+ |
point_on_sphere(ps,p,SM_VIEW_CENTER(sm)); |
52 |
+ |
} |
53 |
|
|
54 |
|
smClear_mesh(sm) |
55 |
|
SM *sm; |
261 |
|
} |
262 |
|
|
263 |
|
|
264 |
< |
int |
265 |
< |
smLocator_apply_func(sm,v0,v1,v2,func,arg) |
266 |
< |
SM *sm; |
267 |
< |
FVECT v0,v1,v2; |
268 |
< |
int (*func)(); |
269 |
< |
int *arg; |
264 |
> |
smLocator_apply_func(sm,v0,v1,v2,edge_func,interior_func,arg1,arg2) |
265 |
> |
SM *sm; |
266 |
> |
FVECT v0,v1,v2; |
267 |
> |
int (*edge_func)(); |
268 |
> |
int (*interior_func)(); |
269 |
> |
int *arg1,arg2; |
270 |
|
{ |
271 |
|
STREE *st; |
262 |
– |
int found; |
272 |
|
FVECT p0,p1,p2; |
273 |
|
|
274 |
|
st = SM_LOCATOR(sm); |
277 |
|
VSUB(p1,v1,SM_VIEW_CENTER(sm)); |
278 |
|
VSUB(p2,v2,SM_VIEW_CENTER(sm)); |
279 |
|
|
280 |
< |
found = stApply_to_tri_cells(st,p0,p1,p2,func,arg); |
280 |
> |
stApply_to_tri(st,p0,p1,p2,edge_func,interior_func,arg1,arg2); |
281 |
|
|
273 |
– |
return(found); |
282 |
|
} |
283 |
|
|
284 |
|
|
285 |
|
int |
286 |
< |
add_tri_expand(qtptr,q0,q1,q2,t0,t1,t2,n,arg,t_id) |
286 |
> |
add_tri_expand(qtptr,q0,q1,q2,t0,t1,t2,n,arg,t_id,del_set) |
287 |
|
QUADTREE *qtptr; |
288 |
|
FVECT q0,q1,q2; |
289 |
|
FVECT t0,t1,t2; |
290 |
|
int n; |
291 |
|
int *arg; |
292 |
|
int t_id; |
293 |
+ |
OBJECT *del_set; |
294 |
|
{ |
295 |
< |
OBJECT tset[QT_MAXSET+1],*optr; |
295 |
> |
OBJECT t_set[QT_MAXSET+1],*optr,*tptr,r_set[QT_MAXSET+1]; |
296 |
|
int i,id,found; |
297 |
|
FVECT v0,v1,v2; |
298 |
|
TRI *tri; |
299 |
+ |
|
300 |
|
#ifdef DEBUG_TEST_DRIVER |
301 |
|
Pick_tri = t_id; |
302 |
|
Picking = TRUE; |
307 |
|
*qtptr = qtaddelem(*qtptr,t_id); |
308 |
|
return(TRUE); |
309 |
|
} |
310 |
< |
|
310 |
> |
|
311 |
|
optr = qtqueryset(*qtptr); |
312 |
+ |
if(del_set) |
313 |
+ |
{ |
314 |
+ |
setintersect(r_set,del_set,optr); |
315 |
+ |
if(QT_SET_CNT(r_set) > 0) |
316 |
+ |
{ |
317 |
+ |
qtgetset(t_set,*qtptr); |
318 |
+ |
optr = QT_SET_PTR(r_set); |
319 |
+ |
for(i = QT_SET_CNT(r_set); i > 0; i--) |
320 |
+ |
{ |
321 |
+ |
id = QT_SET_NEXT_ELEM(optr); |
322 |
+ |
deletelem(t_set,id); |
323 |
+ |
} |
324 |
+ |
qtfreeleaf(*qtptr); |
325 |
+ |
*qtptr = qtnewleaf(t_set); |
326 |
+ |
optr = t_set; |
327 |
+ |
} |
328 |
+ |
} |
329 |
|
if(!inset(optr,t_id)) |
330 |
|
{ |
331 |
|
if(QT_SET_CNT(optr) < QT_MAXSET) |
342 |
|
if(QT_SET_CNT(optr) >= QT_SET_THRESHOLD) |
343 |
|
if (n < QT_MAX_LEVELS) |
344 |
|
{ |
345 |
< |
qtgetset(tset,*qtptr); |
345 |
> |
qtgetset(t_set,*qtptr); |
346 |
|
/* If set size exceeds threshold: subdivide cell and reinsert tris*/ |
347 |
|
qtfreeleaf(*qtptr); |
348 |
|
qtSubdivide(qtptr); |
349 |
|
|
350 |
< |
for(optr = QT_SET_PTR(tset),i=QT_SET_CNT(tset); i > 0; i--) |
350 |
> |
for(optr = QT_SET_PTR(t_set),i=QT_SET_CNT(t_set); i > 0; i--) |
351 |
|
{ |
352 |
|
id = QT_SET_NEXT_ELEM(optr); |
353 |
|
tri = SM_NTH_TRI(smMesh,id); |
381 |
|
|
382 |
|
|
383 |
|
int |
384 |
< |
add_tri(qtptr,fptr,t_id) |
384 |
> |
add_tri(qtptr,fptr,t_id,del_set) |
385 |
|
QUADTREE *qtptr; |
386 |
|
int *fptr; |
387 |
|
int t_id; |
388 |
+ |
OBJECT *del_set; |
389 |
|
{ |
390 |
|
|
391 |
< |
OBJECT *optr; |
392 |
< |
|
391 |
> |
OBJECT *optr,*tptr; |
392 |
> |
OBJECT t_set[QT_MAXSET +1],r_set[QT_MAXSET +1]; |
393 |
> |
int i,id,found; |
394 |
|
#ifdef DEBUG_TEST_DRIVER |
395 |
|
Pick_tri = t_id; |
396 |
|
Picking = TRUE; |
403 |
|
} |
404 |
|
else |
405 |
|
{ |
406 |
< |
optr = qtqueryset(*qtptr); |
407 |
< |
if(!inset(optr,t_id)) |
408 |
< |
{ |
409 |
< |
if(QT_SET_CNT(optr) < QT_MAXSET) |
406 |
> |
optr = qtqueryset(*qtptr); |
407 |
> |
if(del_set) |
408 |
> |
{ |
409 |
> |
setintersect(r_set,del_set,optr); |
410 |
> |
if(QT_SET_CNT(r_set) > 0) |
411 |
> |
{ |
412 |
> |
qtgetset(t_set,*qtptr); |
413 |
> |
optr = QT_SET_PTR(r_set); |
414 |
> |
for(i = QT_SET_CNT(r_set); i > 0; i--) |
415 |
> |
{ |
416 |
> |
id = QT_SET_NEXT_ELEM(optr); |
417 |
> |
deletelem(t_set,id); |
418 |
> |
} |
419 |
> |
qtfreeleaf(*qtptr); |
420 |
> |
*qtptr = qtnewleaf(t_set); |
421 |
> |
optr = t_set; |
422 |
> |
} |
423 |
> |
} |
424 |
> |
if(!inset(optr,t_id)) |
425 |
|
{ |
426 |
< |
if(QT_SET_CNT(optr) >= QT_SET_THRESHOLD) |
427 |
< |
(*fptr) |= QT_EXPAND; |
428 |
< |
if(!QT_FLAG_FILL_TRI(*fptr)) |
429 |
< |
(*fptr)++; |
430 |
< |
*qtptr = qtaddelem(*qtptr,t_id); |
431 |
< |
} |
432 |
< |
else |
433 |
< |
{ |
426 |
> |
if(QT_SET_CNT(optr) < QT_MAXSET) |
427 |
> |
{ |
428 |
> |
if(QT_SET_CNT(optr) >= QT_SET_THRESHOLD) |
429 |
> |
(*fptr) |= QT_EXPAND; |
430 |
> |
if(!QT_FLAG_FILL_TRI(*fptr)) |
431 |
> |
(*fptr)++; |
432 |
> |
*qtptr = qtaddelem(*qtptr,t_id); |
433 |
> |
} |
434 |
> |
else |
435 |
> |
{ |
436 |
|
#ifdef DEBUG_TESTDRIVER |
437 |
< |
eputs("add_tri():exceeded set size\n"); |
437 |
> |
eputs("add_tri():exceeded set size\n"); |
438 |
|
#endif |
439 |
< |
return(FALSE); |
440 |
< |
} |
441 |
< |
} |
439 |
> |
return(FALSE); |
440 |
> |
} |
441 |
> |
} |
442 |
|
} |
443 |
|
return(TRUE); |
444 |
|
} |
445 |
|
|
446 |
|
|
447 |
< |
int |
402 |
< |
stInsert_tri(st,t_id,t0,t1,t2) |
403 |
< |
STREE *st; |
404 |
< |
int t_id; |
405 |
< |
FVECT t0,t1,t2; |
406 |
< |
{ |
407 |
< |
int f; |
408 |
< |
FVECT dir; |
409 |
< |
|
410 |
< |
/* First add all of the leaf cells lying on the triangle perimeter: |
411 |
< |
mark all cells seen on the way |
412 |
< |
*/ |
413 |
< |
ST_CLEAR_FLAGS(st); |
414 |
< |
f = 0; |
415 |
< |
VSUB(dir,t1,t0); |
416 |
< |
stTrace_edge(st,t0,dir,1.0,add_tri,&f,t_id); |
417 |
< |
VSUB(dir,t2,t1); |
418 |
< |
stTrace_edge(st,t1,dir,1.0,add_tri,&f,t_id); |
419 |
< |
VSUB(dir,t0,t2); |
420 |
< |
stTrace_edge(st,t2,dir,1.0,add_tri,&f,t_id); |
421 |
< |
/* Now visit interior */ |
422 |
< |
if(QT_FLAG_FILL_TRI(f) || QT_FLAG_UPDATE(f)) |
423 |
< |
stVisit_tri_interior(st,t0,t1,t2,add_tri_expand,&f,t_id); |
424 |
< |
} |
425 |
< |
|
426 |
< |
smLocator_add_tri(sm,t_id,v0_id,v1_id,v2_id) |
447 |
> |
smLocator_add_tri(sm,t_id,v0_id,v1_id,v2_id,del_set) |
448 |
|
SM *sm; |
449 |
|
int t_id; |
450 |
< |
int v0_id,v1_id,v2_id; |
450 |
> |
int v0_id,v1_id,v2_id; |
451 |
> |
OBJECT *del_set; |
452 |
|
{ |
453 |
|
STREE *st; |
454 |
|
FVECT v0,v1,v2; |
459 |
|
VSUB(v1,SM_NTH_WV(sm,v1_id),SM_VIEW_CENTER(sm)); |
460 |
|
VSUB(v2,SM_NTH_WV(sm,v2_id),SM_VIEW_CENTER(sm)); |
461 |
|
|
462 |
< |
stUpdate_tri(st,t_id,v0,v1,v2,add_tri,add_tri_expand); |
462 |
> |
qtClearAllFlags(); |
463 |
> |
|
464 |
> |
stApply_to_tri(st,v0,v1,v2,add_tri,add_tri_expand,t_id,del_set); |
465 |
|
|
466 |
|
} |
467 |
|
|
601 |
|
} |
602 |
|
|
603 |
|
void |
604 |
< |
smTris_swap_edge(sm,t_id,t1_id,e,e1,tn_id,tn1_id,add,del) |
604 |
> |
smTris_swap_edge(sm,t_id,t1_id,e,e1,tn_id,tn1_id,add_ptr,del_set) |
605 |
|
SM *sm; |
606 |
|
int t_id,t1_id; |
607 |
|
int e,e1; |
608 |
|
int *tn_id,*tn1_id; |
609 |
< |
LIST **add,**del; |
609 |
> |
LIST **add_ptr; |
610 |
> |
OBJECT *del_set; |
611 |
|
|
612 |
|
{ |
613 |
|
TRI *t,*t1; |
630 |
|
verts[enext] = T_NTH_V(t1,e1prev); |
631 |
|
verts[eprev] = T_NTH_V(t,eprev); |
632 |
|
ta_id = smAdd_tri(sm,verts[0],verts[1],verts[2],&ta); |
633 |
< |
*add = push_data(*add,ta_id); |
633 |
> |
*add_ptr = push_data(*add_ptr,ta_id); |
634 |
|
verts[e1] = T_NTH_V(t1,e1); |
635 |
|
verts[e1next] = T_NTH_V(t,eprev); |
636 |
|
verts[e1prev] = T_NTH_V(t1,e1prev); |
637 |
|
tb_id = smAdd_tri(sm,verts[0],verts[1],verts[2],&tb); |
638 |
< |
*add = push_data(*add,tb_id); |
638 |
> |
*add_ptr = push_data(*add_ptr,tb_id); |
639 |
|
|
640 |
|
/* set the neighbors */ |
641 |
|
T_NTH_NBR(ta,e) = T_NTH_NBR(t1,e1next); |
657 |
|
T_NTH_NBR(n,T_NTH_NBR_PTR(t1_id,n)) = tb_id; |
658 |
|
|
659 |
|
/* Delete two parent triangles */ |
660 |
+ |
if(remove_from_list(t_id,add_ptr)) |
661 |
+ |
smDelete_tri(sm,t_id); |
662 |
+ |
else |
663 |
+ |
insertelem(del_set,t_id); |
664 |
|
|
665 |
< |
*del = push_data(*del,t_id); |
666 |
< |
T_VALID_FLAG(t) = -1; |
667 |
< |
*del = push_data(*del,t1_id); |
668 |
< |
T_VALID_FLAG(t1) = -1; |
665 |
> |
if(remove_from_list(t1_id,add_ptr)) |
666 |
> |
smDelete_tri(sm,t1_id); |
667 |
> |
else |
668 |
> |
insertelem(del_set,t1_id); |
669 |
> |
|
670 |
|
*tn_id = ta_id; |
671 |
|
*tn1_id = tb_id; |
672 |
|
} |
673 |
|
|
674 |
< |
smUpdate_locator(sm,add_list,del_list) |
674 |
> |
smUpdate_locator(sm,add_list,del_set) |
675 |
|
SM *sm; |
676 |
< |
LIST *add_list,*del_list; |
676 |
> |
LIST *add_list; |
677 |
> |
OBJECT *del_set; |
678 |
|
{ |
679 |
< |
int t_id; |
679 |
> |
int t_id,i; |
680 |
|
TRI *t; |
681 |
+ |
OBJECT *optr; |
682 |
+ |
|
683 |
|
while(add_list) |
684 |
|
{ |
685 |
|
t_id = pop_list(&add_list); |
686 |
|
t = SM_NTH_TRI(sm,t_id); |
687 |
< |
if(!T_IS_VALID(t)) |
655 |
< |
{ |
656 |
< |
T_VALID_FLAG(t) = 1; |
657 |
< |
continue; |
658 |
< |
} |
659 |
< |
smLocator_add_tri(sm,t_id,T_NTH_V(t,0),T_NTH_V(t,1),T_NTH_V(t,2)); |
687 |
> |
smLocator_add_tri(sm,t_id,T_NTH_V(t,0),T_NTH_V(t,1),T_NTH_V(t,2),del_set); |
688 |
|
} |
689 |
< |
|
690 |
< |
while(del_list) |
689 |
> |
|
690 |
> |
optr = QT_SET_PTR(del_set); |
691 |
> |
for(i = QT_SET_CNT(del_set); i > 0; i--) |
692 |
|
{ |
693 |
< |
t_id = pop_list(&del_list); |
694 |
< |
t = SM_NTH_TRI(sm,t_id); |
666 |
< |
if(!T_IS_VALID(t)) |
667 |
< |
{ |
668 |
< |
smLocator_remove_tri(sm,t_id); |
669 |
< |
} |
670 |
< |
smDelete_tri(sm,t_id); |
693 |
> |
t_id = QT_SET_NEXT_ELEM(optr); |
694 |
> |
smDelete_tri(sm,t_id); |
695 |
|
} |
696 |
|
} |
697 |
|
/* MUST add check for constrained edges */ |
698 |
|
int |
699 |
< |
smFix_tris(sm,id,tlist,add_list,del_list) |
699 |
> |
smFix_tris(sm,id,tlist,add_list,del_set) |
700 |
|
SM *sm; |
701 |
|
int id; |
702 |
|
LIST *tlist; |
703 |
< |
LIST *add_list,*del_list; |
703 |
> |
LIST *add_list; |
704 |
> |
OBJECT *del_set; |
705 |
|
{ |
706 |
|
TRI *t,*t_opp; |
707 |
|
FVECT p,p1,p2,p3; |
722 |
|
VSUB(p2,SM_T_NTH_WV(sm,t_opp,1),SM_VIEW_CENTER(sm)); |
723 |
|
VSUB(p3,SM_T_NTH_WV(sm,t_opp,2),SM_VIEW_CENTER(sm)); |
724 |
|
*/ |
725 |
< |
smDir(sm,p1,T_NTH_V(t_opp,0)); |
726 |
< |
smDir(sm,p2,T_NTH_V(t_opp,1)); |
727 |
< |
smDir(sm,p3,T_NTH_V(t_opp,2)); |
725 |
> |
smDir_in_cone(sm,p1,T_NTH_V(t_opp,0)); |
726 |
> |
smDir_in_cone(sm,p2,T_NTH_V(t_opp,1)); |
727 |
> |
smDir_in_cone(sm,p3,T_NTH_V(t_opp,2)); |
728 |
|
if(point_in_cone(p,p1,p2,p3)) |
729 |
|
{ |
730 |
|
swapped = 1; |
732 |
|
/* check list for t_opp and Remove if there */ |
733 |
|
remove_from_list(t_opp_id,&tlist); |
734 |
|
smTris_swap_edge(sm,t_id,t_opp_id,e,e1,&t_id,&t_opp_id, |
735 |
< |
&add_list,&del_list); |
735 |
> |
&add_list,del_set); |
736 |
|
tlist = push_data(tlist,t_id); |
737 |
|
tlist = push_data(tlist,t_opp_id); |
738 |
|
} |
739 |
|
} |
740 |
< |
smUpdate_locator(sm,add_list,del_list); |
740 |
> |
smUpdate_locator(sm,add_list,del_set); |
741 |
|
return(swapped); |
742 |
|
} |
743 |
|
|
846 |
|
TRI *tri,*t0,*t1,*t2,*nbr; |
847 |
|
int v0_id,v1_id,v2_id,n_id; |
848 |
|
int t0_id,t1_id,t2_id; |
849 |
< |
LIST *tlist,*add_list,*del_list; |
849 |
> |
LIST *tlist,*add_list; |
850 |
> |
OBJECT del_set[QT_MAXSET+1]; |
851 |
|
FVECT npt; |
852 |
|
|
853 |
< |
add_list = del_list = NULL; |
853 |
> |
add_list = NULL; |
854 |
> |
QT_CLEAR_SET(del_set); |
855 |
|
if(s_id == SM_INVALID) |
856 |
|
s_id = smAdd_sample_point(sm,c,dir,p); |
857 |
|
|
900 |
|
nbr = SM_NTH_TRI(sm,T_NTH_NBR(tri,2)); |
901 |
|
T_NTH_NBR(nbr,T_NTH_NBR_PTR(tri_id,nbr)) = t2_id; |
902 |
|
|
903 |
< |
del_list = push_data(del_list,tri_id); |
877 |
< |
T_VALID_FLAG(tri) = -1; |
903 |
> |
insertelem(del_set,tri_id); |
904 |
|
|
905 |
|
/* Fix up the new triangles*/ |
906 |
|
tlist = push_data(NULL,t0_id); |
907 |
|
tlist = push_data(tlist,t1_id); |
908 |
|
tlist = push_data(tlist,t2_id); |
909 |
|
|
910 |
< |
smFix_tris(sm,s_id,tlist,add_list,del_list); |
910 |
> |
smFix_tris(sm,s_id,tlist,add_list,del_set); |
911 |
|
|
912 |
|
if(n_id != -1) |
913 |
|
smDelete_point(sm,n_id); |
1141 |
|
cntr[1] += .02; |
1142 |
|
cntr[2] += .03; |
1143 |
|
VADD(cntr,cntr,SM_VIEW_CENTER(sm)); |
1144 |
< |
/* WONT use dir */ |
1119 |
< |
point_on_sphere(d,cntr,SM_VIEW_CENTER(sm)); |
1144 |
> |
d[0] = -1; |
1145 |
|
id = smAdd_base_vertex(sm,cntr,d); |
1146 |
|
/* test to make sure vertex allocated */ |
1147 |
|
if(id != -1) |
1157 |
|
v2_id = p[stTri_verts[i][2]]; |
1158 |
|
if((ids[i] = smAdd_tri(sm, v0_id,v1_id,v2_id,&(tris[i])))== -1) |
1159 |
|
return(0); |
1160 |
< |
smLocator_add_tri(sm,ids[i],v0_id,v1_id,v2_id); |
1160 |
> |
smLocator_add_tri(sm,ids[i],v0_id,v1_id,v2_id,NULL); |
1161 |
|
} |
1162 |
|
/* Set neighbors */ |
1163 |
|
|
1224 |
|
|
1225 |
|
if(v0) |
1226 |
|
{ |
1227 |
< |
VCOPY(v0,SM_NTH_WV(smMesh,v0_id)); |
1228 |
< |
VCOPY(v1,SM_NTH_WV(smMesh,v1_id)); |
1229 |
< |
VCOPY(v2,SM_NTH_WV(smMesh,v2_id)); |
1227 |
> |
VSUB(v0,SM_NTH_WV(smMesh,v0_id),SM_VIEW_CENTER(smMesh)); |
1228 |
> |
VSUB(v1,SM_NTH_WV(smMesh,v1_id),SM_VIEW_CENTER(smMesh)); |
1229 |
> |
VSUB(v2,SM_NTH_WV(smMesh,v2_id),SM_VIEW_CENTER(smMesh)); |
1230 |
|
} |
1231 |
|
if(n0) |
1232 |
|
{ |