BRL-CAD
nmg_rt_segs.c
Go to the documentation of this file.
1 /* N M G _ R T _ S E G S . C
2  * BRL-CAD
3  *
4  * Copyright (c) 1993-2014 United States Government as represented by
5  * the U.S. Army Research Laboratory.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * version 2.1 as published by the Free Software Foundation.
10  *
11  * This library is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this file; see the file named COPYING for more
18  * information.
19  */
20 /** @addtogroup nmg */
21 /** @{ */
22 /** @file primitives/nmg/nmg_rt_segs.c
23  *
24  * Support routines for raytracing an NMG.
25  *
26  */
27 /** @} */
28 
29 #include "common.h"
30 
31 #include <stdlib.h>
32 #include <stddef.h>
33 #include <string.h>
34 #include <math.h>
35 #include "bio.h"
36 
37 #include "bu/parallel.h"
38 #include "vmath.h"
39 #include "nmg.h"
40 #include "raytrace.h"
41 #include "plot3.h"
42 
43 
44 /* EDGE-FACE correlation data
45  * used in edge_hit() for 3manifold case
46  */
47 struct ef_data {
48  fastf_t fdotr; /* face vector VDOT with ray */
49  fastf_t fdotl; /* face vector VDOT with ray-left */
50  fastf_t ndotr; /* face normal VDOT with ray */
51  struct edgeuse *eu;
52 };
53 
54 
55 #define CK_SEGP(_p) if (!(_p) || !(*(_p))) {\
56  bu_log("%s[line:%d]: Bad seg_p pointer\n", __FILE__, __LINE__); \
57  nmg_rt_segs_exit("Goodbye"); }
58 #define DO_LONGJMP
59 #ifdef DO_LONGJMP
60 static jmp_buf nmg_longjump_env;
61 #define nmg_rt_segs_exit(_s) {bu_log("%s\n", _s);longjmp(nmg_longjump_env, -1);}
62 #else
63 #define nmg_rt_segs_exit(_s) bu_bomb(_s)
64 #endif
65 
66 
67 HIDDEN void
68 print_seg_list(struct seg *seghead, int seg_count, char *s)
69 {
70  struct seg *seg_p;
71 
72  bu_log("Segment List (%d segments) (%s):\n", seg_count, s);
73  /* print debugging data before returning */
74  bu_log("Seghead:\n%p magic: %08x forw:%p back:%p\n\n",
75  (void *)seghead,
76  seghead->l.magic,
77  (void *)seghead->l.forw,
78  (void *)seghead->l.back);
79 
80  for (BU_LIST_FOR(seg_p, seg, &seghead->l)) {
81  bu_log("%p magic: %08x forw:%p back:%p\n",
82  (void *)seg_p,
83  seg_p->l.magic,
84  (void *)seg_p->l.forw,
85  (void *)seg_p->l.back);
86  bu_log("dist %g pt(%g, %g, %g) N(%g, %g, %g) =>\n",
87  seg_p->seg_in.hit_dist,
88  seg_p->seg_in.hit_point[0],
89  seg_p->seg_in.hit_point[1],
90  seg_p->seg_in.hit_point[2],
91  seg_p->seg_in.hit_normal[0],
92  seg_p->seg_in.hit_normal[1],
93  seg_p->seg_in.hit_normal[2]);
94  bu_log("dist %g pt(%g, %g, %g) N(%g, %g, %g)\n",
95  seg_p->seg_out.hit_dist,
96  seg_p->seg_out.hit_point[0],
97  seg_p->seg_out.hit_point[1],
98  seg_p->seg_out.hit_point[2],
99  seg_p->seg_out.hit_normal[0],
100  seg_p->seg_out.hit_normal[1],
101  seg_p->seg_out.hit_normal[2]);
102  }
103 }
104 
105 
106 HIDDEN void
107 pl_ray(struct ray_data *rd)
108 {
109  FILE *fp;
110  char name[80];
111  static int plot_file_number=0;
112  struct hitmiss *a_hit;
113  int old_state = NMG_RAY_STATE_OUTSIDE;
114  int in_state;
115  int out_state;
116  point_t old_point;
117  point_t end_point;
118  int old_cond = 0;
119 
120  sprintf(name, "nmg_ray%02d.plot3", plot_file_number++);
121  fp=fopen(name, "wb");
122  if (fp == (FILE *)NULL) {
123  perror(name);
124  bu_bomb("unable to open file for writing");
125  } else {
126  bu_log("overlay %s\n", name);
127  }
128 
129  VMOVE(old_point, rd->rp->r_pt);
130 
131  for (BU_LIST_FOR(a_hit, hitmiss, &rd->rd_hit)) {
132  NMG_CK_HITMISS(a_hit);
133 
134  in_state = HMG_INBOUND_STATE(a_hit);
135  out_state = HMG_OUTBOUND_STATE(a_hit);
136 
137  if (in_state == old_state) {
138  switch (in_state) {
140  pl_color(fp, 55, 255, 55);
141  pdv_3line(fp, old_point, a_hit->hit.hit_point);
142  break;
143  case NMG_RAY_STATE_ON:
144  pl_color(fp, 155, 155, 255);
145  pdv_3line(fp, old_point, a_hit->hit.hit_point);
146  break;
148  pl_color(fp, 255, 255, 255);
149  pdv_3line(fp, old_point, a_hit->hit.hit_point);
150  break;
151  }
152  old_cond = 0;
153  } else {
154  if (old_cond) {
155  pl_color(fp, 255, 155, 255);
156  old_cond = 0;
157  } else {
158  pl_color(fp, 255, 55, 255);
159  old_cond = 1;
160  }
161  pdv_3line(fp, old_point, a_hit->hit.hit_point);
162  }
163  VMOVE(old_point, a_hit->hit.hit_point);
164  old_state = out_state;
165  }
166 
167  if (old_state == NMG_RAY_STATE_OUTSIDE)
168  pl_color(fp, 255, 255, 255);
169  else
170  pl_color(fp, 255, 55, 255);
171 
172  VADD2(end_point, old_point, rd->rp->r_dir);
173  pdv_3line(fp, old_point, end_point);
174 
175  fclose(fp);
176 }
177 
178 
179 /*
180  * Current_State
181  * Input | 0 1 2 3 4 5 6
182  * -------------------------------------------
183  * O_N = | i1 1 Ci1 5 1 5 5
184  * O_N != | i1 1|E Ci1 C1 Ci1 Ci1 Ci1
185  * N_N = | E 1 E 3 E 1 1
186  * N_N != | E 1 E E E 1 1
187  * N_O = | E o2 o2 ?o2 E o2 o2
188  * N_O != | E o2 o2 E E o2 o2
189  * O_O = |io3 o2 o2 3 3 6 6
190  * O_O != |io3 o2|E Cio3 Cio3 Cio3 Cio3 Cio3
191  * A_A = |io4 1 2 3 4 5 6
192  * A_A != |io4 1 Cio4 Cio4 Cio4 Cio4 Cio4
193  * EOI | N E CN CN CN CN CN
194  *
195  * = -> ray dist to point within tol (along ray) of last hit point
196  * != -> ray dist to point outside tol (along ray) of last hit point
197  *
198  * State Prefix
199  * C segment now completed, add to list & alloc new segment
200  * i set inpoint for current segment
201  * o set outpoint for current segment
202  *
203  * State
204  * E Error termination
205  * N Normal termination
206  * 1 "Entering" solid
207  * 2 "Leaving" solid
208  * 3 O_O from outside state
209  * 4 A_A from outside state
210  * 5 O_O=O_N Fuzzy state 1 or state 2 from state 3
211  * 6 0_0=O_N=O_O
212  */
213 
214 
215 HIDDEN void
216 set_inpoint(struct seg **seg_p, struct hitmiss *a_hit, struct soltab *stp, struct application *ap)
217 /* The segment we're building */
218 /* The input hit point */
219 
220 
221 {
222  if (!seg_p) {
223  bu_log("%s[line:%d]: Null pointer to segment pointer\n",
224  __FILE__, __LINE__);
225  nmg_rt_segs_exit("Goodbye");
226  }
227 
228  /* if we don't have a seg struct yet, get one */
229  if (*seg_p == (struct seg *)NULL) {
230  RT_GET_SEG(*seg_p, ap->a_resource);
231  (*seg_p)->seg_stp = stp;
232  }
233 
234  /* copy the "in" hit */
235  memcpy(&(*seg_p)->seg_in, &a_hit->hit, sizeof(struct hit));
236 
237  /* copy the normal */
238  VMOVE((*seg_p)->seg_in.hit_normal, a_hit->inbound_norm);
239 
240  if (RTG.NMG_debug & DEBUG_RT_SEGS) {
241  bu_log("Set seg_in:\n\tdist %g pt(%g, %g, %g) N(%g, %g, %g)\n",
242  (*seg_p)->seg_in.hit_dist,
243  (*seg_p)->seg_in.hit_point[0],
244  (*seg_p)->seg_in.hit_point[1],
245  (*seg_p)->seg_in.hit_point[2],
246  (*seg_p)->seg_in.hit_normal[0],
247  (*seg_p)->seg_in.hit_normal[1],
248  (*seg_p)->seg_in.hit_normal[2]);
249  }
250 }
251 
252 
253 HIDDEN void
254 set_outpoint(struct seg **seg_p, struct hitmiss *a_hit)
255 /* The segment we're building */
256 /* The input hit point */
257 {
258  if (!seg_p) {
259  bu_log("%s[line:%d]: Null pointer to segment pointer\n",
260  __FILE__, __LINE__);
261  nmg_rt_segs_exit("Goodbye");
262  }
263 
264  /* if we don't have a seg struct yet, get one */
265  if (*seg_p == (struct seg *)NULL)
266  nmg_rt_segs_exit("bad seg pointer\n");
267 
268  /* copy the "out" hit */
269  memcpy(&(*seg_p)->seg_out, &a_hit->hit, sizeof(struct hit));
270 
271  /* copy the normal */
272  VMOVE((*seg_p)->seg_out.hit_normal, a_hit->outbound_norm);
273 
274  if (RTG.NMG_debug & DEBUG_RT_SEGS) {
275  bu_log("Set seg_out:\n\tdist %g pt(%g, %g, %g) N(%g, %g, %g) =>\n",
276  (*seg_p)->seg_in.hit_dist,
277  (*seg_p)->seg_in.hit_point[0],
278  (*seg_p)->seg_in.hit_point[1],
279  (*seg_p)->seg_in.hit_point[2],
280  (*seg_p)->seg_in.hit_normal[0],
281  (*seg_p)->seg_in.hit_normal[1],
282  (*seg_p)->seg_in.hit_normal[2]);
283  bu_log("\tdist %g pt(%g, %g, %g) N(%g, %g, %g)\n",
284  (*seg_p)->seg_out.hit_dist,
285  (*seg_p)->seg_out.hit_point[0],
286  (*seg_p)->seg_out.hit_point[1],
287  (*seg_p)->seg_out.hit_point[2],
288  (*seg_p)->seg_out.hit_normal[0],
289  (*seg_p)->seg_out.hit_normal[1],
290  (*seg_p)->seg_out.hit_normal[2]);
291  }
292 }
293 
294 
295 HIDDEN int
296 state0(struct seg *UNUSED(seghead), struct seg **seg_p, int *UNUSED(seg_count), struct hitmiss *a_hit, struct soltab *stp, struct application *ap, struct bn_tol *UNUSED(tol))
297 /* intersection w/ ray */
298 /* The segment we're building */
299 /* The number of valid segments built */
300 /* The input hit point */
301 
302 
303 {
304  int ret_val = -1;
305 
306  NMG_CK_HITMISS(a_hit);
307 
308  switch (a_hit->in_out) {
309  case HMG_HIT_OUT_IN:
310  case HMG_HIT_OUT_ON:
311  /* save the in-hit point */
312  set_inpoint(seg_p, a_hit, stp, ap);
313  ret_val = 1;
314  break;
315  case HMG_HIT_ON_ON:
316  case HMG_HIT_IN_IN:
317  case HMG_HIT_ON_IN:
318  case HMG_HIT_IN_ON:
319  case HMG_HIT_IN_OUT:
320  case HMG_HIT_ON_OUT:
321  /* error */
322  bu_log("%s[line:%d]: State transition error: exit without entry.\n",
323  __FILE__, __LINE__);
324  ret_val = -2;
325  break;
326  case HMG_HIT_OUT_OUT:
327  /* Save the in/out points */
328  set_inpoint(seg_p, a_hit, stp, ap);
329  set_outpoint(seg_p, a_hit);
330  ret_val = 3;
331  break;
332  case HMG_HIT_ANY_ANY:
333  /* Save the in/out points */
334  set_inpoint(seg_p, a_hit, stp, ap);
335  set_outpoint(seg_p, a_hit);
336  ret_val = 4;
337  break;
338  default:
339  bu_log("%s[line:%d]: bogus hit in/out status\n",
340  __FILE__, __LINE__);
341  nmg_rt_segs_exit("Goodbye\n");
342  break;
343  }
344 
345  return ret_val;
346 }
347 
348 
349 HIDDEN int
350 state1(struct seg *UNUSED(seghead), struct seg **seg_p, int *UNUSED(seg_count), struct hitmiss *a_hit, struct soltab *stp, struct application *ap, struct bn_tol *UNUSED(tol))
351 /* intersection w/ ray */
352 /* The segment we're building */
353 /* The number of valid segments built */
354 /* The input hit point */
355 
356 
357 {
358  int ret_val = -1;
359 
360  if (stp) RT_CK_SOLTAB(stp);
361  if (ap) RT_CK_APPLICATION(ap);
362  NMG_CK_HITMISS(a_hit);
363 
364  switch (a_hit->in_out) {
365  case HMG_HIT_OUT_ON:
366  case HMG_HIT_OUT_IN:
367  case HMG_HIT_IN_IN:
368  case HMG_HIT_ON_IN:
369  case HMG_HIT_IN_ON:
370  case HMG_HIT_ON_ON:
371  ret_val = 1;
372  break;
373  case HMG_HIT_ON_OUT:
374  case HMG_HIT_IN_OUT:
375  set_outpoint(seg_p, a_hit);
376  ret_val = 2;
377  break;
378  case HMG_HIT_OUT_OUT:
379  /* XXX possibly an error condition if not within tol */
380  set_outpoint(seg_p, a_hit);
381  ret_val = 2;
382  break;
383  case HMG_HIT_ANY_ANY:
384  ret_val = 1;
385  break;
386  default:
387  bu_log("%s[line:%d]: bogus hit in/out status\n",
388  __FILE__, __LINE__);
389  nmg_rt_segs_exit("Goodbye\n");
390  break;
391  }
392 
393  return ret_val;
394 }
395 
396 
397 HIDDEN int
398 state2(struct seg *seghead, struct seg **seg_p, int *seg_count, struct hitmiss *a_hit, struct soltab *stp, struct application *ap, struct bn_tol *tol)
399 /* intersection w/ ray */
400 /* The segment we're building */
401 /* The number of valid segments built */
402 /* The input hit point */
403 
404 
405 {
406  int ret_val = -1;
407  double delta;
408 
409  NMG_CK_HITMISS(a_hit);
410 
411  switch (a_hit->in_out) {
412  case HMG_HIT_OUT_ON:
413  case HMG_HIT_OUT_IN:
414  /* Segment completed. Insert into segment list */
415  BU_LIST_MAGIC_SET(&((*seg_p)->l), RT_SEG_MAGIC);
416  BU_LIST_INSERT(&(seghead->l), &((*seg_p)->l));
417  (*seg_count)++;
418 
419  /* start new segment */
420  (*seg_p) = (struct seg *)NULL;
421  set_inpoint(seg_p, a_hit, stp, ap);
422 
423  ret_val = 1;
424  break;
425  case HMG_HIT_IN_IN:
426  case HMG_HIT_ON_ON:
427  case HMG_HIT_ON_IN:
428  case HMG_HIT_IN_ON:
429  /* Error */
430  bu_log("%s[line:%d]: State transition error.\n",
431  __FILE__, __LINE__);
432  ret_val = -2;
433  break;
434  case HMG_HIT_ON_OUT:
435  case HMG_HIT_IN_OUT:
436  /* progress the out-point */
437  set_outpoint(seg_p, a_hit);
438  ret_val = 2;
439  break;
440  case HMG_HIT_OUT_OUT:
441  CK_SEGP(seg_p);
442  BN_CK_TOL(tol);
443  delta = fabs((*seg_p)->seg_in.hit_dist - a_hit->hit.hit_dist);
444  if (delta < tol->dist) {
445  set_outpoint(seg_p, a_hit);
446  ret_val = 2;
447  break;
448  }
449  /* complete the segment */
450  BU_LIST_MAGIC_SET(&((*seg_p)->l), RT_SEG_MAGIC);
451  BU_LIST_INSERT(&(seghead->l), &((*seg_p)->l));
452  (*seg_count)++;
453 
454  /* start new segment */
455  (*seg_p) = (struct seg *)NULL;
456  set_inpoint(seg_p, a_hit, stp, ap);
457  set_outpoint(seg_p, a_hit);
458 
459  ret_val = 3;
460  break;
461  case HMG_HIT_ANY_ANY:
462  CK_SEGP(seg_p);
463  BN_CK_TOL(tol);
464  delta = fabs((*seg_p)->seg_in.hit_dist - a_hit->hit.hit_dist);
465  if (delta < tol->dist) {
466  set_outpoint(seg_p, a_hit);
467  ret_val = 2;
468  break;
469  }
470  /* complete the segment */
471  BU_LIST_MAGIC_SET(&((*seg_p)->l), RT_SEG_MAGIC);
472  BU_LIST_INSERT(&(seghead->l), &((*seg_p)->l));
473  (*seg_count)++;
474 
475  /* start new segment */
476  (*seg_p) = (struct seg *)NULL;
477  set_inpoint(seg_p, a_hit, stp, ap);
478  set_outpoint(seg_p, a_hit);
479 
480  ret_val = 4;
481  break;
482  default:
483  bu_log("%s[line:%d]: bogus hit in/out status\n",
484  __FILE__, __LINE__);
485  nmg_rt_segs_exit("Goodbye\n");
486  break;
487  }
488 
489  return ret_val;
490 }
491 
492 
493 HIDDEN int
494 state3(struct seg *seghead, struct seg **seg_p, int *seg_count, struct hitmiss *a_hit, struct soltab *stp, struct application *ap, struct bn_tol *tol)
495 /* intersection w/ ray */
496 /* The segment we're building */
497 /* The number of valid segments built */
498 /* The input hit point */
499 
500 
501 {
502  int ret_val = -1;
503  double delta;
504 
505  NMG_CK_HITMISS(a_hit);
506  CK_SEGP(seg_p);
507  BN_CK_TOL(tol);
508  delta = fabs((*seg_p)->seg_in.hit_dist - a_hit->hit.hit_dist);
509 
510  switch (a_hit->in_out) {
511  case HMG_HIT_OUT_ON:
512  case HMG_HIT_OUT_IN:
513  if (delta < tol->dist) {
514  ret_val = 5;
515  } else {
516  /* complete the segment */
517  BU_LIST_MAGIC_SET(&((*seg_p)->l), RT_SEG_MAGIC);
518  BU_LIST_INSERT(&(seghead->l), &((*seg_p)->l));
519  (*seg_count)++;
520 
521  /* start new segment */
522  (*seg_p) = (struct seg *)NULL;
523  set_inpoint(seg_p, a_hit, stp, ap);
524 
525  ret_val = 1;
526  }
527  break;
528  case HMG_HIT_IN_IN:
529  case HMG_HIT_ON_IN:
530  case HMG_HIT_IN_ON:
531  case HMG_HIT_ON_ON:
532  if (delta < tol->dist) {
533  ret_val = 3;
534  } else {
535  /* Error */
536  bu_log("%s[line:%d]: State transition error.\n",
537  __FILE__, __LINE__);
538  ret_val = -2;
539  }
540  break;
541  case HMG_HIT_ON_OUT:
542  case HMG_HIT_IN_OUT:
543  /*
544  * This can happen when the ray hits an edge/vertex and
545  * (due to floating point fuzz) also appears to have a
546  * hit point in the area of a face:
547  *
548  * ------->o
549  * / \------------>
550  * / \
551  *
552  */
553  set_outpoint(seg_p, a_hit);
554  ret_val = 2;
555  break;
556  case HMG_HIT_OUT_OUT:
557  if (delta > tol->dist) {
558  /* complete the segment */
559  BU_LIST_MAGIC_SET(&((*seg_p)->l), RT_SEG_MAGIC);
560  BU_LIST_INSERT(&(seghead->l), &((*seg_p)->l));
561  (*seg_count)++;
562 
563  /* start new segment */
564  (*seg_p) = (struct seg *)NULL;
565  set_inpoint(seg_p, a_hit, stp, ap);
566  set_outpoint(seg_p, a_hit);
567  }
568  ret_val = 3;
569  break;
570  case HMG_HIT_ANY_ANY:
571  if (delta < tol->dist) {
572  ret_val = 3;
573  } else {
574  /* complete the segment */
575  BU_LIST_MAGIC_SET(&((*seg_p)->l), RT_SEG_MAGIC);
576  BU_LIST_INSERT(&(seghead->l), &((*seg_p)->l));
577  (*seg_count)++;
578 
579  /* start new segment */
580  (*seg_p) = (struct seg *)NULL;
581  set_inpoint(seg_p, a_hit, stp, ap);
582  ret_val = 4;
583  }
584  break;
585  default:
586  bu_log("%s[line:%d]: bogus hit in/out status\n",
587  __FILE__, __LINE__);
588  nmg_rt_segs_exit("Goodbye\n");
589  break;
590  }
591 
592  return ret_val;
593 }
594 
595 
596 HIDDEN int
597 state4(struct seg *seghead, struct seg **seg_p, int *seg_count, struct hitmiss *a_hit, struct soltab *stp, struct application *ap, struct bn_tol *tol)
598 /* intersection w/ ray */
599 /* The segment we're building */
600 /* The number of valid segments built */
601 /* The input hit point */
602 
603 
604 {
605  int ret_val = -1;
606  double delta;
607 
608  NMG_CK_HITMISS(a_hit);
609 
610  switch (a_hit->in_out) {
611  case HMG_HIT_OUT_ON:
612  case HMG_HIT_OUT_IN:
613  CK_SEGP(seg_p);
614  BN_CK_TOL(tol);
615  delta = fabs((*seg_p)->seg_in.hit_dist - a_hit->hit.hit_dist);
616  if (delta > tol->dist) {
617  /* complete the segment */
618  BU_LIST_MAGIC_SET(&((*seg_p)->l), RT_SEG_MAGIC);
619  BU_LIST_INSERT(&(seghead->l), &((*seg_p)->l));
620  (*seg_count)++;
621 
622  /* start new segment */
623  (*seg_p) = (struct seg *)NULL;
624  set_inpoint(seg_p, a_hit, stp, ap);
625  }
626  ret_val = 1;
627  break;
628  case HMG_HIT_IN_IN:
629  case HMG_HIT_ON_IN:
630  case HMG_HIT_IN_ON:
631  case HMG_HIT_ON_ON:
632  case HMG_HIT_ON_OUT:
633  case HMG_HIT_IN_OUT:
634  /* Error */
635  bu_log("%s[line:%d]: State transition error.\n",
636  __FILE__, __LINE__);
637  ret_val = -2;
638  break;
639  case HMG_HIT_OUT_OUT:
640  CK_SEGP(seg_p);
641  BN_CK_TOL(tol);
642  delta = fabs((*seg_p)->seg_in.hit_dist - a_hit->hit.hit_dist);
643  if (delta > tol->dist) {
644  /* complete the segment */
645  BU_LIST_MAGIC_SET(&((*seg_p)->l), RT_SEG_MAGIC);
646  BU_LIST_INSERT(&(seghead->l), &((*seg_p)->l));
647  (*seg_count)++;
648 
649  /* start new segment */
650  (*seg_p) = (struct seg *)NULL;
651  set_inpoint(seg_p, a_hit, stp, ap);
652  set_outpoint(seg_p, a_hit);
653  }
654  ret_val = 3;
655  break;
656  case HMG_HIT_ANY_ANY:
657  CK_SEGP(seg_p);
658  BN_CK_TOL(tol);
659  delta = fabs((*seg_p)->seg_in.hit_dist - a_hit->hit.hit_dist);
660  if (delta > tol->dist) {
661  /* complete the segment */
662  BU_LIST_MAGIC_SET(&((*seg_p)->l), RT_SEG_MAGIC);
663  BU_LIST_INSERT(&(seghead->l), &((*seg_p)->l));
664  (*seg_count)++;
665 
666  /* start new segment */
667  (*seg_p) = (struct seg *)NULL;
668  set_inpoint(seg_p, a_hit, stp, ap);
669  set_outpoint(seg_p, a_hit);
670  }
671  ret_val = 4;
672  break;
673  default:
674  bu_log("%s[line:%d]: bogus hit in/out status\n",
675  __FILE__, __LINE__);
676  nmg_rt_segs_exit("Goodbye\n");
677  break;
678  }
679 
680  return ret_val;
681 }
682 
683 HIDDEN int
684 state5and6(struct seg *seghead, struct seg **seg_p, int *seg_count, struct hitmiss *a_hit, struct soltab *stp, struct application *ap, struct bn_tol *tol, int ret_val_7)
685 {
686  int ret_val = -1;
687  double delta;
688 
689  NMG_CK_HITMISS(a_hit);
690 
691  switch (a_hit->in_out) {
692  case HMG_HIT_OUT_ON:
693  case HMG_HIT_OUT_IN:
694  CK_SEGP(seg_p);
695  BN_CK_TOL(tol);
696  delta = fabs((*seg_p)->seg_in.hit_dist - a_hit->hit.hit_dist);
697  if (delta < tol->dist) {
698  ret_val = 5;
699  } else {
700  /* complete the segment */
701  BU_LIST_MAGIC_SET(&((*seg_p)->l), RT_SEG_MAGIC);
702  BU_LIST_INSERT(&(seghead->l), &((*seg_p)->l));
703  (*seg_count)++;
704 
705  /* start new segment */
706  (*seg_p) = (struct seg *)NULL;
707  set_inpoint(seg_p, a_hit, stp, ap);
708  ret_val = 1;
709  }
710  break;
711  case HMG_HIT_IN_IN:
712  case HMG_HIT_ON_IN:
713  case HMG_HIT_IN_ON:
714  case HMG_HIT_ON_ON:
715  ret_val = 1;
716  break;
717  case HMG_HIT_ON_OUT:
718  case HMG_HIT_IN_OUT:
719  set_outpoint(seg_p, a_hit);
720  ret_val = 2;
721  break;
722  case HMG_HIT_OUT_OUT:
723  CK_SEGP(seg_p);
724  BN_CK_TOL(tol);
725  delta = fabs((*seg_p)->seg_in.hit_dist - a_hit->hit.hit_dist);
726  if (delta < tol->dist) {
727  ret_val = 6;
728  } else {
729  /* complete the segment */
730  BU_LIST_MAGIC_SET(&((*seg_p)->l), RT_SEG_MAGIC);
731  BU_LIST_INSERT(&(seghead->l), &((*seg_p)->l));
732  (*seg_count)++;
733 
734  /* start new segment */
735  (*seg_p) = (struct seg *)NULL;
736  set_inpoint(seg_p, a_hit, stp, ap);
737  set_outpoint(seg_p, a_hit);
738  ret_val = 3;
739  }
740  break;
741  case HMG_HIT_ANY_ANY:
742  CK_SEGP(seg_p);
743  BN_CK_TOL(tol);
744  delta = fabs((*seg_p)->seg_in.hit_dist - a_hit->hit.hit_dist);
745  if (delta < tol->dist) {
746  ret_val = ret_val_7;
747  } else {
748  /* complete the segment */
749  BU_LIST_MAGIC_SET(&((*seg_p)->l), RT_SEG_MAGIC);
750  BU_LIST_INSERT(&(seghead->l), &((*seg_p)->l));
751  (*seg_count)++;
752 
753  /* start new segment */
754  (*seg_p) = (struct seg *)NULL;
755  set_inpoint(seg_p, a_hit, stp, ap);
756  set_outpoint(seg_p, a_hit);
757  ret_val = 4;
758  }
759  break;
760  default:
761  bu_log("%s[line:%d]: bogus hit in/out status\n",
762  __FILE__, __LINE__);
763  nmg_rt_segs_exit("Goodbye\n");
764  break;
765  }
766 
767  return ret_val;
768 }
769 
770 HIDDEN int
771 state5(struct seg *seghead, struct seg **seg_p, int *seg_count, struct hitmiss *a_hit, struct soltab *stp, struct application *ap, struct bn_tol *tol)
772 /* intersection w/ ray */
773 /* The segment we're building */
774 /* The number of valid segments built */
775 /* The input hit point */
776 
777 {
778  return state5and6(seghead, seg_p, seg_count, a_hit, stp, ap, tol, 5);
779 }
780 
781 
782 HIDDEN int
783 state6(struct seg *seghead, struct seg **seg_p, int *seg_count, struct hitmiss *a_hit, struct soltab *stp, struct application *ap, struct bn_tol *tol)
784 /* intersection w/ ray */
785 /* The segment we're building */
786 /* The number of valid segments built */
787 /* The input hit point */
788 
789 {
790  return state5and6(seghead, seg_p, seg_count, a_hit, stp, ap, tol, 6);
791 }
792 
793 
794 static int (*state_table[7])(void) = {
795  (int (*)(void))state0,
796  (int (*)(void))state1,
797  (int (*)(void))state2,
798  (int (*)(void))state3,
799  (int (*)(void))state4,
800  (int (*)(void))state5,
801  (int (*)(void))state6
802 };
803 
804 
805 HIDDEN int
806 nmg_bsegs(struct ray_data *rd, struct application *ap, struct seg *seghead, struct soltab *stp)
807 
808 
809 /* intersection w/ ray */
810 
811 {
812  int ray_state = 0;
813  int new_state;
814  struct hitmiss *a_hit = (struct hitmiss *)NULL;
815  struct hitmiss *hm = (struct hitmiss *)NULL;
816  struct seg *seg_p = (struct seg *)NULL;
817  int seg_count = 0;
818 
819  for (BU_LIST_FOR(a_hit, hitmiss, &rd->rd_hit)) {
820  int (*state_table_func)(struct seg *, struct seg **, int *, struct hitmiss *, struct soltab *, struct application *, struct bn_tol *);
821 
822  NMG_CK_HITMISS(a_hit);
823 
824  /* cast function pointers for use */
825  state_table_func = (int (*)(struct seg *, struct seg **, int *, struct hitmiss *, struct soltab *, struct application *, struct bn_tol *))state_table[ray_state];
826  new_state = state_table_func(seghead, &seg_p, &seg_count, a_hit, stp, ap, (struct bn_tol *)rd->tol);
827  if (new_state < 0) {
828  /* state transition error. Print out the hit list
829  * and indicate where we were in processing it.
830  */
831  for (BU_LIST_FOR(hm, hitmiss, &rd->rd_hit)) {
832  if (hm == a_hit) {
833  bu_log("======= State %d ======\n",
834  ray_state);
836  bu_log("================\n");
837  } else
839  }
840 
841  /* Now bomb off */
842  bu_log("Primitive: %s, pixel=%d %d, lvl=%d %s\n",
843  rd->stp->st_dp->d_namep,
844  rd->ap->a_x, rd->ap->a_y, rd->ap->a_level,
845  rd->ap->a_purpose);
846  bu_log("Ray: pt:(%g %g %g) dir:(%g %g %g)\n",
847  V3ARGS(rd->rp->r_pt), V3ARGS(rd->rp->r_dir));
848  nmg_rt_segs_exit("Goodbye\n");
849  }
850 
851  ray_state = new_state;
852  }
853 
854  /* Check to make sure the input ran out in the right place
855  * in the state table.
856  */
857  if (ray_state == 1) {
858  bu_log("%s[line:%d]: Input ended at non-terminal FSM state\n",
859  __FILE__, __LINE__);
860 
861  bu_log("Ray: pt:(%g %g %g) dir:(%g %g %g)\n",
862  V3ARGS(rd->rp->r_pt), V3ARGS(rd->rp->r_dir));
863 
864  bu_log("Primitive: %s, pixel=%d %d, lvl=%d %s\n",
865  stp->st_dp->d_namep,
866  ap->a_x, ap->a_y, ap->a_level,
867  ap->a_purpose);
868  nmg_rt_segs_exit("Goodbye");
869  }
870 
871  /* Insert the last segment if appropriate */
872  if (ray_state > 1) {
873  /* complete the segment */
874  BU_LIST_MAGIC_SET(&(seg_p->l), RT_SEG_MAGIC);
875  BU_LIST_INSERT(&(seghead->l), &(seg_p->l));
876  seg_count++;
877  }
878 
879  return seg_count;
880 }
881 
882 
883 /**
884  * If a_tbl and next_tbl have an element in common, return it.
885  * Otherwise return a NULL pointer.
886  */
887 HIDDEN long *
888 common_topo(struct bu_ptbl *a_tbl, struct bu_ptbl *next_tbl)
889 {
890  long **p;
891 
892  for (p = &a_tbl->buffer[a_tbl->end]; p >= a_tbl->buffer; p--) {
893  if (bu_ptbl_locate(next_tbl, *p) >= 0)
894  return *p;
895  }
896 
897  return (long *)NULL;
898 }
899 
900 
901 HIDDEN void
902 visitor(uint32_t *l_p, void *tbl, int UNUSED(unused))
903 {
904  (void)bu_ptbl_ins_unique((struct bu_ptbl *)tbl, (long *)l_p);
905 }
906 
907 
908 /**
909  * Add an element provided by nmg_visit to a bu_ptbl struct.
910  */
911 HIDDEN void
912 build_topo_list(uint32_t *l_p, struct bu_ptbl *tbl)
913 {
914  struct loopuse *lu;
915  struct edgeuse *eu;
916  struct edgeuse *eu_p;
917  struct vertexuse *vu;
918  struct vertexuse *vu_p;
919  int radial_not_mate=0;
920  static const struct nmg_visit_handlers htab = {NULL, NULL, NULL, NULL, NULL,
921  NULL, NULL, NULL, NULL, NULL,
922  visitor, NULL, NULL, NULL, NULL,
923  NULL, NULL, NULL, visitor, NULL,
924  NULL, NULL, NULL, visitor, NULL};
925  /* htab.vis_face = htab.vis_edge = htab.vis_vertex = visitor; */
926 
927  if (!l_p) {
928  bu_log("%s:%d NULL l_p\n", __FILE__, __LINE__);
929  nmg_rt_segs_exit("");
930  }
931 
932  switch (*l_p) {
933  case NMG_FACEUSE_MAGIC:
934  nmg_visit(l_p, &htab, (void *)tbl);
935  break;
936  case NMG_EDGEUSE_MAGIC:
937  eu = eu_p = (struct edgeuse *)l_p;
938  do {
939  /* if the parent of this edgeuse is a face loopuse
940  * add the face to the list of shared topology
941  */
942  if (*eu->up.magic_p == NMG_LOOPUSE_MAGIC &&
943  *eu->up.lu_p->up.magic_p == NMG_FACEUSE_MAGIC)
944  bu_ptbl_ins_unique(tbl,
945  (long *)eu->up.lu_p->up.fu_p->f_p);
946 
947  if (radial_not_mate) eu = eu->radial_p;
948  else eu = eu->eumate_p;
949  radial_not_mate = ! radial_not_mate;
950  } while (eu != eu_p);
951 
952  bu_ptbl_ins_unique(tbl, (long *)eu->e_p);
953  bu_ptbl_ins_unique(tbl, (long *)eu->vu_p->v_p);
954  bu_ptbl_ins_unique(tbl, (long *)eu->eumate_p->vu_p->v_p);
955 
956  break;
957  case NMG_VERTEXUSE_MAGIC:
958  vu_p = (struct vertexuse *)l_p;
959  bu_ptbl_ins_unique(tbl, (long *)vu_p->v_p);
960 
961  for (BU_LIST_FOR(vu, vertexuse, &vu_p->v_p->vu_hd)) {
962  lu = (struct loopuse *)NULL;
963  switch (*vu->up.magic_p) {
964  case NMG_EDGEUSE_MAGIC:
965  eu = vu->up.eu_p;
966  bu_ptbl_ins_unique(tbl, (long *)eu->e_p);
967  if (*eu->up.magic_p != NMG_LOOPUSE_MAGIC)
968  break;
969 
970  lu = eu->up.lu_p;
971  /* fallthrough */
972 
973  case NMG_LOOPUSE_MAGIC:
974  if (! lu) lu = vu->up.lu_p;
975 
976  if (*lu->up.magic_p == NMG_FACEUSE_MAGIC)
977  bu_ptbl_ins_unique(tbl,
978  (long *)lu->up.fu_p->f_p);
979  break;
980  case NMG_SHELL_MAGIC:
981  break;
982  default:
983  bu_log("Bogus vertexuse parent magic:%s.",
984  bu_identify_magic(*vu->up.magic_p));
985  nmg_rt_segs_exit("goodbye");
986  }
987  }
988  break;
989  default:
990  bu_log("Bogus magic number pointer:%s", bu_identify_magic(*l_p));
991  nmg_rt_segs_exit("goodbye");
992  }
993 }
994 
995 
996 HIDDEN void
997 unresolved(struct hitmiss *next_hit, struct bu_ptbl *a_tbl, struct bu_ptbl *next_tbl, struct bu_list *hd, struct ray_data *rd)
998 {
999 
1000  struct hitmiss *hm;
1001  register long **l_p;
1002  register long **b;
1003 
1004  bu_log("Unable to fix state transition--->\n");
1005  bu_log("\tray start = (%f %f %f) dir = (%f %f %f)\n",
1006  V3ARGS(rd->rp->r_pt), V3ARGS(rd->rp->r_dir));
1007  for (BU_LIST_FOR(hm, hitmiss, hd)) {
1008  if (hm == next_hit) {
1009  bu_log("======= ======\n");
1011  bu_log("================\n");
1012  } else
1014  }
1015 
1016  bu_log("topo table A\n");
1017  b = &a_tbl->buffer[a_tbl->end];
1018  l_p = &a_tbl->buffer[0];
1019  for (; l_p < b; l_p ++)
1020  bu_log("\t%ld %s\n", **l_p, bu_identify_magic(**l_p));
1021 
1022  bu_log("topo table NEXT\n");
1023  b = &next_tbl->buffer[next_tbl->end];
1024  l_p = &next_tbl->buffer[0];
1025  for (; l_p < b; l_p ++)
1026  bu_log("\t%ld %s\n", **l_p, bu_identify_magic(**l_p));
1027 
1028  bu_log("<---Unable to fix state transition\n");
1029  pl_ray(rd);
1030  bu_log("Primitive: %s, pixel=%d %d, lvl=%d %s\n",
1031  rd->stp->st_dp->d_namep,
1032  rd->ap->a_x, rd->ap->a_y, rd->ap->a_level,
1033  rd->ap->a_purpose);
1034 }
1035 
1036 
1037 HIDDEN int
1038 check_hitstate(struct bu_list *hd, struct ray_data *rd)
1039 {
1040  struct hitmiss *a_hit;
1041  struct hitmiss *next_hit;
1042  int ibs;
1043  int obs;
1044  struct bu_ptbl *a_tbl = (struct bu_ptbl *)NULL;
1045  struct bu_ptbl *next_tbl = (struct bu_ptbl *)NULL;
1046  struct bu_ptbl *tbl_p = (struct bu_ptbl *)NULL;
1047  long *long_ptr;
1048 
1049  BU_CK_LIST_HEAD(hd);
1050 
1051  /* find that first "OUTSIDE" point */
1052  a_hit = BU_LIST_FIRST(hitmiss, hd);
1053  NMG_CK_HITMISS(a_hit);
1054 
1055  if (((a_hit->in_out & 0x0f0) >> 4) != NMG_RAY_STATE_OUTSIDE ||
1056  RTG.NMG_debug & DEBUG_RT_SEGS) {
1057  bu_log("check_hitstate()\n");
1059 
1060  bu_log("Ray: pt:(%g %g %g) dir:(%g %g %g)\n",
1061  V3ARGS(rd->rp->r_pt), V3ARGS(rd->rp->r_dir));
1062  }
1063 
1064  while (BU_LIST_NOT_HEAD(a_hit, hd) &&
1065  ((a_hit->in_out & 0x0f0) >> 4) != NMG_RAY_STATE_OUTSIDE) {
1066 
1067  NMG_CK_HITMISS(a_hit);
1068 
1069  /* this better be a 2-manifold face */
1070  bu_log("%s[%d]: This better be a 2-manifold face\n",
1071  __FILE__, __LINE__);
1072  bu_log("Primitive: %s, pixel=%d %d, lvl=%d %s\n",
1073  rd->stp->st_dp->d_namep,
1074  rd->ap->a_x, rd->ap->a_y, rd->ap->a_level,
1075  rd->ap->a_purpose);
1076  a_hit = BU_LIST_PNEXT(hitmiss, a_hit);
1077  }
1078  if (BU_LIST_IS_HEAD(a_hit, hd)) return 1;
1079 
1080  BU_ALLOC(a_tbl, struct bu_ptbl);
1081  bu_ptbl_init(a_tbl, 64, "a_tbl");
1082 
1083  BU_ALLOC(next_tbl, struct bu_ptbl);
1084  bu_ptbl_init(next_tbl, 64, "next_tbl");
1085 
1086  /* check the state transition on the rest of the hit points */
1087  while (BU_LIST_NOT_HEAD((next_hit = BU_LIST_PNEXT(hitmiss, &a_hit->l)), hd)) {
1088  NMG_CK_HITMISS(next_hit);
1089 
1090  ibs = HMG_INBOUND_STATE(next_hit);
1091  obs = HMG_OUTBOUND_STATE(a_hit);
1092  if (ibs != obs) {
1093  /* if these two hits share some common topological
1094  * element, then we can fix things.
1095  *
1096  * First we build the table of elements associated
1097  * with each hit.
1098  */
1099 
1100  bu_ptbl_reset(a_tbl);
1101  NMG_CK_HITMISS(a_hit);
1102  build_topo_list((uint32_t *)a_hit->outbound_use, a_tbl);
1103 
1104  bu_ptbl_reset(next_tbl);
1105  NMG_CK_HITMISS(next_hit);
1106  build_topo_list((uint32_t *)next_hit->outbound_use, next_tbl);
1107 
1108 
1109  /* If the tables have elements in common,
1110  * then resolve the conflict by
1111  * morphing the two hits to match.
1112  * else
1113  * This is a real conflict.
1114  */
1115  long_ptr = common_topo(a_tbl, next_tbl);
1116  if (long_ptr) {
1117  /* morf the two hit points */
1118  a_hit->in_out = (a_hit->in_out & 0x0f0) +
1120  a_hit->outbound_use = long_ptr;
1121 
1122  next_hit->in_out = (next_hit->in_out & 0x0f) +
1123  (NMG_RAY_STATE_ON << 4);
1124  a_hit->inbound_use = long_ptr;
1125 
1126  } else
1127  unresolved(next_hit, a_tbl, next_tbl, hd, rd);
1128 
1129  }
1130 
1131  /* save next_tbl as a_tbl for next iteration */
1132  tbl_p = a_tbl;
1133  a_tbl = next_tbl;
1134  next_tbl = tbl_p;
1135 
1136  a_hit = next_hit;
1137  }
1138 
1139  bu_ptbl_free(next_tbl);
1140  bu_ptbl_free(a_tbl);
1141  (void)bu_free((char *)a_tbl, "a_tbl");
1142  (void)bu_free((char *)next_tbl, "next_tbl");
1143 
1144  return 0;
1145 }
1146 
1147 
1148 /**
1149  * Obtain the list of ray segments which intersect with the nmg.
1150  * This routine does all of the "work" for rt_nmg_shot()
1151  *
1152  * Return:
1153  * # of segments added to list.
1154  */
1155 int
1157 {
1158  struct hitmiss *a_hit;
1159  static int last_miss=0;
1160 
1161 #ifdef DO_LONGJMP
1162  if (setjmp(nmg_longjump_env) != 0) {
1163  return 0;
1164  }
1165 #endif
1166 
1168 
1169  if (BU_LIST_IS_EMPTY(&rd->rd_hit)) {
1170 
1171  NMG_FREE_HITLIST(&rd->rd_miss, rd->ap);
1172 
1173  if (RTG.NMG_debug & DEBUG_RT_SEGS) {
1174  if (last_miss) bu_log(".");
1175  else bu_log("ray missed NMG\n");
1176  }
1177  last_miss = 1;
1178  return 0; /* MISS */
1179  } else if (RTG.NMG_debug & DEBUG_RT_SEGS) {
1180  int seg_count=0;
1181 
1182  print_seg_list(rd->seghead, seg_count, "before");
1183 
1184  bu_log("\n\nnmg_ray_segs(rd)\nsorted nmg/ray hit list\n");
1185 
1186  for (BU_LIST_FOR(a_hit, hitmiss, &rd->rd_hit))
1187  nmg_rt_print_hitmiss(a_hit);
1188  }
1189 
1190  last_miss = 0;
1191 
1192  if (check_hitstate(&rd->rd_hit, rd)) {
1193  NMG_FREE_HITLIST(&rd->rd_hit, rd->ap);
1194  NMG_FREE_HITLIST(&rd->rd_miss, rd->ap);
1195  return 0;
1196  }
1197 
1198  if (RTG.NMG_debug & DEBUG_RT_SEGS) {
1199  bu_log("----------morphed nmg/ray hit list---------\n");
1200  for (BU_LIST_FOR(a_hit, hitmiss, &rd->rd_hit))
1201  nmg_rt_print_hitmiss(a_hit);
1202 
1203  pl_ray(rd);
1204  }
1205 
1206  {
1207  int seg_count = nmg_bsegs(rd, rd->ap, rd->seghead, rd->stp);
1208 
1209 
1210  NMG_FREE_HITLIST(&rd->rd_hit, rd->ap);
1211  NMG_FREE_HITLIST(&rd->rd_miss, rd->ap);
1212 
1213 
1214  if (RTG.NMG_debug & DEBUG_RT_SEGS) {
1215  /* print debugging data before returning */
1216  print_seg_list(rd->seghead, seg_count, "after");
1217  }
1218  return seg_count;
1219  }
1220 }
1221 
1222 
1223 /*
1224  * Local Variables:
1225  * mode: C
1226  * tab-width: 8
1227  * indent-tabs-mode: t
1228  * c-file-style: "stroustrup"
1229  * End:
1230  * ex: shiftwidth=4 tabstop=8
1231  */
fastf_t ndotr
Definition: nmg_rt_segs.c:50
#define HMG_HIT_OUT_OUT
edge/vertex graze
Definition: raytrace.h:2318
HIDDEN int nmg_bsegs(struct ray_data *rd, struct application *ap, struct seg *seghead, struct soltab *stp)
Definition: nmg_rt_segs.c:806
char * d_namep
pointer to name string
Definition: raytrace.h:859
#define BU_LIST_FOR(p, structure, hp)
Definition: list.h:365
long ** buffer
Definition: ptbl.h:66
#define NMG_EDGEUSE_MAGIC
Definition: magic.h:120
void bu_log(const char *,...) _BU_ATTR_PRINTF12
Definition: log.c:176
#define BU_LIST_INSERT(old, new)
Definition: list.h:183
HIDDEN void set_outpoint(struct seg **seg_p, struct hitmiss *a_hit)
Definition: nmg_rt_segs.c:254
HIDDEN void pl_ray(struct ray_data *rd)
Definition: nmg_rt_segs.c:107
struct hit seg_in
IN information.
Definition: raytrace.h:370
Definition: list.h:118
const struct directory * st_dp
Directory entry of solid.
Definition: raytrace.h:436
#define NMG_SHELL_MAGIC
Definition: magic.h:142
#define RT_CK_APPLICATION(_p)
Definition: raytrace.h:1675
#define HMG_HIT_OUT_IN
breaking in
Definition: raytrace.h:2317
HIDDEN long * common_topo(struct bu_ptbl *a_tbl, struct bu_ptbl *next_tbl)
Definition: nmg_rt_segs.c:888
double dist
>= 0
Definition: tol.h:73
fastf_t fdotr
Definition: nmg_rt_segs.c:48
#define HMG_HIT_OUT_ON
Definition: raytrace.h:2322
HIDDEN void set_inpoint(struct seg **seg_p, struct hitmiss *a_hit, struct soltab *stp, struct application *ap)
Definition: nmg_rt_segs.c:216
if lu s
Definition: nmg_mod.c:3860
long * outbound_use
Definition: raytrace.h:2343
Definition: clone.c:90
void bu_ptbl_init(struct bu_ptbl *b, size_t len, const char *str)
Definition: ptbl.c:32
struct soltab * stp
Definition: raytrace.h:2420
#define HMG_HIT_IN_IN
hit internal structure
Definition: raytrace.h:2315
lu
Definition: nmg_mod.c:3855
#define BU_LIST_IS_EMPTY(hp)
Definition: list.h:295
Definition: raytrace.h:368
#define BU_LIST_MAGIC_SET(_l, _magic)
Definition: list.h:129
Definition: raytrace.h:248
long * inbound_use
Definition: raytrace.h:2341
HIDDEN int state5(struct seg *seghead, struct seg **seg_p, int *seg_count, struct hitmiss *a_hit, struct soltab *stp, struct application *ap, struct bn_tol *tol)
Definition: nmg_rt_segs.c:771
struct bu_list rd_hit
list of hit elements
Definition: raytrace.h:2423
vect_t inbound_norm
Definition: raytrace.h:2342
Header file for the BRL-CAD common definitions.
int bu_ptbl_ins_unique(struct bu_ptbl *b, long *p)
struct resource * a_resource
dynamic memory resources
Definition: raytrace.h:1591
#define HMG_INBOUND_STATE(_hm)
Definition: raytrace.h:2306
void bu_ptbl_reset(struct bu_ptbl *b)
Definition: ptbl.c:49
#define NMG_LOOPUSE_MAGIC
Definition: magic.h:130
#define HIDDEN
Definition: common.h:86
struct bu_list l
Definition: raytrace.h:369
HIDDEN int state2(struct seg *seghead, struct seg **seg_p, int *seg_count, struct hitmiss *a_hit, struct soltab *stp, struct application *ap, struct bn_tol *tol)
Definition: nmg_rt_segs.c:398
Definition: ptbl.h:62
HIDDEN void print_seg_list(struct seg *seghead, int seg_count, char *s)
Definition: nmg_rt_segs.c:68
HIDDEN int check_hitstate(struct bu_list *hd, struct ray_data *rd)
Definition: nmg_rt_segs.c:1038
struct bu_list l
Definition: raytrace.h:2335
#define BU_LIST_IS_HEAD(p, hp)
Definition: list.h:322
#define NMG_RAY_STATE_ON
Definition: raytrace.h:2311
uint32_t NMG_debug
debug bits for NMG's see nmg.h
Definition: raytrace.h:1699
#define BU_ALLOC(_ptr, _type)
Definition: malloc.h:223
#define NMG_RAY_STATE_OUTSIDE
Definition: raytrace.h:2312
#define V3ARGS(a)
Definition: color.c:56
int a_x
Screen X of ray, if applicable.
Definition: raytrace.h:1596
HIDDEN int state0(struct seg *seghead, struct seg **seg_p, int *seg_count, struct hitmiss *a_hit, struct soltab *stp, struct application *ap, struct bn_tol *tol)
Definition: nmg_rt_segs.c:296
struct bu_list * back
"back", "last"
Definition: list.h:121
point_t hit_point
DEPRECATED: Intersection point, use VJOIN1 hit_dist.
Definition: raytrace.h:251
void nmg_rt_print_hitmiss(struct hitmiss *a_hit)
Definition: nmg_rt_isect.c:211
HIDDEN int state6(struct seg *seghead, struct seg **seg_p, int *seg_count, struct hitmiss *a_hit, struct soltab *stp, struct application *ap, struct bn_tol *tol)
Definition: nmg_rt_segs.c:783
struct hit seg_out
OUT information.
Definition: raytrace.h:371
HIDDEN int state5and6(struct seg *seghead, struct seg **seg_p, int *seg_count, struct hitmiss *a_hit, struct soltab *stp, struct application *ap, struct bn_tol *tol, int ret_val_7)
Definition: nmg_rt_segs.c:684
void nmg_rt_print_hitlist(struct bu_list *hd)
Definition: nmg_rt_isect.c:234
#define BU_LIST_PNEXT(structure, p)
Definition: list.h:422
int a_level
recursion level (for printing)
Definition: raytrace.h:1595
const char * a_purpose
Debug string: purpose of ray.
Definition: raytrace.h:1598
#define UNUSED(parameter)
Definition: common.h:239
vect_t outbound_norm
Definition: raytrace.h:2344
#define NMG_CK_HITMISS(hm)
Definition: raytrace.h:2356
Support for uniform tolerances.
Definition: tol.h:71
#define BN_CK_TOL(_p)
Definition: tol.h:82
HIDDEN void unresolved(struct hitmiss *next_hit, struct bu_ptbl *a_tbl, struct bu_ptbl *next_tbl, struct bu_list *hd, struct ray_data *rd)
Definition: nmg_rt_segs.c:997
#define NMG_VERTEXUSE_MAGIC
Definition: magic.h:145
uint32_t magic
Magic # for mem id/check.
Definition: list.h:119
void nmg_visit(const uint32_t *magicp, const struct nmg_visit_handlers *htab, void *state)
Definition: nmg_visit.c:263
void pl_color(register FILE *plotfp, int r, int g, int b)
Definition: plot3.c:325
fastf_t fdotl
Definition: nmg_rt_segs.c:49
vect_t r_dir
Direction of ray (UNIT Length)
Definition: raytrace.h:219
void pdv_3line(register FILE *plotfp, const fastf_t *a, const fastf_t *b)
Definition: plot3.c:642
int bu_ptbl_locate(const struct bu_ptbl *b, const long *p)
void bu_ptbl_free(struct bu_ptbl *b)
Definition: ptbl.c:226
#define HMG_HIT_IN_ON
Definition: raytrace.h:2319
int in_out
status of ray as it transitions this hit point.
Definition: raytrace.h:2338
#define nmg_rt_segs_exit(_s)
Definition: nmg_rt_segs.c:61
oldeumate e_p eu_p
Definition: nmg_mod.c:3940
#define RT_GET_SEG(p, res)
Definition: raytrace.h:379
#define HMG_HIT_IN_OUT
breaking out
Definition: raytrace.h:2316
struct edgeuse * eu
Definition: nmg_rt_segs.c:51
#define CK_SEGP(_p)
Definition: nmg_rt_segs.c:55
point_t r_pt
Point at which ray starts.
Definition: raytrace.h:218
#define NMG_RAY_STATE_INSIDE
Definition: raytrace.h:2310
#define RT_SEG_MAGIC
Definition: magic.h:167
int nmg_ray_segs(struct ray_data *rd)
Definition: nmg_rt_segs.c:1156
HIDDEN int state4(struct seg *seghead, struct seg **seg_p, int *seg_count, struct hitmiss *a_hit, struct soltab *stp, struct application *ap, struct bn_tol *tol)
Definition: nmg_rt_segs.c:597
#define HMG_HIT_ON_ON
Definition: raytrace.h:2321
int a_y
Screen Y of ray, if applicable.
Definition: raytrace.h:1597
#define HMG_HIT_ON_OUT
Definition: raytrace.h:2323
#define RT_CK_SOLTAB(_p)
Definition: raytrace.h:453
HIDDEN int state1(struct seg *seghead, struct seg **seg_p, int *seg_count, struct hitmiss *a_hit, struct soltab *stp, struct application *ap, struct bn_tol *tol)
Definition: nmg_rt_segs.c:350
struct hit hit
Definition: raytrace.h:2336
#define NMG_CK_HITMISS_LISTS(rd)
Definition: raytrace.h:2384
void bu_free(void *ptr, const char *str)
Definition: malloc.c:328
vect_t hit_normal
DEPRECATED: Surface Normal at hit_point, use RT_HIT_NORMAL.
Definition: raytrace.h:252
HIDDEN void build_topo_list(uint32_t *l_p, struct bu_ptbl *tbl)
Definition: nmg_rt_segs.c:912
struct xray * rp
Definition: raytrace.h:2417
#define BU_CK_LIST_HEAD(_p)
Definition: list.h:142
struct application * ap
Definition: raytrace.h:2418
off_t end
Definition: ptbl.h:64
#define NMG_FREE_HITLIST(_p, _ap)
Definition: raytrace.h:2474
struct bu_list rd_miss
list of missed/sub-hit elements
Definition: raytrace.h:2424
struct bu_list * forw
"forward", "next"
Definition: list.h:120
#define NMG_FACEUSE_MAGIC
Definition: magic.h:124
fastf_t hit_dist
dist from r_pt to hit_point
Definition: raytrace.h:250
#define HMG_HIT_ON_IN
Definition: raytrace.h:2320
void bu_bomb(const char *str) _BU_ATTR_NORETURN
Definition: bomb.c:91
HIDDEN const point_t delta
Definition: sh_prj.c:618
double fastf_t
Definition: defines.h:300
HIDDEN int state3(struct seg *seghead, struct seg **seg_p, int *seg_count, struct hitmiss *a_hit, struct soltab *stp, struct application *ap, struct bn_tol *tol)
Definition: nmg_rt_segs.c:494
const char * bu_identify_magic(uint32_t magic)
struct seg * seghead
Definition: raytrace.h:2419
HIDDEN void visitor(uint32_t *l_p, void *tbl, int unused)
Definition: nmg_rt_segs.c:902
#define BU_LIST_NOT_HEAD(p, hp)
Definition: list.h:324
#define HMG_OUTBOUND_STATE(_hm)
Definition: raytrace.h:2307
#define HMG_HIT_ANY_ANY
hit on non-3-manifold
Definition: raytrace.h:2324
#define BU_LIST_FIRST(structure, hp)
Definition: list.h:312
struct rt_g RTG
Definition: globals.c:39