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

# Content
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