ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/hd/sm_del.c
Revision: 3.5
Committed: Wed Sep 16 18:16:28 1998 UTC (25 years, 7 months ago) by gwlarson
Content type: text/plain
Branch: MAIN
Changes since 3.4: +38 -74 lines
Log Message:
implemented integer triangle tracing

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