16 |
|
static EDGE Edges[MAX_EDGES]; |
17 |
|
static int Ecnt=0; |
18 |
|
|
19 |
+ |
int |
20 |
+ |
remove_tri(qtptr,fptr,t_id) |
21 |
+ |
QUADTREE *qtptr; |
22 |
+ |
int *fptr; |
23 |
+ |
int t_id; |
24 |
+ |
{ |
25 |
+ |
OBJECT tset[QT_MAXSET+1]; |
26 |
+ |
int n; |
27 |
|
|
28 |
+ |
if(QT_IS_EMPTY(*qtptr)) |
29 |
+ |
return(FALSE); |
30 |
+ |
/* remove id from set */ |
31 |
+ |
else |
32 |
+ |
{ |
33 |
+ |
if(!qtinset(*qtptr,t_id)) |
34 |
+ |
return(FALSE); |
35 |
+ |
n = QT_SET_CNT(qtqueryset(*qtptr))-1; |
36 |
+ |
*qtptr = qtdelelem(*qtptr,t_id); |
37 |
+ |
if(n == 0) |
38 |
+ |
(*fptr) |= QT_COMPRESS; |
39 |
+ |
if(!QT_FLAG_FILL_TRI(*fptr)) |
40 |
+ |
(*fptr)++; |
41 |
+ |
} |
42 |
+ |
return(TRUE); |
43 |
+ |
} |
44 |
+ |
|
45 |
+ |
int |
46 |
+ |
remove_tri_compress(qtptr,q0,q1,q2,t0,t1,t2,n,arg,t_id) |
47 |
+ |
QUADTREE *qtptr; |
48 |
+ |
FVECT q0,q1,q2; |
49 |
+ |
FVECT t0,t1,t2; |
50 |
+ |
int n; |
51 |
+ |
int *arg; |
52 |
+ |
int t_id; |
53 |
+ |
{ |
54 |
+ |
int f = 0; |
55 |
+ |
/* NOTE compress */ |
56 |
+ |
return(remove_tri(qtptr,&f,t_id)); |
57 |
+ |
} |
58 |
+ |
|
59 |
+ |
|
60 |
+ |
|
61 |
+ |
int |
62 |
+ |
stDelete_tri(st,t_id,t0,t1,t2) |
63 |
+ |
STREE *st; |
64 |
+ |
int t_id; |
65 |
+ |
FVECT t0,t1,t2; |
66 |
+ |
{ |
67 |
+ |
int f; |
68 |
+ |
FVECT dir; |
69 |
+ |
|
70 |
+ |
/* First add all of the leaf cells lying on the triangle perimeter: |
71 |
+ |
mark all cells seen on the way |
72 |
+ |
*/ |
73 |
+ |
ST_CLEAR_FLAGS(st); |
74 |
+ |
f = 0; |
75 |
+ |
VSUB(dir,t1,t0); |
76 |
+ |
stTrace_edge(st,t0,dir,1.0,remove_tri,&f,t_id); |
77 |
+ |
VSUB(dir,t2,t1); |
78 |
+ |
stTrace_edge(st,t1,dir,1.0,remove_tri,&f,t_id); |
79 |
+ |
VSUB(dir,t0,t2); |
80 |
+ |
stTrace_edge(st,t2,dir,1.0,remove_tri,&f,t_id); |
81 |
+ |
/* Now visit interior */ |
82 |
+ |
if(QT_FLAG_FILL_TRI(f) || QT_FLAG_UPDATE(f)) |
83 |
+ |
stVisit_tri_interior(st,t0,t1,t2,remove_tri_compress,&f,t_id); |
84 |
+ |
} |
85 |
+ |
|
86 |
+ |
|
87 |
|
smLocator_remove_tri(sm,t_id) |
88 |
|
SM *sm; |
89 |
|
int t_id; |
91 |
|
STREE *st; |
92 |
|
char found; |
93 |
|
TRI *t; |
94 |
< |
FVECT p0,p1,p2; |
94 |
> |
FVECT v0,v1,v2; |
95 |
|
|
96 |
|
st = SM_LOCATOR(sm); |
97 |
|
|
98 |
|
t = SM_NTH_TRI(sm,t_id); |
99 |
|
|
100 |
< |
smDir(sm,p0,T_NTH_V(t,0)); |
101 |
< |
smDir(sm,p1,T_NTH_V(t,1)); |
102 |
< |
smDir(sm,p2,T_NTH_V(t,2)); |
103 |
< |
|
37 |
< |
found = stRemove_tri(st,t_id,p0,p1,p2); |
38 |
< |
|
100 |
> |
VSUB(v0,SM_T_NTH_WV(sm,t,0),SM_VIEW_CENTER(sm)); |
101 |
> |
VSUB(v1,SM_T_NTH_WV(sm,t,1),SM_VIEW_CENTER(sm)); |
102 |
> |
VSUB(v2,SM_T_NTH_WV(sm,t,2),SM_VIEW_CENTER(sm)); |
103 |
> |
found = stUpdate_tri(st,t_id,v0,v1,v2,remove_tri,remove_tri_compress); |
104 |
|
return(found); |
105 |
|
} |
106 |
|
|
125 |
|
int t_id; |
126 |
|
{ |
127 |
|
|
63 |
– |
/* first remove from point location structure */ |
64 |
– |
smLocator_remove_tri(sm,t_id); |
128 |
|
|
129 |
|
/* NOTE: Assumes that a new triangle adjacent to each vertex |
130 |
|
has been added- before the deletion: replacing |
205 |
|
while(tlist) |
206 |
|
{ |
207 |
|
t_id = (int)pop_list(&tlist); |
208 |
+ |
/* first remove from point location structure */ |
209 |
+ |
smLocator_remove_tri(sm,t_id); |
210 |
|
smDelete_tri(sm,t_id); |
211 |
|
} |
212 |
|
return(elist); |
233 |
|
e = (int)LIST_DATA(el); |
234 |
|
id_e0 = E_NTH_VERT(e,0); |
235 |
|
id_e1 = E_NTH_VERT(e,1); |
236 |
< |
|
237 |
< |
smDir(sm,e0,id_e0); |
238 |
< |
smDir(sm,e1,id_e1); |
239 |
< |
if(spherical_polygon_edge_intersect(v0,v1,e0,e1)) |
236 |
> |
/* NOTE: DO these need to be normalized? Just subtract center? */ |
237 |
> |
/* |
238 |
> |
smDir(sm,e0,id_e0); |
239 |
> |
smDir(sm,e1,id_e1); |
240 |
> |
*/ |
241 |
> |
VSUB(e0,SM_NTH_WV(sm,id_e0),SM_VIEW_CENTER(sm)); |
242 |
> |
VSUB(e1,SM_NTH_WV(sm,id_e1),SM_VIEW_CENTER(sm)); |
243 |
> |
if(sedge_intersect(v0,v1,e0,e1)) |
244 |
|
return(TRUE); |
245 |
|
|
246 |
|
el = LIST_NEXT(el); |
353 |
|
} |
354 |
|
|
355 |
|
|
356 |
< |
|
357 |
< |
LIST |
289 |
< |
*smTriangulate_convex(sm,plist) |
356 |
> |
int |
357 |
> |
smTriangulate_convex(sm,plist) |
358 |
|
SM *sm; |
359 |
|
LIST *plist; |
360 |
|
{ |
375 |
|
v_id2 = E_NTH_VERT(e_id1,1); |
376 |
|
/* form a triangle for each triple of with v0 as base of star */ |
377 |
|
t_id = smAdd_tri(sm,v_id0,v_id1,v_id2,&tri); |
378 |
+ |
smLocator_add_tri(sm,t_id,v_id0,v_id1,v_id2); |
379 |
|
/* add which pointer?*/ |
380 |
|
|
381 |
|
lptr = LIST_NEXT(lptr); |
396 |
|
|
397 |
|
e_id0 = -e_id2; |
398 |
|
} |
399 |
+ |
|
400 |
|
free_list(plist); |
401 |
+ |
return(TRUE); |
402 |
|
} |
403 |
< |
|
403 |
> |
int |
404 |
|
smTriangulate_elist(sm,plist) |
405 |
|
SM *sm; |
406 |
|
LIST *plist; |
409 |
|
FVECT v0,v1,v2; |
410 |
|
int id0,id1,id2,e,id_next; |
411 |
|
char flipped; |
412 |
< |
int debug = TRUE; |
412 |
> |
int done; |
413 |
|
|
414 |
|
l = plist; |
415 |
|
|
441 |
|
#ifdef DEBUG |
442 |
|
eputs("smTriangulate_elist():Unable to find convex vertex\n"); |
443 |
|
#endif |
444 |
< |
return; |
444 |
> |
return(FALSE); |
445 |
|
} |
446 |
|
/* add edge */ |
447 |
|
el1 = NULL; |
448 |
|
/* Split edge list l into two lists: one from id1-id_next-id1, |
449 |
|
and the next from id2-id_next-id2 |
450 |
|
*/ |
451 |
< |
debug = split_edge_list(id1,id_next,&l,&el1); |
451 |
> |
split_edge_list(id1,id_next,&l,&el1); |
452 |
|
/* Recurse and triangulate the two edge lists */ |
453 |
< |
if(debug) |
454 |
< |
debug = smTriangulate_elist(sm,l); |
455 |
< |
if(debug) |
456 |
< |
debug = smTriangulate_elist(sm,el1); |
386 |
< |
|
387 |
< |
return(debug); |
453 |
> |
done = smTriangulate_elist(sm,l); |
454 |
> |
if(done) |
455 |
> |
done = smTriangulate_elist(sm,el1); |
456 |
> |
return(done); |
457 |
|
} |
458 |
< |
smTriangulate_convex(sm,plist); |
459 |
< |
return(TRUE); |
458 |
> |
done = smTriangulate_convex(sm,plist); |
459 |
> |
return(done); |
460 |
|
} |
461 |
|
|
462 |
|
int |
463 |
< |
smTriangulate_polygon(sm,plist) |
463 |
> |
smTriangulate(sm,plist) |
464 |
|
SM *sm; |
465 |
|
LIST *plist; |
466 |
|
{ |
468 |
|
TRI *t0,*t1; |
469 |
|
int test; |
470 |
|
|
471 |
< |
test = smTriangulate_elist(sm,plist,NULL); |
471 |
> |
test = smTriangulate_elist(sm,plist); |
472 |
|
|
473 |
|
if(!test) |
474 |
|
return(test); |
479 |
|
if((id_t0==SM_INVALID) || (id_t1==SM_INVALID)) |
480 |
|
{ |
481 |
|
#ifdef DEBUG |
482 |
< |
eputs("smTriangulate_polygon(): Unassigned edge neighbor\n"); |
482 |
> |
eputs("smTriangulate(): Unassigned edge neighbor\n"); |
483 |
|
#endif |
484 |
|
continue; |
485 |
|
} |
516 |
|
TRI *t0,*t1,*nt0,*nt1; |
517 |
|
int i,id_v0,id_v1,id_v2,id_p,nid_t0,nid_t1; |
518 |
|
FVECT v0,v1,v2,p,np,v; |
519 |
< |
|
519 |
> |
LIST *add,*del; |
520 |
> |
|
521 |
> |
add = del = NULL; |
522 |
|
FOR_ALL_EDGES(e) |
523 |
|
{ |
524 |
|
id_t0 = E_NTH_TRI(e,0); |
550 |
|
VSUB(p,p,SM_VIEW_CENTER(sm)); |
551 |
|
if(point_in_cone(p,v0,v1,v2)) |
552 |
|
{ |
553 |
< |
smTris_swap_edge(sm,id_t0,id_t1,e0,e1,&nid_t0,&nid_t1); |
553 |
> |
smTris_swap_edge(sm,id_t0,id_t1,e0,e1,&nid_t0,&nid_t1,&add,&del); |
554 |
|
|
555 |
|
nt0 = SM_NTH_TRI(sm,nid_t0); |
556 |
|
nt1 = SM_NTH_TRI(sm,nid_t1); |
581 |
|
SET_E_NTH_TRI(e_new,1,id_t1); |
582 |
|
} |
583 |
|
} |
584 |
< |
|
584 |
> |
smUpdate_locator(sm,add,del); |
585 |
|
} |
586 |
|
|
587 |
|
int |
602 |
|
return(FALSE); |
603 |
|
|
604 |
|
/* Triangulate spherical polygon */ |
605 |
< |
debug = smTriangulate_polygon(sm,elist); |
605 |
> |
smTriangulate(sm,elist); |
606 |
|
|
607 |
|
|
608 |
|
/* Fix up new triangles to be Delaunay */ |
609 |
< |
if(debug) |
539 |
< |
smFix_edges(sm); |
609 |
> |
smFix_edges(sm); |
610 |
|
|
611 |
|
return(TRUE); |
612 |
|
} |