ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/hd/sm_del.c
Revision: 3.1
Committed: Wed Aug 19 17:45:24 1998 UTC (25 years, 8 months ago) by gwlarson
Content type: text/plain
Branch: MAIN
Log Message:
Initial revision

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    
20     smLocator_remove_tri(sm,t_id)
21     SM *sm;
22     int t_id;
23     {
24     STREE *st;
25     char found;
26     TRI *t;
27     FVECT p0,p1,p2;
28    
29     st = SM_LOCATOR(sm);
30    
31     t = SM_NTH_TRI(sm,t_id);
32    
33     smDir(sm,p0,T_NTH_V(t,0));
34     smDir(sm,p1,T_NTH_V(t,1));
35     smDir(sm,p2,T_NTH_V(t,2));
36    
37     found = stRemove_tri(st,t_id,p0,p1,p2);
38    
39     return(found);
40     }
41    
42     smFree_tri(sm,id)
43     SM *sm;
44     int id;
45     {
46     TRI *tri;
47    
48     tri = SM_NTH_TRI(sm,id);
49     /* Add to the free_list */
50     T_NEXT_FREE(tri) = SM_FREE_TRIS(sm);
51     SM_FREE_TRIS(sm) = id;
52     T_VALID_FLAG(tri) = -1;
53     }
54    
55     /* Assumes mesh pointers have been cleaned up appropriately: just deletes from
56     Point location and triangle data structure
57     */
58     smDelete_tri(sm,t_id)
59     SM *sm;
60     int t_id;
61     {
62    
63     /* first remove from point location structure */
64     smLocator_remove_tri(sm,t_id);
65    
66     /* NOTE: Assumes that a new triangle adjacent to each vertex
67     has been added- before the deletion: replacing
68     the old tri- and therefore dont need to dereference any pointers
69     to id because the vertices can no longer
70     point to tri id as being the first triangle pointer
71     */
72     if(!SM_IS_NTH_T_BASE(sm,t_id))
73     {
74     SM_NUM_TRIS(sm)--;
75     if(SM_IS_NTH_T_NEW(sm,t_id))
76     smNew_tri_cnt--;
77     }
78     smClear_tri_flags(sm,t_id);
79    
80     smFree_tri(sm,t_id);
81    
82     }
83    
84    
85    
86     LIST
87     *smVertex_star_polygon(sm,id)
88     SM *sm;
89     int id;
90     {
91     TRI *tri,*t_next;
92     LIST *elist,*end,*tlist;
93     int t_id,v_next,t_next_id;
94     int e;
95    
96     elist = end = NULL;
97     /* Get the first triangle adjacent to vertex id */
98     t_id = SM_NTH_VERT(sm,id);
99     tri = SM_NTH_TRI(sm,t_id);
100    
101    
102     if((e = eNew_edge()) == SM_INVALID)
103     {
104     #ifdef DEBUG
105     eputs("smVertex_star_polygon():Too many edges\n");
106     #endif
107     return(NULL);
108     }
109     elist = add_data_to_circular_list(elist,&end,e);
110     v_next = (T_WHICH_V(tri,id)+1)%3;
111     SET_E_NTH_VERT(e,0,T_NTH_V(tri,v_next));
112     SET_E_NTH_TRI(e,0,SM_INVALID);
113     SET_E_NTH_TRI(e,1,T_NTH_NBR(tri,v_next));
114     v_next = (T_WHICH_V(tri,id)+2)%3;
115     SET_E_NTH_VERT(e,1,T_NTH_V(tri,v_next));
116    
117    
118     t_next_id = t_id;
119     t_next = tri;
120    
121     tlist = push_data(NULL,t_id);
122    
123     while((t_next_id = smTri_next_ccw_nbr(sm,t_next,id)) != t_id)
124     {
125     if((e = eNew_edge()) == SM_INVALID)
126     {
127     #ifdef DEBUG
128     eputs("smVertex_star_polygon():Too many edges\n");
129     #endif
130     return(NULL);
131     }
132     elist = add_data_to_circular_list(elist,&end,e);
133     t_next = SM_NTH_TRI(sm,t_next_id);
134     v_next = (T_WHICH_V(t_next,id)+1)%3;
135     SET_E_NTH_VERT(e,0,T_NTH_V(t_next,v_next));
136     SET_E_NTH_TRI(e,0,SM_INVALID);
137     SET_E_NTH_TRI(e,1,T_NTH_NBR(t_next,v_next));
138     v_next = (T_WHICH_V(t_next,id)+2)%3;
139     SET_E_NTH_VERT(e,1,T_NTH_V(t_next,v_next));
140     tlist = push_data(tlist,t_next_id);
141     }
142     while(tlist)
143     {
144     t_id = (int)pop_list(&tlist);
145     smDelete_tri(sm,t_id);
146     }
147     return(elist);
148     }
149    
150     int
151     smEdge_intersect_polygon(sm,v0,v1,l)
152     SM *sm;
153     FVECT v0,v1;
154     LIST *l;
155     {
156     FVECT e0,e1;
157     int e,id_e0,id_e1;
158     LIST *el,*eptr;
159    
160     /* Test the edges in l against v0v1 to see if v0v1 intersects
161     any other edges
162     */
163    
164     el = l;
165    
166     while(el)
167     {
168     e = (int)LIST_DATA(el);
169     id_e0 = E_NTH_VERT(e,0);
170     id_e1 = E_NTH_VERT(e,1);
171    
172     smDir(sm,e0,id_e0);
173     smDir(sm,e1,id_e1);
174     if(spherical_polygon_edge_intersect(v0,v1,e0,e1))
175     return(TRUE);
176    
177     el = LIST_NEXT(el);
178     if(el == l)
179     break;
180     }
181     return(FALSE);
182     }
183    
184     int
185     smFind_next_convex_vertex(sm,id0,id1,v0,v1,l)
186     SM *sm;
187     int id0,id1;
188     FVECT v0,v1;
189     LIST *l;
190     {
191     int e,id;
192     LIST *el;
193     FVECT v;
194    
195     /* starting with the end of edge at head of l, search sequentially for
196     vertex v such that v0v1v is a convex angle, and the edge v1v does
197     not intersect any other edges
198     */
199     id = SM_INVALID;
200     el = l;
201     while(id != id0)
202     {
203     e = (int)LIST_DATA(el);
204     id = E_NTH_VERT(e,1);
205    
206     smDir(sm,v,id);
207    
208     if(convex_angle(v0,v1,v) && !smEdge_intersect_polygon(sm,v1,v,l))
209     return(id);
210    
211     el = LIST_NEXT(el);
212     if(el == l)
213     break;
214     }
215     return(SM_INVALID);
216     }
217    
218     int
219     split_edge_list(id0,id_new,l,lnew)
220     int id0,id_new;
221     LIST **l,**lnew;
222     {
223     LIST *list,*lptr,*end;
224     int e,e1,e2,new_e;
225    
226     e2 = SM_INVALID;
227     list = lptr = *l;
228    
229     if((new_e = eNew_edge())==SM_INVALID)
230     {
231     #ifdef DEBUG
232     eputs("split_edge_list():Too many edges\n");
233     #endif
234     return(FALSE);
235     }
236     SET_E_NTH_VERT(new_e,0,id0);
237     SET_E_NTH_VERT(new_e,1,id_new);
238     SET_E_NTH_TRI(new_e,0,SM_INVALID);
239     SET_E_NTH_TRI(new_e,1,SM_INVALID);
240    
241     while(e2 != id_new)
242     {
243     lptr = LIST_NEXT(lptr);
244     e = (int)LIST_DATA(lptr);
245     e2 = E_NTH_VERT(e,1);
246     if(lptr == list)
247     {
248     #ifdef DEBUG
249     eputs("split_edge_list():cant find vertex\n");
250     #endif
251     *lnew = NULL;
252     return(FALSE);
253     }
254    
255     }
256     end = lptr;
257     lptr = LIST_NEXT(lptr);
258     list = add_data_to_circular_list(list,&end,-new_e);
259     *lnew = list;
260    
261     /* now follow other cycle */
262    
263     list = lptr;
264     e2 = SM_INVALID;
265     while(e2 != id0)
266     {
267     lptr = LIST_NEXT(lptr);
268     e = (int)LIST_DATA(lptr);
269     e2 = E_NTH_VERT(e,1);
270     if(lptr == list)
271     {
272     #ifdef DEBUG
273     eputs("split_edge_list():cant find intial vertex\n");
274     #endif
275     *l = NULL;
276     return(FALSE);
277     }
278    
279     }
280     end = lptr;
281     list = add_data_to_circular_list(list,&end,new_e);
282     *l = list;
283     return(TRUE);
284     }
285    
286    
287    
288     LIST
289     *smTriangulate_convex(sm,plist)
290     SM *sm;
291     LIST *plist;
292     {
293     TRI *tri;
294     int t_id,e_id0,e_id1,e_id2;
295     int v_id0,v_id1,v_id2;
296     LIST *lptr;
297     int cnt;
298    
299     lptr = plist;
300     e_id0 = (int)LIST_DATA(lptr);
301     v_id0 = E_NTH_VERT(e_id0,0);
302     lptr = LIST_NEXT(lptr);
303     while(LIST_NEXT(lptr) != plist)
304     {
305     e_id1 = (int)LIST_DATA(lptr);
306     v_id1 = E_NTH_VERT(e_id1,0);
307     v_id2 = E_NTH_VERT(e_id1,1);
308     /* form a triangle for each triple of with v0 as base of star */
309     t_id = smAdd_tri(sm,v_id0,v_id1,v_id2,&tri);
310     /* add which pointer?*/
311    
312     lptr = LIST_NEXT(lptr);
313    
314     if(LIST_NEXT(lptr) != plist)
315     {
316     e_id2 = eNew_edge();
317     SET_E_NTH_VERT(e_id2,0,v_id2);
318     SET_E_NTH_VERT(e_id2,1,v_id0);
319     }
320     else
321     e_id2 = (int)LIST_DATA(lptr);
322    
323     /* set appropriate tri for each edge*/
324     SET_E_NTH_TRI(e_id0,0,t_id);
325     SET_E_NTH_TRI(e_id1,0,t_id);
326     SET_E_NTH_TRI(e_id2,0,t_id);
327    
328     e_id0 = -e_id2;
329     }
330     free_list(plist);
331     }
332    
333     smTriangulate_elist(sm,plist)
334     SM *sm;
335     LIST *plist;
336     {
337     LIST *l,*el1;
338     FVECT v0,v1,v2;
339     int id0,id1,id2,e,id_next;
340     char flipped;
341     int debug = TRUE;
342    
343     l = plist;
344    
345     while(l)
346     {
347     /* get v0,v1,v2 */
348     e = (int)LIST_DATA(l);
349     id0 = E_NTH_VERT(e,0);
350     id1 = E_NTH_VERT(e,1);
351     l = LIST_NEXT(l);
352     e = (int)LIST_DATA(l);
353     id2 = E_NTH_VERT(e,1);
354    
355     smDir(sm,v0,id0);
356     smDir(sm,v1,id1);
357     smDir(sm,v2,id2);
358     /* determine if convex (left turn), or concave(right turn) angle */
359     if(convex_angle(v0,v1,v2))
360     {
361     if(l == plist)
362     break;
363     else
364     continue;
365     }
366     /* if concave: add edge and recurse on two sub polygons */
367     id_next = smFind_next_convex_vertex(sm,id0,id1,v0,v1,LIST_NEXT(l));
368     if(id_next == SM_INVALID)
369     {
370     #ifdef DEBUG
371     eputs("smTriangulate_elist():Unable to find convex vertex\n");
372     #endif
373     return;
374     }
375     /* add edge */
376     el1 = NULL;
377     /* Split edge list l into two lists: one from id1-id_next-id1,
378     and the next from id2-id_next-id2
379     */
380     debug = split_edge_list(id1,id_next,&l,&el1);
381     /* Recurse and triangulate the two edge lists */
382     if(debug)
383     debug = smTriangulate_elist(sm,l);
384     if(debug)
385     debug = smTriangulate_elist(sm,el1);
386    
387     return(debug);
388     }
389     smTriangulate_convex(sm,plist);
390     return(TRUE);
391     }
392    
393     int
394     smTriangulate_polygon(sm,plist)
395     SM *sm;
396     LIST *plist;
397     {
398     int e,id_t0,id_t1,e0,e1;
399     TRI *t0,*t1;
400     int test;
401    
402     test = smTriangulate_elist(sm,plist,NULL);
403    
404     if(!test)
405     return(test);
406     FOR_ALL_EDGES(e)
407     {
408     id_t0 = E_NTH_TRI(e,0);
409     id_t1 = E_NTH_TRI(e,1);
410     if((id_t0==SM_INVALID) || (id_t1==SM_INVALID))
411     {
412     #ifdef DEBUG
413     eputs("smTriangulate_polygon(): Unassigned edge neighbor\n");
414     #endif
415     continue;
416     }
417     t0 = SM_NTH_TRI(sm,id_t0);
418     t1 = SM_NTH_TRI(sm,id_t1);
419    
420     e0 = T_WHICH_V(t0,E_NTH_VERT(e,0));
421     T_NTH_NBR(t0,e0) = id_t1;
422    
423     e1 = T_WHICH_V(t1,E_NTH_VERT(e,1));
424     T_NTH_NBR(t1,e1) = id_t0;
425     }
426     return(test);
427     }
428    
429     eIn_tri(e,t)
430     int e;
431     TRI *t;
432     {
433    
434     if(T_NTH_V(t,0)==E_NTH_VERT(e,0))
435     return(T_NTH_V(t,1)==E_NTH_VERT(e,1)||T_NTH_V(t,2)==E_NTH_VERT(e,1));
436     else
437     if(T_NTH_V(t,1)==E_NTH_VERT(e,0))
438     return(T_NTH_V(t,0)==E_NTH_VERT(e,1)||T_NTH_V(t,2)==E_NTH_VERT(e,1));
439     else if(T_NTH_V(t,2)==E_NTH_VERT(e,0))
440     return(T_NTH_V(t,0)==E_NTH_VERT(e,1)||T_NTH_V(t,1)==E_NTH_VERT(e,1));
441     return(FALSE);
442     }
443     smFix_edges(sm)
444     SM *sm;
445     {
446     int e,id_t0,id_t1,e_new,e0,e1,e0_next,e1_next;
447     TRI *t0,*t1,*nt0,*nt1;
448     int i,id_v0,id_v1,id_v2,id_p,nid_t0,nid_t1;
449     FVECT v0,v1,v2,p,np,v;
450    
451     FOR_ALL_EDGES(e)
452     {
453     id_t0 = E_NTH_TRI(e,0);
454     id_t1 = E_NTH_TRI(e,1);
455     if((id_t0==SM_INVALID) || (id_t1==SM_INVALID))
456     {
457     #ifdef DEBUG
458     eputs("smFix_edges: Unassigned edge nbr\n");
459     #endif
460     continue;
461     }
462     t0 = SM_NTH_TRI(sm,id_t0);
463     t1 = SM_NTH_TRI(sm,id_t1);
464    
465     e0 = T_WHICH_V(t0,E_NTH_VERT(e,0));
466     e1 = T_WHICH_V(t1,E_NTH_VERT(-e,0));
467     e0_next = (e0+2)%3;
468     e1_next = (e1+2)%3;
469     id_v0 = E_NTH_VERT(e,0);
470     id_v1 = E_NTH_VERT(e,1);
471     id_v2 = T_NTH_V(t0,e0_next);
472     id_p = T_NTH_V(t1,e1_next);
473    
474     smDir(sm,v0,id_v0);
475     smDir(sm,v1,id_v1);
476     smDir(sm,v2,id_v2);
477    
478     VCOPY(p,SM_NTH_WV(sm,id_p));
479     VSUB(p,p,SM_VIEW_CENTER(sm));
480     if(point_in_cone(p,v0,v1,v2))
481     {
482     smTris_swap_edge(sm,id_t0,id_t1,e0,e1,&nid_t0,&nid_t1);
483    
484     nt0 = SM_NTH_TRI(sm,nid_t0);
485     nt1 = SM_NTH_TRI(sm,nid_t1);
486     FOR_ALL_EDGES_FROM(e,i)
487     {
488     if(E_NTH_TRI(i,0)==id_t0 || E_NTH_TRI(i,0)==id_t1)
489     {
490     if(eIn_tri(i,nt0))
491     SET_E_NTH_TRI(i,0,nid_t0);
492     else
493     SET_E_NTH_TRI(i,0,nid_t1);
494     }
495    
496     if(E_NTH_TRI(i,1)==id_t0 || E_NTH_TRI(i,1)==id_t1)
497     {
498     if(eIn_tri(i,nt0))
499     SET_E_NTH_TRI(i,1,nid_t0);
500     else
501     SET_E_NTH_TRI(i,1,nid_t1);
502     }
503     }
504     id_t0 = nid_t0;
505     id_t1 = nid_t1;
506     e_new = eNew_edge();
507     SET_E_NTH_VERT(e_new,0,id_p);
508     SET_E_NTH_VERT(e_new,1,id_v2);
509     SET_E_NTH_TRI(e_new,0,id_t0);
510     SET_E_NTH_TRI(e_new,1,id_t1);
511     }
512     }
513    
514     }
515    
516     int
517     smMesh_remove_vertex(sm,id)
518     SM *sm;
519     int id;
520     {
521     int tri;
522     LIST *elist;
523     int cnt,debug;
524     /* generate list of vertices that form the boundary of the
525     star polygon formed by vertex id and all of its adjacent
526     triangles
527     */
528     eClear_edges();
529     elist = smVertex_star_polygon(sm,id);
530     if(!elist)
531     return(FALSE);
532    
533     /* Triangulate spherical polygon */
534     debug = smTriangulate_polygon(sm,elist);
535    
536    
537     /* Fix up new triangles to be Delaunay */
538     if(debug)
539     smFix_edges(sm);
540    
541     return(TRUE);
542     }
543    
544     /* Remove point from samples, and from mesh. Delete any triangles
545     adjacent to the point and re-triangulate the hole
546     Return TRUE is point found , FALSE otherwise
547     */
548     int
549     smDelete_point(sm,id)
550     SM *sm;
551     int id;
552     {
553    
554     /* Remove the corresponding vertex from the mesh */
555     smMesh_remove_vertex(sm,id);
556     /* Free the sample point */
557     smDelete_sample(sm,id);
558     return(TRUE);
559     }
560    
561    
562    
563    
564    
565    
566    
567    
568    
569    
570    
571    
572    
573