BRL-CAD
raytrace.h
Go to the documentation of this file.
1 /* R A Y T R A C E . H
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 librt */
21 /** @{ */
22 /** @file raytrace.h
23  *
24  * All the data structures and manifest constants necessary for
25  * interacting with the BRL-CAD LIBRT ray-tracing library.
26  *
27  * Note that this header file defines many internal data structures,
28  * as well as the library's external (interface) data structures.
29  * These are provided for the convenience of applications builders.
30  * However, the internal data structures are subject to change in each
31  * release.
32  *
33  */
34 
35 #ifndef RAYTRACE_H
36 #define RAYTRACE_H
37 
38 #include "common.h"
39 
40 /* interface headers */
41 #include "tcl.h"
42 #include "bu/avs.h"
43 #include "bu/bitv.h"
44 #include "bu/bu_tcl.h"
45 #include "bu/file.h"
46 #include "bu/hash.h"
47 #include "bu/hist.h"
48 #include "bu/malloc.h"
49 #include "bu/mapped_file.h"
50 #include "bu/list.h"
51 #include "bu/log.h"
52 #include "bu/parallel.h" /* needed for BU_SEM_LAST */
53 #include "bu/parse.h"
54 #include "bu/ptbl.h"
55 #include "bu/str.h"
56 #include "bu/vls.h"
57 #include "bn.h"
58 #include "db5.h"
59 #include "nmg.h"
60 #include "pc.h"
61 #include "rtgeom.h"
62 
63 
64 #include "rt/defines.h"
65 #include "rt/db_fullpath.h"
66 
67 
69 
70 /**
71  * Each type of debugging support is independently controlled, by a
72  * separate bit in the word RT_G_DEBUG
73  *
74  * For programs based on the "RT" program, these flags follow the "-x"
75  * (lower case x) option.
76  */
77 #define DEBUG_OFF 0 /**< @brief No debugging */
78 
79 /* These definitions are each for one bit */
80 
81 /* Options useful for debugging applications */
82 #define DEBUG_ALLRAYS 0x00000001 /**< @brief 1 Print calls to rt_shootray() */
83 #define DEBUG_ALLHITS 0x00000002 /**< @brief 2 Print partitions passed to a_hit() */
84 #define DEBUG_SHOOT 0x00000004 /**< @brief 3 Info about rt_shootray() processing */
85 #define DEBUG_INSTANCE 0x00000008 /**< @brief 4 regionid instance revectoring */
86 
87 /* Options useful for debugging the database */
88 #define DEBUG_DB 0x00000010 /**< @brief 5 Database debugging */
89 #define DEBUG_SOLIDS 0x00000020 /**< @brief 6 Print prep'ed solids */
90 #define DEBUG_REGIONS 0x00000040 /**< @brief 7 Print regions & boolean trees */
91 #define DEBUG_ARB8 0x00000080 /**< @brief 8 Print voluminous ARB8 details */
92 #define DEBUG_SPLINE 0x00000100 /**< @brief 9 Splines */
93 #define DEBUG_ANIM 0x00000200 /**< @brief 10 Animation */
94 #define DEBUG_ANIM_FULL 0x00000400 /**< @brief 11 Animation matrices */
95 #define DEBUG_VOL 0x00000800 /**< @brief 12 Volume & opaque Binary solid */
96 
97 /* Options useful for debugging the library */
98 #define DEBUG_ROOTS 0x00001000 /**< @brief 13 Print rootfinder details */
99 #define DEBUG_PARTITION 0x00002000 /**< @brief 14 Info about bool_weave() */
100 #define DEBUG_CUT 0x00004000 /**< @brief 15 Print space cutting statistics */
101 #define DEBUG_BOXING 0x00008000 /**< @brief 16 Object/box checking details */
102 #define DEBUG_MEM 0x00010000 /**< @brief 17 -->> BU_DEBUG_MEM_LOG */
103 #define DEBUG_MEM_FULL 0x00020000 /**< @brief 18 -->> BU_DEBUG_MEM_CHECK */
104 #define DEBUG_FDIFF 0x00040000 /**< @brief 19 bool/fdiff debugging */
105 #define DEBUG_PARALLEL 0x00080000 /**< @brief 20 -->> BU_DEBUG_PARALLEL */
106 #define DEBUG_CUTDETAIL 0x00100000 /**< @brief 21 Print space cutting details */
107 #define DEBUG_TREEWALK 0x00200000 /**< @brief 22 Database tree traversal */
108 #define DEBUG_TESTING 0x00400000 /**< @brief 23 One-shot debugging flag */
109 #define DEBUG_ADVANCE 0x00800000 /**< @brief 24 Cell-to-cell space partitioning */
110 #define DEBUG_MATH 0x01000000 /**< @brief 25 nmg math routines */
111 
112 /* Options for debugging particular solids */
113 #define DEBUG_EBM 0x02000000 /**< @brief 26 Extruded bit-map solids */
114 #define DEBUG_HF 0x04000000 /**< @brief 27 Height Field solids */
115 
116 #define DEBUG_UNUSED1 0x08000000 /**< @brief 28 unused */
117 #define DEBUG_UNUSED2 0x10000000 /**< @brief 29 unused */
118 #define DEBUG_UNUSED3 0x20000000 /**< @brief 30 unused */
119 
120 /* Options which will cause the library to write binary debugging output */
121 #define DEBUG_PL_SOLIDS 0x40000000 /**< @brief 31 plot all solids */
122 #define DEBUG_PL_BOX 0x80000000 /**< @brief 32 Plot(3) bounding boxes and cuts */
123 
124 /** Format string for bu_printb() */
125 #define DEBUG_FORMAT \
126  "\020\040PLOTBOX\
127 \037PLOTSOLIDS\
128 \033HF\032EBM\031MATH\030ADVANCE\
129 \027TESTING\026TREEWALK\025CUTDETAIL\024PARALLEL\023FDIFF\022MEM_FULL\
130 \021MEM\020BOXING\017CUTTING\016PARTITION\015ROOTS\014VOL\
131 \013ANIM_FULL\012ANIM\011SPLINE\010ARB8\7REGIONS\6SOLIDS\5DB\
132 \4INSTANCE\3SHOOT\2ALLHITS\1ALLRAYS"
133 
134 /**
135  * FIXME: These should probably be vmath macros
136  */
137 #define RT_BADNUM(n) (!((n) >= -INFINITY && (n) <= INFINITY))
138 #define RT_BADVEC(v) (RT_BADNUM((v)[X]) || RT_BADNUM((v)[Y]) || RT_BADNUM((v)[Z]))
139 
140 
141 /*
142  * Unfortunately, to prevent divide-by-zero, some tolerancing needs to
143  * be introduced.
144  *
145  *
146  * RT_LEN_TOL is the shortest length, in mm, that can be stood as the
147  * dimensions of a primitive. Can probably become at least
148  * SQRT_SMALL_FASTF.
149  *
150  * Dot products smaller than RT_DOT_TOL are considered to have a dot
151  * product of zero, i.e., the angle is effectively zero. This is used
152  * to check vectors that should be perpendicular.
153  *
154  * asin(0.1) = 5.73917 degrees
155  * asin(0.01) = 0.572967 degrees
156  * asin(0.001) = 0.0572958 degrees
157  * asin(0.0001) = 0.00572958 degrees
158  *
159  * sin(0.01 degrees) = sin(0.000174 radians) = 0.000174533
160  *
161  * Many TGCs at least, in existing databases, will fail the
162  * perpendicularity test if DOT_TOL is much smaller than 0.001, which
163  * establishes a 1/20th degree tolerance. The intent is to eliminate
164  * grossly bad primitives, not pick nits.
165  *
166  * RT_PCOEF_TOL is a tolerance on polynomial coefficients to prevent
167  * the root finder from having heartburn.
168  */
169 #define RT_LEN_TOL (1.0e-8)
170 #define RT_DOT_TOL (0.001)
171 #define RT_PCOEF_TOL (1.0e-10)
172 
173 
174 /**
175  * Tessellation (geometric) tolerances, different beasts than the
176  * calculation tolerance in bn_tol.
177  */
178 struct rt_tess_tol {
179  uint32_t magic;
180  double abs; /**< @brief absolute dist tol */
181  double rel; /**< @brief rel dist tol */
182  double norm; /**< @brief normal tol */
183 };
184 #define RT_CK_TESS_TOL(_p) BU_CKMAG(_p, RT_TESS_TOL_MAGIC, "rt_tess_tol")
185 #define RT_TESS_TOL_INIT_ZERO {RT_TESS_TOL_MAGIC, 0.0, 0.0, 0.0}
186 
187 /**
188  * A handle on the internal format of an MGED database object.
189  */
191  uint32_t idb_magic;
193  int idb_minor_type; /**< @brief ID_xxx */
194  const struct rt_functab *idb_meth; /**< @brief for ft_ifree(), etc. */
195  void * idb_ptr;
197 };
198 #define idb_type idb_minor_type
199 #define RT_DB_INTERNAL_INIT(_p) { \
200  (_p)->idb_magic = RT_DB_INTERNAL_MAGIC; \
201  (_p)->idb_major_type = -1; \
202  (_p)->idb_minor_type = -1; \
203  (_p)->idb_meth = (const struct rt_functab *) ((void *)0); \
204  (_p)->idb_ptr = ((void *)0); \
205  bu_avs_init_empty(&(_p)->idb_avs); \
206  }
207 #define RT_CK_DB_INTERNAL(_p) BU_CKMAG(_p, RT_DB_INTERNAL_MAGIC, "rt_db_internal")
208 
209 
210 /**
211  * All necessary information about a ray.
212  *
213  * Not called just "ray" to prevent conflicts with VLD stuff.
214  */
215 struct xray {
216  uint32_t magic;
217  int index; /**< @brief Which ray of a bundle */
218  point_t r_pt; /**< @brief Point at which ray starts */
219  vect_t r_dir; /**< @brief Direction of ray (UNIT Length) */
220  fastf_t r_min; /**< @brief entry dist to bounding sphere */
221  fastf_t r_max; /**< @brief exit dist from bounding sphere */
222 };
223 #define RAY_NULL ((struct xray *)0)
224 #define RT_CK_RAY(_p) BU_CKMAG(_p, RT_RAY_MAGIC, "struct xray");
225 
226 /**
227  * This plural xrays structure is a bu_list based container designed
228  * to hold a list or bundle of xray(s). This bundle is utilized by
229  * rt_shootrays() through its application bundle input.
230  */
231 struct xrays
232 {
233  struct bu_list l;
234  struct xray ray;
235 };
236 
237 
238 /**
239  * Information about where a ray hits the surface.
240  *
241  * Important Note: Surface Normals always point OUT of a solid.
242  *
243  * DEPRECATED: The hit_point and hit_normal elements will be removed
244  * from this structure, so as to separate the concept of the solid's
245  * normal at the hit point from the post-boolean normal at the hit
246  * point.
247  */
248 struct hit {
249  uint32_t hit_magic;
250  fastf_t hit_dist; /**< @brief dist from r_pt to hit_point */
251  point_t hit_point; /**< @brief DEPRECATED: Intersection point, use VJOIN1 hit_dist */
252  vect_t hit_normal; /**< @brief DEPRECATED: Surface Normal at hit_point, use RT_HIT_NORMAL */
253  vect_t hit_vpriv; /**< @brief PRIVATE vector for xxx_*() */
254  void * hit_private; /**< @brief PRIVATE handle for xxx_shot() */
255  int hit_surfno; /**< @brief solid-specific surface indicator */
256  struct xray * hit_rayp; /**< @brief pointer to defining ray */
257 };
258 #define HIT_NULL ((struct hit *)0)
259 #define RT_CK_HIT(_p) BU_CKMAG(_p, RT_HIT_MAGIC, "struct hit")
260 #define RT_HIT_INIT_ZERO { RT_HIT_MAGIC, 0.0, VINIT_ZERO, VINIT_ZERO, VINIT_ZERO, NULL, 0, NULL }
261 
262 /**
263  * Compute normal into (_hitp)->hit_normal.
264  *
265  * Set flip-flag accordingly depending on boolean logic, as one hit
266  * may be shared between multiple partitions with different flip
267  * status.
268  *
269  * Example: box.r = box.s - sph.s; sph.r = sph.s
270  *
271  * Return the post-boolean normal into caller-provided _normal vector.
272  */
273 #define RT_HIT_NORMAL(_normal, _hitp, _stp, _unused, _flipflag) { \
274  RT_CK_HIT(_hitp); \
275  RT_CK_SOLTAB(_stp); \
276  RT_CK_FUNCTAB((_stp)->st_meth); \
277  { \
278  void *_n = (void *)_normal; \
279  if ((_stp)->st_meth->ft_norm) { \
280  (_stp)->st_meth->ft_norm(_hitp, _stp, (_hitp)->hit_rayp); \
281  } \
282  if (_n != NULL) { \
283  int _f = (int)_flipflag; \
284  if (_f) { \
285  VREVERSE((fastf_t *)_normal, (_hitp)->hit_normal); \
286  } else { \
287  VMOVE((fastf_t *)_normal, (_hitp)->hit_normal); \
288  } \
289  } \
290  } \
291  }
292 
293 /* A more powerful interface would be: */
294 /* RT_GET_NORMAL(_normal, _partition, inhit/outhit flag, ap) */
295 
296 
297 /**
298  * Information about curvature of the surface at a hit point. The
299  * principal direction pdir has unit length and principal curvature
300  * c1. |c1| <= |c2|, i.e. c1 is the most nearly flat principle
301  * curvature. A POSITIVE curvature indicates that the surface bends
302  * TOWARD the (outward pointing) normal vector at that point. c1 and
303  * c2 are the inverse radii of curvature. The other principle
304  * direction is implied: pdir2 = normal x pdir1.
305  */
306 struct curvature {
307  vect_t crv_pdir; /**< @brief Principle direction */
308  fastf_t crv_c1; /**< @brief curvature in principle dir */
309  fastf_t crv_c2; /**< @brief curvature in other direction */
310 };
311 #define CURVE_NULL ((struct curvature *)0)
312 #define RT_CURVATURE_INIT_ZERO { VINIT_ZERO, 0.0, 0.0 }
313 
314 /**
315  * Use this macro after having computed the normal, to compute the
316  * curvature at a hit point.
317  *
318  * In Release 4.4 and earlier, this was called RT_CURVE(). When the
319  * extra argument was added the name was changed.
320  */
321 #define RT_CURVATURE(_curvp, _hitp, _flipflag, _stp) { \
322  RT_CK_HIT(_hitp); \
323  RT_CK_SOLTAB(_stp); \
324  RT_CK_FUNCTAB((_stp)->st_meth); \
325  if ((_stp)->st_meth->ft_curve) { \
326  (_stp)->st_meth->ft_curve(_curvp, _hitp, _stp); \
327  } \
328  if (_flipflag) { \
329  (_curvp)->crv_c1 = - (_curvp)->crv_c1; \
330  (_curvp)->crv_c2 = - (_curvp)->crv_c2; \
331  } \
332  }
333 
334 /* A more powerful interface would be: */
335 /* RT_GET_CURVATURE(_curvp, _partition, inhit/outhit flag, ap) */
336 
337 /**
338  * Mostly for texture mapping, information about parametric space.
339  */
340 struct uvcoord {
341  fastf_t uv_u; /**< @brief Range 0..1 */
342  fastf_t uv_v; /**< @brief Range 0..1 */
343  fastf_t uv_du; /**< @brief delta in u */
344  fastf_t uv_dv; /**< @brief delta in v */
345 };
346 #define RT_HIT_UVCOORD(ap, _stp, _hitp, uvp) { \
347  RT_CK_HIT(_hitp); \
348  RT_CK_SOLTAB(_stp); \
349  RT_CK_FUNCTAB((_stp)->st_meth); \
350  if ((_stp)->st_meth->ft_uv) { \
351  (_stp)->st_meth->ft_uv(ap, _stp, _hitp, uvp); \
352  } \
353  }
354 
355 
356 /* A more powerful interface would be: */
357 /* RT_GET_UVCOORD(_uvp, _partition, inhit/outhit flag, ap) */
358 
359 
360 /**
361  * Intersection segment.
362  *
363  * Includes information about both endpoints of intersection.
364  * Contains forward link to additional intersection segments if the
365  * intersection spans multiple segments (e.g., shooting a ray through
366  * a torus).
367  */
368 struct seg {
369  struct bu_list l;
370  struct hit seg_in; /**< @brief IN information */
371  struct hit seg_out; /**< @brief OUT information */
372  struct soltab * seg_stp; /**< @brief pointer back to soltab */
373 };
374 #define RT_SEG_NULL ((struct seg *)0)
375 
376 #define RT_CHECK_SEG(_p) BU_CKMAG(_p, RT_SEG_MAGIC, "struct seg")
377 #define RT_CK_SEG(_p) BU_CKMAG(_p, RT_SEG_MAGIC, "struct seg")
378 
379 #define RT_GET_SEG(p, res) { \
380  while (!BU_LIST_WHILE((p), seg, &((res)->re_seg)) || !(p)) \
381  rt_alloc_seg_block(res); \
382  BU_LIST_DEQUEUE(&((p)->l)); \
383  (p)->l.forw = (p)->l.back = BU_LIST_NULL; \
384  (p)->seg_in.hit_magic = (p)->seg_out.hit_magic = RT_HIT_MAGIC; \
385  res->re_segget++; \
386  }
387 
388 
389 #define RT_FREE_SEG(p, res) { \
390  RT_CHECK_SEG(p); \
391  BU_LIST_INSERT(&((res)->re_seg), &((p)->l)); \
392  res->re_segfree++; \
393  }
394 
395 
396 /**
397  * This could be
398  * BU_LIST_INSERT_LIST(&((_res)->re_seg), &((_segheadp)->l))
399  * except for security of checking & counting each element this way.
400  */
401 #define RT_FREE_SEG_LIST(_segheadp, _res) { \
402  register struct seg *_a; \
403  while (BU_LIST_WHILE(_a, seg, &((_segheadp)->l))) { \
404  BU_LIST_DEQUEUE(&(_a->l)); \
405  RT_FREE_SEG(_a, _res); \
406  } \
407  }
408 
409 
410 /**
411  * Macros to operate on Right Rectangular Parallelepipeds (RPPs).
412  * TODO: move to vmath.h
413  */
414 struct bound_rpp {
415  point_t min;
416  point_t max;
417 };
418 
419 
420 /**
421  * Internal information used to keep track of solids in the model.
422  * Leaf name and Xform matrix are unique identifier. Note that all
423  * objects store dimensional values in millimeters (mm).
424  */
425 struct soltab {
426  struct bu_list l; /**< @brief links, headed by rti_headsolid */
427  struct bu_list l2; /**< @brief links, headed by st_dp->d_use_hd */
428  const struct rt_functab * st_meth; /**< @brief pointer to per-solid methods */
429  struct rt_i * st_rtip; /**< @brief "up" pointer to rt_i */
430  long st_uses; /**< @brief Usage count, for instanced solids */
431  int st_id; /**< @brief Solid ident */
432  point_t st_center; /**< @brief Centroid of solid */
433  fastf_t st_aradius; /**< @brief Radius of APPROXIMATING sphere */
434  fastf_t st_bradius; /**< @brief Radius of BOUNDING sphere */
435  void * st_specific; /**< @brief -> ID-specific (private) struct */
436  const struct directory * st_dp; /**< @brief Directory entry of solid */
437  point_t st_min; /**< @brief min X, Y, Z of bounding RPP */
438  point_t st_max; /**< @brief max X, Y, Z of bounding RPP */
439  long st_bit; /**< @brief solids bit vector index (const) */
440  struct bu_ptbl st_regions; /**< @brief ptrs to regions using this solid (const) */
441  matp_t st_matp; /**< @brief solid coords to model space, NULL=identity */
442  struct db_full_path st_path; /**< @brief path from region to leaf */
443  /* Experimental stuff for accelerating "pieces" of solids */
444  long st_npieces; /**< @brief # pieces used by this solid */
445  long st_piecestate_num; /**< @brief re_pieces[] subscript */
446  struct bound_rpp * st_piece_rpps; /**< @brief bounding RPP of each piece of this solid */
447 };
448 #define st_name st_dp->d_namep
449 #define RT_SOLTAB_NULL ((struct soltab *)0)
450 #define SOLTAB_NULL RT_SOLTAB_NULL /**< @brief backwards compat */
451 
452 #define RT_CHECK_SOLTAB(_p) BU_CKMAG(_p, RT_SOLTAB_MAGIC, "struct soltab")
453 #define RT_CK_SOLTAB(_p) BU_CKMAG(_p, RT_SOLTAB_MAGIC, "struct soltab")
454 
455 /*
456  * Values for Solid ID.
457  */
458 #define ID_NULL 0 /**< @brief Unused */
459 #define ID_TOR 1 /**< @brief Toroid */
460 #define ID_TGC 2 /**< @brief Generalized Truncated General Cone */
461 #define ID_ELL 3 /**< @brief Ellipsoid */
462 #define ID_ARB8 4 /**< @brief Generalized ARB. V + 7 vectors */
463 #define ID_ARS 5 /**< @brief ARS */
464 #define ID_HALF 6 /**< @brief Half-space */
465 #define ID_REC 7 /**< @brief Right Elliptical Cylinder [TGC special] */
466 #define ID_POLY 8 /**< @brief Polygonal faceted object */
467 #define ID_BSPLINE 9 /**< @brief B-spline object */
468 #define ID_SPH 10 /**< @brief Sphere */
469 #define ID_NMG 11 /**< @brief n-Manifold Geometry solid */
470 #define ID_EBM 12 /**< @brief Extruded bitmap solid */
471 #define ID_VOL 13 /**< @brief 3-D Volume */
472 #define ID_ARBN 14 /**< @brief ARB with N faces */
473 #define ID_PIPE 15 /**< @brief Pipe (wire) solid */
474 #define ID_PARTICLE 16 /**< @brief Particle system solid */
475 #define ID_RPC 17 /**< @brief Right Parabolic Cylinder */
476 #define ID_RHC 18 /**< @brief Right Hyperbolic Cylinder */
477 #define ID_EPA 19 /**< @brief Elliptical Paraboloid */
478 #define ID_EHY 20 /**< @brief Elliptical Hyperboloid */
479 #define ID_ETO 21 /**< @brief Elliptical Torus */
480 #define ID_GRIP 22 /**< @brief Pseudo Solid Grip */
481 #define ID_JOINT 23 /**< @brief Pseudo Solid/Region Joint */
482 #define ID_HF 24 /**< @brief Height Field */
483 #define ID_DSP 25 /**< @brief Displacement map */
484 #define ID_SKETCH 26 /**< @brief 2D sketch */
485 #define ID_EXTRUDE 27 /**< @brief Solid of extrusion */
486 #define ID_SUBMODEL 28 /**< @brief Instanced submodel */
487 #define ID_CLINE 29 /**< @brief FASTGEN4 CLINE solid */
488 #define ID_BOT 30 /**< @brief Bag o' triangles */
489 
490 /* Add a new primitive id above here (this is will break v5 format)
491  * NOTE: must update the non-geometric object id's below the
492  * ADD_BELOW_HERE marker
493  */
494 #define ID_MAX_SOLID 44 /**< @brief Maximum defined ID_xxx for solids */
495 
496 /*
497  * Non-geometric objects
498  */
499 #define ID_COMBINATION 31 /**< @brief Combination Record */
500 #define ID_UNUSED1 32 /**< @brief UNUSED (placeholder) */
501 #define ID_BINUNIF 33 /**< @brief Uniform-array binary */
502 #define ID_UNUSED2 34 /**< @brief UNUSED (placeholder) */
503 #define ID_CONSTRAINT 39 /**< @brief Constraint object */
504 
505 /* - ADD_BELOW_HERE - */
506 /* superellipsoid should be 31, but is not v5 compatible */
507 #define ID_SUPERELL 35 /**< @brief Superquadratic ellipsoid */
508 #define ID_METABALL 36 /**< @brief Metaball */
509 #define ID_BREP 37 /**< @brief B-rep object */
510 #define ID_HYP 38 /**< @brief Hyperboloid of one sheet */
511 #define ID_REVOLVE 40 /**< @brief Solid of Revolution */
512 #define ID_PNTS 41 /**< @brief Collection of Points */
513 #define ID_ANNOTATION 42 /**< @brief Annotation */
514 #define ID_HRT 43 /**< @brief Heart */
515 
516 #define ID_MAXIMUM 44 /**< @brief Maximum defined ID_xxx value */
517 
518 /**
519  * Container for material information
520  */
521 struct mater_info {
522  float ma_color[3]; /**< @brief explicit color: 0..1 */
523  float ma_temperature; /**< @brief positive ==> degrees Kelvin */
524  char ma_color_valid; /**< @brief non-0 ==> ma_color is non-default */
525  char ma_cinherit; /**< @brief color: DB_INH_LOWER / DB_INH_HIGHER */
526  char ma_minherit; /**< @brief mater: DB_INH_LOWER / DB_INH_HIGHER */
527  char *ma_shader; /**< @brief shader name & parms */
528 };
529 #define RT_MATER_INFO_INIT_ZERO { VINIT_ZERO, 0.0, 0, 0, 0, NULL }
530 /* From MGED initial tree state */
531 #define RT_MATER_INFO_INIT_IDN { {1.0, 0.0, 0.0} , -1.0, 0, 0, 0, NULL }
532 
533 
534 /**
535  * The region structure.
536  */
537 struct region {
538  struct bu_list l; /**< @brief magic # and doubly linked list */
539  const char * reg_name; /**< @brief Identifying string */
540  union tree * reg_treetop; /**< @brief Pointer to boolean tree */
541  int reg_bit; /**< @brief constant index into Regions[] */
542  int reg_regionid; /**< @brief Region ID code. If <=0, use reg_aircode */
543  int reg_aircode; /**< @brief Region ID AIR code */
544  int reg_gmater; /**< @brief GIFT Material code */
545  int reg_los; /**< @brief approximate line-of-sight thickness equivalence */
546  struct mater_info reg_mater; /**< @brief Real material information */
547  void * reg_mfuncs; /**< @brief User appl. funcs for material */
548  void * reg_udata; /**< @brief User appl. data for material */
549  int reg_transmit; /**< @brief flag: material transmits light */
550  long reg_instnum; /**< @brief instance number, from d_uses */
551  short reg_all_unions; /**< @brief 1=boolean tree is all unions */
552  short reg_is_fastgen; /**< @brief FASTGEN-compatibility mode? */
553 #define REGION_NON_FASTGEN 0
554 #define REGION_FASTGEN_PLATE 1
555 #define REGION_FASTGEN_VOLUME 2
556  struct bu_attribute_value_set attr_values; /**< @brief Attribute/value set */
557 };
558 #define REGION_NULL ((struct region *)0)
559 #define RT_CK_REGION(_p) BU_CKMAG(_p, RT_REGION_MAGIC, "struct region")
560 
561 /**
562  * Partitions of a ray. Passed from rt_shootray() into user's a_hit()
563  * function.
564  *
565  * Not changed to a bu_list for backwards compatibility, but you can
566  * iterate the whole list by writing:
567  *
568  * for (BU_LIST_FOR(pp, partition, (struct bu_list *)PartHeadp))
569  */
570 
571 struct partition {
572  /* This can be thought of and operated on as a struct bu_list */
573  uint32_t pt_magic; /**< @brief sanity check */
574  struct partition * pt_forw; /**< @brief forwards link */
575  struct partition * pt_back; /**< @brief backwards link */
576  struct seg * pt_inseg; /**< @brief IN seg ptr (gives stp) */
577  struct hit * pt_inhit; /**< @brief IN hit pointer */
578  struct seg * pt_outseg; /**< @brief OUT seg pointer */
579  struct hit * pt_outhit; /**< @brief OUT hit ptr */
580  struct region * pt_regionp; /**< @brief ptr to containing region */
581  char pt_inflip; /**< @brief flip inhit->hit_normal */
582  char pt_outflip; /**< @brief flip outhit->hit_normal */
583  struct region ** pt_overlap_reg; /**< @brief NULL-terminated array of overlapping regions. NULL if no overlap. */
584  struct bu_ptbl pt_seglist; /**< @brief all segs in this partition */
585 };
586 #define PT_NULL ((struct partition *)0)
587 
588 #define RT_CHECK_PT(_p) RT_CK_PT(_p) /**< @brief compat */
589 #define RT_CK_PT(_p) BU_CKMAG(_p, PT_MAGIC, "struct partition")
590 #define RT_CK_PARTITION(_p) BU_CKMAG(_p, PT_MAGIC, "struct partition")
591 #define RT_CK_PT_HD(_p) BU_CKMAG(_p, PT_HD_MAGIC, "struct partition list head")
592 
593 /* Macros for copying only the essential "middle" part of a partition struct. */
594 #define RT_PT_MIDDLE_START pt_inseg /**< @brief 1st elem to copy */
595 #define RT_PT_MIDDLE_END pt_seglist.l.magic /**< @brief copy up to this elem (non-inclusive) */
596 #define RT_PT_MIDDLE_LEN(p) \
597  (((char *)&(p)->RT_PT_MIDDLE_END) - ((char *)&(p)->RT_PT_MIDDLE_START))
598 
599 #define RT_DUP_PT(ip, new, old, res) { \
600  GET_PT(ip, new, res); \
601  memcpy((char *)(&(new)->RT_PT_MIDDLE_START), (char *)(&(old)->RT_PT_MIDDLE_START), RT_PT_MIDDLE_LEN(old)); \
602  (new)->pt_overlap_reg = NULL; \
603  bu_ptbl_cat(&(new)->pt_seglist, &(old)->pt_seglist); }
604 
605 /** Clear out the pointers, empty the hit list */
606 #define GET_PT_INIT(ip, p, res) {\
607  GET_PT(ip, p, res); \
608  memset(((char *) &(p)->RT_PT_MIDDLE_START), 0, RT_PT_MIDDLE_LEN(p)); }
609 
610 #define GET_PT(ip, p, res) { \
611  if (BU_LIST_NON_EMPTY_P(p, partition, &res->re_parthead)) { \
612  BU_LIST_DEQUEUE((struct bu_list *)(p)); \
613  bu_ptbl_reset(&(p)->pt_seglist); \
614  } else { \
615  BU_ALLOC((p), struct partition); \
616  (p)->pt_magic = PT_MAGIC; \
617  bu_ptbl_init(&(p)->pt_seglist, 42, "pt_seglist ptbl"); \
618  (res)->re_partlen++; \
619  } \
620  res->re_partget++; }
621 
622 #define FREE_PT(p, res) { \
623  BU_LIST_APPEND(&(res->re_parthead), (struct bu_list *)(p)); \
624  if ((p)->pt_overlap_reg) { \
625  bu_free((void *)((p)->pt_overlap_reg), "pt_overlap_reg");\
626  (p)->pt_overlap_reg = NULL; \
627  } \
628  res->re_partfree++; }
629 
630 #define RT_FREE_PT_LIST(_headp, _res) { \
631  register struct partition *_pp, *_zap; \
632  for (_pp = (_headp)->pt_forw; _pp != (_headp);) { \
633  _zap = _pp; \
634  _pp = _pp->pt_forw; \
635  BU_LIST_DEQUEUE((struct bu_list *)(_zap)); \
636  FREE_PT(_zap, _res); \
637  } \
638  (_headp)->pt_forw = (_headp)->pt_back = (_headp); \
639  }
640 
641 /** Insert "new" partition in front of "old" partition. Note order change */
642 #define INSERT_PT(_new, _old) BU_LIST_INSERT((struct bu_list *)_old, (struct bu_list *)_new)
643 
644 /** Append "new" partition after "old" partition. Note arg order change */
645 #define APPEND_PT(_new, _old) BU_LIST_APPEND((struct bu_list *)_old, (struct bu_list *)_new)
646 
647 /** Dequeue "cur" partition from doubly-linked list */
648 #define DEQUEUE_PT(_cur) BU_LIST_DEQUEUE((struct bu_list *)_cur)
649 
650 /**
651  * The partition_list structure - bu_list based structure for holding
652  * ray bundles.
653  */
655  struct bu_list l;
656  struct application *ap;
658  struct seg segHeadp;
659  void * userptr;
660 };
661 
662 
663 /**
664  * Partition bundle. Passed from rt_shootrays() into user's
665  * bundle_hit() function.
666  */
668  int hits;
669  int misses;
671  struct application *ap;
672 };
673 
674 
675 /**
676  * Structures for space subdivision.
677  *
678  * cut_type is an integer for efficiency of access in rt_shootray() on
679  * non-word addressing machines.
680  *
681  * If a solid has 'pieces', it will be listed either in bn_list
682  * (initially), or in bn_piecelist, but not both.
683  */
684 struct cutnode {
685  int cn_type;
686  int cn_axis; /**< @brief 0, 1, 2 = cut along X, Y, Z */
687  fastf_t cn_point; /**< @brief cut through axis==point */
688  union cutter * cn_l; /**< @brief val < point */
689  union cutter * cn_r; /**< @brief val >= point */
690 };
691 
692 struct boxnode {
693  int bn_type;
696  struct soltab **bn_list; /**< @brief bn_list[bn_len] */
697  size_t bn_len; /**< @brief # of solids in list */
698  size_t bn_maxlen; /**< @brief # of ptrs allocated to list */
699  struct rt_piecelist *bn_piecelist; /**< @brief [] solids with pieces */
700  size_t bn_piecelen; /**< @brief # of piecelists used */
701  size_t bn_maxpiecelen; /**< @brief # of piecelists allocated */
702 };
703 
704 struct nu_axis {
705  fastf_t nu_spos; /**< @brief cell start position */
706  fastf_t nu_epos; /**< @brief cell end position */
707  fastf_t nu_width; /**< @brief voxel size (end - start) */
708 };
709 
710 struct nugridnode {
711  int nu_type;
712  struct nu_axis *nu_axis[3];
713  int nu_cells_per_axis[3]; /**< @brief number of slabs */
714  int nu_stepsize[3]; /**< @brief number of cells to jump for one step in each axis */
715  union cutter *nu_grid; /**< @brief 3-D array of boxnodes */
716 };
717 
718 #define CUT_CUTNODE 1
719 #define CUT_BOXNODE 2
720 #define CUT_NUGRIDNODE 3
721 #define CUT_MAXIMUM 3
722 union cutter {
723  int cut_type;
724  union cutter *cut_forw; /**< @brief Freelist forward link */
725  struct cutnode cn;
726  struct boxnode bn;
727  struct nugridnode nugn;
728 };
729 
730 
731 #define CUTTER_NULL ((union cutter *)0)
732 
733 /**
734  * These structures are used to manage internal resource maps.
735  * Typically these maps describe some kind of memory or file space.
736  */
737 struct mem_map {
738  struct mem_map *m_nxtp; /**< @brief Linking pointer to next element */
739  size_t m_size; /**< @brief Size of this free element */
740  off_t m_addr; /**< @brief Address of start of this element */
741 };
742 #define MAP_NULL ((struct mem_map *) 0)
743 
744 
745 /**
746  * DEPRECATED: external applications should use other LIBRT API to
747  * access database objects.
748  *
749  * The directory is organized as forward linked lists hanging off of
750  * one of RT_DBNHASH headers in the db_i structure.
751  *
752  * FIXME: this should not be public API, push container and iteration
753  * down into LIBRT. External applications should not use this.
754  */
755 #define RT_DBNHASH 8192 /**< @brief hash table is an
756  * array of linked lists with
757  * this many array pointer
758  * elements (Memory use for
759  * 32-bit: 32KB, 64-bit: 64KB)
760  */
761 
762 #if ((RT_DBNHASH)&((RT_DBNHASH)-1)) != 0
763 /**
764  * DEPRECATED: external applications should use other LIBRT API to
765  * access database objects.
766  */
767 #define RT_DBHASH(sum) ((size_t)(sum) % (RT_DBNHASH))
768 #else
769 /**
770  * DEPRECATED: external applications should use other LIBRT API to
771  * access database objects.
772  */
773 #define RT_DBHASH(sum) ((size_t)(sum) & ((RT_DBNHASH)-1))
774 #endif
775 
776 
777 /**
778  * One of these structures is used to describe each separate instance
779  * of a BRL-CAD model database ".g" file.
780  *
781  * dbi_filepath is a C-style argv array of places to search when
782  * opening related files (such as data files for EBM solids or
783  * texture-maps). The array and strings are all dynamically
784  * allocated.
785  *
786  * Note that the current working units are specified as a conversion
787  * factor to/from millimeters (they are the 'base' in local2base and
788  * base2local) because database dimensional values are always stored
789  * as millimeters (mm). The units conversion factor only affects the
790  * display and conversion of input values. This helps prevent error
791  * accumulation and improves numerical stability when calculations are
792  * made.
793  *
794  */
795 struct db_i {
796  uint32_t dbi_magic; /**< @brief magic number */
797 
798  /* THESE ELEMENTS ARE AVAILABLE FOR APPLICATIONS TO READ */
799 
800  char * dbi_filename; /**< @brief file name */
801  int dbi_read_only; /**< @brief !0 => read only file */
802  double dbi_local2base; /**< @brief local2mm */
803  double dbi_base2local; /**< @brief unit conversion factors */
804  char * dbi_title; /**< @brief title from IDENT rec */
805  char ** dbi_filepath; /**< @brief search path for aux file opens (convenience var) */
807  /* THESE ELEMENTS ARE FOR LIBRT ONLY, AND MAY CHANGE */
809  struct directory * dbi_Head[RT_DBNHASH]; /** @brief PRIVATE: object hash table */
810  FILE * dbi_fp; /**< @brief PRIVATE: standard file pointer */
811  off_t dbi_eof; /**< @brief PRIVATE: End+1 pos after db_scan() */
812  size_t dbi_nrec; /**< @brief PRIVATE: # records after db_scan() */
813  int dbi_uses; /**< @brief PRIVATE: # of uses of this struct */
814  struct mem_map * dbi_freep; /**< @brief PRIVATE: map of free granules */
815  void *dbi_inmem; /**< @brief PRIVATE: ptr to in-memory copy */
816  struct animate * dbi_anroot; /**< @brief PRIVATE: heads list of anim at root lvl */
817  struct bu_mapped_file * dbi_mf; /**< @brief PRIVATE: Only in read-only mode */
818  struct bu_ptbl dbi_clients; /**< @brief PRIVATE: List of rtip's using this db_i */
819  int dbi_version; /**< @brief PRIVATE: use db_version() */
820  struct rt_wdb * dbi_wdbp; /**< @brief PRIVATE: ptr back to containing rt_wdb */
821 };
822 #define DBI_NULL ((struct db_i *)0)
823 #define RT_CHECK_DBI(_p) BU_CKMAG(_p, DBI_MAGIC, "struct db_i")
824 #define RT_CK_DBI(_p) RT_CHECK_DBI(_p)
826 
827 /**
828  * One of these structures is allocated in memory to represent each
829  * named object in the database.
830  *
831  * Note that a d_addr of RT_DIR_PHONY_ADDR ((off_t)-1) means that
832  * database storage has not been allocated yet.
833  *
834  * Note that there is special handling for RT_DIR_INMEM "in memory"
835  * overrides.
836  *
837  * Construction should be done only by using RT_GET_DIRECTORY()
838  * Destruction should be done only by using db_dirdelete().
839  *
840  * Special note: In order to reduce the overhead of acquiring heap
841  * memory (e.g., via bu_strdup()) to stash the name in d_namep, we
842  * carry along enough storage for small names right in the structure
843  * itself (d_shortname). Thus, d_namep should never be assigned to
844  * directly, it should always be accessed using RT_DIR_SET_NAMEP() and
845  * RT_DIR_FREE_NAMEP().
846  *
847  * The in-memory name of an object should only be changed using
848  * db_rename(), so that it can be requeued on the correct linked list,
849  * based on new hash. This should be followed by rt_db_put_internal()
850  * on the object to modify the on-disk name.
851  */
852 struct directory {
853  uint32_t d_magic; /**< @brief Magic number */
854  char * d_namep; /**< @brief pointer to name string */
855  union {
856  off_t file_offset; /**< @brief disk address in obj file */
857  void *ptr; /**< @brief ptr to in-memory-only obj */
858  } d_un;
859  struct directory * d_forw; /**< @brief link to next dir entry */
860  struct animate * d_animate; /**< @brief link to animation */
861  long d_uses; /**< @brief # uses, from instancing */
862  size_t d_len; /**< @brief # of db granules used */
863  long d_nref; /**< @brief # times ref'ed by COMBs */
864  int d_flags; /**< @brief flags */
865  unsigned char d_major_type; /**< @brief object major type */
866  unsigned char d_minor_type; /**< @brief object minor type */
867  struct bu_list d_use_hd; /**< @brief heads list of uses (struct soltab l2) */
868  char d_shortname[16]; /**< @brief Stash short names locally */
869 };
870 #define RT_DIR_NULL ((struct directory *)0)
871 #define RT_CK_DIR(_dp) BU_CKMAG(_dp, RT_DIR_MAGIC, "(librt)directory")
873 #define d_addr d_un.file_offset
874 #define RT_DIR_PHONY_ADDR ((off_t)-1) /**< @brief Special marker for d_addr field */
877 /* flags for db_diradd() and friends */
878 #define RT_DIR_SOLID 0x1 /**< @brief this name is a solid */
879 #define RT_DIR_COMB 0x2 /**< @brief combination */
880 #define RT_DIR_REGION 0x4 /**< @brief region */
881 #define RT_DIR_HIDDEN 0x8 /**< @brief object name is hidden */
882 #define RT_DIR_NON_GEOM 0x10 /**< @brief object is not geometry (e.g. binary object) */
883 #define RT_DIR_USED 0x80 /**< @brief One bit, used similar to d_nref */
884 #define RT_DIR_INMEM 0x100 /**< @brief object is in memory (only) */
886 /**< @brief Args to db_lookup() */
887 #define LOOKUP_NOISY 1
888 #define LOOKUP_QUIET 0
890 #define FOR_ALL_DIRECTORY_START(_dp, _dbip) { int _i; \
891  for (_i = RT_DBNHASH-1; _i >= 0; _i--) { \
892  for ((_dp) = (_dbip)->dbi_Head[_i]; (_dp); (_dp) = (_dp)->d_forw) {
894 #define FOR_ALL_DIRECTORY_END }}}
896 #define RT_DIR_SET_NAMEP(_dp, _name) { \
897  if (strlen(_name) < sizeof((_dp)->d_shortname)) {\
898  bu_strlcpy((_dp)->d_shortname, (_name), sizeof((_dp)->d_shortname)); \
899  (_dp)->d_namep = (_dp)->d_shortname; \
900  } else { \
901  (_dp)->d_namep = bu_strdup(_name); /* Calls bu_malloc() */ \
902  } }
903 
904 
905 /**
906  * Use this macro to free the d_namep member, which is sometimes not
907  * dynamic.
908  */
909 #define RT_DIR_FREE_NAMEP(_dp) { \
910  if ((_dp)->d_namep != (_dp)->d_shortname) \
911  bu_free((_dp)->d_namep, "d_namep"); \
912  (_dp)->d_namep = NULL; }
913 
915 /**
916  * allocate and link in a new directory entry to the resource
917  * structure's freelist
918  */
919 #define RT_GET_DIRECTORY(_p, _res) { \
920  while (((_p) = (_res)->re_directory_hd) == NULL) \
921  db_alloc_directory_block(_res); \
922  (_res)->re_directory_hd = (_p)->d_forw; \
923  (_p)->d_forw = NULL; }
925 
926 /**
927  * In-memory format for database "combination" record (non-leaf node).
928  * (Regions and Groups are both a kind of Combination). Perhaps move
929  * to wdb.h or rtgeom.h?
930  */
931 struct rt_comb_internal {
932  uint32_t magic;
933  union tree * tree; /**< @brief Leading to tree_db_leaf leaves */
934  char region_flag; /**< @brief !0 ==> this COMB is a REGION */
935  char is_fastgen; /**< @brief REGION_NON_FASTGEN/_PLATE/_VOLUME */
936  /* Begin GIFT compatibility */
937  long region_id; /* DEPRECATED, use attribute */
938  long aircode; /* DEPRECATED, use attribute */
939  long GIFTmater; /* DEPRECATED, use attribute */
940  long los; /* DEPRECATED, use attribute */
941  /* End GIFT compatibility */
942  char rgb_valid; /**< @brief !0 ==> rgb[] has valid color */
943  unsigned char rgb[3];
944  float temperature; /**< @brief > 0 ==> region temperature */
945  struct bu_vls shader;
946  struct bu_vls material;
947  char inherit;
948 };
949 #define RT_CHECK_COMB(_p) BU_CKMAG(_p, RT_COMB_MAGIC, "rt_comb_internal")
950 #define RT_CK_COMB(_p) RT_CHECK_COMB(_p)
952 /**
953  * initialize an rt_comb_internal to empty.
954  */
955 #define RT_COMB_INTERNAL_INIT(_p) { \
956  (_p)->magic = RT_COMB_MAGIC; \
957  (_p)->tree = TREE_NULL; \
958  (_p)->region_flag = 0; \
959  (_p)->is_fastgen = REGION_NON_FASTGEN; \
960  (_p)->region_id = 0; \
961  (_p)->aircode = 0; \
962  (_p)->GIFTmater = 0; \
963  (_p)->los = 0; \
964  (_p)->rgb_valid = 0; \
965  (_p)->rgb[0] = 0; \
966  (_p)->rgb[1] = 0; \
967  (_p)->rgb[2] = 0; \
968  (_p)->temperature = 0.0; \
969  BU_VLS_INIT(&(_p)->shader); \
970  BU_VLS_INIT(&(_p)->material); \
971  (_p)->inherit = 0; \
972  }
973 
974 /**
975  * deinitialize an rt_comb_internal. the tree pointer is not released
976  * so callers will need to call RT_FREE_TREE() or db_free_tree()
977  * directly if a tree is set. the shader and material strings are
978  * released. the comb itself will need to be released with bu_free()
979  * unless it resides on the stack.
980  */
981 #define RT_FREE_COMB_INTERNAL(_p) { \
982  bu_vls_free(&(_p)->shader); \
983  bu_vls_free(&(_p)->material); \
984  (_p)->tree = TREE_NULL; \
985  (_p)->magic = 0; \
986  }
987 
988 
989 /**
990  * In-memory format for database uniform-array binary object. Perhaps
991  * move to wdb.h or rtgeom.h?
992  */
993 struct rt_binunif_internal {
994  uint32_t magic;
995  int type;
996  size_t count;
997  union {
998  float *flt;
999  double *dbl;
1000  char *int8;
1001  short *int16;
1002  int *int32;
1003  long *int64;
1004  unsigned char *uint8;
1005  unsigned short *uint16;
1006  unsigned int *uint32;
1007  unsigned long *uint64;
1008  } u;
1009 };
1010 #define RT_CHECK_BINUNIF(_p) BU_CKMAG(_p, RT_BINUNIF_INTERNAL_MAGIC, "rt_binunif_internal")
1011 #define RT_CK_BINUNIF(_p) RT_CHECK_BINUNIF(_p)
1013 
1014 /**
1015  * In-memory format for database "constraint" record
1016  */
1017 struct rt_constraint_internal {
1018  uint32_t magic;
1019  int id;
1020  int type;
1021  struct bu_vls expression;
1022 };
1025 #define RT_CHECK_CONSTRAINT(_p) BU_CKMAG(_p, PC_CONSTRAINT_MAGIC, "pc_constraint_internal")
1026 #define RT_CK_CONSTRAINT(_p) PC_CHECK_CONSTRAINT(_p)
1027 
1028 
1029 /**
1030  * State for database tree walker db_walk_tree() and related
1031  * user-provided handler routines.
1032  */
1033 struct db_tree_state {
1034  uint32_t magic;
1035  struct db_i * ts_dbip;
1036  int ts_sofar; /**< @brief Flag bits */
1037 
1038  int ts_regionid; /**< @brief GIFT compat region ID code*/
1039  int ts_aircode; /**< @brief GIFT compat air code */
1040  int ts_gmater; /**< @brief GIFT compat material code */
1041  int ts_los; /**< @brief equivalent LOS estimate */
1042  struct mater_info ts_mater; /**< @brief material properties */
1044  /* FIXME: ts_mat should be a matrix pointer, not a matrix */
1045  mat_t ts_mat; /**< @brief transform matrix */
1046  int ts_is_fastgen; /**< @brief REGION_NON_FASTGEN/_PLATE/_VOLUME */
1047  struct bu_attribute_value_set ts_attrs; /**< @brief attribute/value structure */
1048 
1049  int ts_stop_at_regions; /**< @brief else stop at solids */
1051  const struct db_full_path *pathp,
1052  const struct rt_comb_internal *comb,
1053  void *client_data
1054  ); /**< @brief callback during DAG downward traversal called on region nodes */
1055  union tree * (*ts_region_end_func)(struct db_tree_state *tsp,
1056  const struct db_full_path *pathp,
1057  union tree *curtree,
1058  void *client_data
1059  ); /**< @brief callback during DAG upward traversal called on region nodes */
1060  union tree * (*ts_leaf_func)(struct db_tree_state *tsp,
1061  const struct db_full_path *pathp,
1062  struct rt_db_internal *ip,
1063  void *client_data
1064  ); /**< @brief callback during DAG traversal called on leaf primitive nodes */
1065  const struct rt_tess_tol * ts_ttol; /**< @brief Tessellation tolerance */
1066  const struct bn_tol * ts_tol; /**< @brief Math tolerance */
1067  struct model ** ts_m; /**< @brief ptr to ptr to NMG "model" */
1068  struct rt_i * ts_rtip; /**< @brief Helper for rt_gettrees() */
1069  struct resource * ts_resp; /**< @brief Per-CPU data */
1070 };
1071 #define RT_DBTS_INIT_ZERO { RT_DBTS_MAGIC, NULL, 0, 0, 0, 0, 0, RT_MATER_INFO_INIT_ZERO, MAT_INIT_ZERO, 0, BU_AVS_INIT_ZERO, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
1072 /* from mged_initial_tree_state */
1073 #define RT_DBTS_INIT_IDN { RT_DBTS_MAGIC, NULL, 0, 0, 0, 0, 100, RT_MATER_INFO_INIT_IDN, MAT_INIT_IDN, 0, BU_AVS_INIT_ZERO, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
1075 #define TS_SOFAR_MINUS 1 /**< @brief Subtraction encountered above */
1076 #define TS_SOFAR_INTER 2 /**< @brief Intersection encountered above */
1077 #define TS_SOFAR_REGION 4 /**< @brief Region encountered above */
1079 #define RT_CK_DBTS(_p) BU_CKMAG(_p, RT_DBTS_MAGIC, "db_tree_state")
1081 /**
1082  * State for database traversal functions.
1083  */
1085 {
1086  uint32_t magic;
1087  struct db_i *dbip;
1088  void (*comb_enter_func) (
1089  struct db_i *,
1090  struct directory *,
1091  void *);
1092  void (*comb_exit_func) (
1093  struct db_i *,
1094  struct directory *,
1095  void *);
1096  void (*leaf_func) (
1097  struct db_i *,
1098  struct directory *,
1099  void *);
1100  struct resource *resp;
1102 };
1103 #define RT_DB_TRAVERSE_INIT(_p) {(_p)->magic = RT_DB_TRAVERSE_MAGIC; \
1104  (_p)->dbip = ((void *)0); (_p)->comb_enter_func = ((void *)0); \
1105  (_p)->comb_exit_func = ((void *)0); (_p)->leaf_func = ((void *)0); \
1106  (_p)->resp = ((void *)0); (_p)->client_data = ((void *)0);}
1107 #define RT_CK_DB_TRAVERSE(_p) BU_CKMAG(_p, RT_DB_TRAVERSE_MAGIC, "db_traverse")
1109 struct combined_tree_state {
1110  uint32_t magic;
1111  struct db_tree_state cts_s;
1113 };
1114 #define RT_CK_CTS(_p) BU_CKMAG(_p, RT_CTS_MAGIC, "combined_tree_state")
1116 /**
1117  * Binary trees representing the Boolean operations between solids.
1118  */
1119 #define MKOP(x) (x)
1120 
1121 #define OP_SOLID MKOP(1) /**< @brief Leaf: tr_stp -> solid */
1122 #define OP_UNION MKOP(2) /**< @brief Binary: L union R */
1123 #define OP_INTERSECT MKOP(3) /**< @brief Binary: L intersect R */
1124 #define OP_SUBTRACT MKOP(4) /**< @brief Binary: L subtract R */
1125 #define OP_XOR MKOP(5) /**< @brief Binary: L xor R, not both*/
1126 #define OP_REGION MKOP(6) /**< @brief Leaf: tr_stp -> combined_tree_state */
1127 #define OP_NOP MKOP(7) /**< @brief Leaf with no effect */
1128 /* Internal to library routines */
1129 #define OP_NOT MKOP(8) /**< @brief Unary: not L */
1130 #define OP_GUARD MKOP(9) /**< @brief Unary: not L, or else! */
1131 #define OP_XNOP MKOP(10) /**< @brief Unary: L, mark region */
1132 #define OP_NMG_TESS MKOP(11) /**< @brief Leaf: tr_stp -> nmgregion */
1133 /* LIBWDB import/export interface to combinations */
1134 #define OP_DB_LEAF MKOP(12) /**< @brief Leaf of combination, db fmt */
1135 #define OP_FREE MKOP(13) /**< @brief Unary: L has free chain */
1137 union tree {
1138  uint32_t magic; /**< @brief First word: magic number */
1139  /* Second word is always OP code */
1140  struct tree_node {
1141  uint32_t magic;
1142  int tb_op; /**< @brief non-leaf */
1143  struct region *tb_regionp; /**< @brief ptr to containing region */
1144  union tree *tb_left;
1145  union tree *tb_right;
1146  } tr_b;
1147  struct tree_leaf {
1148  uint32_t magic;
1149  int tu_op; /**< @brief leaf, OP_SOLID */
1150  struct region *tu_regionp; /**< @brief ptr to containing region */
1151  struct soltab *tu_stp;
1152  } tr_a;
1153  struct tree_cts {
1154  uint32_t magic;
1155  int tc_op; /**< @brief leaf, OP_REGION */
1156  struct region *tc_pad; /**< @brief unused */
1157  struct combined_tree_state *tc_ctsp;
1158  } tr_c;
1160  uint32_t magic;
1161  int td_op; /**< @brief leaf, OP_NMG_TESS */
1162  const char *td_name; /**< @brief If non-null, dynamic string describing heritage of this region */
1163  struct nmgregion *td_r; /**< @brief ptr to NMG region */
1164  } tr_d;
1165  struct tree_db_leaf {
1166  uint32_t magic;
1167  int tl_op; /**< @brief leaf, OP_DB_LEAF */
1168  matp_t tl_mat; /**< @brief xform matp, NULL ==> identity */
1169  char *tl_name; /**< @brief Name of this leaf (bu_strdup'ed) */
1170  } tr_l;
1171 };
1172 /* Things which are in the same place in both A & B structures */
1173 #define tr_op tr_a.tu_op
1174 #define tr_regionp tr_a.tu_regionp
1175 
1176 #define TREE_NULL ((union tree *)0)
1177 #define RT_CK_TREE(_p) BU_CKMAG(_p, RT_TREE_MAGIC, "union tree")
1179 /**
1180  * initialize a union tree to zero without a node operation set. Use
1181  * the largest union so all values are effectively zero except for the
1182  * magic number.
1183  */
1184 #define RT_TREE_INIT(_p) { \
1185  (_p)->magic = RT_TREE_MAGIC; \
1186  (_p)->tr_b.tb_op = 0; \
1187  (_p)->tr_b.tb_regionp = NULL; \
1188  (_p)->tr_b.tb_left = NULL; \
1189  (_p)->tr_b.tb_right = NULL; \
1190  }
1191 
1192 /**
1193  * RT_GET_TREE returns a new initialized tree union pointer. The
1194  * magic number is set to RT_TREE_MAGIC and all other members are
1195  * zero-initialized.
1196  *
1197  * This is a malloc-efficient BU_ALLOC(tp, union tree) replacement.
1198  * Previously used tree nodes are stored in the provided resource
1199  * pointer (during RT_FREE_TREE) as a single-linked list using the
1200  * tb_left field. Requests for new nodes are pulled first from that
1201  * list or allocated fresh if needed.
1202  *
1203  * DEPRECATED, use BU_GET()
1204  */
1205 #define RT_GET_TREE(_tp, _res) { \
1206  if (((_tp) = (_res)->re_tree_hd) != TREE_NULL) { \
1207  (_res)->re_tree_hd = (_tp)->tr_b.tb_left; \
1208  (_tp)->tr_b.tb_left = TREE_NULL; \
1209  (_res)->re_tree_get++; \
1210  } else { \
1211  BU_ALLOC(_tp, union tree); \
1212  (_res)->re_tree_malloc++; \
1213  } \
1214  RT_TREE_INIT((_tp)); \
1215  }
1216 
1217 /**
1218  * RT_FREE_TREE deinitializes a tree union pointer.
1219  *
1220  * This is a malloc-efficient replacement for bu_free(tp). Instead of
1221  * actually freeing the nodes, they are added to a single-linked list
1222  * in rt_tree_hd down the tb_left field. Requests for new nodes (via
1223  * RT_GET_TREE()) pull from this list instead of allocating new nodes.
1224  *
1225  * DEPRECATED, use BU_PUT()
1226  */
1227 #define RT_FREE_TREE(_tp, _res) { \
1228  (_tp)->magic = 0; \
1229  (_tp)->tr_b.tb_left = (_res)->re_tree_hd; \
1230  (_tp)->tr_b.tb_right = TREE_NULL; \
1231  (_res)->re_tree_hd = (_tp); \
1232  (_tp)->tr_b.tb_op = OP_FREE; \
1233  (_res)->re_tree_free++; \
1234  }
1235 
1236 
1237 /**
1238  * flattened version of the union tree
1239  */
1240 struct rt_tree_array
1241 {
1242  union tree *tl_tree;
1243  int tl_op;
1244 };
1246 
1247 #define TREE_LIST_NULL ((struct tree_list *)0)
1249 /* FIXME: this is a dubious define that should be removed */
1250 #define RT_MAXLINE 10240
1251 
1252 /**
1253  * This data structure is at the core of the "LIBWDB" support for
1254  * allowing application programs to read and write BRL-CAD databases.
1255  * Many different access styles are supported.
1256  */
1257 
1258 struct rt_wdb {
1259  struct bu_list l;
1260  int type;
1261  struct db_i * dbip;
1262  struct db_tree_state wdb_initial_tree_state;
1264  struct bn_tol wdb_tol;
1267  /* variables for name prefixing */
1271 
1272  /* default region ident codes for this particular database. */
1273  int wdb_item_default;/**< @brief GIFT region ID */
1275  int wdb_mat_default;/**< @brief GIFT material code */
1276  int wdb_los_default;/**< @brief Line-of-sight estimate */
1277 
1278  /* These members are marked for removal */
1279  struct bu_vls wdb_name; /**< @brief database object name */
1281  Tcl_Interp * wdb_interp;
1282 
1283 };
1286 #define RT_CHECK_WDB(_p) BU_CKMAG(_p, RT_WDB_MAGIC, "rt_wdb")
1287 #define RT_CK_WDB(_p) RT_CHECK_WDB(_p)
1288 #define RT_WDB_INIT_ZERO { {RT_WDB_MAGIC, BU_LIST_NULL, BU_LIST_NULL}, 0, NULL, RT_DBTS_INIT_ZERO, RT_TESS_TOL_INIT_ZERO, BN_TOL_INIT_ZERO, NULL, BU_VLS_INIT_ZERO, 0, 0, 0, 0, 0, 0, BU_VLS_INIT_ZERO, BU_OBSERVER_INIT_ZERO, NULL }
1289 #define RT_WDB_NULL ((struct rt_wdb *)NULL)
1290 #define RT_WDB_TYPE_DB_DISK 2
1291 #define RT_WDB_TYPE_DB_DISK_APPEND_ONLY 3
1292 #define RT_WDB_TYPE_DB_INMEM 4
1293 #define RT_WDB_TYPE_DB_INMEM_APPEND_ONLY 5
1296 #define RT_MINVIEWSIZE 0.0001
1297 #define RT_MINVIEWSCALE 0.00005
1299 /**
1300  * Each one of these structures specifies an arc in the tree that is
1301  * to be operated on for animation purposes. More than one animation
1302  * operation may be applied at any given arc. The directory structure
1303  * points to a linked list of animate structures (built by
1304  * rt_anim_add()), and the operations are processed in the order
1305  * given.
1306  */
1307 struct anim_mat {
1308  int anm_op; /**< @brief ANM_RSTACK, ANM_RARC... */
1309  mat_t anm_mat; /**< @brief Matrix */
1310 };
1311 #define ANM_RSTACK 1 /**< @brief Replace stacked matrix */
1312 #define ANM_RARC 2 /**< @brief Replace arc matrix */
1313 #define ANM_LMUL 3 /**< @brief Left (root side) mul */
1314 #define ANM_RMUL 4 /**< @brief Right (leaf side) mul */
1315 #define ANM_RBOTH 5 /**< @brief Replace stack, arc=Idn */
1318  uint32_t magic;
1319  int anp_op; /**< @brief RT_ANP_REPLACE, etc. */
1320  struct bu_vls anp_shader; /**< @brief Update string */
1321 };
1322 #define RT_ANP_REPLACE 1 /**< @brief Replace shader string */
1323 #define RT_ANP_APPEND 2 /**< @brief Append to shader string */
1324 #define RT_CK_ANP(_p) BU_CKMAG((_p), RT_ANP_MAGIC, "rt_anim_property")
1326 struct rt_anim_color {
1327  int anc_rgb[3]; /**< @brief New color */
1328 };
1330 
1331 struct animate {
1332  uint32_t magic; /**< @brief magic number */
1333  struct animate * an_forw; /**< @brief forward link */
1334  struct db_full_path an_path; /**< @brief (sub)-path pattern */
1335  int an_type; /**< @brief AN_MATRIX, AN_COLOR... */
1337  struct anim_mat anu_m;
1340  float anu_t;
1341  } an_u;
1342 };
1343 #define RT_AN_MATRIX 1 /**< @brief Matrix animation */
1344 #define RT_AN_MATERIAL 2 /**< @brief Material property anim */
1345 #define RT_AN_COLOR 3 /**< @brief Material color anim */
1346 #define RT_AN_SOLID 4 /**< @brief Solid parameter anim */
1347 #define RT_AN_TEMPERATURE 5 /**< @brief Region temperature */
1349 #define ANIM_NULL ((struct animate *)0)
1350 #define RT_CK_ANIMATE(_p) BU_CKMAG((_p), ANIMATE_MAGIC, "animate")
1352 /**
1353  * Support for variable length arrays of "struct hit". Patterned
1354  * after the libbu/ptbl.c idea.
1355  */
1356 struct rt_htbl {
1357  struct bu_list l; /**< @brief linked list for caller's use */
1358  size_t end; /**< @brief index of first available location */
1359  size_t blen; /**< @brief # of struct's of storage at *hits */
1360  struct hit * hits; /**< @brief hits[blen] data storage area */
1361 };
1362 #define RT_CK_HTBL(_p) BU_CKMAG(_p, RT_HTBL_MAGIC, "rt_htbl")
1364 /**
1365  * Holds onto memory re-used by rt_shootray() from shot to shot. One
1366  * of these for each solid which uses pieces. There is a separate
1367  * array of these for each cpu. Storage for the bit vectors is
1368  * pre-allocated at prep time. The array is subscripted by
1369  * st_piecestate_num. The bit vector is subscripted by values found
1370  * in rt_piecelist pieces[].
1371  */
1372 struct rt_piecestate {
1373  uint32_t magic;
1374  long ray_seqno; /**< @brief res_nshootray */
1375  struct soltab * stp;
1376  struct bu_bitv * shot;
1377  fastf_t mindist; /**< @brief dist ray enters solids bounding volume */
1378  fastf_t maxdist; /**< @brief dist ray leaves solids bounding volume */
1379  struct rt_htbl htab; /**< @brief accumulating hits here */
1380  const union cutter *cutp; /**< @brief current bounding volume */
1381 };
1382 #define RT_CK_PIECESTATE(_p) BU_CKMAG(_p, RT_PIECESTATE_MAGIC, "struct rt_piecestate")
1384 /**
1385  * For each space partitioning cell, there is one of these for each
1386  * solid in that cell which uses pieces. Storage for the array is
1387  * allocated at cut time, and never changes.
1388  *
1389  * It is expected that the indices allocated by any solid range from
1390  * 0..(npieces-1).
1391  *
1392  * The piece indices are used as a subscript into a solid-specific
1393  * table, and also into the 'shot' bitv of the corresponding
1394  * rt_piecestate.
1395  *
1396  * The values (subscripts) in pieces[] are specific to a single solid
1397  * (stp).
1398  */
1399 struct rt_piecelist {
1400  uint32_t magic;
1401  size_t npieces; /**< @brief number of pieces in pieces[] array */
1402  long *pieces; /**< @brief pieces[npieces], piece indices */
1403  struct soltab *stp; /**< @brief ref back to solid */
1404 };
1405 #define RT_CK_PIECELIST(_p) BU_CKMAG(_p, RT_PIECELIST_MAGIC, "struct rt_piecelist")
1407 /* Used to set globals declared in bot.c */
1408 #define RT_DEFAULT_MINPIECES 32
1409 #define RT_DEFAULT_TRIS_PER_PIECE 4
1410 #define RT_DEFAULT_MINTIE 0 /* TODO: find the best value */
1411 
1412 /**
1413  * Per-CPU statistics and resources.
1414  *
1415  * One of these structures is needed per thread of execution, usually
1416  * with calling applications creating an array with at least MAX_PSW
1417  * elements. To prevent excessive competition for free structures,
1418  * memory is now allocated on a per-processor basis. The application
1419  * structure a_resource element specifies the resource structure to be
1420  * used; if uniprocessing, a null a_resource pointer results in using
1421  * the internal global structure (&rt_uniresource), making initial
1422  * application development simpler.
1423  *
1424  * Note that if multiple models are being used, the partition and bitv
1425  * structures (which are variable length) will require there to be
1426  * ncpus * nmodels resource structures, the selection of which will be
1427  * the responsibility of the application.
1428  *
1429  * Applications are responsible for calling rt_init_resource() on each
1430  * resource structure before letting LIBRT use them.
1431  *
1432  * Per-processor statistics are initially collected in here, and then
1433  * posted to rt_i by rt_add_res_stats().
1434  */
1435 struct resource {
1436  uint32_t re_magic; /**< @brief Magic number */
1437  int re_cpu; /**< @brief processor number, for ID */
1438  struct bu_list re_seg; /**< @brief Head of segment freelist */
1439  struct bu_ptbl re_seg_blocks; /**< @brief Table of malloc'ed blocks of segs */
1443  struct bu_list re_parthead; /**< @brief Head of freelist */
1447  struct bu_list re_solid_bitv; /**< @brief head of freelist */
1448  struct bu_list re_region_ptbl; /**< @brief head of freelist */
1449  struct bu_list re_nmgfree; /**< @brief head of NMG hitmiss freelist */
1450  union tree ** re_boolstack; /**< @brief Stack for rt_booleval() */
1451  long re_boolslen; /**< @brief # elements in re_boolstack[] */
1452  float * re_randptr; /**< @brief ptr into random number table */
1453  /* Statistics. Only for examination by rt_add_res_stats() */
1454  long re_nshootray; /**< @brief Calls to rt_shootray() */
1455  long re_nmiss_model; /**< @brief Rays pruned by model RPP */
1456  /* Solid nshots = shot_hit + shot_miss */
1457  long re_shots; /**< @brief # calls to ft_shot() */
1458  long re_shot_hit; /**< @brief ft_shot() returned a miss */
1459  long re_shot_miss; /**< @brief ft_shot() returned a hit */
1460  /* Optimizations. Rays not shot at solids */
1461  long re_prune_solrpp;/**< @brief shot missed solid RPP, ft_shot skipped */
1462  long re_ndup; /**< @brief ft_shot() calls skipped for already-ft_shot() solids */
1463  long re_nempty_cells; /**< @brief number of empty NUgrid cells passed through */
1464  /* Data for accelerating "pieces" of solids */
1465  struct rt_piecestate *re_pieces; /**< @brief array [rti_nsolids_with_pieces] */
1466  long re_piece_ndup; /**< @brief ft_piece_shot() calls skipped for already-ft_shot() solids */
1467  long re_piece_shots; /**< @brief # calls to ft_piece_shot() */
1468  long re_piece_shot_hit; /**< @brief ft_piece_shot() returned a miss */
1469  long re_piece_shot_miss; /**< @brief ft_piece_shot() returned a hit */
1470  struct bu_ptbl re_pieces_pending; /**< @brief pieces with an odd hit pending */
1471  /* Per-processor cache of tree unions, to accelerate "tops" and treewalk */
1472  union tree * re_tree_hd; /**< @brief Head of free trees */
1476  struct directory * re_directory_hd;
1477  struct bu_ptbl re_directory_blocks; /**< @brief Table of malloc'ed blocks */
1478 };
1480 /**
1481  * Resources for uniprocessor
1482  */
1483 RT_EXPORT extern struct resource rt_uniresource; /**< @brief default. Defined in librt/globals.c */
1484 #define RESOURCE_NULL ((struct resource *)0)
1485 #define RT_CK_RESOURCE(_p) BU_CKMAG(_p, RESOURCE_MAGIC, "struct resource")
1486 #define RT_RESOURCE_INIT_ZERO { RESOURCE_MAGIC, 0, BU_LIST_INIT_ZERO, BU_PTBL_INIT_ZERO, 0, 0, 0, BU_LIST_INIT_ZERO, 0, 0, 0, BU_LIST_INIT_ZERO, BU_LIST_INIT_ZERO, BU_LIST_INIT_ZERO, NULL, 0, NULL, 0, 0, 0, 0, 0, 0, 0, 0, NULL, 0, 0, 0, 0, BU_PTBL_INIT_ZERO, NULL, 0, 0, 0, NULL, BU_PTBL_INIT_ZERO }
1487 
1488 
1489 /**
1490  * Structure used by the "reprep" routines
1491  */
1492 struct rt_reprep_obj_list {
1493  size_t ntopobjs; /**< @brief number of objects in the original call to gettrees */
1494  char **topobjs; /**< @brief list of the above object names */
1495  size_t nunprepped; /**< @brief number of objects to be unprepped and re-prepped */
1496  char **unprepped; /**< @brief list of the above objects */
1497  /* Above here must be filled in by application */
1498  /* Below here is used by dynamic geometry routines, should be zeroed by application before use */
1499  struct bu_ptbl paths; /**< @brief list of all paths from topobjs to unprepped objects */
1500  struct db_tree_state **tsp; /**< @brief tree state used by tree walker in "reprep" routines */
1501  struct bu_ptbl unprep_regions; /**< @brief list of region structures that will be "unprepped" */
1502  size_t old_nsolids; /**< @brief rtip->nsolids before unprep */
1503  size_t old_nregions; /**< @brief rtip->nregions before unprep */
1504  size_t nsolids_unprepped; /**< @brief number of soltab structures eliminated by unprep */
1505  size_t nregions_unprepped; /**< @brief number of region structures eliminated by unprep */
1506 };
1509 /**
1510  * This structure is intended to describe the area and/or volume
1511  * represented by a ray. In the case of the "rt" program it
1512  * represents the extent in model coordinates of the prism behind the
1513  * pixel being rendered.
1514  *
1515  * The r_pt values of the rays indicate the dimensions and location in
1516  * model space of the ray origin (usually the pixel to be rendered).
1517  * The r_dir vectors indicate the edges (and thus the shape) of the
1518  * prism which is formed from the projection of the pixel into space.
1519  */
1520 #define CORNER_PTS 4
1521 struct pixel_ext {
1522  uint32_t magic;
1523  struct xray corner[CORNER_PTS];
1524 };
1525 /* This should have had an RT_ prefix */
1526 #define BU_CK_PIXEL_EXT(_p) BU_CKMAG(_p, PIXEL_EXT_MAGIC, "struct pixel_ext")
1528 /**
1529  * This structure is the only parameter to rt_shootray(). The entire
1530  * structure should be zeroed (e.g. by memset) before it is used the
1531  * first time.
1532  *
1533  * When calling rt_shootray(), these fields are mandatory:
1534  *
1535  * - a_ray.r_pt Starting point of ray to be fired
1536  * - a_ray.r_dir UNIT VECTOR with direction to fire in (dir cosines)
1537  * - a_hit() Routine to call when something is hit
1538  * - a_miss() Routine to call when ray misses everything
1539  * - a_rt_i Must be set to the value returned by rt_dirbuild().
1540  *
1541  * In addition, these fields are used by the library. If they are set
1542  * to zero, default behavior will be used.
1543  *
1544  * - a_resource Pointer to CPU-specific resources. Multi-CPU only.
1545  * - a_overlap() DEPRECATED, set a_multioverlap() instead.
1546  * If non-null, this routine will be called to
1547  * handle overlap conditions. See librt/bool.c
1548  * for calling sequence.
1549  * Return of 0 eliminates partition with overlap entirely
1550  * Return of !0 retains one partition in output
1551  * - a_multioverlap() Called when two or more regions overlap in a partition.
1552  * Default behavior used if pointer not set.
1553  * See librt/bool.c for calling sequence.
1554  * - a_level Printed by librt on errors, but otherwise not used.
1555  * - a_x Printed by librt on errors, but otherwise not used.
1556  * - a_y Printed by librt on errors, but otherwise not used.
1557  * - a_purpose Printed by librt on errors, but otherwise not used.
1558  * - a_rbeam Used to compute beam coverage on geometry,
1559  * - a_diverge for spline subdivision & many UV mappings.
1560  *
1561  * Note that rt_shootray() returns the (int) return of the
1562  * a_hit()/a_miss() function called, as well as placing it in
1563  * a_return. A future "multiple rays at a time" interface will only
1564  * provide a_return.
1565  *
1566  * Note that the organization of this structure, and the details of
1567  * the non-mandatory elements are subject to change in every release.
1568  * Therefore, rather than using compile-time structure
1569  * initialization, you should create a zeroed-out structure, and then
1570  * assign the intended values at runtime. A zeroed structure can be
1571  * obtained at compile time with "static struct application
1572  * zero_ap;", or at run time by using memset(), bu_calloc(), or
1573  * BU_ALLOC().
1574  */
1575 struct application {
1576  uint32_t a_magic;
1577  /* THESE ELEMENTS ARE MANDATORY */
1578  struct xray a_ray; /**< @brief Actual ray to be shot */
1579  int (*a_hit)(struct application *, struct partition *, struct seg *); /**< @brief called when shot hits model */
1580  int (*a_miss)(struct application *); /**< @brief called when shot misses */
1581  int a_onehit; /**< @brief flag to stop on first hit */
1582  fastf_t a_ray_length; /**< @brief distance from ray start to end intersections */
1583  struct rt_i * a_rt_i; /**< @brief this librt instance */
1584  int a_zero1; /**< @brief must be zero (sanity check) */
1585  /* THESE ELEMENTS ARE USED BY THE LIBRARY, BUT MAY BE LEFT ZERO */
1586  struct resource * a_resource; /**< @brief dynamic memory resources */
1587  int (*a_overlap)(struct application *, struct partition *, struct region *, struct region *, struct partition *); /**< @brief DEPRECATED */
1588  void (*a_multioverlap)(struct application *, struct partition *, struct bu_ptbl *, struct partition *); /**< @brief called to resolve overlaps */
1589  void (*a_logoverlap)(struct application *, const struct partition *, const struct bu_ptbl *, const struct partition *); /**< @brief called to log overlaps */
1590  int a_level; /**< @brief recursion level (for printing) */
1591  int a_x; /**< @brief Screen X of ray, if applicable */
1592  int a_y; /**< @brief Screen Y of ray, if applicable */
1593  const char * a_purpose; /**< @brief Debug string: purpose of ray */
1594  fastf_t a_rbeam; /**< @brief initial beam radius (mm) */
1595  fastf_t a_diverge; /**< @brief slope of beam divergence/mm */
1596  int a_return; /**< @brief Return of a_hit()/a_miss() */
1597  int a_no_booleans; /**< @brief 1= partitions==segs, no booleans */
1598  char ** attrs; /**< @brief null terminated list of attributes
1599  * This list should be the same as passed to
1600  * rt_gettrees_and_attrs() */
1601  int a_bot_reverse_normal_disabled; /**< @brief 1= no bot normals get reversed in BOT_UNORIENTED_NORM */
1602  /* THESE ELEMENTS ARE USED BY THE PROGRAM "rt" AND MAY BE USED BY */
1603  /* THE LIBRARY AT SOME FUTURE DATE */
1604  /* AT THIS TIME THEY MAY BE LEFT ZERO */
1605  struct pixel_ext * a_pixelext; /**< @brief locations of pixel corners */
1606  /* THESE ELEMENTS ARE WRITTEN BY THE LIBRARY, AND MAY BE READ IN a_hit() */
1607  struct seg * a_finished_segs_hdp;
1608  struct partition * a_Final_Part_hdp;
1609  vect_t a_inv_dir; /**< @brief filled in by rt_shootray(), inverse of ray direction cosines */
1610  /* THE FOLLOWING ELEMENTS ARE MAINLINE & APPLICATION SPECIFIC. */
1611  /* THEY ARE NEVER EXAMINED BY THE LIBRARY. */
1612  int a_user; /**< @brief application-specific value */
1613  void * a_uptr; /**< @brief application-specific pointer */
1614  struct bn_tabdata * a_spectrum; /**< @brief application-specific bn_tabdata pointer */
1615  fastf_t a_color[3]; /**< @brief application-specific color */
1616  fastf_t a_dist; /**< @brief application-specific distance */
1617  vect_t a_uvec; /**< @brief application-specific vector */
1618  vect_t a_vvec; /**< @brief application-specific vector */
1619  fastf_t a_refrac_index; /**< @brief current index of refraction */
1620  fastf_t a_cumlen; /**< @brief cumulative length of ray */
1621  int a_flag; /**< @brief application-specific flag */
1622  int a_zero2; /**< @brief must be zero (sanity check) */
1623 };
1626 /**
1627  * This structure is the only parameter to rt_shootrays(). The entire
1628  * structure should be zeroed (e.g. by memset) before it is used the
1629  * first time.
1630  *
1631  * When calling rt_shootrays(), these fields are mandatory:
1632  *
1633  * - b_ap Members in this single ray application structure should
1634  * be set in a similar fashion as when used with
1635  * rt_shootray() with the exception of a_hit() and
1636  * a_miss(). Default implementations of these routines
1637  * are provided that simple update hit/miss counters and
1638  * attach the hit partitions and segments to the
1639  * partition_bundle structure. Users can still override
1640  * this default functionality but have to make sure to
1641  * move the partition and segment list to the new
1642  * partition_bundle structure.
1643  * - b_hit() Routine to call when something is hit by the ray bundle.
1644  * - b_miss() Routine to call when ray bundle misses everything.
1645  *
1646  * Note that rt_shootrays() returns the (int) return of the
1647  * b_hit()/b_miss() function called, as well as placing it in
1648  * b_return.
1649  *
1650  * An integer field b_user and a void *field b_uptr are provided in
1651  * the structure for custom user data.
1652  */
1653 struct application_bundle
1654 {
1655  uint32_t b_magic;
1656  /* THESE ELEMENTS ARE MANDATORY */
1657  struct xrays b_rays; /**< @brief Actual bundle of rays to be shot */
1658  struct application b_ap; /**< @brief application setting to be applied to each ray */
1659  int (*b_hit)(struct application_bundle *, struct partition_bundle *); /**< @brief called when bundle hits model */
1660  int (*b_miss)(struct application_bundle *); /**< @brief called when entire bundle misses */
1661  int b_user; /**< @brief application_bundle-specific value */
1662  void *b_uptr; /**< @brief application_bundle-specific pointer */
1664 };
1667 #define RT_APPLICATION_NULL ((struct application *)0)
1668 #define RT_AFN_NULL ((int (*)(struct application *, struct partition *, struct region *, struct region *, struct partition *))NULL)
1669 #define RT_CK_AP(_p) BU_CKMAG(_p, RT_AP_MAGIC, "struct application")
1670 #define RT_CK_APPLICATION(_p) BU_CKMAG(_p, RT_AP_MAGIC, "struct application")
1671 #define RT_APPLICATION_INIT(_p) { \
1672  memset((char *)(_p), 0, sizeof(struct application)); \
1673  (_p)->a_magic = RT_AP_MAGIC; \
1674  }
1677 #ifdef NO_BOMBING_MACROS
1678 # define RT_AP_CHECK(_ap) BU_IGNORE((_ap))
1679 #else
1680 # define RT_AP_CHECK(_ap) \
1681  {if ((_ap)->a_zero1||(_ap)->a_zero2) \
1682  bu_bomb("corrupt application struct"); }
1683 #endif
1684 
1685 /**
1686  * Definitions for librt.a which are global to the library regardless
1687  * of how many different models are being worked on
1688  */
1689 struct rt_g {
1690  uint32_t debug; /**< @brief !0 for debug, see librt/debug.h */
1691  /* DEPRECATED: rtg_parallel is not used by LIBRT any longer (and will be removed) */
1692  int8_t rtg_parallel; /**< @brief !0 = trying to use multi CPUs */
1693  struct bu_list rtg_vlfree; /**< @brief head of bn_vlist freelist */
1694  uint32_t NMG_debug; /**< @brief debug bits for NMG's see nmg.h */
1695  struct rt_wdb rtg_headwdb; /**< @brief head of database object list */
1696 };
1697 #define RT_G_INIT_ZERO { 0, 0, BU_LIST_INIT_ZERO, 0, RT_WDB_INIT_ZERO }
1700 /**
1701  * global ray-trace geometry state
1702  */
1703 RT_EXPORT extern struct rt_g RTG;
1704 
1705 /* Normally set when in production mode, setting the RT_G_DEBUG define
1706  * to 0 will allow chucks of code to poof away at compile time (since
1707  * they are truth-functionally constant (false)) This can boost
1708  * raytrace performance considerably (~10%).
1709  */
1710 #ifdef NO_DEBUG_CHECKING
1711 # define RT_G_DEBUG 0
1712 #else
1713 # define RT_G_DEBUG RTG.debug
1714 #endif
1715 
1716 /**
1717  * Definition of global parallel-processing semaphores.
1718  *
1719  * res_syscall is now BU_SEM_SYSCALL
1720  */
1721 #define RT_SEM_TREE0 (BU_SEM_LAST)
1722 #define RT_SEM_TREE1 (RT_SEM_TREE0+1)
1723 #define RT_SEM_TREE2 (RT_SEM_TREE1+1)
1724 #define RT_SEM_TREE3 (RT_SEM_TREE2+1)
1725 #define RT_SEM_WORKER (RT_SEM_TREE3+1)
1726 #define RT_SEM_STATS (RT_SEM_WORKER+1)
1727 #define RT_SEM_RESULTS (RT_SEM_STATS+1)
1728 #define RT_SEM_MODEL (RT_SEM_RESULTS+1)
1730 #define RT_SEM_LAST (RT_SEM_MODEL+1)
1733 /**
1734  * This structure keeps track of almost everything for ray-tracing
1735  * support: Regions, primitives, model bounding box, statistics.
1736  *
1737  * Definitions for librt which are specific to the particular model
1738  * being processed, one copy for each model. Initially, a pointer to
1739  * this is returned from rt_dirbuild().
1740  *
1741  * During gettree processing, the most time consuming step is
1742  * searching the list of existing solids to see if a new solid is
1743  * actually an identical instance of a previous solid. Therefore, the
1744  * list has been divided into several lists. The same macros & hash
1745  * value that accesses the dbi_Head[] array are used here. The hash
1746  * value is computed by db_dirhash().
1747  */
1748 struct rt_i {
1749  uint32_t rti_magic; /**< @brief magic # for integrity check */
1750  /* THESE ITEMS ARE AVAILABLE FOR APPLICATIONS TO READ & MODIFY */
1751  int useair; /**< @brief 1="air" regions are retained while prepping */
1752  int rti_save_overlaps; /**< @brief 1=fill in pt_overlap_reg, change boolweave behavior */
1753  int rti_dont_instance; /**< @brief 1=Don't compress instances of solids into 1 while prepping */
1754  int rti_hasty_prep; /**< @brief 1=hasty prep, slower ray-trace */
1755  int rti_nlights; /**< @brief number of light sources */
1756  int rti_prismtrace; /**< @brief add support for pixel prism trace */
1757  char * rti_region_fix_file; /**< @brief rt_regionfix() file or NULL */
1758  int rti_space_partition; /**< @brief space partitioning method */
1759  int rti_nugrid_dimlimit; /**< @brief limit on nugrid dimensions */
1760  struct bn_tol rti_tol; /**< @brief Math tolerances for this model */
1761  struct rt_tess_tol rti_ttol; /**< @brief Tessellation tolerance defaults */
1762  fastf_t rti_max_beam_radius; /**< @brief Max threat radius for FASTGEN cline solid */
1763  /* THESE ITEMS ARE AVAILABLE FOR APPLICATIONS TO READ */
1764  point_t mdl_min; /**< @brief min corner of model bounding RPP */
1765  point_t mdl_max; /**< @brief max corner of model bounding RPP */
1766  point_t rti_pmin; /**< @brief for plotting, min RPP */
1767  point_t rti_pmax; /**< @brief for plotting, max RPP */
1768  double rti_radius; /**< @brief radius of model bounding sphere */
1769  struct db_i * rti_dbip; /**< @brief prt to Database instance struct */
1770  /* THESE ITEMS SHOULD BE CONSIDERED OPAQUE, AND SUBJECT TO CHANGE */
1771  int needprep; /**< @brief needs rt_prep */
1772  struct region ** Regions; /**< @brief ptrs to regions [reg_bit] */
1773  struct bu_list HeadRegion; /**< @brief ptr of list of regions in model */
1774  void * Orca_hash_tbl; /**< @brief Hash table in matrices for ORCA */
1775  struct bu_ptbl delete_regs; /**< @brief list of region pointers to delete after light_init() */
1776  /* Ray-tracing statistics */
1777  size_t nregions; /**< @brief total # of regions participating */
1778  size_t nsolids; /**< @brief total # of solids participating */
1779  size_t rti_nrays; /**< @brief # calls to rt_shootray() */
1780  size_t nmiss_model; /**< @brief rays missed model RPP */
1781  size_t nshots; /**< @brief # of calls to ft_shot() */
1782  size_t nmiss; /**< @brief solid ft_shot() returned a miss */
1783  size_t nhits; /**< @brief solid ft_shot() returned a hit */
1784  size_t nmiss_tree; /**< @brief shots missed sub-tree RPP */
1785  size_t nmiss_solid; /**< @brief shots missed solid RPP */
1786  size_t ndup; /**< @brief duplicate shots at a given solid */
1787  size_t nempty_cells; /**< @brief number of empty NUgrid cells */
1788  union cutter rti_CutHead; /**< @brief Head of cut tree */
1789  union cutter rti_inf_box; /**< @brief List of infinite solids */
1790  union cutter * rti_CutFree; /**< @brief cut Freelist */
1791  struct bu_ptbl rti_busy_cutter_nodes; /**< @brief List of "cutter" mallocs */
1793  int rti_cut_maxlen; /**< @brief max len RPP list in 1 cut bin */
1794  int rti_ncut_by_type[CUT_MAXIMUM+1]; /**< @brief number of cuts by type */
1795  int rti_cut_totobj; /**< @brief # objs in all bins, total */
1796  int rti_cut_maxdepth;/**< @brief max depth of cut tree */
1800  int rti_air_discards;/**< @brief # of air regions discarded */
1801  struct bu_hist rti_hist_cellsize; /**< @brief occupancy of cut cells */
1802  struct bu_hist rti_hist_cell_pieces; /**< @brief solid pieces per cell */
1803  struct bu_hist rti_hist_cutdepth; /**< @brief depth of cut tree */
1804  struct soltab ** rti_Solids; /**< @brief ptrs to soltab [st_bit] */
1805  struct bu_list rti_solidheads[RT_DBNHASH]; /**< @brief active solid lists */
1806  struct bu_ptbl rti_resources; /**< @brief list of 'struct resource's encountered */
1807  double rti_nu_gfactor; /**< @brief constant in numcells computation */
1808  size_t rti_cutlen; /**< @brief goal for # solids per boxnode */
1809  size_t rti_cutdepth; /**< @brief goal for depth of NUBSPT cut tree */
1810  /* Parameters required for rt_submodel */
1811  char * rti_treetop; /**< @brief bu_strduped, for rt_submodel rti's only */
1812  size_t rti_uses; /**< @brief for rt_submodel */
1813  /* Parameters for accelerating "pieces" of solids */
1814  size_t rti_nsolids_with_pieces; /**< @brief # solids using pieces */
1815  /* Parameters for dynamic geometry */
1818 };
1820 
1821 #define RT_NU_GFACTOR_DEFAULT 1.5 /**< @brief see rt_cut_it() for a description
1822  of this */
1823 
1824 #define RTI_NULL ((struct rt_i *)0)
1825 
1826 #define RT_CHECK_RTI(_p) BU_CKMAG(_p, RTI_MAGIC, "struct rt_i")
1827 #define RT_CK_RTI(_p) RT_CHECK_RTI(_p)
1828 
1829 #define RT_PART_NUBSPT 0
1830 #define RT_PART_NUGRID 1
1831 
1832 /**
1833  * Macros to painlessly visit all the active solids. Serving suggestion:
1834  *
1835  * RT_VISIT_ALL_SOLTABS_START(stp, rtip) {
1836  * rt_pr_soltab(stp);
1837  * } RT_VISIT_ALL_SOLTABS_END
1838  */
1839 #define RT_VISIT_ALL_SOLTABS_START(_s, _rti) { \
1840  register struct bu_list *_head = &((_rti)->rti_solidheads[0]); \
1841  for (; _head < &((_rti)->rti_solidheads[RT_DBNHASH]); _head++) \
1842  for (BU_LIST_FOR(_s, soltab, _head)) {
1843 
1844 #define RT_VISIT_ALL_SOLTABS_END } }
1846 /**
1847  * Applications that are going to use RT_ADD_VLIST and RT_GET_VLIST
1848  * are required to execute this macro once, first:
1849  *
1850  * BU_LIST_INIT(&RTG.rtg_vlfree);
1851  *
1852  * Note that RT_GET_VLIST and RT_FREE_VLIST are non-PARALLEL.
1853  */
1854 #define RT_GET_VLIST(p) BN_GET_VLIST(&RTG.rtg_vlfree, p)
1855 
1856 /** Place an entire chain of bn_vlist structs on the freelist */
1857 #define RT_FREE_VLIST(hd) BN_FREE_VLIST(&RTG.rtg_vlfree, hd)
1858 
1859 #define RT_ADD_VLIST(hd, pnt, draw) BN_ADD_VLIST(&RTG.rtg_vlfree, hd, pnt, draw)
1861 /** Set a point size to apply to the vlist elements that follow. */
1862 #define RT_VLIST_SET_POINT_SIZE(hd, size) BN_VLIST_SET_POINT_SIZE(&RTG.rtg_vlfree, hd, size)
1864 /** Set a line width to apply to the vlist elements that follow. */
1865 #define RT_VLIST_SET_LINE_WIDTH(hd, width) BN_VLIST_SET_LINE_WIDTH(&RTG.rtg_vlfree, hd, width)
1866 
1867 
1868 /*
1869  * Replacements for definitions from vmath.h
1870  */
1871 #undef V2PRINT
1872 #undef VPRINT
1873 #undef HPRINT
1874 #define V2PRINT(a, b) bu_log("%s (%g, %g)\n", a, (b)[0], (b)[1]);
1875 #define VPRINT(a, b) bu_log("%s (%g, %g, %g)\n", a, (b)[0], (b)[1], (b)[2])
1876 #define HPRINT(a, b) bu_log("%s (%g, %g, %g, %g)\n", a, (b)[0], (b)[1], (b)[2], (b)[3])
1877 
1878 /**
1879  * Table for driving generic command-parsing routines
1880  */
1881 struct command_tab {
1882  const char *ct_cmd;
1883  const char *ct_parms;
1884  const char *ct_comment;
1885  int (*ct_func)(const int, const char **);
1886  int ct_min; /**< @brief min number of words in cmd */
1887  int ct_max; /**< @brief max number of words in cmd */
1888 };
1891 /**
1892  * Used by MGED for labeling vertices of a solid.
1893  */
1894 struct rt_point_labels {
1895  char str[8];
1896  point_t pt;
1897 };
1898 
1899 
1900 /**
1901  * Used by rpc.c, ehy.c, epa.c, eto.c and rhc.c to contain
1902  * forward-linked lists of points.
1903  */
1904 struct rt_pt_node {
1905  point_t p; /**< @brief a point */
1906  struct rt_pt_node *next; /**< @brief ptr to next pt */
1907 };
1908 
1909 /**
1910  * Normally, librt doesn't have a concept of a "display" of the
1911  * geometry. However for at least the plotting routines, view
1912  * information is sometimes needed to produce more intelligent output.
1913  * In those situations, the application should populate and pass an
1914  * rt_view_info struct.
1915  *
1916  * **TODO** this structure is NOT in final form and should not be
1917  * relied upon.
1918  */
1919 struct rt_view_info {
1920  struct bu_list *vhead;
1921  const struct bn_tol *tol;
1922 
1923  /**
1924  * The average distance between the segment points of plotted
1925  * curves. Smaller spacing means more points per curve, and thus
1926  * smoother (more accurate) plot curves.
1927  */
1929 
1930  /** The average distance between plotted surface curves.
1931  * Smaller spacing means more curves are drawn, increasing the overall
1932  * density of the plot.
1933  */
1935 };
1936 
1937 /**
1938  * Specifies a subset of a primitive's geometry as the target for an
1939  * operation.
1940  *
1941  * TODO: This structure is tentative and subject to change or removal
1942  * without notice.
1943  */
1944 struct rt_selection {
1945  void *obj; /**< @brief primitive-specific selection object */
1946 };
1947 
1948 /**
1949  * TODO: This structure is tentative and subject to change or removal
1950  * without notice.
1951  */
1952 struct rt_selection_set {
1953  struct bu_ptbl selections; /**< @brief holds struct rt_selection */
1954 
1955  /** selection-object-specific routine that will free all memory
1956  * associated with any of the stored selections
1957  */
1958  void (*free_selection)(struct rt_selection *);
1959 };
1960 
1961 /**
1962  * Stores selections associated with an object. There is an entry in
1963  * the selections table for each kind of selection (e.g. "active",
1964  * "option"). The table entries are sets to allow more than one
1965  * selection of the same type (e.g. multiple "option" selections).
1966  *
1967  * TODO: This structure is tentative and subject to change or removal
1968  * without notice.
1969  */
1970 struct rt_object_selections {
1971  /** selection type -> struct rt_selection_set */
1972  struct bu_hash_tbl *sets;
1973 };
1974 
1975 /**
1976  * Analogous to a database query. Specifies how to filter and sort the
1977  * selectable components of a primitive in order to find the most
1978  * relevant selections for a particular application.
1979  *
1980  * TODO: This structure is tentative and subject to change or removal
1981  * without notice.
1982  */
1983 struct rt_selection_query {
1984  point_t start; /**< @brief start point of query ray */
1985  vect_t dir; /**< @brief direction of query ray */
1986 
1987 #define RT_SORT_UNSORTED 0
1988 #define RT_SORT_CLOSEST_TO_START 1
1989  int sorting;
1990 };
1992 /**
1993  * Parameters of a translation applied to a selection.
1994  *
1995  * TODO: This structure is tentative and subject to change or removal
1996  * without notice.
1997  */
1998 struct rt_selection_translation {
1999  fastf_t dx;
2000  fastf_t dy;
2001  fastf_t dz;
2002 };
2003 
2004 /**
2005  * Describes an operation that can be applied to a selection.
2006  *
2007  * TODO: This structure is tentative and subject to change or removal
2008  * without notice.
2009  */
2010 struct rt_selection_operation {
2011 #define RT_SELECTION_NOP 0
2012 #define RT_SELECTION_TRANSLATION 1
2013  int type;
2014  union {
2015  struct rt_selection_translation tran;
2017 };
2019 /**
2020  * Object-oriented interface to BRL-CAD geometry.
2021  *
2022  * These are the methods for a notional object class "brlcad_solid".
2023  * The data for each instance is found separately in struct soltab.
2024  * This table is indexed by ID_xxx value of particular solid found in
2025  * st_id, or directly pointed at by st_meth.
2026  *
2027  * This needs to be at the end of the raytrace.h header file, so that
2028  * all the structure names are known. The "union record" and "struct
2029  * nmgregion" pointers are problematic, so generic pointers are used
2030  * when those header files have not yet been seen.
2031  *
2032  * DEPRECATED: the size of this structure will likely change with new
2033  * size for ft_label and new object callbacks.
2034  */
2035 struct rt_functab {
2036  uint32_t magic;
2037  char ft_name[17]; /* current longest name is 16 chars, need one element for terminating NULL */
2038  char ft_label[9]; /* current longest label is 8 chars, need one element for terminating NULL */
2039 
2040  int ft_use_rpp;
2041  int (*ft_prep)(struct soltab *stp,
2042  struct rt_db_internal *ip,
2043  struct rt_i *rtip);
2044 #define RTFUNCTAB_FUNC_PREP_CAST(_func) ((int (*)(struct soltab *, struct rt_db_internal *, struct rt_i *))_func)
2045 
2046  int (*ft_shot)(struct soltab *stp,
2047  struct xray *rp,
2048  struct application *ap, /* has resource */
2049  struct seg *seghead);
2050 #define RTFUNCTAB_FUNC_SHOT_CAST(_func) ((int (*)(struct soltab *, struct xray *, struct application *, struct seg *))_func)
2051 
2052  void (*ft_print)(const struct soltab *stp);
2053 #define RTFUNCTAB_FUNC_PRINT_CAST(_func) ((void (*)(const struct soltab *))_func)
2054 
2055  void (*ft_norm)(struct hit *hitp,
2056  struct soltab *stp,
2057  struct xray *rp);
2058 #define RTFUNCTAB_FUNC_NORM_CAST(_func) ((void (*)(struct hit *, struct soltab *, struct xray *))_func)
2060  int (*ft_piece_shot)(struct rt_piecestate *psp,
2061  struct rt_piecelist *plp,
2062  double dist, /* correction to apply to hit distances */
2063  struct xray *ray, /* ray transformed to be near cut cell */
2064  struct application *ap, /* has resource */
2065  struct seg *seghead); /* used only for PLATE mode hits */
2066 #define RTFUNCTAB_FUNC_PIECE_SHOT_CAST(_func) ((int (*)(struct rt_piecestate *, struct rt_piecelist *, double dist, struct xray *, struct application *, struct seg *))_func)
2067 
2068  void (*ft_piece_hitsegs)(struct rt_piecestate *psp,
2069  struct seg *seghead,
2070  struct application *ap); /* has resource */
2071 #define RTFUNCTAB_FUNC_PIECE_HITSEGS_CAST(_func) ((void (*)(struct rt_piecestate *, struct seg *, struct application *))_func)
2073  void (*ft_uv)(struct application *ap, /* has resource */
2074  struct soltab *stp,
2075  struct hit *hitp,
2076  struct uvcoord *uvp);
2077 #define RTFUNCTAB_FUNC_UV_CAST(_func) ((void (*)(struct application *, struct soltab *, struct hit *, struct uvcoord *))_func)
2078 
2079  void (*ft_curve)(struct curvature *cvp,
2080  struct hit *hitp,
2081  struct soltab *stp);
2082 #define RTFUNCTAB_FUNC_CURVE_CAST(_func) ((void (*)(struct curvature *, struct hit *, struct soltab *))_func)
2084  int (*ft_classify)(const struct soltab * /*stp*/, const vect_t /*min*/, const vect_t /*max*/, const struct bn_tol * /*tol*/);
2085 #define RTFUNCTAB_FUNC_CLASS_CAST(_func) ((int (*)(const struct soltab *, const vect_t, const vect_t, const struct bn_tol *))_func)
2086 
2087  void (*ft_free)(struct soltab * /*stp*/);
2088 #define RTFUNCTAB_FUNC_FREE_CAST(_func) ((void (*)(struct soltab *))_func)
2089 
2090  int (*ft_plot)(struct bu_list * /*vhead*/,
2091  struct rt_db_internal * /*ip*/,
2092  const struct rt_tess_tol * /*ttol*/,
2093  const struct bn_tol * /*tol*/,
2094  const struct rt_view_info * /*view info*/);
2095 #define RTFUNCTAB_FUNC_PLOT_CAST(_func) ((int (*)(struct bu_list *, struct rt_db_internal *, const struct rt_tess_tol *, const struct bn_tol *, const struct rt_view_info *))_func)
2097  int (*ft_adaptive_plot)(struct rt_db_internal * /*ip*/,
2098  const struct rt_view_info * /*view info*/);
2099 #define RTFUNCTAB_FUNC_ADAPTIVE_PLOT_CAST(_func) ((int (*)(struct rt_db_internal *, const struct rt_view_info *))_func)
2100 
2101  void (*ft_vshot)(struct soltab * /*stp*/[],
2102  struct xray *[] /*rp*/,
2103  struct seg * /*segp*/,
2104  int /*n*/,
2105  struct application * /*ap*/);
2106 #define RTFUNCTAB_FUNC_VSHOT_CAST(_func) ((void (*)(struct soltab *[], struct xray *[], struct seg *, int, struct application *))_func)
2108  int (*ft_tessellate)(struct nmgregion ** /*r*/,
2109  struct model * /*m*/,
2110  struct rt_db_internal * /*ip*/,
2111  const struct rt_tess_tol * /*ttol*/,
2112  const struct bn_tol * /*tol*/);
2113 #define RTFUNCTAB_FUNC_TESS_CAST(_func) ((int (*)(struct nmgregion **, struct model *, struct rt_db_internal *, const struct rt_tess_tol *, const struct bn_tol *))_func)
2114  int (*ft_tnurb)(struct nmgregion ** /*r*/,
2115  struct model * /*m*/,
2116  struct rt_db_internal * /*ip*/,
2117  const struct bn_tol * /*tol*/);
2118 #define RTFUNCTAB_FUNC_TNURB_CAST(_func) ((int (*)(struct nmgregion **, struct model *, struct rt_db_internal *, const struct bn_tol *))_func)
2120  void (*ft_brep)(ON_Brep ** /*b*/,
2121  struct rt_db_internal * /*ip*/,
2122  const struct bn_tol * /*tol*/);
2123 #define RTFUNCTAB_FUNC_BREP_CAST(_func) ((void (*)(ON_Brep **, struct rt_db_internal *, const struct bn_tol *))_func)
2125  int (*ft_import5)(struct rt_db_internal * /*ip*/,
2126  const struct bu_external * /*ep*/,
2127  const mat_t /*mat*/,
2128  const struct db_i * /*dbip*/,
2129  struct resource * /*resp*/);
2130 #define RTFUNCTAB_FUNC_IMPORT5_CAST(_func) ((int (*)(struct rt_db_internal *, const struct bu_external *, const mat_t, const struct db_i *, struct resource *))_func)
2132  int (*ft_export5)(struct bu_external * /*ep*/,
2133  const struct rt_db_internal * /*ip*/,
2134  double /*local2mm*/,
2135  const struct db_i * /*dbip*/,
2136  struct resource * /*resp*/);
2137 #define RTFUNCTAB_FUNC_EXPORT5_CAST(_func) ((int (*)(struct bu_external *, const struct rt_db_internal *, double, const struct db_i *, struct resource *))_func)
2139  int (*ft_import4)(struct rt_db_internal * /*ip*/,
2140  const struct bu_external * /*ep*/,
2141  const mat_t /*mat*/,
2142  const struct db_i * /*dbip*/,
2143  struct resource * /*resp*/);
2144 #define RTFUNCTAB_FUNC_IMPORT4_CAST(_func) ((int (*)(struct rt_db_internal *, const struct bu_external *, const mat_t, const struct db_i *, struct resource *))_func)
2146  int (*ft_export4)(struct bu_external * /*ep*/,
2147  const struct rt_db_internal * /*ip*/,
2148  double /*local2mm*/,
2149  const struct db_i * /*dbip*/,
2150  struct resource * /*resp*/);
2151 #define RTFUNCTAB_FUNC_EXPORT4_CAST(_func) ((int (*)(struct bu_external *, const struct rt_db_internal *, double, const struct db_i *, struct resource *))_func)
2153  void (*ft_ifree)(struct rt_db_internal * /*ip*/);
2154 #define RTFUNCTAB_FUNC_IFREE_CAST(_func) ((void (*)(struct rt_db_internal *))_func)
2155 
2156  int (*ft_describe)(struct bu_vls * /*str*/,
2157  const struct rt_db_internal * /*ip*/,
2158  int /*verbose*/,
2159  double /*mm2local*/,
2160  struct resource * /*resp*/,
2161  struct db_i *);
2162 #define RTFUNCTAB_FUNC_DESCRIBE_CAST(_func) ((int (*)(struct bu_vls *, const struct rt_db_internal *, int, double, struct resource *, struct db_i *))_func)
2163 
2164  int (*ft_xform)(struct rt_db_internal * /*op*/,
2165  const mat_t /*mat*/, struct rt_db_internal * /*ip*/,
2166  int /*free*/, struct db_i * /*dbip*/,
2167  struct resource * /*resp*/);
2168 #define RTFUNCTAB_FUNC_XFORM_CAST(_func) ((int (*)(struct rt_db_internal *, const mat_t, struct rt_db_internal *, int, struct db_i *, struct resource *))_func)
2169 
2170  const struct bu_structparse *ft_parsetab; /**< @brief rt_xxx_parse */
2171  size_t ft_internal_size; /**< @brief sizeof(struct rt_xxx_internal) */
2172  uint32_t ft_internal_magic; /**< @brief RT_XXX_INTERNAL_MAGIC */
2173 
2174  int (*ft_get)(struct bu_vls *, const struct rt_db_internal *, const char *item);
2175 #define RTFUNCTAB_FUNC_GET_CAST(_func) ((int (*)(struct bu_vls *, const struct rt_db_internal *, const char *))_func)
2177  int (*ft_adjust)(struct bu_vls *, struct rt_db_internal *, int /*argc*/, const char ** /*argv*/);
2178 #define RTFUNCTAB_FUNC_ADJUST_CAST(_func) ((int (*)(struct bu_vls *, struct rt_db_internal *, int, const char **))_func)
2179 
2180  int (*ft_form)(struct bu_vls *, const struct rt_functab *);
2181 #define RTFUNCTAB_FUNC_FORM_CAST(_func) ((int (*)(struct bu_vls *, const struct rt_functab *))_func)
2182 
2183  void (*ft_make)(const struct rt_functab *, struct rt_db_internal * /*ip*/);
2184 #define RTFUNCTAB_FUNC_MAKE_CAST(_func) ((void (*)(const struct rt_functab *, struct rt_db_internal *))_func)
2185 
2186  int (*ft_params)(struct pc_pc_set *, const struct rt_db_internal * /*ip*/);
2187 #define RTFUNCTAB_FUNC_PARAMS_CAST(_func) ((int (*)(struct pc_pc_set *, const struct rt_db_internal *))_func)
2188 
2189  /* Axis aligned bounding box */
2190  int (*ft_bbox)(struct rt_db_internal * /*ip*/,
2191  point_t * /*min X, Y, Z of bounding RPP*/,
2192  point_t * /*max X, Y, Z of bounding RPP*/,
2193  const struct bn_tol *);
2194 #define RTFUNCTAB_FUNC_BBOX_CAST(_func) ((int (*)(struct rt_db_internal *, point_t *, point_t *, const struct bn_tol *))_func)
2195 
2196  void (*ft_volume)(fastf_t * /*vol*/, const struct rt_db_internal * /*ip*/);
2197 #define RTFUNCTAB_FUNC_VOLUME_CAST(_func) ((void (*)(fastf_t *, const struct rt_db_internal *))_func)
2198 
2199  void (*ft_surf_area)(fastf_t * /*area*/, const struct rt_db_internal * /*ip*/);
2200 #define RTFUNCTAB_FUNC_SURF_AREA_CAST(_func) ((void (*)(fastf_t *, const struct rt_db_internal *))_func)
2201 
2202  void (*ft_centroid)(point_t * /*cent*/, const struct rt_db_internal * /*ip*/);
2203 #define RTFUNCTAB_FUNC_CENTROID_CAST(_func) ((void (*)(point_t *, const struct rt_db_internal *))_func)
2204 
2205  int (*ft_oriented_bbox)(struct rt_arb_internal * /* bounding arb8 */,
2206  struct rt_db_internal * /*ip*/,
2207  const fastf_t);
2208 #define RTFUNCTAB_FUNC_ORIENTED_BBOX_CAST(_func) ((int (*)(struct rt_arb_internal *, struct rt_db_internal *, const fastf_t))_func)
2210  /** get a list of the selections matching a query */
2211  struct rt_selection_set *(*ft_find_selections)(const struct rt_db_internal *,
2212  const struct rt_selection_query *);
2213 #define RTFUNCTAB_FUNC_FIND_SELECTIONS_CAST(_func) ((struct rt_selection_set *(*)(const struct rt_db_internal *, const struct rt_selection_query *))_func)
2215  /** evaluate a logical selection expression (e.g. a INTERSECT b,
2216  * NOT a) to create a new selection
2217  */
2218  struct rt_selection *(*ft_evaluate_selection)(const struct rt_db_internal *,
2219  int op,
2220  const struct rt_selection *,
2221  const struct rt_selection *);
2222 #define RTFUNCTAB_FUNC_EVALUATE_SELECTION_CAST(_func) ((struct rt_selection *(*)(const struct rt_db_internal *, int op, const struct rt_selection *, const struct rt_selection *))_func)
2223 
2224  /** apply an operation to a selected subset of a primitive */
2225  int (*ft_process_selection)(struct rt_db_internal *,
2226  struct db_i *,
2227  const struct rt_selection *,
2228  const struct rt_selection_operation *);
2229 #define RTFUNCTAB_FUNC_PROCESS_SELECTION_CAST(_func) ((int (*)(struct rt_db_internal *, struct db_i *, const struct rt_selection *, const struct rt_selection_operation *))_func)
2230 
2231 };
2232 
2233 
2234 RT_EXPORT extern const struct rt_functab OBJ[];
2236 #define RT_CK_FUNCTAB(_p) BU_CKMAG(_p, RT_FUNCTAB_MAGIC, "functab");
2237 
2238 
2239 /**
2240  * Internal to shoot.c and bundle.c
2241  */
2243  fastf_t dist_corr; /**< @brief correction distance */
2247  fastf_t box_end;
2251  struct xray newray; /**< @brief closer ray start */
2252  struct application *ap;
2253  struct resource * resp;
2254  vect_t inv_dir; /**< @brief inverses of ap->a_ray.r_dir */
2255  vect_t abs_inv_dir; /**< @brief absolute values of inv_dir */
2256  int rstep[3]; /**< @brief -/0/+ dir of ray in axis */
2257  const union cutter *lastcut, *lastcell;
2258  const union cutter *curcut;
2259  point_t curmin, curmax;
2260  int igrid[3]; /**< @brief integer cell coordinates */
2261  vect_t tv; /**< @brief next t intercept values */
2262  int out_axis; /**< @brief axis ray will leave through */
2264  int box_num; /**< @brief which cell along ray */
2265 };
2268 #define NUGRID_T_SETUP(_ax, _cval, _cno) \
2269  if (ssp->rstep[_ax] > 0) { \
2270  ssp->tv[_ax] = t0 + (nu_axis[_ax][_cno].nu_epos - _cval) * \
2271  ssp->inv_dir[_ax]; \
2272  } else if (ssp->rstep[_ax] < 0) { \
2273  ssp->tv[_ax] = t0 + (nu_axis[_ax][_cno].nu_spos - _cval) * \
2274  ssp->inv_dir[_ax]; \
2275  } else { \
2276  ssp->tv[_ax] = INFINITY; \
2277  }
2278 #define NUGRID_T_ADV(_ax, _cno) \
2279  if (ssp->rstep[_ax] != 0) { \
2280  ssp->tv[_ax] += nu_axis[_ax][_cno].nu_width * \
2281  ssp->abs_inv_dir[_ax]; \
2282  }
2283 
2284 #define BACKING_DIST (-2.0) /**< @brief mm to look behind start point */
2285 #define OFFSET_DIST 0.01 /**< @brief mm to advance point into box */
2286 
2287 /*********************************************************************************
2288  * The following section is an exact copy of what was previously "nmg_rt.h" *
2289  * (with minor changes to NMG_GET_HITMISS and NMG_FREE_HITLIST *
2290  * moved here to use RTG.rtg_nmgfree freelist for hitmiss structs. *
2291  ******************************************************************************* */
2292 
2293 #define NMG_HIT_LIST 0
2294 #define NMG_MISS_LIST 1
2295 
2296 
2297 /* These values are for the hitmiss "in_out" variable and indicate the
2298  * nature of the hit when known
2299  */
2300 #define HMG_INBOUND_STATE(_hm) (((_hm)->in_out & 0x0f0) >> 4)
2301 #define HMG_OUTBOUND_STATE(_hm) ((_hm)->in_out & 0x0f)
2302 
2303 
2304 #define NMG_RAY_STATE_INSIDE 1
2305 #define NMG_RAY_STATE_ON 2
2306 #define NMG_RAY_STATE_OUTSIDE 4
2307 #define NMG_RAY_STATE_ANY 8
2308 
2309 #define HMG_HIT_IN_IN 0x11 /**< @brief hit internal structure */
2310 #define HMG_HIT_IN_OUT 0x14 /**< @brief breaking out */
2311 #define HMG_HIT_OUT_IN 0x41 /**< @brief breaking in */
2312 #define HMG_HIT_OUT_OUT 0x44 /**< @brief edge/vertex graze */
2313 #define HMG_HIT_IN_ON 0x12
2314 #define HMG_HIT_ON_IN 0x21
2315 #define HMG_HIT_ON_ON 0x22
2316 #define HMG_HIT_OUT_ON 0x42
2317 #define HMG_HIT_ON_OUT 0x24
2318 #define HMG_HIT_ANY_ANY 0x88 /**< @brief hit on non-3-manifold */
2320 #define NMG_VERT_ENTER 1
2321 #define NMG_VERT_ENTER_LEAVE 0
2322 #define NMG_VERT_LEAVE -1
2323 #define NMG_VERT_UNKNOWN -2
2325 #define NMG_HITMISS_SEG_IN 0x696e00 /**< @brief "in" */
2326 #define NMG_HITMISS_SEG_OUT 0x6f757400 /**< @brief "out" */
2328 struct hitmiss {
2329  struct bu_list l;
2330  struct hit hit;
2331  fastf_t dist_in_plane; /**< @brief distance from plane intersect */
2332  int in_out; /**< @brief status of ray as it transitions
2333  * this hit point.
2334  */
2339  int start_stop; /**< @brief is this a seg_in or seg_out */
2340  struct hitmiss *other; /**< @brief for keeping track of the other
2341  * end of the segment when we know
2342  * it
2343  */
2344 };
2347 #ifdef NO_BOMBING_MACROS
2348 # define NMG_CK_HITMISS(hm) BU_IGNORE((hm))
2349 #else
2350 # define NMG_CK_HITMISS(hm) \
2351  {\
2352  switch (hm->l.magic) { \
2353  case NMG_RT_HIT_MAGIC: \
2354  case NMG_RT_HIT_SUB_MAGIC: \
2355  case NMG_RT_MISS_MAGIC: \
2356  break; \
2357  case NMG_MISS_LIST: \
2358  bu_log(BU_FLSTR ": struct hitmiss has NMG_MISS_LIST magic #\n"); \
2359  bu_bomb("NMG_CK_HITMISS: going down in flames\n"); \
2360  case NMG_HIT_LIST: \
2361  bu_log(BU_FLSTR ": struct hitmiss has NMG_MISS_LIST magic #\n"); \
2362  bu_bomb("NMG_CK_HITMISS: going down in flames\n"); \
2363  default: \
2364  bu_log(BU_FLSTR ": bad struct hitmiss magic: %u:(0x%08x)\n", \
2365  hm->l.magic, hm->l.magic); \
2366  bu_bomb("NMG_CK_HITMISS: going down in flames\n"); \
2367  }\
2368  if (!hm->hit.hit_private) { \
2369  bu_log(BU_FLSTR ": NULL hit_private in hitmiss struct\n"); \
2370  bu_bomb("NMG_CK_HITMISS: going down in flames\n"); \
2371  } \
2372  }
2373 #endif
2374 
2375 #ifdef NO_BOMBING_MACROS
2376 # define NMG_CK_HITMISS_LISTS(rd) BU_IGNORE((rd))
2377 #else
2378 # define NMG_CK_HITMISS_LISTS(rd) \
2379  { \
2380  struct hitmiss *_a_hit; \
2381  for (BU_LIST_FOR(_a_hit, hitmiss, &rd->rd_hit)) {NMG_CK_HITMISS(_a_hit);} \
2382  for (BU_LIST_FOR(_a_hit, hitmiss, &rd->rd_miss)) {NMG_CK_HITMISS(_a_hit);} \
2383  }
2384 #endif
2385 
2386 
2387 /**
2388  * Ray Data structure
2389  *
2390  * A) the hitmiss table has one element for each nmg structure in the
2391  * nmgmodel. The table keeps track of which elements have been
2392  * processed before and which haven't. Elements in this table will
2393  * either be: (NULL) item not previously processed hitmiss ptr item
2394  * previously processed
2395  *
2396  * the 0th item in the array is a pointer to the head of the "hit"
2397  * list. The 1th item in the array is a pointer to the head of the
2398  * "miss" list.
2399  *
2400  * B) If plane_pt is non-null then we are currently processing a face
2401  * intersection. The plane_dist and ray_dist_to_plane are valid. The
2402  * ray/edge intersector should check the distance from the plane
2403  * intercept to the edge and update "plane_closest" if the current
2404  * edge is closer to the intercept than the previous closest object.
2405  */
2406 struct ray_data {
2407  uint32_t magic;
2408  struct model *rd_m;
2409  char *manifolds; /**< @brief structure 1-3manifold table */
2410  vect_t rd_invdir;
2411  struct xray *rp;
2412  struct application *ap;
2413  struct seg *seghead;
2414  struct soltab *stp;
2415  const struct bn_tol *tol;
2416  struct hitmiss **hitmiss; /**< @brief 1 struct hitmiss ptr per elem. */
2417  struct bu_list rd_hit; /**< @brief list of hit elements */
2418  struct bu_list rd_miss; /**< @brief list of missed/sub-hit elements */
2420 /* The following are to support isect_ray_face() */
2422  /**
2423  * plane_pt is the intercept point of the ray with the plane of
2424  * the face.
2425  */
2426  point_t plane_pt; /**< @brief ray/plane(face) intercept point */
2427 
2428  /**
2429  * ray_dist_to_plane is the parametric distance along the ray from
2430  * the ray origin (rd->rp->r_pt) to the ray/plane intercept point
2431  */
2432  fastf_t ray_dist_to_plane; /**< @brief ray parametric dist to plane */
2433 
2434  /**
2435  * the "face_subhit" element is a boolean used by isect_ray_face
2436  * and [e|v]u_touch_func to record the fact that the
2437  * ray/(plane/face) intercept point was within tolerance of an
2438  * edge/vertex of the face. In such instances, isect_ray_face
2439  * does NOT need to generate a hit point for the face, as the hit
2440  * point for the edge/vertex will suffice.
2441  */
2442  int face_subhit;
2443 
2444  /**
2445  * the "classifying_ray" flag indicates that this ray is being
2446  * used to classify a point, so that the "eu_touch" and "vu_touch"
2447  * functions should not be called.
2448  */
2449  int classifying_ray;
2450 };
2451 
2452 
2453 #define NMG_PCA_EDGE 1
2454 #define NMG_PCA_EDGE_VERTEX 2
2455 #define NMG_PCA_VERTEX 3
2456 #define NMG_CK_RD(_rd) NMG_CKMAG(_rd, NMG_RAY_DATA_MAGIC, "ray data");
2457 
2458 
2459 #define NMG_GET_HITMISS(_p, _ap) { \
2460  (_p) = BU_LIST_FIRST(hitmiss, &((_ap)->a_resource->re_nmgfree)); \
2461  if (BU_LIST_IS_HEAD((_p), &((_ap)->a_resource->re_nmgfree))) \
2462  BU_ALLOC((_p), struct hitmiss); \
2463  else \
2464  BU_LIST_DEQUEUE(&((_p)->l)); \
2465  }
2466 
2467 
2468 #define NMG_FREE_HITLIST(_p, _ap) { \
2469  BU_CK_LIST_HEAD((_p)); \
2470  BU_LIST_APPEND_LIST(&((_ap)->a_resource->re_nmgfree), (_p)); \
2471  }
2472 
2473 
2474 #define HIT 1 /**< @brief a hit on a face */
2475 #define MISS 0 /**< @brief a miss on the face */
2476 
2477 
2478 #ifdef NO_BOMBING_MACROS
2479 # define nmg_bu_bomb(rd, str) BU_IGNORE((rd))
2480 #else
2481 # define nmg_bu_bomb(rd, str) { \
2482  bu_log("%s", str); \
2483  if (RTG.NMG_debug & DEBUG_NMGRT) bu_bomb("End of diagnostics"); \
2484  BU_LIST_INIT(&rd->rd_hit); \
2485  BU_LIST_INIT(&rd->rd_miss); \
2486  RTG.NMG_debug |= DEBUG_NMGRT; \
2487  nmg_isect_ray_model(rd); \
2488  (void) nmg_ray_segs(rd); \
2489  bu_bomb("Should have bombed before this\n"); \
2490  }
2491 #endif
2492 
2493 
2494 struct nmg_radial {
2495  struct bu_list l;
2496  struct edgeuse *eu;
2497  struct faceuse *fu; /**< @brief Derived from eu */
2498  struct shell *s; /**< @brief Derived from eu */
2499  int existing_flag; /**< @brief !0 if this eu exists on dest edge */
2500  int is_crack; /**< @brief This eu is part of a crack. */
2501  int is_outie; /**< @brief This crack is an "outie" */
2502  int needs_flip; /**< @brief Insert eumate, not eu */
2503  fastf_t ang; /**< @brief angle, in radians. 0 to 2pi */
2504 };
2505 #define NMG_CK_RADIAL(_p) NMG_CKMAG(_p, NMG_RADIAL_MAGIC, "nmg_radial")
2508  uint32_t magic;
2509  struct bu_ptbl *l1; /**< @brief vertexuses on the line of */
2510  struct bu_ptbl *l2; /**< @brief intersection between planes */
2511  fastf_t *mag1; /**< @brief Distances along intersection line */
2512  fastf_t *mag2; /**< @brief for each vertexuse in l1 and l2. */
2513  int mag_len; /**< @brief Array size of mag1 and mag2 */
2514  struct shell *s1;
2515  struct shell *s2;
2516  struct faceuse *fu1; /**< @brief null if l1 comes from a wire */
2517  struct faceuse *fu2; /**< @brief null if l2 comes from a wire */
2518  struct bn_tol tol;
2519  int coplanar; /**< @brief a flag */
2520  struct edge_g_lseg *on_eg; /**< @brief edge_g for line of intersection */
2521  point_t pt; /**< @brief 3D line of intersection */
2522  vect_t dir;
2523  point_t pt2d; /**< @brief 2D projection of isect line */
2524  vect_t dir2d;
2525  fastf_t *vert2d; /**< @brief Array of 2d vertex projections [index] */
2526  int maxindex; /**< @brief size of vert2d[] */
2527  mat_t proj; /**< @brief Matrix to project onto XY plane */
2528  const uint32_t *twod; /**< @brief ptr to face/edge of 2d projection */
2529 };
2530 #define NMG_CK_INTER_STRUCT(_p) NMG_CKMAG(_p, NMG_INTER_STRUCT_MAGIC, "nmg_inter_struct")
2532 /*****************************************************************
2533  * *
2534  * Applications interface to the RT library *
2535  * *
2536  *****************************************************************/
2537 
2538 /* Prepare for raytracing */
2539 
2540 RT_EXPORT extern struct rt_i *rt_new_rti(struct db_i *dbip);
2541 RT_EXPORT extern void rt_free_rti(struct rt_i *rtip);
2542 RT_EXPORT extern void rt_prep(struct rt_i *rtip);
2543 RT_EXPORT extern void rt_prep_parallel(struct rt_i *rtip,
2544  int ncpu);
2545 
2546 /**
2547  * Default version of a_multioverlap().
2548  *
2549  * Resolve the overlap of multiple regions withing a single partition.
2550  * There are no null pointers in the table (they have been compressed
2551  * out by our caller). Consider BU_PTBL_LEN(regiontable) overlapping
2552  * regions, and reduce to zero or one "claiming" regions, by setting
2553  * pointers in the bu_ptbl of non-claiming regions to NULL.
2554  *
2555  * This default routine reproduces the behavior of BRL-CAD Release 5.0
2556  * by considering the regions pairwise and calling the old
2557  * a_overlap().
2558  *
2559  * An application which knew how to handle multiple overlapping air
2560  * regions would provide its own very different version of this
2561  * routine as the a_multioverlap() handler.
2562  *
2563  * This routine is for resolving overlaps only, and should not print
2564  * any messages in normal operation; a_logoverlap() is for logging.
2565  *
2566  * InputHdp is the list of partitions up to this point. It allows us
2567  * to look at the regions that have come before in deciding what to do
2568  */
2569 RT_EXPORT extern void rt_default_multioverlap(struct application *ap,
2570  struct partition *pp,
2571  struct bu_ptbl *regiontable,
2572  struct partition *InputHdp);
2573 
2574 /**
2575  * If an application doesn't want any logging from LIBRT, it should
2576  * just set ap->a_logoverlap = rt_silent_logoverlap.
2577  */
2578 RT_EXPORT extern void rt_silent_logoverlap(struct application *ap,
2579  const struct partition *pp,
2580  const struct bu_ptbl *regiontable,
2581  const struct partition *InputHdp);
2582 
2583 /**
2584  * Log a multiplicity of overlaps within a single partition. This
2585  * function is intended for logging only, and a_multioverlap() is
2586  * intended for resolving the overlap, only. This function can be
2587  * replaced by an application setting a_logoverlap().
2588  */
2589 RT_EXPORT extern void rt_default_logoverlap(struct application *ap,
2590  const struct partition *pp,
2591  const struct bu_ptbl *regiontable,
2592  const struct partition *InputHdp);
2593 
2594 /**
2595  * Initial set of 'xrays' pattern generators that can
2596  * used to feed a bundle set of rays to rt_shootrays()
2597  */
2598 
2599 /**
2600  * Make a bundle of rays around a main ray using a uniform rectangular
2601  * grid pattern with an elliptical extent.
2602  *
2603  * avec and bvec a. The gridsize is
2604  * given in mm.
2605  *
2606  * rp[0].r_dir must have unit length.
2607  */
2608 RT_EXPORT extern int rt_gen_elliptical_grid(struct xrays *rays,
2609  const struct xray *center_ray,
2610  const fastf_t *avec,
2611  const fastf_t *bvec,
2612  fastf_t gridsize);
2613 
2614 /**
2615  * Make a bundle of rays around a main ray using a uniform rectangular
2616  * grid pattern with a circular extent. The radius, gridsize is given
2617  * in mm.
2618  *
2619  * rp[0].r_dir must have unit length.
2620  */
2621 RT_EXPORT extern int rt_gen_circular_grid(struct xrays *ray_bundle,
2622  const struct xray *center_ray,
2623  fastf_t radius,
2624  const fastf_t *up_vector,
2625  fastf_t gridsize);
2626 
2627 /**
2628  * Make a bundle of rays around a main ray in the shape of a cone,
2629  * using a uniform rectangular grid; theta is the angle of divergence
2630  * of the cone, and rays_per_radius is the number of rays that lie on
2631  * any given radius of the cone.
2632  *
2633  * center_ray.r_dir must have unit length.
2634  */
2635 RT_EXPORT extern int rt_gen_conic(struct xrays *rays,
2636  const struct xray *center_ray,
2637  fastf_t theta,
2638  vect_t up_vector,
2639  int rays_per_radius);
2640 
2641 /**
2642  * Make a bundle of rays around a main ray in the shape of a frustum
2643  * as a uniform rectangular grid. a_vec and b_vec are the directions
2644  * for up and right, respectively; a_theta and b_theta are the angles
2645  * of divergence in the directions of a_vec and b_vec respectively.
2646  * This is useful for creating a grid of rays for perspective
2647  * rendering.
2648  */
2649 RT_EXPORT extern int rt_gen_frustum(struct xrays *rays,
2650  const struct xray *center_ray,
2651  const vect_t a_vec,
2652  const vect_t b_vec,
2653  const fastf_t a_theta,
2654  const fastf_t b_theta,
2655  const fastf_t a_num,
2656  const fastf_t b_num);
2657 
2658 /**
2659  * Make a bundle of orthogonal rays around a center ray as a uniform
2660  * rectangular grid. a_vec and b_vec are the directions for up and
2661  * right, respectively; their magnitudes determine the extent of the
2662  * grid (the grid extends from -a_vec to a_vec in the up-direction and
2663  * from -b_vec to b_vec in the right direction). da and db are the
2664  * offset between rays in the a and b directions respectively.
2665  */
2666 RT_EXPORT extern int rt_gen_rect(struct xrays *rays,
2667  const struct xray *center_ray,
2668  const vect_t a_vec,
2669  const vect_t b_vec,
2670  const fastf_t da,
2671  const fastf_t db);
2672 
2673 /* Shoot a ray */
2674 /**
2675  * Note that the direction vector r_dir must have unit length; this is
2676  * mandatory, and is not ordinarily checked, in the name of
2677  * efficiency.
2678  *
2679  * Input: Pointer to an application structure, with these mandatory fields:
2680  * a_ray.r_pt ==> Starting point of ray to be fired
2681  * a_ray.r_dir => UNIT VECTOR with direction to fire in (dir cosines)
2682  * a_hit =======> Routine to call when something is hit
2683  * a_miss ======> Routine to call when ray misses everything
2684  *
2685  * Calls user's a_miss() or a_hit() routine as appropriate. Passes
2686  * a_hit() routine list of partitions, with only hit_dist fields
2687  * valid. Normal computation deferred to user code, to avoid needless
2688  * computation here.
2689  *
2690  * Formal Return: whatever the application function returns (an int).
2691  *
2692  * NOTE: The application functions may call rt_shootray() recursively.
2693  * Thus, none of the local variables may be static.
2694  *
2695  * To prevent having to lock the statistics variables in a PARALLEL
2696  * environment, all the statistics variables have been moved into the
2697  * 'resource' structure, which is allocated per-CPU.
2698  */
2699 RT_EXPORT extern int rt_shootray(struct application *ap);
2700 /* Shoot a bundle of rays */
2701 
2702 /*
2703  * Function for shooting a bundle of rays. Iteratively walks list of
2704  * rays contained in the application bundles xrays field 'b_rays'
2705  * passing each single ray to r_shootray().
2706  *
2707  * Input:
2708  *
2709  * bundle - Pointer to an application_bundle structure.
2710  *
2711  * b_ap - Members in this single ray application structure should be
2712  * set in a similar fashion as when used with rt_shootray() with the
2713  * exception of a_hit() and a_miss(). Default implementations of these
2714  * routines are provided that simple update hit/miss counters and
2715  * attach the hit partitions and segments to the partition_bundle
2716  * structure. Users can still override this default functionality but
2717  * have to make sure to move the partition and segment list to the new
2718  * partition_bundle structure.
2719  *
2720  * b_hit() Routine to call when something is hit by the ray bundle.
2721  *
2722  * b_miss() Routine to call when ray bundle misses everything.
2723  *
2724  */
2725 RT_EXPORT extern int rt_shootrays(struct application_bundle *bundle);
2726 
2727 /**
2728  * PRIVATE: this is new API and should be considered private for the
2729  * time being.
2730  */
2731 RT_EXPORT extern int rt_shootray_bundle(register struct application *ap, struct xray *rays, int nrays);
2732 
2733 /**
2734  * PRIVATE: this is new API and should be considered private for the
2735  * time being.
2736  */
2737 RT_EXPORT extern int rt_raybundle_maker(struct xray *rp, double radius, const fastf_t *avec, const fastf_t *bvec, int rays_per_ring, int nring);
2738 
2739 /* Shoot a ray, returning the partition list */
2740 /**
2741  * Shoot a single ray and return the partition list. Handles callback
2742  * issues.
2743  *
2744  * Note that it calls malloc(), therefore should NOT be used if
2745  * performance matters.
2746  */
2747 RT_EXPORT extern struct partition *rt_shootray_simple(struct application *ap,
2748  point_t origin,
2749  vect_t direction);
2750 /* Get expr tree for object */
2751 /**
2752  * Decrement use count on soltab structure. If no longer needed,
2753  * release associated storage, and free the structure.
2754  *
2755  * This routine semaphore protects against other copies of itself
2756  * running in parallel, and against other routines (such as
2757  * _rt_find_identical_solid()) which might also be modifying the
2758  * linked list heads.
2759  *
2760  * Called by -
2761  * db_free_tree()
2762  * rt_clean()
2763  * rt_gettrees()
2764  * rt_kill_deal_solid_refs()
2765  */
2766 RT_EXPORT extern void rt_free_soltab(struct soltab *stp);
2767 
2768 
2769 /**
2770  * User-called function to add a tree hierarchy to the displayed set.
2771  *
2772  * This function is not multiply re-entrant.
2773  *
2774  * Returns -
2775  * 0 Ordinarily
2776  * -1 On major error
2777  *
2778  * Note: -2 returns from rt_gettrees_and_attrs are filtered.
2779  */
2780 RT_EXPORT extern int rt_gettree(struct rt_i *rtip,
2781  const char *node);
2782 RT_EXPORT extern int rt_gettrees(struct rt_i *rtip,
2783  int argc,
2784  const char **argv, int ncpus);
2785 
2786 /**
2787  * User-called function to add a set of tree hierarchies to the active
2788  * set.
2789  *
2790  * This function may run in parallel, but is not multiply re-entrant
2791  * itself, because db_walk_tree() isn't multiply re-entrant.
2792  *
2793  * Semaphores used for critical sections in parallel mode:
2794  * RT_SEM_TREE* protects rti_solidheads[] lists, d_uses(solids)
2795  * RT_SEM_RESULTS protects HeadRegion, mdl_min/max, d_uses(reg), nregions
2796  * RT_SEM_WORKER (db_walk_dispatcher, from db_walk_tree)
2797  * RT_SEM_STATS nsolids
2798  *
2799  * Returns -
2800  * 0 Ordinarily
2801  * -1 On major error
2802  * -2 If there were unresolved names
2803  */
2804 RT_EXPORT extern int rt_gettrees_and_attrs(struct rt_i *rtip,
2805  const char **attrs,
2806  int argc,
2807  const char **argv, int ncpus);
2808 
2809 
2810 /**
2811  * User-called function to add a set of tree hierarchies to the active
2812  * set. Includes getting the indicated list of attributes and a
2813  * Tcl_HashTable for use with the ORCA man regions. (stashed in the
2814  * rt_i structure).
2815  *
2816  * This function may run in parallel, but is not multiply re-entrant
2817  * itself, because db_walk_tree() isn't multiply re-entrant.
2818  *
2819  * Semaphores used for critical sections in parallel mode:
2820  * RT_SEM_TREE ====> protects rti_solidheads[] lists, d_uses(solids)
2821  * RT_SEM_RESULTS => protects HeadRegion, mdl_min/max, d_uses(reg), nregions
2822  * RT_SEM_WORKER ==> (db_walk_dispatcher, from db_walk_tree)
2823  * RT_SEM_STATS ===> nsolids
2824  *
2825  * INPUTS:
2826  *
2827  * rtip - RT instance pointer
2828  *
2829  * attrs - attribute value set
2830  *
2831  * argc - number of trees to get
2832  *
2833  * argv - array of char pointers to the names of the tree tops
2834  *
2835  * ncpus - number of cpus to use
2836  *
2837  * Returns -
2838  * 0 Ordinarily
2839  * -1 On major error
2840  */
2841 RT_EXPORT extern int rt_gettrees_muves(struct rt_i *rtip,
2842  const char **attrs,
2843  int argc,
2844  const char **argv,
2845  int ncpus);
2846 DEPRECATED RT_EXPORT extern int rt_load_attrs(struct rt_i *rtip,
2847  char **attrs);
2848 /* Print seg struct */
2849 RT_EXPORT extern void rt_pr_seg(const struct seg *segp);
2850 /* Print the partitions */
2851 RT_EXPORT extern void rt_pr_partitions(const struct rt_i *rtip,
2852  const struct partition *phead,
2853  const char *title);
2854 /* Find solid by leaf name */
2855 /**
2856  * Given the (leaf) name of a solid, find the first occurrence of it
2857  * in the solid list. Used mostly to find the light source. Returns
2858  * soltab pointer, or RT_SOLTAB_NULL.
2859  */
2860 RT_EXPORT extern struct soltab *rt_find_solid(const struct rt_i *rtip,
2861  const char *name);
2862 /* Start the global timer */
2863 /** @addtogroup timer */
2864 /** @{ */
2865 /** @file librt/timerhep.c
2866  *
2867  * To provide timing information for RT.
2868  * THIS VERSION FOR Denelcor HEP/UPX (System III-like)
2869  */
2870 
2871 /** @file librt/timer42.c
2872 *
2873 * To provide timing information for RT when running on 4.2 BSD UNIX.
2874 *
2875 */
2876 
2877  /** @file librt/timer-nt.c
2878  *
2879  * To provide timing information on Microsoft Windows NT.
2880  */
2881  /** @file librt/timerunix.c
2882  *
2883  * To provide timing information for RT. This version for any non-BSD
2884  * UNIX system, including System III, Vr1, Vr2. Version 6 & 7 should
2885  * also be able to use this (untested). The time() and times()
2886  * sys-calls are used for all timing.
2887  *
2888  */
2889 
2890 
2891 RT_EXPORT extern void rt_prep_timer(void);
2892 /* Read global timer, return time + str */
2893 /**
2894  * Reports on the passage of time, since rt_prep_timer() was called.
2895  * Explicit return is number of CPU seconds. String return is
2896  * descriptive. If "elapsed" pointer is non-null, number of elapsed
2897  * seconds are returned. Times returned will never be zero.
2898  */
2899 RT_EXPORT extern double rt_get_timer(struct bu_vls *vp,
2900  double *elapsed);
2901 /* Return CPU time, text, & wall clock time off the global timer */
2902 /**
2903  * Compatibility routine
2904  */
2905 RT_EXPORT extern double rt_read_timer(char *str, int len);
2906 /* Plot a solid */
2907 int rt_plot_solid(
2908  FILE *fp,
2909  struct rt_i *rtip,
2910  const struct soltab *stp,
2911  struct resource *resp);
2912 
2913 /** @} */
2914 /* Release storage assoc with rt_i */
2915 RT_EXPORT extern void rt_clean(struct rt_i *rtip);
2916 RT_EXPORT extern int rt_del_regtree(struct rt_i *rtip,
2917  struct region *delregp,
2918  struct resource *resp);
2919 /* Check in-memory data structures */
2920 RT_EXPORT extern void rt_ck(struct rt_i *rtip);
2921 /* apply a matrix transformation */
2922 /**
2923  * apply a matrix transformation to a given input object, setting the
2924  * resultant transformed object as the output solid. if freeflag is
2925  * set, the input object will be released.
2926  *
2927  * returns zero if matrix transform was applied, non-zero on failure.
2928  */
2929 RT_EXPORT extern int rt_matrix_transform(struct rt_db_internal *output, const mat_t matrix, struct rt_db_internal *input, int free_input, struct db_i *dbip, struct resource *resource);
2930 
2931 
2932 /*****************************************************************
2933  * *
2934  * Internal routines in the RT library. *
2935  * These routines are *not* intended for Applications to use. *
2936  * The interface to these routines may change significantly *
2937  * from release to release of this software. *
2938  * *
2939  *****************************************************************/
2940 
2941 /* Weave segs into partitions */
2942 
2943 /**
2944  * Weave a chain of segments into an existing set of partitions. The
2945  * edge of each partition is an inhit or outhit of some solid (seg).
2946  *
2947  * NOTE: When the final partitions are completed, it is the users
2948  * responsibility to honor the inflip and outflip flags. They can not
2949  * be flipped here because an outflip=1 edge and an inflip=0 edge
2950  * following it may in fact be the same edge. This could be dealt
2951  * with by giving the partition struct a COPY of the inhit and outhit
2952  * rather than a pointer, but that's more cycles than the neatness is
2953  * worth.
2954  *
2955  * Inputs -
2956  * Pointer to first segment in seg chain.
2957  * Pointer to head of circular doubly-linked list of
2958  * partitions of the original ray.
2959  *
2960  * Outputs -
2961  * Partitions, queued on doubly-linked list specified.
2962  *
2963  * Notes -
2964  * It is the responsibility of the CALLER to free the seg chain, as
2965  * well as the partition list that we return.
2966  */
2967 RT_EXPORT extern void rt_boolweave(struct seg *out_hd,
2968  struct seg *in_hd,
2969  struct partition *PartHeadp,
2970  struct application *ap);
2971 /* Eval booleans over partitions */
2972 
2973 /**
2974  * Consider each partition on the sorted & woven input partition list.
2975  * If the partition ends before this box's start, discard it
2976  * immediately. If the partition begins beyond this box's end,
2977  * return.
2978  *
2979  * Next, evaluate the boolean expression tree for all regions that
2980  * have some presence in the partition.
2981  *
2982  * If 0 regions result, continue with next partition.
2983  *
2984  * If 1 region results, a valid hit has occurred, so transfer the
2985  * partition from the Input list to the Final list.
2986  *
2987  * If 2 or more regions claim the partition, then an overlap exists.
2988  *
2989  * If the overlap handler gives a non-zero return, then the
2990  * overlapping partition is kept, with the region ID being the first
2991  * one encountered.
2992  *
2993  * Otherwise, the partition is eliminated from further consideration.
2994  *
2995  * All partitions in the indicated range of the ray are evaluated.
2996  * All partitions which really exist (booleval is true) are appended
2997  * to the Final partition list. All partitions on the Final partition
2998  * list have completely valid entry and exit information, except for
2999  * the last partition's exit information when a_onehit!=0 and a_onehit
3000  * is odd.
3001  *
3002  * The flag a_onehit is interpreted as follows:
3003  *
3004  * If a_onehit = 0, then the ray is traced to +infinity, and all hit
3005  * points in the final partition list are valid.
3006  *
3007  * If a_onehit != 0, the ray is traced through a_onehit hit points.
3008  * (Recall that each partition has 2 hit points, entry and exit).
3009  * Thus, if a_onehit is odd, the value of pt_outhit.hit_dist in the
3010  * last partition may be incorrect; this should not mater because the
3011  * application specifically said it only wanted pt_inhit there. This
3012  * is most commonly seen when a_onehit = 1, which is useful for
3013  * lighting models. Not having to correctly determine the exit point
3014  * can result in a significant savings of computer time.
3015  *
3016  * If a_onehit is negative, it indicates the number of non-air hits
3017  * needed.
3018  *
3019  * Returns -
3020  * 0 If more partitions need to be done
3021  * 1 Requested number of hits are available in FinalHdp
3022  *
3023  * The caller must free whatever is in both partition chains.
3024  *
3025  * NOTES for code improvements -
3026  *
3027  * With a_onehit != 0, it is difficult to stop at the 'enddist' value
3028  * (or the a_ray_length value), and always get correct results. Need
3029  * to take into account some additional factors:
3030  *
3031  * 1) A region shouldn't be evaluated until all its solids have been
3032  * intersected, to prevent the "CERN" problem of out points being
3033  * wrong because subtracted solids aren't intersected yet.
3034  *
3035  * Maybe "all" solids don't have to be intersected, but some strong
3036  * statements are needed along these lines.
3037  *
3038  * A region is definitely ready to be evaluated IF all its solids
3039  * have been intersected.
3040  *
3041  * 2) A partition shouldn't be evaluated until all the regions within
3042  * it are ready to be evaluated.
3043  */
3044 RT_EXPORT extern int rt_boolfinal(struct partition *InputHdp,
3045  struct partition *FinalHdp,
3046  fastf_t startdist,
3047  fastf_t enddist,
3048  struct bu_ptbl *regionbits,
3049  struct application *ap,
3050  const struct bu_bitv *solidbits);
3051 
3052 /**
3053  * Increase the size of re_boolstack to double the previous size.
3054  * Depend on bu_realloc() to copy the previous data to the new area
3055  * when the size is increased.
3056  *
3057  * Return the new pointer for what was previously the last element.
3058  */
3059 RT_EXPORT extern void rt_grow_boolstack(struct resource *res);
3060 
3061 /* Print a soltab */
3062 RT_EXPORT extern void rt_pr_soltab(const struct soltab *stp);
3063 /* Print a region */
3064 RT_EXPORT extern void rt_pr_region(const struct region *rp);
3065 /* Print an expr tree */
3066 RT_EXPORT extern void rt_pr_tree(const union tree *tp,
3067  int lvl);
3068 /* Print value of tree for a partition */
3069 RT_EXPORT extern void rt_pr_tree_val(const union tree *tp,
3070  const struct partition *partp,
3071  int pr_name, int lvl);
3072 /* Print a partition */
3073 RT_EXPORT extern void rt_pr_pt(const struct rt_i *rtip,
3074  const struct partition *pp);
3075 /* Print a bit vector */
3076 RT_EXPORT extern void rt_pr_hit(const char *str,
3077  const struct hit *hitp);
3078 
3079 /* rt_fastf_float, rt_mat_dbmat, rt_dbmat_mat
3080  * declarations moved to db.h */
3081 
3082 /**
3083  * Go through all the solids in the model, given the model mins and
3084  * maxes, and generate a cutting tree. A strategy better than
3085  * incrementally cutting each solid is to build a box node which
3086  * contains everything in the model, and optimize it.
3087  *
3088  * This is the main entry point into space partitioning from
3089  * rt_prep().
3090  */
3091 RT_EXPORT extern void rt_cut_it(struct rt_i *rtip,
3092  int ncpu);
3093 
3094 /* print cut node */
3095 
3096 /**
3097  * Print out a cut tree.
3098  *
3099  * lvl is recursion level.
3100  */
3101 RT_EXPORT extern void rt_pr_cut(const union cutter *cutp,
3102  int lvl);
3103 /* free a cut tree */
3104 /**
3105  * Free a whole cut tree below the indicated node. The strategy we
3106  * use here is to free everything BELOW the given node, so as not to
3107  * clobber rti_CutHead !
3108  */
3109 RT_EXPORT extern void rt_fr_cut(struct rt_i *rtip,
3110  union cutter *cutp);
3111 
3112 /* regionid-driven color override */
3113 
3114 /* bool.c */
3115 
3116 /**
3117  * XXX This routine seems to free things more than once. For a
3118  * temporary measure, don't free things.
3119  */
3120 RT_EXPORT extern void rt_rebuild_overlaps(struct partition *PartHdp,
3121  struct application *ap,
3122  int rebuild_fastgen_plates_only);
3123 
3124 /**
3125  * Return the length of a partition linked list.
3126  */
3127 RT_EXPORT extern int rt_partition_len(const struct partition *partheadp);
3128 
3129 /**
3130  * Default handler for overlaps in rt_boolfinal().
3131  *
3132  * Returns -
3133  * 0 to eliminate partition with overlap entirely
3134  * 1 to retain partition in output list, claimed by reg1
3135  * 2 to retain partition in output list, claimed by reg2
3136  */
3137 RT_EXPORT extern int rt_defoverlap(struct application *ap,
3138  struct partition *pp,
3139  struct region *reg1,
3140  struct region *reg2,
3141  struct partition *pheadp);
3142 
3143 /* extend a cut box */
3144 
3145 /* cut.c */
3146 
3147 RT_EXPORT extern void rt_pr_cut_info(const struct rt_i *rtip,
3148  const char *str);
3149 RT_EXPORT extern void remove_from_bsp(struct soltab *stp,
3150  union cutter *cutp,
3151  struct bn_tol *tol);
3152 RT_EXPORT extern void insert_in_bsp(struct soltab *stp,
3153  union cutter *cutp);
3154 RT_EXPORT extern void fill_out_bsp(struct rt_i *rtip,
3155  union cutter *cutp,
3156  struct resource *resp,
3157  fastf_t bb[6]);
3158 
3159 /**
3160  * Add a solid into a given boxnode, extending the lists there. This
3161  * is used only for building the root node, which will then be
3162  * subdivided.
3163  *
3164  * Solids with pieces go onto a special list.
3165  */
3166 RT_EXPORT extern void rt_cut_extend(union cutter *cutp,
3167  struct soltab *stp,
3168  const struct rt_i *rtip);
3169 /* find RPP of one region */
3170 
3171 /**
3172  * Calculate the bounding RPP for a region given the name of the
3173  * region node in the database. See remarks in _rt_getregion() above
3174  * for name conventions. Returns 0 for failure (and prints a
3175  * diagnostic), or 1 for success.
3176  */
3177 RT_EXPORT extern int rt_rpp_region(struct rt_i *rtip,
3178  const char *reg_name,
3179  fastf_t *min_rpp,
3180  fastf_t *max_rpp);
3181 
3182 /**
3183  * Compute the intersections of a ray with a rectangular
3184  * parallelepiped (RPP) that has faces parallel to the coordinate
3185  * planes
3186  *
3187  * The algorithm here was developed by Gary Kuehl for GIFT. A good
3188  * description of the approach used can be found in "??" by XYZZY and
3189  * Barsky, ACM Transactions on Graphics, Vol 3 No 1, January 1984.
3190  *
3191  * Note: The computation of entry and exit distance is mandatory, as
3192  * the final test catches the majority of misses.
3193  *
3194  * Note: A hit is returned if the intersect is behind the start point.
3195  *
3196  * Returns -
3197  * 0 if ray does not hit RPP,
3198  * !0 if ray hits RPP.
3199  *
3200  * Implicit return -
3201  * rp->r_min = dist from start of ray to point at which ray ENTERS solid
3202  * rp->r_max = dist from start of ray to point at which ray LEAVES solid
3203  */
3204 RT_EXPORT extern int rt_in_rpp(struct xray *rp,
3205  const fastf_t *invdir,
3206  const fastf_t *min,
3207  const fastf_t *max);
3208 
3209 
3210 /**
3211  * Return pointer to cell 'n' along a given ray. Used for debugging
3212  * of how space partitioning interacts with shootray. Intended to
3213  * mirror the operation of rt_shootray(). The first cell is 0.
3214  */
3215 RT_EXPORT extern const union cutter *rt_cell_n_on_ray(struct application *ap,
3216  int n);
3217 
3218 /*
3219  * The rtip->rti_CutFree list can not be freed directly because is
3220  * bulk allocated. Fortunately, we have a list of all the
3221  * bu_malloc()'ed blocks. This routine may be called before the first
3222  * frame is done, so it must be prepared for uninitialized items.
3223  */
3224 RT_EXPORT extern void rt_cut_clean(struct rt_i *rtip);
3225 
3226 /* Find the bounding box given a struct rt_db_internal : bbox.c */
3227 
3228 /**
3229  *
3230  * Calculate the bounding RPP of the internal format passed in 'ip'.
3231  * The bounding RPP is returned in rpp_min and rpp_max in mm FIXME:
3232  * This function needs to be modified to eliminate the rt_gettree()
3233  * call and the related parameters. In that case calling code needs to
3234  * call another function before calling this function That function
3235  * must create a union tree with tr_a.tu_op=OP_SOLID. It can look as
3236  * follows : union tree * rt_comb_tree(const struct db_i *dbip, const
3237  * struct rt_db_internal *ip). The tree is set in the struct
3238  * rt_db_internal * ip argument. Once a suitable tree is set in the
3239  * ip, then this function can be called with the struct rt_db_internal
3240  * * to return the BB properly without getting stuck during tree
3241  * traversal in rt_bound_tree()
3242  *
3243  * Returns -
3244  * 0 success
3245  * -1 failure, the model bounds could not be got
3246  *
3247  */
3248 RT_EXPORT extern int rt_bound_internal(struct db_i *dbip,
3249  struct directory *dp,
3250  point_t rpp_min,
3251  point_t rpp_max);
3252 
3253 /* cmd.c */
3254 /* Read semi-colon terminated line */
3255 
3256 /*
3257  * Read one semi-colon terminated string of arbitrary length from the
3258  * given file into a dynamically allocated buffer. Various commenting
3259  * and escaping conventions are implemented here.
3260  *
3261  * Returns:
3262  * NULL on EOF
3263  * char * on good read
3264  */
3265 RT_EXPORT extern char *rt_read_cmd(FILE *fp);
3266 /* do cmd from string via cmd table */
3267 
3268 /*
3269  * Slice up input buffer into whitespace separated "words", look up
3270  * the first word as a command, and if it has the correct number of
3271  * args, call that function. Negative min/max values in the tp
3272  * command table effectively mean that they're not bounded.
3273  *
3274  * Expected to return -1 to halt command processing loop.
3275  *
3276  * Based heavily on mged/cmd.c by Chuck Kennedy.
3277  *
3278  * DEPRECATED: needs to migrate to libbu
3279  */
3280 RT_EXPORT extern int rt_do_cmd(struct rt_i *rtip,
3281  const char *ilp,
3282  const struct command_tab *tp);
3283 
3284 /* The database library */
3285 
3286 /* wdb.c */
3287 /** @addtogroup wdb */
3288 /** @{ */
3289 /** @file librt/wdb.c
3290  *
3291  * Routines to allow libwdb to use librt's import/export interface,
3292  * rather than having to know about the database formats directly.
3293  *
3294  */
3295 RT_EXPORT extern struct rt_wdb *wdb_fopen(const char *filename);
3296 
3297 
3298 /**
3299  * Create a libwdb output stream destined for a disk file. This will
3300  * destroy any existing file by this name, and start fresh. The file
3301  * is then opened in the normal "update" mode and an in-memory
3302  * directory is built along the way, allowing retrievals and object
3303  * replacements as needed.
3304  *
3305  * Users can change the database title by calling: ???
3306  */
3307 RT_EXPORT extern struct rt_wdb *wdb_fopen_v(const char *filename,
3308  int version);
3309 
3310 
3311 /**
3312  * Create a libwdb output stream destined for an existing BRL-CAD
3313  * database, already opened via a db_open() call.
3314  *
3315  * RT_WDB_TYPE_DB_DISK Add to on-disk database
3316  * RT_WDB_TYPE_DB_DISK_APPEND_ONLY Add to on-disk database, don't clobber existing names, use prefix
3317  * RT_WDB_TYPE_DB_INMEM Add to in-memory database only
3318  * RT_WDB_TYPE_DB_INMEM_APPEND_ONLY Ditto, but give errors if name in use.
3319  */
3320 RT_EXPORT extern struct rt_wdb *wdb_dbopen(struct db_i *dbip,
3321  int mode);
3322 
3323 
3324 /**
3325  * Returns -
3326  * 0 and modified *internp;
3327  * -1 ft_import failure (from rt_db_get_internal)
3328  * -2 db_get_external failure (from rt_db_get_internal)
3329  * -3 Attempt to import from write-only (stream) file.
3330  * -4 Name not found in database TOC.
3331  *
3332  * NON-PARALLEL because of rt_uniresource
3333  */
3334 RT_EXPORT extern int wdb_import(struct rt_wdb *wdbp,
3335  struct rt_db_internal *internp,
3336  const char *name,
3337  const mat_t mat);
3338 
3339 
3340 /**
3341  * The caller must free "ep".
3342  *
3343  * Returns -
3344  * 0 OK
3345  * <0 error
3346  */
3347 RT_EXPORT extern int wdb_export_external(struct rt_wdb *wdbp,
3348  struct bu_external *ep,
3349  const char *name,
3350  int flags,
3351  unsigned char minor_type);
3352 
3353 
3354 /**
3355  * Convert the internal representation of a solid to the external one,
3356  * and write it into the database.
3357  *
3358  * The internal representation is always freed. This is the analog of
3359  * rt_db_put_internal() for rt_wdb objects.
3360  *
3361  * Use this routine in preference to wdb_export() whenever the caller
3362  * already has an rt_db_internal structure handy.
3363  *
3364  * NON-PARALLEL because of rt_uniresource
3365  *
3366  * Returns -
3367  * 0 OK
3368  * <0 error
3369  */
3370 RT_EXPORT extern int wdb_put_internal(struct rt_wdb *wdbp,
3371  const char *name,
3372  struct rt_db_internal *ip,
3373  double local2mm);
3374 
3375 
3376 /**
3377  * Export an in-memory representation of an object, as described in
3378  * the file h/rtgeom.h, into the indicated database.
3379  *
3380  * The internal representation (gp) is always freed.
3381  *
3382  * WARNING: The caller must be careful not to double-free gp,
3383  * particularly if it's been extracted from an rt_db_internal, e.g. by
3384  * passing intern.idb_ptr for gp.
3385  *
3386  * If the caller has an rt_db_internal structure handy already, they
3387  * should call wdb_put_internal() directly -- this is a convenience
3388  * routine intended primarily for internal use in LIBWDB.
3389  *
3390  * Returns -
3391  * 0 OK
3392  * <0 error
3393  */
3394 RT_EXPORT extern int wdb_export(struct rt_wdb *wdbp,
3395  const char *name,
3396  void *gp,
3397  int id,
3398  double local2mm);
3399 RT_EXPORT extern void wdb_init(struct rt_wdb *wdbp,
3400  struct db_i *dbip,
3401  int mode);
3402 
3403 
3404 /**
3405  * Release from associated database "file", destroy dynamic data
3406  * structure.
3407  */
3408 RT_EXPORT extern void wdb_close(struct rt_wdb *wdbp);
3409 
3410 
3411 /**
3412  * Given the name of a database object or a full path to a leaf
3413  * object, obtain the internal form of that leaf. Packaged separately
3414  * mainly to make available nice Tcl error handling.
3415  *
3416  * Returns -
3417  * BRLCAD_OK
3418  * BRLCAD_ERROR
3419  */
3420 RT_EXPORT extern int wdb_import_from_path(struct bu_vls *logstr,
3421  struct rt_db_internal *ip,
3422  const char *path,
3423  struct rt_wdb *wdb);
3424 
3425 
3426 /**
3427  * Given the name of a database object or a full path to a leaf
3428  * object, obtain the internal form of that leaf. Packaged separately
3429  * mainly to make available nice Tcl error handling. Additionally,
3430  * copies ts.ts_mat to matp.
3431  *
3432  * Returns -
3433  * BRLCAD_OK
3434  * BRLCAD_ERROR
3435  */
3436 RT_EXPORT extern int wdb_import_from_path2(struct bu_vls *logstr,
3437  struct rt_db_internal *ip,
3438  const char *path,
3439  struct rt_wdb *wdb,
3440  matp_t matp);
3441 
3442 /** @} */
3443 
3444 /* db_anim.c */
3445 RT_EXPORT extern struct animate *db_parse_1anim(struct db_i *dbip,
3446  int argc,
3447  const char **argv);
3448 
3449 
3450 /**
3451  * A common parser for mged and rt. Experimental. Not the best name
3452  * for this.
3453  */
3454 RT_EXPORT extern int db_parse_anim(struct db_i *dbip,
3455  int argc,
3456  const char **argv);
3457 
3458 /**
3459  * Add a user-supplied animate structure to the end of the chain of
3460  * such structures hanging from the directory structure of the last
3461  * node of the path specifier. When 'root' is non-zero, this matrix
3462  * is located at the root of the tree itself, rather than an arc, and
3463  * is stored differently.
3464  *
3465  * In the future, might want to check to make sure that callers
3466  * directory references are in the right database (dbip).
3467  */
3468 RT_EXPORT extern int db_add_anim(struct db_i *dbip,
3469  struct animate *anp,
3470  int root);
3471 
3472 /**
3473  * Perform the one animation operation. Leave results in form that
3474  * additional operations can be cascaded.
3475  *
3476  * Note that 'materp' may be a null pointer, signifying that the
3477  * region has already been finalized above this point in the tree.
3478  */
3479 RT_EXPORT extern int db_do_anim(struct animate *anp,
3480  mat_t stack,
3481  mat_t arc,
3482  struct mater_info *materp);
3483 
3484 /**
3485  * Release chain of animation structures
3486  *
3487  * An unfortunate choice of name.
3488  */
3489 RT_EXPORT extern void db_free_anim(struct db_i *dbip);
3490 
3491 /**
3492  * Writes 'count' bytes into at file offset 'offset' from buffer at
3493  * 'addr'. A wrapper for the UNIX write() sys-call that takes into
3494  * account syscall semaphores, stdio-only machines, and in-memory
3495  * buffering.
3496  *
3497  * Returns -
3498  * 0 OK
3499  * -1 FAILURE
3500  */
3501 /* should be HIDDEN */
3502 RT_EXPORT extern void db_write_anim(FILE *fop,
3503  struct animate *anp);
3504 
3505 /**
3506  * Parse one "anim" type command into an "animate" structure.
3507  *
3508  * argv[1] must be the "a/b" path spec,
3509  * argv[2] indicates what is to be animated on that arc.
3510  */
3511 RT_EXPORT extern struct animate *db_parse_1anim(struct db_i *dbip,
3512  int argc,
3513  const char **argv);
3514 
3515 
3516 /**
3517  * Free one animation structure
3518  */
3519 RT_EXPORT extern void db_free_1anim(struct animate *anp);
3520 
3521 /* db_path.c */
3522 
3523 /**
3524  * Normalize a BRL-CAD path according to rules used for realpath, but
3525  * without filesystem (or database object) validation.
3526  *
3527  * @return
3528  * A STATIC buffer is returned. It is the caller's responsibility to
3529  * call bu_strdup() or make other provisions to save the returned
3530  * string, before calling again.
3531  */
3532 RT_EXPORT extern const char *db_normalize(const char *path);
3533 
3534 
3535 /* search.c */
3536 
3537 #include "./rt/search.h"
3538 
3539 /* db_open.c */
3540 /**
3541  * Ensure that the on-disk database has been completely written out of
3542  * the operating system's cache.
3543  */
3544 RT_EXPORT extern void db_sync(struct db_i *dbip);
3545 
3546 
3547 /**
3548  * for db_open(), open the specified file as read-only
3549  */
3550 #define DB_OPEN_READONLY "r"
3551 
3552 /**
3553  * for db_open(), open the specified file as read-write
3554  */
3555 #define DB_OPEN_READWRITE "rw"
3556 
3557 /**
3558  * Open the named database.
3559  *
3560  * The 'name' parameter specifies the file or filepath to a .g
3561  * geometry database file for reading and/or writing.
3562  *
3563  * The 'mode' parameter specifies whether to open read-only or in
3564  * read-write mode, specified via the DB_OPEN_READONLY and
3565  * DB_OPEN_READWRITE symbols respectively.
3566  *
3567  * As a convenience, the returned db_t structure's dbi_filepath field
3568  * is a C-style argv array of dirs to search when attempting to open
3569  * related files (such as data files for EBM solids or texture-maps).
3570  * The default values are "." and the directory containing the ".g"
3571  * file. They may be overridden by setting the environment variable
3572  * BRLCAD_FILE_PATH.
3573  *
3574  * Returns:
3575  * DBI_NULL error
3576  * db_i * success
3577  */
3578 RT_EXPORT extern struct db_i *
3579 db_open(const char *name, const char *mode);
3580 
3581 
3582 /* create a new model database */
3583 /**
3584  * Create a new database containing just a header record, regardless
3585  * of whether the database previously existed or not, and open it for
3586  * reading and writing.
3587  *
3588  * This routine also calls db_dirbuild(), so the caller doesn't need
3589  * to.
3590  *
3591  * Returns:
3592  * DBI_NULL on error
3593  * db_i * on success
3594  */
3595 RT_EXPORT extern struct db_i *db_create(const char *name,
3596  int version);
3597 
3598 /* close a model database */
3599 /**
3600  * De-register a client of this database instance, if provided, and
3601  * close out the instance.
3602  */
3603 RT_EXPORT extern void db_close_client(struct db_i *dbip,
3604  long *client);
3605 
3606 /**
3607  * Close a database, releasing dynamic memory Wait until last user is
3608  * done, though.
3609  */
3610 RT_EXPORT extern void db_close(struct db_i *dbip);
3611 
3612 
3613 /* dump a full copy of a database */
3614 /**
3615  * Dump a full copy of one database into another. This is a good way
3616  * of committing a ".inmem" database to a ".g" file. The input is a
3617  * database instance, the output is a LIBWDB object, which could be a
3618  * disk file or another database instance.
3619  *
3620  * Returns -
3621  * -1 error
3622  * 0 success
3623  */
3624 RT_EXPORT extern int db_dump(struct rt_wdb *wdbp,
3625  struct db_i *dbip);
3626 
3627 /**
3628  * Obtain an additional instance of this same database. A new client
3629  * is registered at the same time if one is specified.
3630  */
3631 RT_EXPORT extern struct db_i *db_clone_dbi(struct db_i *dbip,
3632  long *client);
3633 
3634 
3635 /**
3636  * Create a v5 database "free" object of the specified size, and place
3637  * it at the indicated location in the database.
3638  *
3639  * There are two interesting cases:
3640  * - The free object is "small". Just write it all at once.
3641  * - The free object is "large". Write header and trailer
3642  * separately
3643  *
3644  * @return 0 OK
3645  * @return -1 Fail. This is a horrible error.
3646  */
3647 RT_EXPORT extern int db5_write_free(struct db_i *dbip,
3648  struct directory *dp,
3649  size_t length);
3650 
3651 
3652 /**
3653  * Change the size of a v5 database object.
3654  *
3655  * If the object is getting smaller, break it into two pieces, and
3656  * write out free objects for both. The caller is expected to
3657  * re-write new data on the first one.
3658  *
3659  * If the object is getting larger, seek a suitable "hole" large
3660  * enough to hold it, throwing back any surplus, properly marked.
3661  *
3662  * If the object is getting larger and there is no suitable "hole" in
3663  * the database, extend the file, write a free object in the new
3664  * space, and write a free object in the old space.
3665  *
3666  * There is no point to trying to extend in place, that would require
3667  * two searches through the memory map, and doesn't save any disk I/O.
3668  *
3669  * Returns -
3670  * 0 OK
3671  * -1 Failure
3672  */
3673 RT_EXPORT extern int db5_realloc(struct db_i *dbip,
3674  struct directory *dp,
3675  struct bu_external *ep);
3676 
3677 
3678 /**
3679  * A routine for merging together the three optional parts of an
3680  * object into the final on-disk format. Results in extra data
3681  * copies, but serves as a starting point for testing. Any of name,
3682  * attrib, and body may be null.
3683  */
3684 RT_EXPORT extern void db5_export_object3(struct bu_external *out,
3685  int dli,
3686  const char *name,
3687  const unsigned char hidden,
3688  const struct bu_external *attrib,
3689  const struct bu_external *body,
3690  int major,
3691  int minor,
3692  int a_zzz,
3693  int b_zzz);
3694 
3695 
3696 /**
3697  * The attributes are taken from ip->idb_avs
3698  *
3699  * If present, convert attributes to on-disk format. This must happen
3700  * after exporting the body, in case the ft_export5() method happened
3701  * to extend the attribute set. Combinations are one "solid" which
3702  * does this.
3703  *
3704  * The internal representation is NOT freed, that's the caller's job.
3705  *
3706  * The 'ext' pointer is accepted in uninitialized form, and an
3707  * initialized structure is always returned, so that the caller may
3708  * free it even when an error return is given.
3709  *
3710  * Returns -
3711  * 0 OK
3712  * -1 FAIL
3713  */
3714 RT_EXPORT extern int rt_db_cvt_to_external5(struct bu_external *ext,
3715  const char *name,
3716  const struct rt_db_internal *ip,
3717  double conv2mm,
3718  struct db_i *dbip,
3719  struct resource *resp,
3720  const int major);
3721 
3722 
3723 /*
3724  * Modify name of external object, if necessary.
3725  */
3726 RT_EXPORT extern int db_wrap_v5_external(struct bu_external *ep,
3727  const char *name);
3728 
3729 
3730 /**
3731  * Get an object from the database, and convert it into its internal
3732  * representation.
3733  *
3734  * Applications and middleware shouldn't call this directly, they
3735  * should use the generic interface "rt_db_get_internal()".
3736  *
3737  * Returns -
3738  * <0 On error
3739  * id On success.
3740  */
3741 RT_EXPORT extern int rt_db_get_internal5(struct rt_db_internal *ip,
3742  const struct directory *dp,
3743  const struct db_i *dbip,
3744  const mat_t mat,
3745  struct resource *resp);
3746 
3747 
3748 /**
3749  * Convert the internal representation of a solid to the external one,
3750  * and write it into the database.
3751  *
3752  * Applications and middleware shouldn't call this directly, they
3753  * should use the version-generic interface "rt_db_put_internal()".
3754  *
3755  * The internal representation is always freed. (Not the pointer,
3756  * just the contents).
3757  *
3758  * Returns -
3759  * <0 error
3760  * 0 success
3761  */
3762 RT_EXPORT extern int rt_db_put_internal5(struct directory *dp,
3763  struct db_i *dbip,
3764  struct rt_db_internal *ip,
3765  struct resource *resp,
3766  const int major);
3767 
3768 
3769 /**
3770  * Make only the front (header) portion of a free object. This is
3771  * used when operating on very large contiguous free objects in the
3772  * database (e.g. 50 MBytes).
3773  */
3774 RT_EXPORT extern void db5_make_free_object_hdr(struct bu_external *ep,
3775  size_t length);
3776 
3777 
3778 /**
3779  * Make a complete, zero-filled, free object. Note that free objects
3780  * can sometimes get quite large.
3781  */
3782 RT_EXPORT extern void db5_make_free_object(struct bu_external *ep,
3783  size_t length);
3784 
3785 
3786 /**
3787  * Given a variable-width length field in network order (XDR), store
3788  * it in *lenp.
3789  *
3790  * This routine processes signed values.
3791  *
3792  * Returns -
3793  * The number of bytes of input that were decoded.
3794  */
3795 RT_EXPORT extern int db5_decode_signed(size_t *lenp,
3796  const unsigned char *cp,
3797  int format);
3798 
3799 /**
3800  * Given a variable-width length field in network order (XDR), store
3801  * it in *lenp.
3802  *
3803  * This routine processes unsigned values.
3804  *
3805  * Returns -
3806  * The number of bytes of input that were decoded.
3807  */
3808 RT_EXPORT extern size_t db5_decode_length(size_t *lenp,
3809  const unsigned char *cp,
3810  int format);
3811 
3812 /**
3813  * Given a number to encode, decide which is the smallest encoding
3814  * format which will contain it.
3815  */
3816 RT_EXPORT extern int db5_select_length_encoding(size_t len);
3817 
3818 
3819 RT_EXPORT extern void db5_import_color_table(char *cp);
3820 
3821 /**
3822  * Convert the on-disk encoding into a handy easy-to-use
3823  * bu_attribute_value_set structure.
3824  *
3825  * Take advantage of the readonly_min/readonly_max capability so that
3826  * we don't have to bu_strdup() each string, but can simply point to
3827  * it in the provided buffer *ap. Important implication: don't free
3828  * *ap until you're done with this avs.
3829  *
3830  * The upshot of this is that bu_avs_add() and bu_avs_remove() can be
3831  * safely used with this *avs.
3832  *
3833  * Returns -
3834  * >0 count of attributes successfully imported
3835  * -1 Error, mal-formed input
3836  */
3837 RT_EXPORT extern int db5_import_attributes(struct bu_attribute_value_set *avs,
3838  const struct bu_external *ap);
3839 
3840 /**
3841  * Encode the attribute-value pair information into the external
3842  * on-disk format.
3843  *
3844  * The on-disk encoding is:
3845  *
3846  * name1 NULL value1 NULL ... nameN NULL valueN NULL NULL
3847  *
3848  * 'ext' is initialized on behalf of the caller.
3849  */
3850 RT_EXPORT extern void db5_export_attributes(struct bu_external *ap,
3851  const struct bu_attribute_value_set *avs);
3852 
3853 
3854 /**
3855  * Returns -
3856  * 0 on success
3857  * -1 on EOF
3858  * -2 on error
3859  */
3860 RT_EXPORT extern int db5_get_raw_internal_fp(struct db5_raw_internal *rip,
3861  FILE *fp);
3862 
3863 /**
3864  * Verify that this is a valid header for a BRL-CAD v5 database.
3865  *
3866  * Returns -
3867  * 0 Not valid v5 header
3868  * 1 Valid v5 header
3869  */
3870 RT_EXPORT extern int db5_header_is_valid(const unsigned char *hp);
3871 
3872 RT_EXPORT extern int db5_fwrite_ident(FILE *,
3873  const char *,
3874  double);
3875 
3876 
3877 /**
3878  * Put the old region-id-color-table into the global object. A null
3879  * attribute is set if the material table is empty.
3880  *
3881  * Returns -
3882  * <0 error
3883  * 0 OK
3884  */
3885 RT_EXPORT extern int db5_put_color_table(struct db_i *dbip);
3886 RT_EXPORT extern int db5_update_ident(struct db_i *dbip,
3887  const char *title,
3888  double local2mm);
3889 
3890 /**
3891  *
3892  * Given that caller already has an external representation of the
3893  * database object, update it to have a new name (taken from
3894  * dp->d_namep) in that external representation, and write the new
3895  * object into the database, obtaining different storage if the size
3896  * has changed.
3897  *
3898  * Changing the name on a v5 object is a relatively expensive
3899  * operation.
3900  *
3901  * Caller is responsible for freeing memory of external
3902  * representation, using bu_free_external().
3903  *
3904  * This routine is used to efficiently support MGED's "cp" and "keep"
3905  * commands, which don't need to import and decompress objects just to
3906  * rename and copy them.
3907  *
3908  * Returns -
3909  * -1 error
3910  * 0 success
3911  */
3912 RT_EXPORT extern int db_put_external5(struct bu_external *ep,
3913  struct directory *dp,
3914  struct db_i *dbip);
3915 
3916 /**
3917  * Update an arbitrary number of attributes on a given database
3918  * object. For efficiency, this is done without looking at the object
3919  * body at all.
3920  *
3921  * Contents of the bu_attribute_value_set are freed, but not the
3922  * struct itself.
3923  *
3924  * Returns -
3925  * 0 on success
3926  * <0 on error
3927  */
3928 RT_EXPORT extern int db5_update_attributes(struct directory *dp,
3929  struct bu_attribute_value_set *avsp,
3930  struct db_i *dbip);
3931 
3932 /**
3933  * A convenience routine to update the value of a single attribute.
3934  *
3935  * Returns -
3936  * 0 on success
3937  * <0 on error
3938  */
3939 RT_EXPORT extern int db5_update_attribute(const char *obj_name,
3940  const char *aname,
3941  const char *value,
3942  struct db_i *dbip);
3943 
3944 /**
3945  * Replace the attributes of a given database object.
3946  *
3947  * For efficiency, this is done without looking at the object body at
3948  * all. Contents of the bu_attribute_value_set are freed, but not the
3949  * struct itself.
3950  *
3951  * Returns -
3952  * 0 on success
3953  * <0 on error
3954  */
3955 RT_EXPORT extern int db5_replace_attributes(struct directory *dp,
3956  struct bu_attribute_value_set *avsp,
3957  struct db_i *dbip);
3958 
3959 /**
3960  *
3961  * Get attributes for an object pointed to by *dp
3962  *
3963  * returns:
3964  * 0 - all is well
3965  * <0 - error
3966  */
3967 RT_EXPORT extern int db5_get_attributes(const struct db_i *dbip,
3968  struct bu_attribute_value_set *avs,
3969  const struct directory *dp);
3970 
3971 /* db_comb.c */
3972 
3973 /**
3974  * Return count of number of leaf nodes in this tree.
3975  */
3976 RT_EXPORT extern size_t db_tree_nleaves(const union tree *tp);
3977 
3978 /**
3979  * Take a binary tree in "V4-ready" layout (non-unions pushed below
3980  * unions, left-heavy), and flatten it into an array layout, ready for
3981  * conversion back to the GIFT-inspired V4 database format.
3982  *
3983  * This is done using the db_non_union_push() routine.
3984  *
3985  * If argument 'free' is non-zero, then the non-leaf nodes are freed
3986  * along the way, to prevent memory leaks. In this case, the caller's
3987  * copy of 'tp' will be invalid upon return.
3988  *
3989  * When invoked at the very top of the tree, the op argument must be
3990  * OP_UNION.
3991  */
3992 RT_EXPORT extern struct rt_tree_array *db_flatten_tree(struct rt_tree_array *rt_tree_array, union tree *tp, int op, int avail, struct resource *resp);
3993 
3994 /**
3995  * Import a combination record from a V4 database into internal form.
3996  */
3997 RT_EXPORT extern int rt_comb_import4(struct rt_db_internal *ip,
3998  const struct bu_external *ep,
3999  const mat_t matrix, /* NULL if identity */
4000  const struct db_i *dbip,
4001  struct resource *resp);
4002 
4003 RT_EXPORT extern int rt_comb_export4(struct bu_external *ep,
4004  const struct rt_db_internal *ip,
4005  double local2mm,
4006  const struct db_i *dbip,
4007  struct resource *resp);
4008 
4009 /**
4010  * Produce a GIFT-compatible listing, one "member" per line,
4011  * regardless of the structure of the tree we've been given.
4012  */
4013 RT_EXPORT extern void db_tree_flatten_describe(struct bu_vls *vls,
4014  const union tree *tp,
4015  int indented,
4016  int lvl,
4017  double mm2local,
4018  struct resource *resp);
4019 
4020 RT_EXPORT extern void db_tree_describe(struct bu_vls *vls,
4021  const union tree *tp,
4022  int indented,
4023  int lvl,
4024  double mm2local);
4025 
4026 RT_EXPORT extern void db_comb_describe(struct bu_vls *str,
4027  const struct rt_comb_internal *comb,
4028  int verbose,
4029  double mm2local,
4030  struct resource *resp);
4031 
4032 /**
4033  * OBJ[ID_COMBINATION].ft_describe() method
4034  */
4035 RT_EXPORT extern int rt_comb_describe(struct bu_vls *str,
4036  const struct rt_db_internal *ip,
4037  int verbose,
4038  double mm2local,
4039  struct resource *resp,
4040  struct db_i *db_i);
4041 
4042 /*==================== END g_comb.c / table.c interface ========== */
4043 
4044 /**
4045  * As the v4 database does not really have the notion of "wrapping",
4046  * this function writes the object name into the proper place (a
4047  * standard location in all granules).
4048  */
4049 RT_EXPORT extern void db_wrap_v4_external(struct bu_external *op,
4050  const char *name);
4051 
4052 /* Some export support routines */
4053 
4054 /**
4055  * Support routine for db_ck_v4gift_tree().
4056  * Ensure that the tree below 'tp' is left-heavy, i.e. that there are
4057  * nothing but solids on the right side of any binary operations.
4058  *
4059  * Returns -
4060  * -1 ERROR
4061  * 0 OK
4062  */
4063 RT_EXPORT extern int db_ck_left_heavy_tree(const union tree *tp,
4064  int no_unions);
4065 
4066 /**
4067  * Look a gift-tree in the mouth.
4068  *
4069  * Ensure that this boolean tree conforms to the GIFT convention that
4070  * union operations must bind the loosest.
4071  *
4072  * There are two stages to this check:
4073  * 1) Ensure that if unions are present they are all at the root of tree,
4074  * 2) Ensure non-union children of union nodes are all left-heavy
4075  * (nothing but solid nodes permitted on rhs of binary operators).
4076  *
4077  * Returns -
4078  * -1 ERROR
4079  * 0 OK
4080  */
4081 RT_EXPORT extern int db_ck_v4gift_tree(const union tree *tp);
4082 
4083 /**
4084  * Given a rt_tree_array array, build a tree of "union tree" nodes
4085  * appropriately connected together. Every element of the
4086  * rt_tree_array array used is replaced with a TREE_NULL. Elements
4087  * which are already TREE_NULL are ignored. Returns a pointer to the
4088  * top of the tree.
4089  */
4090 RT_EXPORT extern union tree *db_mkbool_tree(struct rt_tree_array *rt_tree_array,
4091  size_t howfar,
4092  struct resource *resp);
4093 
4094 RT_EXPORT extern union tree *db_mkgift_tree(struct rt_tree_array *trees,
4095  size_t subtreecount,
4096  struct resource *resp);
4097 
4098 /**
4099  * fills in rgb with the color for a given comb combination
4100  *
4101  * returns truthfully if a color could be got
4102  */
4103 RT_EXPORT extern int rt_comb_get_color(unsigned char rgb[3], const struct rt_comb_internal *comb);
4104 
4105 /* tgc.c */
4106 RT_EXPORT extern void rt_pt_sort(fastf_t t[],
4107  int npts);
4108 
4109 /* ell.c */
4110 RT_EXPORT extern void rt_ell_16pts(fastf_t *ov,
4111  fastf_t *V,
4112  fastf_t *A,
4113  fastf_t *B);
4114 
4115 
4116 /**
4117  * change all matching object names in the comb tree from old_name to
4118  * new_name
4119  *
4120  * calling function must supply an initialized bu_ptbl, and free it
4121  * once done.
4122  */
4123 RT_EXPORT extern int db_comb_mvall(struct directory *dp,
4124  struct db_i *dbip,
4125  const char *old_name,
4126  const char *new_name,
4127  struct bu_ptbl *stack);
4128 
4129 /* roots.c */
4130 /** @addtogroup librt */
4131 /** @{ */
4132 /** @file librt/roots.c
4133  *
4134  * Find the roots of a polynomial
4135  *
4136  */
4137 
4138 /**
4139  * WARNING: The polynomial given as input is destroyed by this
4140  * routine. The caller must save it if it is important!
4141  *
4142  * NOTE : This routine is written for polynomials with real
4143  * coefficients ONLY. To use with complex coefficients, the Complex
4144  * Math library should be used throughout. Some changes in the
4145  * algorithm will also be required.
4146  */
4147 RT_EXPORT extern int rt_poly_roots(bn_poly_t *eqn,
4148  bn_complex_t roots[],
4149  const char *name);
4150 
4151 /** @} */
4152 /* db_io.c */
4153 RT_EXPORT extern int db_write(struct db_i *dbip,
4154  const void * addr,
4155  size_t count,
4156  off_t offset);
4157 
4158 /**
4159  * Add name from dp->d_namep to external representation of solid, and
4160  * write it into a file.
4161  *
4162  * Caller is responsible for freeing memory of external
4163  * representation, using bu_free_external().
4164  *
4165  * The 'name' field of the external representation is modified to
4166  * contain the desired name. The 'ep' parameter cannot be const.
4167  *
4168  * THIS ROUTINE ONLY SUPPORTS WRITING V4 GEOMETRY.
4169  *
4170  * Returns -
4171  * <0 error
4172  * 0 OK
4173  *
4174  * NOTE: Callers of this should be using wdb_export_external()
4175  * instead.
4176  */
4177 RT_EXPORT extern int db_fwrite_external(FILE *fp,
4178  const char *name,
4179  struct bu_external *ep);
4180 
4181 /* malloc & read records */
4182 
4183 /**
4184  * Retrieve all records in the database pertaining to an object, and
4185  * place them in malloc()'ed storage, which the caller is responsible
4186  * for free()'ing.
4187  *
4188  * This loads the combination into a local record buffer. This is in
4189  * external v4 format.
4190  *
4191  * Returns -
4192  * union record * - OK
4193  * (union record *)0 - FAILURE
4194  */
4195 RT_EXPORT extern union record *db_getmrec(const struct db_i *,
4196  const struct directory *dp);
4197 /* get several records from db */
4198 
4199 /**
4200  * Retrieve 'len' records from the database, "offset" granules into
4201  * this entry.
4202  *
4203  * Returns -
4204  * 0 OK
4205  * -1 FAILURE
4206  */
4207 RT_EXPORT extern int db_get(const struct db_i *,
4208  const struct directory *dp,
4209  union record *where,
4210  off_t offset,
4211  size_t len);
4212 /* put several records into db */
4213 
4214 /**
4215  * Store 'len' records to the database, "offset" granules into this
4216  * entry.
4217  *
4218  * Returns:
4219  * 0 OK
4220  * non-0 FAILURE
4221  */
4222 RT_EXPORT extern int db_put(struct db_i *,
4223  const struct directory *dp,
4224  union record *where,
4225  off_t offset, size_t len);
4226 
4227 /**
4228  * Obtains a object from the database, leaving it in external
4229  * (on-disk) format.
4230  *
4231  * The bu_external structure represented by 'ep' is initialized here,
4232  * the caller need not pre-initialize it. On error, 'ep' is left
4233  * un-initialized and need not be freed, to simplify error recovery.
4234  * On success, the caller is responsible for calling
4235  * bu_free_external(ep);
4236  *
4237  * Returns -
4238  * -1 error
4239  * 0 success
4240  */
4241 RT_EXPORT extern int db_get_external(struct bu_external *ep,
4242  const struct directory *dp,
4243  const struct db_i *dbip);
4244 
4245 /**
4246  * Given that caller already has an external representation of the
4247  * database object, update it to have a new name (taken from
4248  * dp->d_namep) in that external representation, and write the new
4249  * object into the database, obtaining different storage if the size
4250  * has changed.
4251  *
4252  * Caller is responsible for freeing memory of external
4253  * representation, using bu_free_external().
4254  *
4255  * This routine is used to efficiently support MGED's "cp" and "keep"
4256  * commands, which don't need to import objects just to rename and
4257  * copy them.
4258  *
4259  * Returns -
4260  * <0 error
4261  * 0 success
4262  */
4263 RT_EXPORT extern int db_put_external(struct bu_external *ep,
4264  struct directory *dp,
4265  struct db_i *dbip);
4266 
4267 /* db_scan.c */
4268 /* read db (to build directory) */
4269 RT_EXPORT extern int db_scan(struct db_i *,
4270  int (*handler)(struct db_i *,
4271  const char *name,
4272  off_t addr,
4273  size_t nrec,
4274  int flags,
4275  void *client_data),
4276  int do_old_matter,
4277  void *client_data);
4278 /* update db unit conversions */
4279 #define db_ident(a, b, c) +++error+++
4280 
4281 /**
4282  * Update the _GLOBAL object, which in v5 serves the place of the
4283  * "ident" header record in v4 as the place to stash global
4284  * information. Since every database will have one of these things,
4285  * it's no problem to update it.
4286  *
4287  * Returns -
4288  * 0 Success
4289  * -1 Fatal Error
4290  */
4291 RT_EXPORT extern int db_update_ident(struct db_i *dbip,
4292  const char *title,
4293  double local2mm);
4294 
4295 /**
4296  * Create a header for a v5 database.
4297  *
4298  * This routine has the same calling sequence as db_fwrite_ident()
4299  * which makes a v4 database header.
4300  *
4301  * In the v5 database, two database objects must be created to match
4302  * the semantics of what was in the v4 header:
4303  *
4304  * First, a database header object.
4305  *
4306  * Second, create a specially named attribute-only object which
4307  * contains the attributes "title=" and "units=" with the values of
4308  * title and local2mm respectively.
4309  *
4310  * Note that the current working units are specified as a conversion
4311  * factor to millimeters because database dimensional values are
4312  * always stored as millimeters (mm). The units conversion factor
4313  * only affects the display and conversion of input values. This
4314  * helps prevent error accumulation and improves numerical stability
4315  * when calculations are made.
4316  *
4317  * This routine should only be used by db_create(). Everyone else
4318  * should use db5_update_ident().
4319  *
4320  * Returns -
4321  * 0 Success
4322  * -1 Fatal Error
4323  */
4324 RT_EXPORT extern int db_fwrite_ident(FILE *fp,
4325  const char *title,
4326  double local2mm);
4327 
4328 /**
4329  * Initialize conversion factors given the v4 database unit
4330  */
4331 RT_EXPORT extern void db_conversions(struct db_i *,
4332  int units);
4333 
4334 /**
4335  * Given a string, return the V4 database code representing the user's
4336  * preferred editing units. The v4 database format does not have many
4337  * choices.
4338  *
4339  * Returns -
4340  * -1 Not a legal V4 database code
4341  * # The V4 database code number
4342  */
4343 RT_EXPORT extern int db_v4_get_units_code(const char *str);
4344 
4345 /* db5_scan.c */
4346 
4347 /**
4348  * A generic routine to determine the type of the database, (v4 or v5)
4349  * and to invoke the appropriate db_scan()-like routine to build the
4350  * in-memory directory.
4351  *
4352  * It is the caller's responsibility to close the database in case of
4353  * error.
4354  *
4355  * Called from rt_dirbuild() and other places directly where a
4356  * raytrace instance is not required.
4357  *
4358  * Returns -
4359  * 0 OK
4360  * -1 failure
4361  */
4362 RT_EXPORT extern int db_dirbuild(struct db_i *dbip);
4363 RT_EXPORT extern struct directory *db5_diradd(struct db_i *dbip,
4364  const struct db5_raw_internal *rip,
4365  off_t laddr,
4366  void *client_data);
4367 
4368 /**
4369  * Scan a v5 database, sending each object off to a handler.
4370  *
4371  * Returns -
4372  * 0 Success
4373  * -1 Fatal Error
4374  */
4375 RT_EXPORT extern int db5_scan(struct db_i *dbip,
4376  void (*handler)(struct db_i *,
4377  const struct db5_raw_internal *,
4378  off_t addr,
4379  void *client_data),
4380  void *client_data);
4381 
4382 /**
4383  * obtain the database version for a given database instance.
4384  *
4385  * presently returns only a 4 or 5 accordingly.
4386  */
4387 RT_EXPORT extern int db_version(struct db_i *dbip);
4388 
4389 
4390 /* db_corrupt.c */
4391 
4392 /**
4393  * Detect whether a given geometry database file seems to be corrupt
4394  * or invalid due to flipped endianness. Only relevant for v4
4395  * geometry files that are binary-incompatible with the runtime
4396  * platform.
4397  *
4398  * Returns true if flipping the endian type fixes all combination
4399  * member matrices.
4400  */
4401 RT_EXPORT extern int rt_db_flip_endian(struct db_i *dbip);
4402 
4403 
4404 /* db5_comb.c */
4405 
4406 /**
4407  * Read a combination object in v5 external (on-disk) format, and
4408  * convert it into the internal format described in rtgeom.h
4409  *
4410  * This is an unusual conversion, because some of the data is taken
4411  * from attributes, not just from the object body. By the time this
4412  * is called, the attributes will already have been cracked into
4413  * ip->idb_avs, we get the attributes from there.
4414  *
4415  * Returns -
4416  * 0 OK
4417  * -1 FAIL
4418  */
4419 RT_EXPORT extern int rt_comb_import5(struct rt_db_internal *ip, const struct bu_external *ep, const mat_t mat, const struct db_i *dbip, struct resource *resp);
4420 
4421 /* extrude.c */
4422 RT_EXPORT extern int rt_extrude_import5(struct rt_db_internal *ip, const struct bu_external *ep, const mat_t mat, const struct db_i *dbip, struct resource *resp);
4423 
4424 
4425 /**
4426  * "open" an in-memory-only database instance. this initializes a
4427  * dbip for use, creating an inmem dbi_wdbp as the means to add
4428  * geometry to the directory (use wdb_export_external()).
4429  */
4430 RT_EXPORT extern struct db_i * db_open_inmem(void);
4431 
4432 /**
4433  * creates an in-memory-only database. this is very similar to
4434  * db_open_inmem() with the exception that the this routine adds a
4435  * default _GLOBAL object.
4436  */
4437 RT_EXPORT extern struct db_i * db_create_inmem(void);
4438 
4439 
4440 /**
4441  * Transmogrify an existing directory entry to be an in-memory-only
4442  * one, stealing the external representation from 'ext'.
4443  */
4444 RT_EXPORT extern void db_inmem(struct directory *dp,
4445  struct bu_external *ext,
4446  int flags,
4447  struct db_i *dbip);
4448 
4449 /* db_lookup.c */
4450 
4451 /**
4452  * Return the number of "struct directory" nodes in the given
4453  * database.
4454  */
4455 RT_EXPORT extern size_t db_directory_size(const struct db_i *dbip);
4456 
4457 /**
4458  * For debugging, ensure that all the linked-lists for the directory
4459  * structure are intact.
4460  */
4461 RT_EXPORT extern void db_ck_directory(const struct db_i *dbip);
4462 
4463 /**
4464  * Returns -
4465  * 0 if the in-memory directory is empty
4466  * 1 if the in-memory directory has entries,
4467  * which implies that a db_scan() has already been performed.
4468  */
4469 RT_EXPORT extern int db_is_directory_non_empty(const struct db_i *dbip);
4470 
4471 /**
4472  * Returns a hash index for a given string that corresponds with the
4473  * head of that string's hash chain.
4474  */
4475 RT_EXPORT extern int db_dirhash(const char *str);
4476 
4477 /**
4478  * This routine ensures that ret_name is not already in the
4479  * directory. If it is, it tries a fixed number of times to modify
4480  * ret_name before giving up. Note - most of the time, the hash for
4481  * ret_name is computed once.
4482  *
4483  * Inputs -
4484  * dbip database instance pointer
4485  * ret_name the original name
4486  * noisy to blather or not
4487  *
4488  * Outputs -
4489  * ret_name the name to use
4490  * headp pointer to the first (struct directory *) in the bucket
4491  *
4492  * Returns -
4493  * 0 success
4494  * <0 fail
4495  */
4496 RT_EXPORT extern int db_dircheck(struct db_i *dbip,
4497  struct bu_vls *ret_name,
4498  int noisy,
4499  struct directory ***headp);
4500 /* convert name to directory ptr */
4501 
4502 /**
4503  * This routine takes a name and looks it up in the directory table.
4504  * If the name is present, a pointer to the directory struct element
4505  * is returned, otherwise NULL is returned.
4506  *
4507  * If noisy is non-zero, a print occurs, else only the return code
4508  * indicates failure.
4509  *
4510  * Returns -
4511  * struct directory if name is found
4512  * RT_DIR_NULL on failure
4513  */
4514 RT_EXPORT extern struct directory *db_lookup(const struct db_i *,
4515  const char *name,
4516  int noisy);
4517 /* lookup directory entries based on attributes */
4518 
4519 /**
4520  * lookup directory entries based on directory flags (dp->d_flags) and
4521  * attributes the "dir_flags" arg is a mask for the directory flags
4522  * the *"avs" is an attribute value set used to select from the
4523  * objects that *pass the flags mask. if "op" is 1, then the object
4524  * must have all the *attributes and values that appear in "avs" in
4525  * order to be *selected. If "op" is 2, then the object must have at
4526  * least one of *the attribute/value pairs from "avs".
4527  *
4528  * dir_flags are in the form used in struct directory (d_flags)
4529  *
4530  * for op:
4531  * 1 -> all attribute name/value pairs must be present and match
4532  * 2 -> at least one of the name/value pairs must be present and match
4533  *
4534  * returns a ptbl list of selected directory pointers an empty list
4535  * means nothing met the requirements a NULL return means something
4536  * went wrong.
4537  */
4538 RT_EXPORT extern struct bu_ptbl *db_lookup_by_attr(struct db_i *dbip,
4539  int dir_flags,
4540  struct bu_attribute_value_set *avs,
4541  int op);
4542 
4543 /* add entry to directory */
4544 
4545 /**
4546  * Add an entry to the directory. Try to make the regular path
4547  * through the code as fast as possible, to speed up building the
4548  * table of contents.
4549  *
4550  * dbip is a pointer to a valid/opened database instance
4551  *
4552  * name is the string name of the object being added
4553  *
4554  * laddr is the offset into the file to the object
4555  *
4556  * len is the length of the object, number of db granules used
4557  *
4558  * flags are defined in raytrace.h (RT_DIR_SOLID, RT_DIR_COMB, RT_DIR_REGION,
4559  * RT_DIR_INMEM, etc.) for db version 5, ptr is the minor_type
4560  * (non-null pointer to valid unsigned char code)
4561  *
4562  * an laddr of RT_DIR_PHONY_ADDR means that database storage has not
4563  * been allocated yet.
4564  */
4565 RT_EXPORT extern struct directory *db_diradd(struct db_i *,
4566  const char *name,
4567  off_t laddr,
4568  size_t len,
4569  int flags,
4570  void *ptr);
4571 RT_EXPORT extern struct directory *db_diradd5(struct db_i *dbip,
4572  const char *name,
4573  off_t laddr,
4574  unsigned char major_type,
4575  unsigned char minor_type,
4576  unsigned char name_hidden,
4577  size_t object_length,
4578  struct bu_attribute_value_set *avs);
4579 
4580 /* delete entry from directory */
4581 
4582 /**
4583  * Given a pointer to a directory entry, remove it from the linked
4584  * list, and free the associated memory.
4585  *
4586  * It is the responsibility of the caller to have released whatever
4587  * structures have been hung on the d_use_hd bu_list, first.
4588  *
4589  * Returns -
4590  * 0 on success
4591  * non-0 on failure
4592  */
4593 RT_EXPORT extern int db_dirdelete(struct db_i *,
4594  struct directory *dp);
4595 RT_EXPORT extern int db_fwrite_ident(FILE *,
4596  const char *,
4597  double);
4598 
4599 /**
4600  * For debugging, print the entire contents of the database directory.
4601  */
4602 RT_EXPORT extern void db_pr_dir(const struct db_i *dbip);
4603 
4604 /**
4605  * Change the name string of a directory entry. Because of the
4606  * hashing function, this takes some extra work.
4607  *
4608  * Returns -
4609  * 0 on success
4610  * non-0 on failure
4611  */
4612 RT_EXPORT extern int db_rename(struct db_i *,
4613  struct directory *,
4614  const char *newname);
4615 
4616 
4617 /**
4618  * Updates the d_nref fields (which count the number of times a given
4619  * entry is referenced by a COMBination in the database).
4620  *
4621  */
4622 RT_EXPORT extern void db_update_nref(struct db_i *dbip,
4623  struct resource *resp);
4624 
4625 
4626 /**
4627  * DEPRECATED: Use db_ls() instead of this function.
4628  *
4629  * Appends a list of all database matches to the given vls, or the
4630  * pattern itself if no matches are found. Returns the number of
4631  * matches.
4632  */
4633 DEPRECATED RT_EXPORT extern int db_regexp_match_all(struct bu_vls *dest,
4634  struct db_i *dbip,
4635  const char *pattern);
4636 
4637 /* db_ls.c */
4638 /**
4639  * db_ls takes a database instance pointer and assembles a directory
4640  * pointer array of objects in the database according to a set of
4641  * flags. An optional pattern can be supplied for match filtering
4642  * via globbing rules (see bu_fnmatch). If pattern is NULL, filtering
4643  * is performed using only the flags.
4644  *
4645  * The caller is responsible for freeing the array.
4646  *
4647  * Returns -
4648  * integer count of objects in dpv
4649  * struct directory ** array of objects in dpv via argument
4650  *
4651  */
4652 #define DB_LS_PRIM 0x1 /* filter for primitives (solids)*/
4653 #define DB_LS_COMB 0x2 /* filter for combinations */
4654 #define DB_LS_REGION 0x4 /* filter for regions */
4655 #define DB_LS_HIDDEN 0x8 /* include hidden objects in results */
4656 #define DB_LS_NON_GEOM 0x10 /* filter for non-geometry objects */
4657 #define DB_LS_TOPS 0x20 /* filter for objects un-referenced by other objects */
4658 /* TODO - implement this flag
4659 #define DB_LS_REGEX 0x40*/ /* interpret pattern using regex rules, instead of
4660  globbing rules (default) */
4661 RT_EXPORT extern size_t db_ls(const struct db_i *dbip,
4662  int flags,
4663  const char *pattern,
4664  struct directory ***dpv);
4665 
4666 /**
4667  * convert an argv list of names to a directory pointer array.
4668  *
4669  * If db_lookup fails for any individual argv, an empty directory
4670  * structure is created and assigned the name and RT_DIR_PHONY_ADDR
4671  *
4672  * The returned directory ** structure is NULL terminated.
4673  */
4674 RT_EXPORT extern struct directory **db_argv_to_dpv(const struct db_i *dbip,
4675  const char **argv);
4676 
4677 
4678 /**
4679  * convert a directory pointer array to an argv char pointer array.
4680  */
4681 RT_EXPORT extern char **db_dpv_to_argv(struct directory **dpv);
4682 
4683 
4684 /* db_flags.c */
4685 /**
4686  * Given the internal form of a database object, return the
4687  * appropriate 'flags' word for stashing in the in-memory directory of
4688  * objects.
4689  */
4690 RT_EXPORT extern int db_flags_internal(const struct rt_db_internal *intern);
4691 
4692 
4693 /* XXX - should use in db5_diradd() */
4694 /**
4695  * Given a database object in "raw" internal form, return the
4696  * appropriate 'flags' word for stashing in the in-memory directory of
4697  * objects.
4698  */
4699 RT_EXPORT extern int db_flags_raw_internal(const struct db5_raw_internal *intern);
4700 
4701 /* db_alloc.c */
4702 
4703 /* allocate "count" granules */
4704 RT_EXPORT extern int db_alloc(struct db_i *,
4705  struct directory *dp,
4706  size_t count);
4707 /* delete "recnum" from entry */
4708 RT_EXPORT extern int db_delrec(struct db_i *,
4709  struct directory *dp,
4710  int recnum);
4711 /* delete all granules assigned dp */
4712 RT_EXPORT extern int db_delete(struct db_i *,
4713  struct directory *dp);
4714 /* write FREE records from 'start' */
4715 RT_EXPORT extern int db_zapper(struct db_i *,
4716  struct directory *dp,
4717  size_t start);
4718 
4719 /**
4720  * This routine is called by the RT_GET_DIRECTORY macro when the
4721  * freelist is exhausted. Rather than simply getting one additional
4722  * structure, we get a whole batch, saving overhead.
4723  */
4724 RT_EXPORT extern void db_alloc_directory_block(struct resource *resp);
4725 
4726 /**
4727  * This routine is called by the GET_SEG macro when the freelist is
4728  * exhausted. Rather than simply getting one additional structure, we
4729  * get a whole batch, saving overhead. When this routine is called,
4730  * the seg resource must already be locked. malloc() locking is done
4731  * in bu_malloc.
4732  */
4733 RT_EXPORT extern void rt_alloc_seg_block(struct resource *res);
4734 
4735 /* db_tree.c */
4736 
4737 /**
4738  * Duplicate the contents of a db_tree_state structure, including a
4739  * private copy of the ts_mater field(s) and the attribute/value set.
4740  */
4741 RT_EXPORT extern void db_dup_db_tree_state(struct db_tree_state *otsp,
4742  const struct db_tree_state *itsp);
4743 
4744 /**
4745  * Release dynamic fields inside the structure, but not the structure
4746  * itself.
4747  */
4748 RT_EXPORT extern void db_free_db_tree_state(struct db_tree_state *tsp);
4749 
4750 /**
4751  * In most cases, you don't want to use this routine, you want to
4752  * struct copy mged_initial_tree_state or rt_initial_tree_state, and
4753  * then set ts_dbip in your copy.
4754  */
4755 RT_EXPORT extern void db_init_db_tree_state(struct db_tree_state *tsp,
4756  struct db_i *dbip,
4757  struct resource *resp);
4758 RT_EXPORT extern struct combined_tree_state *db_new_combined_tree_state(const struct db_tree_state *tsp,
4759  const struct db_full_path *pathp);
4760 RT_EXPORT extern struct combined_tree_state *db_dup_combined_tree_state(const struct combined_tree_state *old);
4761 RT_EXPORT extern void db_free_combined_tree_state(struct combined_tree_state *ctsp);
4762 RT_EXPORT extern void db_pr_tree_state(const struct db_tree_state *tsp);
4763 RT_EXPORT extern void db_pr_combined_tree_state(const struct combined_tree_state *ctsp);
4764 
4765 /**
4766  * Handle inheritance of material property found in combination
4767  * record. Color and the material property have separate inheritance
4768  * interlocks.
4769  *
4770  * Returns -
4771  * -1 failure
4772  * 0 success
4773  * 1 success, this is the top of a new region.
4774  */
4775 RT_EXPORT extern int db_apply_state_from_comb(struct db_tree_state *tsp,
4776  const struct db_full_path *pathp,
4777  const struct rt_comb_internal *comb);
4778 
4779 /**
4780  * Updates state via *tsp, pushes member's directory entry on *pathp.
4781  * (Caller is responsible for popping it).
4782  *
4783  * Returns -
4784  * -1 failure
4785  * 0 success, member pushed on path
4786  */
4787 RT_EXPORT extern int db_apply_state_from_memb(struct db_tree_state *tsp,
4788  struct db_full_path *pathp,
4789  const union tree *tp);
4790 
4791 /**
4792  * Returns -
4793  * -1 found member, failed to apply state
4794  * 0 unable to find member 'cp'
4795  * 1 state applied OK
4796  */
4797 RT_EXPORT extern int db_apply_state_from_one_member(struct db_tree_state *tsp,
4798  struct db_full_path *pathp,
4799  const char *cp,
4800  int sofar,
4801  const union tree *tp);
4802 
4803 /**
4804  * The search stops on the first match.
4805  *
4806  * Returns -
4807  * tp if found
4808  * TREE_NULL if not found in this tree
4809  */
4810 RT_EXPORT extern union tree *db_find_named_leaf(union tree *tp, const char *cp);
4811 
4812 /**
4813  * The search stops on the first match.
4814  *
4815  * Returns -
4816  * TREE_NULL if not found in this tree
4817  * tp if found
4818  * *side == 1 if leaf is on lhs.
4819  * *side == 2 if leaf is on rhs.
4820  *
4821  */
4822 RT_EXPORT extern union tree *db_find_named_leafs_parent(int *side,
4823  union tree *tp,
4824  const char *cp);
4825 RT_EXPORT extern void db_tree_del_lhs(union tree *tp,
4826  struct resource *resp);
4827 RT_EXPORT extern void db_tree_del_rhs(union tree *tp,
4828  struct resource *resp);
4829 
4830 /**
4831  * Given a name presumably referenced in a OP_DB_LEAF node, delete
4832  * that node, and the operation node that references it. Not that
4833  * this may not produce an equivalent tree, for example when rewriting
4834  * (A - subtree) as (subtree), but that will be up to the caller/user
4835  * to adjust. This routine gets rid of exactly two nodes in the tree:
4836  * leaf, and op. Use some other routine if you wish to kill the
4837  * entire rhs below "-" and "intersect" nodes.
4838  *
4839  * The two nodes deleted will have their memory freed.
4840  *
4841  * If the tree is a single OP_DB_LEAF node, the leaf is freed and *tp
4842  * is set to NULL.
4843  *
4844  * Returns -
4845  * -3 Internal error
4846  * -2 Tree is empty
4847  * -1 Unable to find OP_DB_LEAF node specified by 'cp'.
4848  * 0 OK
4849  */
4850 RT_EXPORT extern int db_tree_del_dbleaf(union tree **tp,
4851  const char *cp,
4852  struct resource *resp,
4853  int nflag);
4854 
4855 /**
4856  * Multiply on the left every matrix found in a DB_LEAF node in a
4857  * tree.
4858  */
4859 RT_EXPORT extern void db_tree_mul_dbleaf(union tree *tp,
4860  const mat_t mat);
4861 
4862 /**
4863  * This routine traverses a combination (union tree) in LNR order and
4864  * calls the provided function for each OP_DB_LEAF node. Note that
4865  * this routine does not go outside this one combination!!!!
4866  *
4867  * was previously named comb_functree()
4868  */
4869 RT_EXPORT extern void db_tree_funcleaf(struct db_i *dbip,
4870  struct rt_comb_internal *comb,
4871  union tree *comb_tree,
4872  void (*leaf_func)(struct db_i *, struct rt_comb_internal *, union tree *,
4873  void *, void *, void *, void *),
4874  void * user_ptr1,
4875  void * user_ptr2,
4876  void * user_ptr3,
4877  void * user_ptr4);
4878 
4879 /**
4880  * Starting with possible prior partial path and corresponding
4881  * accumulated state, follow the path given by "new_path", updating
4882  * *tsp and *total_path with full state information along the way. In
4883  * a better world, there would have been a "combined_tree_state" arg.
4884  *
4885  * Parameter 'depth' controls how much of 'new_path' is used:
4886  *
4887  * 0 use all of new_path
4888  * >0 use only this many of the first elements of the path
4889  * <0 use all but this many path elements.
4890  *
4891  * A much more complete version of rt_plookup() and pathHmat(). There
4892  * is also a TCL interface.
4893  *
4894  * Returns -
4895  * 0 success (plus *tsp is updated)
4896  * -1 error (*tsp values are not useful)
4897  */
4898 RT_EXPORT extern int db_follow_path(struct db_tree_state *tsp,
4899  struct db_full_path *total_path,
4900  const struct db_full_path *new_path,
4901  int noisy,
4902  long pdepth);
4903 
4904 /**
4905  * Follow the slash-separated path given by "cp", and update *tsp and
4906  * *total_path with full state information along the way.
4907  *
4908  * A much more complete version of rt_plookup().
4909  *
4910  * Returns -
4911  * 0 success (plus *tsp is updated)
4912  * -1 error (*tsp values are not useful)
4913  */
4914 RT_EXPORT extern int db_follow_path_for_state(struct db_tree_state *tsp,
4915  struct db_full_path *pathp,
4916  const char *orig_str, int noisy);
4917 
4918 /**
4919  * Recurse down the tree, finding all the leaves (or finding just all
4920  * the regions).
4921  *
4922  * ts_region_start_func() is called to permit regions to be skipped.
4923  * It is not intended to be used for collecting state.
4924  */
4925 RT_EXPORT extern union tree *db_recurse(struct db_tree_state *tsp,
4926  struct db_full_path *pathp,
4927  struct combined_tree_state **region_start_statepp,
4928  void *client_data);
4929 RT_EXPORT extern union tree *db_dup_subtree(const union tree *tp,
4930  struct resource *resp);
4931 RT_EXPORT extern void db_ck_tree(const union tree *tp);
4932 
4933 
4934 /**
4935  * Release all storage associated with node 'tp', including children
4936  * nodes.
4937  */
4938 RT_EXPORT extern void db_free_tree(union tree *tp,
4939  struct resource *resp);
4940 
4941 
4942 /**
4943  * Re-balance this node to make it left heavy. Union operators will
4944  * be moved to left side. when finished "tp" MUST still point to top
4945  * node of this subtree.
4946  */
4947 RT_EXPORT extern void db_left_hvy_node(union tree *tp);
4948 
4949 
4950 /**
4951  * If there are non-union operations in the tree, above the region
4952  * nodes, then rewrite the tree so that the entire tree top is nothing
4953  * but union operations, and any non-union operations are clustered
4954  * down near the region nodes.
4955  */
4956 RT_EXPORT extern void db_non_union_push(union tree *tp,
4957  struct resource *resp);
4958 
4959 
4960 /**
4961  * Return a count of the number of "union tree" nodes below "tp",
4962  * including tp.
4963  */
4964 RT_EXPORT extern int db_count_tree_nodes(const union tree *tp,
4965  int count);
4966 
4967 
4968 /**
4969  * Returns -
4970  * 1 if this tree contains nothing but union operations.
4971  * 0 if at least one subtraction or intersection op exists.
4972  */
4973 RT_EXPORT extern int db_is_tree_all_unions(const union tree *tp);
4974 RT_EXPORT extern int db_count_subtree_regions(const union tree *tp);
4975 RT_EXPORT extern int db_tally_subtree_regions(union tree *tp,
4976  union tree **reg_trees,
4977  int cur,
4978  int lim,
4979  struct resource *resp);
4980 
4981 /**
4982  * This is the top interface to the "tree walker."
4983  *
4984  * Parameters:
4985  * rtip rt_i structure to database (open with rt_dirbuild())
4986  * argc # of tree-tops named
4987  * argv names of tree-tops to process
4988  * init_state Input parameter: initial state of the tree.
4989  * For example: rt_initial_tree_state,
4990  * and mged_initial_tree_state.
4991  *
4992  * These parameters are pointers to callback routines. If NULL, they
4993  * won't be called.
4994  *
4995  * reg_start_func Called at beginning of each region, before
4996  * visiting any nodes within the region. Return
4997  * 0 if region should be skipped without
4998  * recursing, otherwise non-zero. DO NOT USE FOR
4999  * OTHER PURPOSES! For example, can be used to
5000  * quickly skip air regions.
5001  *
5002  * reg_end_func Called after all nodes within a region have been
5003  * recursively processed by leaf_func. If it
5004  * wants to retain 'curtree' then it may steal
5005  * that pointer and return TREE_NULL. If it
5006  * wants us to clean up some or all of that tree,
5007  * then it returns a non-null (union tree *)
5008  * pointer, and that tree is safely freed in a
5009  * non-parallel section before we return.
5010  *
5011  * leaf_func Function to process a leaf node. It is actually
5012  * invoked from db_recurse() from
5013  * _db_walk_subtree(). Returns (union tree *)
5014  * representing the leaf, or TREE_NULL if leaf
5015  * does not exist or has an error.
5016  *
5017  *
5018  * This routine will employ multiple CPUs if asked, but is not
5019  * multiply-parallel-recursive. Call this routine with ncpu > 1 from
5020  * serial code only. When called from within an existing thread, ncpu
5021  * must be 1.
5022