ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/hd/sm_del.c
Revision: 3.3
Committed: Fri Sep 11 11:52:25 1998 UTC (25 years, 7 months ago) by gwlarson
Content type: text/plain
Branch: MAIN
Changes since 3.2: +93 -30 lines
Log Message:
fixed triangle insertion using edge tracing

File Contents

# User Rev Content
1 gwlarson 3.1 /* Copyright (c) 1998 Silicon Graphics, Inc. */
2    
3     #ifndef lint
4     static char SCCSid[] = "$SunId$ SGI";
5     #endif
6    
7     /*
8     * sm_del.c
9     */
10     #include "standard.h"
11    
12     #include "sm_list.h"
13     #include "sm_geom.h"
14     #include "sm.h"
15    
16     static EDGE Edges[MAX_EDGES];
17     static int Ecnt=0;
18    
19 gwlarson 3.3 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 gwlarson 3.1
28 gwlarson 3.3 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 gwlarson 3.1 smLocator_remove_tri(sm,t_id)
88     SM *sm;
89     int t_id;
90     {
91     STREE *st;
92     char found;
93     TRI *t;
94 gwlarson 3.3 FVECT v0,v1,v2;
95 gwlarson 3.1
96     st = SM_LOCATOR(sm);
97    
98     t = SM_NTH_TRI(sm,t_id);
99    
100 gwlarson 3.3 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 gwlarson 3.1 return(found);
105     }
106    
107     smFree_tri(sm,id)
108     SM *sm;
109     int id;
110     {
111     TRI *tri;
112    
113     tri = SM_NTH_TRI(sm,id);
114     /* Add to the free_list */
115     T_NEXT_FREE(tri) = SM_FREE_TRIS(sm);
116     SM_FREE_TRIS(sm) = id;
117     T_VALID_FLAG(tri) = -1;
118     }
119    
120     /* Assumes mesh pointers have been cleaned up appropriately: just deletes from
121     Point location and triangle data structure
122     */
123     smDelete_tri(sm,t_id)
124     SM *sm;
125     int t_id;
126     {
127    
128    
129     /* NOTE: Assumes that a new triangle adjacent to each vertex
130     has been added- before the deletion: replacing
131     the old tri- and therefore dont need to dereference any pointers
132     to id because the vertices can no longer
133     point to tri id as being the first triangle pointer
134     */
135     if(!SM_IS_NTH_T_BASE(sm,t_id))
136     {
137     SM_NUM_TRIS(sm)--;
138     if(SM_IS_NTH_T_NEW(sm,t_id))
139     smNew_tri_cnt--;
140     }
141     smClear_tri_flags(sm,t_id);
142    
143     smFree_tri(sm,t_id);
144    
145     }
146    
147    
148    
149     LIST
150     *smVertex_star_polygon(sm,id)
151     SM *sm;
152     int id;
153     {
154     TRI *tri,*t_next;
155     LIST *elist,*end,*tlist;
156     int t_id,v_next,t_next_id;
157     int e;
158    
159     elist = end = NULL;
160     /* Get the first triangle adjacent to vertex id */
161     t_id = SM_NTH_VERT(sm,id);
162     tri = SM_NTH_TRI(sm,t_id);
163    
164    
165     if((e = eNew_edge()) == SM_INVALID)
166     {
167     #ifdef DEBUG
168     eputs("smVertex_star_polygon():Too many edges\n");
169     #endif
170     return(NULL);
171     }
172     elist = add_data_to_circular_list(elist,&end,e);
173     v_next = (T_WHICH_V(tri,id)+1)%3;
174     SET_E_NTH_VERT(e,0,T_NTH_V(tri,v_next));
175     SET_E_NTH_TRI(e,0,SM_INVALID);
176     SET_E_NTH_TRI(e,1,T_NTH_NBR(tri,v_next));
177     v_next = (T_WHICH_V(tri,id)+2)%3;
178     SET_E_NTH_VERT(e,1,T_NTH_V(tri,v_next));
179    
180    
181     t_next_id = t_id;
182     t_next = tri;
183    
184     tlist = push_data(NULL,t_id);
185    
186     while((t_next_id = smTri_next_ccw_nbr(sm,t_next,id)) != t_id)
187     {
188     if((e = eNew_edge()) == SM_INVALID)
189     {
190     #ifdef DEBUG
191     eputs("smVertex_star_polygon():Too many edges\n");
192     #endif
193     return(NULL);
194     }
195     elist = add_data_to_circular_list(elist,&end,e);
196     t_next = SM_NTH_TRI(sm,t_next_id);
197     v_next = (T_WHICH_V(t_next,id)+1)%3;
198     SET_E_NTH_VERT(e,0,T_NTH_V(t_next,v_next));
199     SET_E_NTH_TRI(e,0,SM_INVALID);
200     SET_E_NTH_TRI(e,1,T_NTH_NBR(t_next,v_next));
201     v_next = (T_WHICH_V(t_next,id)+2)%3;
202     SET_E_NTH_VERT(e,1,T_NTH_V(t_next,v_next));
203     tlist = push_data(tlist,t_next_id);
204     }
205     while(tlist)
206     {
207     t_id = (int)pop_list(&tlist);
208 gwlarson 3.2 /* first remove from point location structure */
209     smLocator_remove_tri(sm,t_id);
210 gwlarson 3.1 smDelete_tri(sm,t_id);
211     }
212     return(elist);
213     }
214    
215     int
216     smEdge_intersect_polygon(sm,v0,v1,l)
217     SM *sm;
218     FVECT v0,v1;
219     LIST *l;
220     {
221     FVECT e0,e1;
222     int e,id_e0,id_e1;
223     LIST *el,*eptr;
224    
225     /* Test the edges in l against v0v1 to see if v0v1 intersects
226     any other edges
227     */
228    
229     el = l;
230    
231     while(el)
232     {
233     e = (int)LIST_DATA(el);
234     id_e0 = E_NTH_VERT(e,0);
235     id_e1 = E_NTH_VERT(e,1);
236 gwlarson 3.3 /* NOTE: DO these need to be normalized? Just subtract center? */
237 gwlarson 3.1 smDir(sm,e0,id_e0);
238     smDir(sm,e1,id_e1);
239 gwlarson 3.3 if(sedge_intersect(v0,v1,e0,e1))
240 gwlarson 3.1 return(TRUE);
241    
242     el = LIST_NEXT(el);
243     if(el == l)
244     break;
245     }
246     return(FALSE);
247     }
248    
249     int
250     smFind_next_convex_vertex(sm,id0,id1,v0,v1,l)
251     SM *sm;
252     int id0,id1;
253     FVECT v0,v1;
254     LIST *l;
255     {
256     int e,id;
257     LIST *el;
258     FVECT v;
259    
260     /* starting with the end of edge at head of l, search sequentially for
261     vertex v such that v0v1v is a convex angle, and the edge v1v does
262     not intersect any other edges
263     */
264     id = SM_INVALID;
265     el = l;
266     while(id != id0)
267     {
268     e = (int)LIST_DATA(el);
269     id = E_NTH_VERT(e,1);
270    
271     smDir(sm,v,id);
272    
273     if(convex_angle(v0,v1,v) && !smEdge_intersect_polygon(sm,v1,v,l))
274     return(id);
275    
276     el = LIST_NEXT(el);
277     if(el == l)
278     break;
279     }
280     return(SM_INVALID);
281     }
282    
283     int
284     split_edge_list(id0,id_new,l,lnew)
285     int id0,id_new;
286     LIST **l,**lnew;
287     {
288     LIST *list,*lptr,*end;
289     int e,e1,e2,new_e;
290    
291     e2 = SM_INVALID;
292     list = lptr = *l;
293    
294     if((new_e = eNew_edge())==SM_INVALID)
295     {
296     #ifdef DEBUG
297     eputs("split_edge_list():Too many edges\n");
298     #endif
299     return(FALSE);
300     }
301     SET_E_NTH_VERT(new_e,0,id0);
302     SET_E_NTH_VERT(new_e,1,id_new);
303     SET_E_NTH_TRI(new_e,0,SM_INVALID);
304     SET_E_NTH_TRI(new_e,1,SM_INVALID);
305    
306     while(e2 != id_new)
307     {
308     lptr = LIST_NEXT(lptr);
309     e = (int)LIST_DATA(lptr);
310     e2 = E_NTH_VERT(e,1);
311     if(lptr == list)
312     {
313     #ifdef DEBUG
314     eputs("split_edge_list():cant find vertex\n");
315     #endif
316     *lnew = NULL;
317     return(FALSE);
318     }
319    
320     }
321     end = lptr;
322     lptr = LIST_NEXT(lptr);
323     list = add_data_to_circular_list(list,&end,-new_e);
324     *lnew = list;
325    
326     /* now follow other cycle */
327    
328     list = lptr;
329     e2 = SM_INVALID;
330     while(e2 != id0)
331     {
332     lptr = LIST_NEXT(lptr);
333     e = (int)LIST_DATA(lptr);
334     e2 = E_NTH_VERT(e,1);
335     if(lptr == list)
336     {
337     #ifdef DEBUG
338     eputs("split_edge_list():cant find intial vertex\n");
339     #endif
340     *l = NULL;
341     return(FALSE);
342     }
343    
344     }
345     end = lptr;
346     list = add_data_to_circular_list(list,&end,new_e);
347     *l = list;
348     return(TRUE);
349     }
350    
351    
352 gwlarson 3.3 int
353     smTriangulate_convex(sm,plist)
354 gwlarson 3.1 SM *sm;
355     LIST *plist;
356     {
357     TRI *tri;
358     int t_id,e_id0,e_id1,e_id2;
359     int v_id0,v_id1,v_id2;
360     LIST *lptr;
361     int cnt;
362    
363     lptr = plist;
364     e_id0 = (int)LIST_DATA(lptr);
365     v_id0 = E_NTH_VERT(e_id0,0);
366     lptr = LIST_NEXT(lptr);
367     while(LIST_NEXT(lptr) != plist)
368     {
369     e_id1 = (int)LIST_DATA(lptr);
370     v_id1 = E_NTH_VERT(e_id1,0);
371     v_id2 = E_NTH_VERT(e_id1,1);
372     /* form a triangle for each triple of with v0 as base of star */
373     t_id = smAdd_tri(sm,v_id0,v_id1,v_id2,&tri);
374 gwlarson 3.2 smLocator_add_tri(sm,t_id,v_id0,v_id1,v_id2);
375 gwlarson 3.1 /* add which pointer?*/
376    
377     lptr = LIST_NEXT(lptr);
378    
379     if(LIST_NEXT(lptr) != plist)
380     {
381     e_id2 = eNew_edge();
382     SET_E_NTH_VERT(e_id2,0,v_id2);
383     SET_E_NTH_VERT(e_id2,1,v_id0);
384     }
385     else
386     e_id2 = (int)LIST_DATA(lptr);
387    
388     /* set appropriate tri for each edge*/
389     SET_E_NTH_TRI(e_id0,0,t_id);
390     SET_E_NTH_TRI(e_id1,0,t_id);
391     SET_E_NTH_TRI(e_id2,0,t_id);
392    
393     e_id0 = -e_id2;
394     }
395 gwlarson 3.3
396 gwlarson 3.1 free_list(plist);
397 gwlarson 3.3 return(TRUE);
398 gwlarson 3.1 }
399 gwlarson 3.3 int
400 gwlarson 3.1 smTriangulate_elist(sm,plist)
401     SM *sm;
402     LIST *plist;
403     {
404     LIST *l,*el1;
405     FVECT v0,v1,v2;
406     int id0,id1,id2,e,id_next;
407     char flipped;
408 gwlarson 3.3 int done;
409 gwlarson 3.1
410     l = plist;
411    
412     while(l)
413     {
414     /* get v0,v1,v2 */
415     e = (int)LIST_DATA(l);
416     id0 = E_NTH_VERT(e,0);
417     id1 = E_NTH_VERT(e,1);
418     l = LIST_NEXT(l);
419     e = (int)LIST_DATA(l);
420     id2 = E_NTH_VERT(e,1);
421    
422     smDir(sm,v0,id0);
423     smDir(sm,v1,id1);
424     smDir(sm,v2,id2);
425     /* determine if convex (left turn), or concave(right turn) angle */
426     if(convex_angle(v0,v1,v2))
427     {
428     if(l == plist)
429     break;
430     else
431     continue;
432     }
433     /* if concave: add edge and recurse on two sub polygons */
434     id_next = smFind_next_convex_vertex(sm,id0,id1,v0,v1,LIST_NEXT(l));
435     if(id_next == SM_INVALID)
436     {
437     #ifdef DEBUG
438     eputs("smTriangulate_elist():Unable to find convex vertex\n");
439     #endif
440 gwlarson 3.3 return(FALSE);
441 gwlarson 3.1 }
442     /* add edge */
443     el1 = NULL;
444     /* Split edge list l into two lists: one from id1-id_next-id1,
445     and the next from id2-id_next-id2
446     */
447 gwlarson 3.3 split_edge_list(id1,id_next,&l,&el1);
448 gwlarson 3.1 /* Recurse and triangulate the two edge lists */
449 gwlarson 3.3 done = smTriangulate_elist(sm,l);
450     if(done)
451     done = smTriangulate_elist(sm,el1);
452     return(done);
453 gwlarson 3.1 }
454 gwlarson 3.3 done = smTriangulate_convex(sm,plist);
455     return(done);
456 gwlarson 3.1 }
457    
458     int
459 gwlarson 3.3 smTriangulate(sm,plist)
460 gwlarson 3.1 SM *sm;
461     LIST *plist;
462     {
463     int e,id_t0,id_t1,e0,e1;
464     TRI *t0,*t1;
465     int test;
466    
467 gwlarson 3.3 test = smTriangulate_elist(sm,plist);
468 gwlarson 3.1
469     if(!test)
470     return(test);
471     FOR_ALL_EDGES(e)
472     {
473     id_t0 = E_NTH_TRI(e,0);
474     id_t1 = E_NTH_TRI(e,1);
475     if((id_t0==SM_INVALID) || (id_t1==SM_INVALID))
476     {
477     #ifdef DEBUG
478 gwlarson 3.3 eputs("smTriangulate(): Unassigned edge neighbor\n");
479 gwlarson 3.1 #endif
480     continue;
481     }
482     t0 = SM_NTH_TRI(sm,id_t0);
483     t1 = SM_NTH_TRI(sm,id_t1);
484    
485     e0 = T_WHICH_V(t0,E_NTH_VERT(e,0));
486     T_NTH_NBR(t0,e0) = id_t1;
487    
488     e1 = T_WHICH_V(t1,E_NTH_VERT(e,1));
489     T_NTH_NBR(t1,e1) = id_t0;
490     }
491     return(test);
492     }
493    
494     eIn_tri(e,t)
495     int e;
496     TRI *t;
497     {
498    
499     if(T_NTH_V(t,0)==E_NTH_VERT(e,0))
500     return(T_NTH_V(t,1)==E_NTH_VERT(e,1)||T_NTH_V(t,2)==E_NTH_VERT(e,1));
501     else
502     if(T_NTH_V(t,1)==E_NTH_VERT(e,0))
503     return(T_NTH_V(t,0)==E_NTH_VERT(e,1)||T_NTH_V(t,2)==E_NTH_VERT(e,1));
504     else if(T_NTH_V(t,2)==E_NTH_VERT(e,0))
505     return(T_NTH_V(t,0)==E_NTH_VERT(e,1)||T_NTH_V(t,1)==E_NTH_VERT(e,1));
506     return(FALSE);
507     }
508     smFix_edges(sm)
509     SM *sm;
510     {
511     int e,id_t0,id_t1,e_new,e0,e1,e0_next,e1_next;
512     TRI *t0,*t1,*nt0,*nt1;
513     int i,id_v0,id_v1,id_v2,id_p,nid_t0,nid_t1;
514     FVECT v0,v1,v2,p,np,v;
515 gwlarson 3.2 LIST *add,*del;
516    
517     add = del = NULL;
518 gwlarson 3.1 FOR_ALL_EDGES(e)
519     {
520     id_t0 = E_NTH_TRI(e,0);
521     id_t1 = E_NTH_TRI(e,1);
522     if((id_t0==SM_INVALID) || (id_t1==SM_INVALID))
523     {
524     #ifdef DEBUG
525     eputs("smFix_edges: Unassigned edge nbr\n");
526     #endif
527     continue;
528     }
529     t0 = SM_NTH_TRI(sm,id_t0);
530     t1 = SM_NTH_TRI(sm,id_t1);
531    
532     e0 = T_WHICH_V(t0,E_NTH_VERT(e,0));
533     e1 = T_WHICH_V(t1,E_NTH_VERT(-e,0));
534     e0_next = (e0+2)%3;
535     e1_next = (e1+2)%3;
536     id_v0 = E_NTH_VERT(e,0);
537     id_v1 = E_NTH_VERT(e,1);
538     id_v2 = T_NTH_V(t0,e0_next);
539     id_p = T_NTH_V(t1,e1_next);
540    
541     smDir(sm,v0,id_v0);
542     smDir(sm,v1,id_v1);
543     smDir(sm,v2,id_v2);
544    
545     VCOPY(p,SM_NTH_WV(sm,id_p));
546     VSUB(p,p,SM_VIEW_CENTER(sm));
547     if(point_in_cone(p,v0,v1,v2))
548     {
549 gwlarson 3.2 smTris_swap_edge(sm,id_t0,id_t1,e0,e1,&nid_t0,&nid_t1,&add,&del);
550 gwlarson 3.1
551     nt0 = SM_NTH_TRI(sm,nid_t0);
552     nt1 = SM_NTH_TRI(sm,nid_t1);
553     FOR_ALL_EDGES_FROM(e,i)
554     {
555     if(E_NTH_TRI(i,0)==id_t0 || E_NTH_TRI(i,0)==id_t1)
556     {
557     if(eIn_tri(i,nt0))
558     SET_E_NTH_TRI(i,0,nid_t0);
559     else
560     SET_E_NTH_TRI(i,0,nid_t1);
561     }
562    
563     if(E_NTH_TRI(i,1)==id_t0 || E_NTH_TRI(i,1)==id_t1)
564     {
565     if(eIn_tri(i,nt0))
566     SET_E_NTH_TRI(i,1,nid_t0);
567     else
568     SET_E_NTH_TRI(i,1,nid_t1);
569     }
570     }
571     id_t0 = nid_t0;
572     id_t1 = nid_t1;
573     e_new = eNew_edge();
574     SET_E_NTH_VERT(e_new,0,id_p);
575     SET_E_NTH_VERT(e_new,1,id_v2);
576     SET_E_NTH_TRI(e_new,0,id_t0);
577     SET_E_NTH_TRI(e_new,1,id_t1);
578     }
579     }
580 gwlarson 3.2 smUpdate_locator(sm,add,del);
581 gwlarson 3.1 }
582    
583     int
584     smMesh_remove_vertex(sm,id)
585     SM *sm;
586     int id;
587     {
588     int tri;
589     LIST *elist;
590     int cnt,debug;
591     /* generate list of vertices that form the boundary of the
592     star polygon formed by vertex id and all of its adjacent
593     triangles
594     */
595     eClear_edges();
596     elist = smVertex_star_polygon(sm,id);
597     if(!elist)
598     return(FALSE);
599    
600     /* Triangulate spherical polygon */
601 gwlarson 3.3 smTriangulate(sm,elist);
602 gwlarson 3.1
603    
604     /* Fix up new triangles to be Delaunay */
605 gwlarson 3.3 smFix_edges(sm);
606 gwlarson 3.1
607     return(TRUE);
608     }
609    
610     /* Remove point from samples, and from mesh. Delete any triangles
611     adjacent to the point and re-triangulate the hole
612     Return TRUE is point found , FALSE otherwise
613     */
614     int
615     smDelete_point(sm,id)
616     SM *sm;
617     int id;
618     {
619    
620     /* Remove the corresponding vertex from the mesh */
621     smMesh_remove_vertex(sm,id);
622     /* Free the sample point */
623     smDelete_sample(sm,id);
624     return(TRUE);
625     }
626    
627    
628    
629    
630    
631    
632    
633    
634    
635    
636    
637    
638    
639