BRL-CAD
tree.h
Go to the documentation of this file.
1 /* T R E E . H
2  * BRL-CAD
3  *
4  * Copyright (c) 1993-2024 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 /** @file rt/tree.h
21  *
22  */
23 
24 #ifndef RT_TREE_H
25 #define RT_TREE_H
26 
27 #include "common.h"
28 #include "vmath.h"
29 #include "bu/avs.h"
30 #include "bu/magic.h"
31 #include "bu/malloc.h"
32 #include "bn/tol.h"
33 #include "rt/geom.h"
34 #include "rt/defines.h"
35 #include "rt/db_instance.h"
36 #include "rt/directory.h"
37 #include "rt/mater.h"
38 #include "rt/op.h"
39 #include "rt/region.h"
40 #include "rt/soltab.h"
41 #include "rt/tol.h"
42 #include "nmg.h"
43 
44 __BEGIN_DECLS
45 
46 union tree; /* forward declaration */
47 struct resource; /* forward declaration */
48 struct rt_i; /* forward declaration */
49 struct rt_comb_internal; /* forward declaration */
50 struct rt_db_internal; /* forward declaration */
51 
52 /**
53  * State for database tree walker db_walk_tree() and related
54  * user-provided handler routines.
55  */
56 struct db_tree_state {
57  uint32_t magic;
58  struct db_i * ts_dbip;
59  int ts_sofar; /**< @brief Flag bits */
60 
61  int ts_regionid; /**< @brief GIFT compat region ID code*/
62  int ts_aircode; /**< @brief GIFT compat air code */
63  int ts_gmater; /**< @brief GIFT compat material code */
64  int ts_los; /**< @brief equivalent LOS estimate */
65  struct mater_info ts_mater; /**< @brief material properties */
66 
67  /* FIXME: ts_mat should be a matrix pointer, not a matrix */
68  mat_t ts_mat; /**< @brief transform matrix */
69  int ts_is_fastgen; /**< @brief REGION_NON_FASTGEN/_PLATE/_VOLUME */
70  struct bu_attribute_value_set ts_attrs; /**< @brief attribute/value structure */
71 
72  int ts_stop_at_regions; /**< @brief else stop at solids */
73  int (*ts_region_start_func)(struct db_tree_state *tsp,
74  const struct db_full_path *pathp,
75  const struct rt_comb_internal *comb,
76  void *client_data
77  ); /**< @brief callback during DAG downward traversal called on region nodes */
78  union tree * (*ts_region_end_func)(struct db_tree_state *tsp,
79  const struct db_full_path *pathp,
80  union tree *curtree,
81  void *client_data
82  ); /**< @brief callback during DAG upward traversal called on region nodes */
83  union tree * (*ts_leaf_func)(struct db_tree_state *tsp,
84  const struct db_full_path *pathp,
85  struct rt_db_internal *ip,
86  void *client_data
87  ); /**< @brief callback during DAG traversal called on leaf primitive nodes */
88  const struct bg_tess_tol * ts_ttol; /**< @brief Tessellation tolerance */
89  const struct bn_tol * ts_tol; /**< @brief Math tolerance */
90  struct model ** ts_m; /**< @brief ptr to ptr to NMG "model" */
91  struct rt_i * ts_rtip; /**< @brief Helper for rt_gettrees() */
92  struct resource * ts_resp; /**< @brief Per-CPU data */
93 };
94 #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 }
95 /* from mged_initial_tree_state */
96 #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 }
97 
98 #define TS_SOFAR_MINUS 1 /**< @brief Subtraction encountered above */
99 #define TS_SOFAR_INTER 2 /**< @brief Intersection encountered above */
100 #define TS_SOFAR_REGION 4 /**< @brief Region encountered above */
101 
102 #define RT_CK_DBTS(_p) BU_CKMAG(_p, RT_DBTS_MAGIC, "db_tree_state")
103 
104 /**
105  * initial tree start for db tree walkers.
106  *
107  * Also used by converters in conv/ directory. Don't forget to
108  * initialize ts_dbip before use.
109  */
110 RT_EXPORT extern const struct db_tree_state rt_initial_tree_state;
111 
112 /**
113  * State for database traversal functions.
114  */
115 struct db_traverse
116 {
117  uint32_t magic;
118  struct db_i *dbip;
119  void (*comb_enter_func) (
120  struct db_i *,
121  struct directory *,
122  void *);
123  void (*comb_exit_func) (
124  struct db_i *,
125  struct directory *,
126  void *);
127  void (*leaf_func) (
128  struct db_i *,
129  struct directory *,
130  void *);
131  struct resource *resp;
132  void *client_data;
133 };
134 #define RT_DB_TRAVERSE_INIT(_p) {(_p)->magic = RT_DB_TRAVERSE_MAGIC; \
135  (_p)->dbip = ((void *)0); (_p)->comb_enter_func = ((void *)0); \
136  (_p)->comb_exit_func = ((void *)0); (_p)->leaf_func = ((void *)0); \
137  (_p)->resp = ((void *)0); (_p)->client_data = ((void *)0);}
138 #define RT_CK_DB_TRAVERSE(_p) BU_CKMAG(_p, RT_DB_TRAVERSE_MAGIC, "db_traverse")
139 
140 struct combined_tree_state {
141  uint32_t magic;
143  struct db_full_path cts_p;
144 };
145 #define RT_CK_CTS(_p) BU_CKMAG(_p, RT_CTS_MAGIC, "combined_tree_state")
146 
147 union tree {
148  uint32_t magic; /**< @brief First word: magic number */
149  /* Second word is always OP code */
150  struct tree_node {
151  uint32_t magic;
152  int tb_op; /**< @brief non-leaf */
153  struct region *tb_regionp; /**< @brief ptr to containing region */
154  union tree *tb_left;
155  union tree *tb_right;
156  } tr_b;
157  struct tree_leaf {
158  uint32_t magic;
159  int tu_op; /**< @brief leaf, OP_SOLID */
160  struct region *tu_regionp; /**< @brief ptr to containing region */
161  struct soltab *tu_stp;
162  } tr_a;
163  struct tree_cts {
164  uint32_t magic;
165  int tc_op; /**< @brief leaf, OP_REGION */
166  struct region *tc_pad; /**< @brief unused */
168  } tr_c;
170  uint32_t magic;
171  int td_op; /**< @brief leaf, OP_TESS */
172  const char *td_name; /**< @brief If non-null, dynamic string describing heritage of this region */
173  struct nmgregion *td_r; /**< @brief ptr to NMG region */
174  void *td_d; /**< @brief tessellation related data */
175  struct rt_db_internal *td_i; /**< @brief For special cases like half spaces */
176  } tr_d;
177  struct tree_db_leaf {
178  uint32_t magic;
179  int tl_op; /**< @brief leaf, OP_DB_LEAF */
180  matp_t tl_mat; /**< @brief xform matp, NULL ==> identity */
181  char *tl_name; /**< @brief Name of this leaf (bu_strdup'ed) */
182  } tr_l;
183 };
184 /* Things which are in the same place in both A & B structures */
185 #define tr_op tr_a.tu_op
186 #define tr_regionp tr_a.tu_regionp
187 
188 #define TREE_NULL ((union tree *)0)
189 #define RT_CK_TREE(_p) BU_CKMAG(_p, RT_TREE_MAGIC, "union tree")
190 
191 /**
192  * initialize a union tree to zero without a node operation set. Use
193  * the largest union so all values are effectively zero except for the
194  * magic number.
195  */
196 #define RT_TREE_INIT(_p) { \
197  (_p)->magic = RT_TREE_MAGIC; \
198  (_p)->tr_b.tb_op = 0; \
199  (_p)->tr_b.tb_regionp = NULL; \
200  (_p)->tr_b.tb_left = NULL; \
201  (_p)->tr_b.tb_right = NULL; \
202  }
203 
204 /**
205  * RT_GET_TREE returns a union tree pointer with the magic number is
206  * set to RT_TREE_MAGIC.
207  *
208  * DEPRECATED, use BU_GET()+RT_TREE_INIT()
209  */
210 #define RT_GET_TREE(_tp, _res) { \
211  BU_GET((_tp), union tree); \
212  RT_TREE_INIT((_tp)); \
213  }
214 
215 
216 /**
217  * RT_FREE_TREE deinitializes a tree union pointer.
218  *
219  * DEPRECATED, use BU_PUT()
220  */
221 #define RT_FREE_TREE(_tp, _res) { \
222  BU_PUT((_tp), union tree); \
223  }
224 
225 
226 /**
227  * flattened version of the union tree
228  */
229 struct rt_tree_array
230 {
231  union tree *tl_tree;
232  int tl_op;
233 };
234 
235 #define TREE_LIST_NULL ((struct tree_list *)0)
236 
237 #ifdef USE_OPENCL
238 /**
239  * Flattened version of the infix union tree.
240  */
241 #define UOP_UNION 1 /**< @brief Binary: L union R */
242 #define UOP_INTERSECT 2 /**< @brief Binary: L intersect R */
243 #define UOP_SUBTRACT 3 /**< @brief Binary: L subtract R */
244 #define UOP_XOR 4 /**< @brief Binary: L xor R, not both*/
245 #define UOP_NOT 5 /**< @brief Unary: not L */
246 #define UOP_GUARD 6 /**< @brief Unary: not L, or else! */
247 #define UOP_XNOP 7 /**< @brief Unary: L, mark region */
248 
249 #define UOP_SOLID 0 /**< @brief Leaf: tr_stp -> solid */
250 
251 /**
252  * bit expr tree representation
253  *
254  * node:
255  * uint uop : 3
256  * uint right_child : 29
257  *
258  * leaf:
259  * uint uop : 3
260  * uint st_bit : 29
261  */
262 struct bit_tree {
263  unsigned val;
264 };
265 
266 struct cl_tree_bit {
267  cl_uint val;
268 };
269 
270 /* Print a bit expr tree */
271 RT_EXPORT extern void rt_pr_bit_tree(const struct bit_tree *btp,
272  int idx,
273  int lvl);
274 
275 RT_EXPORT extern void rt_bit_tree(struct bit_tree *btp,
276  const union tree *tp,
277  size_t *len);
278 #endif
279 
280 /* Print an expr tree */
281 RT_EXPORT extern void rt_pr_tree(const union tree *tp,
282  int lvl);
283 RT_EXPORT extern void rt_pr_tree_vls(struct bu_vls *vls,
284  const union tree *tp);
285 RT_EXPORT extern char *rt_pr_tree_str(const union tree *tree);
286 
287 struct partition; /* forward declaration */
288 RT_EXPORT extern void rt_pr_tree_val(const union tree *tp,
289  const struct partition *partp,
290  int pr_name,
291  int lvl);
292 
293 /**
294  * Duplicate the contents of a db_tree_state structure, including a
295  * private copy of the ts_mater field(s) and the attribute/value set.
296  */
297 RT_EXPORT extern void db_dup_db_tree_state(struct db_tree_state *otsp,
298  const struct db_tree_state *itsp);
299 
300 /**
301  * Release dynamic fields inside the structure, but not the structure
302  * itself.
303  */
304 RT_EXPORT extern void db_free_db_tree_state(struct db_tree_state *tsp);
305 
306 /**
307  * In most cases, you don't want to use this routine, you want to
308  * struct copy mged_initial_tree_state or rt_initial_tree_state, and
309  * then set ts_dbip in your copy.
310  */
311 RT_EXPORT extern void db_init_db_tree_state(struct db_tree_state *tsp,
312  struct db_i *dbip,
313  struct resource *resp);
314 RT_EXPORT extern struct combined_tree_state *db_new_combined_tree_state(const struct db_tree_state *tsp,
315  const struct db_full_path *pathp);
316 RT_EXPORT extern struct combined_tree_state *db_dup_combined_tree_state(const struct combined_tree_state *old);
317 RT_EXPORT extern void db_free_combined_tree_state(struct combined_tree_state *ctsp);
318 RT_EXPORT extern void db_pr_tree_state(const struct db_tree_state *tsp);
319 RT_EXPORT extern void db_pr_combined_tree_state(const struct combined_tree_state *ctsp);
320 
321 /**
322  * Handle inheritance of material property found in combination
323  * record. Color and the material property have separate inheritance
324  * interlocks.
325  *
326  * Returns -
327  * -1 failure
328  * 0 success
329  * 1 success, this is the top of a new region.
330  */
331 RT_EXPORT extern int db_apply_state_from_comb(struct db_tree_state *tsp,
332  const struct db_full_path *pathp,
333  const struct rt_comb_internal *comb);
334 
335 /**
336  * The search stops on the first match.
337  *
338  * Returns -
339  * tp if found
340  * TREE_NULL if not found in this tree
341  */
342 RT_EXPORT extern union tree *db_find_named_leaf(union tree *tp, const char *cp);
343 
344 /**
345  * The search stops on the first match.
346  *
347  * Returns -
348  * TREE_NULL if not found in this tree
349  * tp if found
350  * *side == 1 if leaf is on lhs.
351  * *side == 2 if leaf is on rhs.
352  *
353  */
354 RT_EXPORT extern union tree *db_find_named_leafs_parent(int *side,
355  union tree *tp,
356  const char *cp);
357 RT_EXPORT extern void db_tree_del_lhs(union tree *tp,
358  struct resource *resp);
359 RT_EXPORT extern void db_tree_del_rhs(union tree *tp,
360  struct resource *resp);
361 
362 /**
363  * Given a name presumably referenced in a OP_DB_LEAF node, delete
364  * that node, and the operation node that references it. Not that
365  * this may not produce an equivalent tree, for example when rewriting
366  * (A - subtree) as (subtree), but that will be up to the caller/user
367  * to adjust. This routine gets rid of exactly two nodes in the tree:
368  * leaf, and op. Use some other routine if you wish to kill the
369  * entire rhs below "-" and "intersect" nodes.
370  *
371  * The two nodes deleted will have their memory freed.
372  *
373  * If the tree is a single OP_DB_LEAF node, the leaf is freed and *tp
374  * is set to NULL.
375  *
376  * Returns -
377  * -3 Internal error
378  * -2 Tree is empty
379  * -1 Unable to find OP_DB_LEAF node specified by 'cp'.
380  * 0 OK
381  */
382 RT_EXPORT extern int db_tree_del_dbleaf(union tree **tp,
383  const char *cp,
384  struct resource *resp,
385  int nflag);
386 
387 /**
388  * Multiply on the left every matrix found in a DB_LEAF node in a
389  * tree.
390  */
391 RT_EXPORT extern void db_tree_mul_dbleaf(union tree *tp,
392  const mat_t mat);
393 
394 /**
395  * This routine traverses a combination (union tree) in LNR order and
396  * calls the provided function for each OP_DB_LEAF node. Note that
397  * this routine does not go outside this one combination!!!!
398  *
399  * was previously named comb_functree()
400  */
401 RT_EXPORT extern void db_tree_funcleaf(struct db_i *dbip,
402  struct rt_comb_internal *comb,
403  union tree *comb_tree,
404  void (*leaf_func)(struct db_i *, struct rt_comb_internal *, union tree *,
405  void *, void *, void *, void *),
406  void * user_ptr1,
407  void * user_ptr2,
408  void * user_ptr3,
409  void * user_ptr4);
410 
411 /**
412  * Starting with possible prior partial path and corresponding
413  * accumulated state, follow the path given by "new_path", updating
414  * *tsp and *total_path with full state information along the way. In
415  * a better world, there would have been a "combined_tree_state" arg.
416  *
417  * Parameter 'depth' controls how much of 'new_path' is used:
418  *
419  * 0 use all of new_path
420  * >0 use only this many of the first elements of the path
421  * <0 use all but this many path elements.
422  *
423  * A much more complete version of rt_plookup() and pathHmat(). There
424  * is also a TCL interface.
425  *
426  * Returns -
427  * 0 success (plus *tsp is updated)
428  * -1 error (*tsp values are not useful)
429  */
430 RT_EXPORT extern int db_follow_path(struct db_tree_state *tsp,
431  struct db_full_path *total_path,
432  const struct db_full_path *new_path,
433  int noisy,
434  long pdepth);
435 
436 /**
437  * Follow the slash-separated path given by "cp", and update *tsp and
438  * *total_path with full state information along the way.
439  *
440  * A much more complete version of rt_plookup().
441  *
442  * TODO - need to extend this to support specifiers orig_str to
443  * call out particular instances of combs in a tree...
444  *
445  * Returns -
446  * 0 success (plus *tsp is updated)
447  * -1 error (*tsp values are not useful)
448  */
449 RT_EXPORT extern int db_follow_path_for_state(struct db_tree_state *tsp,
450  struct db_full_path *pathp,
451  const char *orig_str, int noisy);
452 
453 RT_EXPORT extern union tree *db_dup_subtree(const union tree *tp,
454  struct resource *resp);
455 RT_EXPORT extern void db_ck_tree(const union tree *tp);
456 
457 
458 /**
459  * Release all storage associated with node 'tp', including children
460  * nodes.
461  */
462 RT_EXPORT extern void db_free_tree(union tree *tp,
463  struct resource *resp);
464 
465 
466 /**
467  * Re-balance this node to make it left heavy. Union operators will
468  * be moved to left side. when finished "tp" MUST still point to top
469  * node of this subtree.
470  */
471 RT_EXPORT extern void db_left_hvy_node(union tree *tp);
472 
473 
474 /**
475  * If there are non-union operations in the tree, above the region
476  * nodes, then rewrite the tree so that the entire tree top is nothing
477  * but union operations, and any non-union operations are clustered
478  * down near the region nodes.
479  */
480 RT_EXPORT extern void db_non_union_push(union tree *tp,
481  struct resource *resp);
482 
483 /**
484  * Return a count of the number of "union tree" nodes below "tp",
485  * including tp.
486  */
487 RT_EXPORT extern int db_count_tree_nodes(const union tree *tp,
488  int count);
489 
490 
491 /**
492  * Returns -
493  * 1 if this tree contains nothing but union operations.
494  * 0 if at least one subtraction or intersection op exists.
495  */
496 RT_EXPORT extern int db_is_tree_all_unions(const union tree *tp);
497 RT_EXPORT extern int db_count_subtree_regions(const union tree *tp);
498 RT_EXPORT extern int db_tally_subtree_regions(union tree *tp,
499  union tree **reg_trees,
500  int cur,
501  int lim,
502  struct resource *resp);
503 
504 /**
505  * This is the top interface to the "tree walker."
506  *
507  * Parameters:
508  * rtip rt_i structure to database (open with rt_dirbuild())
509  * argc # of tree-tops named
510  * argv names of tree-tops to process
511  * init_state Input parameter: initial state of the tree.
512  * For example: rt_initial_tree_state,
513  * and mged_initial_tree_state.
514  *
515  * These parameters are pointers to callback routines. If NULL, they
516  * won't be called.
517  *
518  * reg_start_func Called at beginning of each region, before
519  * visiting any nodes within the region. Return
520  * 0 if region should be skipped without
521  * recursing, otherwise non-zero. DO NOT USE FOR
522  * OTHER PURPOSES! For example, can be used to
523  * quickly skip air regions.
524  *
525  * reg_end_func Called after all nodes within a region have been
526  * recursively processed by leaf_func. If it
527  * wants to retain 'curtree' then it may steal
528  * that pointer and return TREE_NULL. If it
529  * wants us to clean up some or all of that tree,
530  * then it returns a non-null (union tree *)
531  * pointer, and that tree is safely freed in a
532  * non-parallel section before we return.
533  *
534  * leaf_func Function to process a leaf node. It is actually
535  * invoked from db_recurse() from
536  * _db_walk_subtree(). Returns (union tree *)
537  * representing the leaf, or TREE_NULL if leaf
538  * does not exist or has an error.
539  *
540  *
541  * This routine will employ multiple CPUs if asked, but is not
542  * multiply-parallel-recursive. Call this routine with ncpu > 1 from
543  * serial code only. When called from within an existing thread, ncpu
544  * must be 1.
545  *
546  * If ncpu > 1, the caller is responsible for making sure that
547  * RTG.rtg_parallel is non-zero.
548  *
549  * Plucks per-cpu resources out of rtip->rti_resources[]. They need
550  * to have been initialized first.
551  *
552  * Returns -
553  * -1 Failure to prepare even a single sub-tree
554  * 0 OK
555  */
556 RT_EXPORT extern int db_walk_tree(struct db_i *dbip,
557  int argc,
558  const char **argv,
559  int ncpu,
560  const struct db_tree_state *init_state,
561  int (*reg_start_func) (struct db_tree_state * /*tsp*/,
562  const struct db_full_path * /*pathp*/,
563  const struct rt_comb_internal * /* combp */,
564  void *client_data),
565  union tree *(*reg_end_func) (struct db_tree_state * /*tsp*/,
566  const struct db_full_path * /*pathp*/,
567  union tree * /*curtree*/,
568  void *client_data),
569  union tree *(*leaf_func) (struct db_tree_state * /*tsp*/,
570  const struct db_full_path * /*pathp*/,
571  struct rt_db_internal * /*ip*/,
572  void *client_data),
573  void *client_data);
574 
575 /**
576  * Fills a bu_vls with a representation of the given tree appropriate
577  * for processing by Tcl scripts.
578  *
579  * A tree 't' is represented in the following manner:
580  *
581  * t := { l dbobjname { mat } }
582  * | { l dbobjname }
583  * | { u t1 t2 }
584  * | { n t1 t2 }
585  * | { - t1 t2 }
586  * | { ^ t1 t2 }
587  * | { ! t1 }
588  * | { G t1 }
589  * | { X t1 }
590  * | { N }
591  * | {}
592  *
593  * where 'dbobjname' is a string containing the name of a database object,
594  * 'mat' is the matrix preceding a leaf,
595  * 't1', 't2' are trees (recursively defined).
596  *
597  * Notice that in most cases, this tree will be grossly unbalanced.
598  */
599 RT_EXPORT extern int db_tree_list(struct bu_vls *vls, const union tree *tp);
600 
601 /**
602  * Take a TCL-style string description of a binary tree, as produced
603  * by db_tree_list(), and reconstruct the in-memory form of that tree.
604  */
605 RT_EXPORT extern union tree *db_tree_parse(struct bu_vls *vls, const char *str, struct resource *resp);
606 
607 /**
608  * This subroutine is called for a no-frills tree-walk, with the
609  * provided subroutines being called at every combination and leaf
610  * (solid) node, respectively.
611  *
612  * This routine is recursive, so no variables may be declared static.
613  */
614 RT_EXPORT extern void db_functree(struct db_i *dbip,
615  struct directory *dp,
616  void (*comb_func)(struct db_i *,
617  struct directory *,
618  void *),
619  void (*leaf_func)(struct db_i *,
620  struct directory *,
621  void *),
622  struct resource *resp,
623  void *client_data);
624 /**
625  * Ray Tracing library database tree walker.
626  *
627  * Collect and prepare regions and solids for subsequent ray-tracing.
628  *
629  */
630 
631 
632 /**
633  * Calculate the bounding RPP of the region whose boolean tree is
634  * 'tp'. The bounding RPP is returned in tree_min and tree_max, which
635  * need not have been initialized first.
636  *
637  * Returns -
638  * 0 success
639  * -1 failure (tree_min and tree_max may have been altered)
640  */
641 RT_EXPORT extern int rt_bound_tree(const union tree *tp,
642  vect_t tree_min,
643  vect_t tree_max);
644 
645 /**
646  * Eliminate any references to NOP nodes from the tree. It is safe to
647  * use db_free_tree() here, because there will not be any dead solids.
648  * They will all have been converted to OP_NOP nodes by
649  * _rt_tree_kill_dead_solid_refs(), previously, so there is no need to
650  * worry about multiple db_free_tree()'s repeatedly trying to free one
651  * solid that has been instanced multiple times.
652  *
653  * Returns -
654  * 0 this node is OK.
655  * -1 request caller to kill this node
656  */
657 RT_EXPORT extern int rt_tree_elim_nops(union tree *,
658  struct resource *resp);
659 
660 /**
661  * Return count of number of leaf nodes in this tree.
662  */
663 RT_EXPORT extern size_t db_tree_nleaves(const union tree *tp);
664 
665 /**
666  * Take a binary tree in "V4-ready" layout (non-unions pushed below
667  * unions, left-heavy), and flatten it into an array layout, ready for
668  * conversion back to the GIFT-inspired V4 database format.
669  *
670  * This is done using the db_non_union_push() routine.
671  *
672  * If argument 'free' is non-zero, then the non-leaf nodes are freed
673  * along the way, to prevent memory leaks. In this case, the caller's
674  * copy of 'tp' will be invalid upon return.
675  *
676  * When invoked at the very top of the tree, the op argument must be
677  * OP_UNION.
678  */
679 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);
680 
681 
682 /**
683  * Produce a GIFT-compatible listing, one "member" per line,
684  * regardless of the structure of the tree we've been given.
685  */
686 RT_EXPORT extern void db_tree_flatten_describe(struct bu_vls *vls,
687  const union tree *tp,
688  int indented,
689  int lvl,
690  double mm2local,
691  struct resource *resp);
692 
693 RT_EXPORT extern void db_tree_describe(struct bu_vls *vls,
694  const union tree *tp,
695  int indented,
696  int lvl,
697  double mm2local);
698 
699 /**
700  * Support routine for db_ck_v4gift_tree().
701  * Ensure that the tree below 'tp' is left-heavy, i.e. that there are
702  * nothing but solids on the right side of any binary operations.
703  *
704  * Returns -
705  * -1 ERROR
706  * 0 OK
707  */
708 RT_EXPORT extern int db_ck_left_heavy_tree(const union tree *tp,
709  int no_unions);
710 /**
711  * Look a gift-tree in the mouth.
712  *
713  * Ensure that this boolean tree conforms to the GIFT convention that
714  * union operations must bind the loosest.
715  *
716  * There are two stages to this check:
717  * 1) Ensure that if unions are present they are all at the root of tree,
718  * 2) Ensure non-union children of union nodes are all left-heavy
719  * (nothing but solid nodes permitted on rhs of binary operators).
720  *
721  * Returns -
722  * -1 ERROR
723  * 0 OK
724  */
725 RT_EXPORT extern int db_ck_v4gift_tree(const union tree *tp);
726 
727 /**
728  * Given a rt_tree_array array, build a tree of "union tree" nodes
729  * appropriately connected together. Every element of the
730  * rt_tree_array array used is replaced with a TREE_NULL. Elements
731  * which are already TREE_NULL are ignored. Returns a pointer to the
732  * top of the tree.
733  */
734 RT_EXPORT extern union tree *db_mkbool_tree(struct rt_tree_array *rt_tree_array,
735  size_t howfar,
736  struct resource *resp);
737 
738 RT_EXPORT extern union tree *db_mkgift_tree(struct rt_tree_array *trees,
739  size_t subtreecount,
740  struct resource *resp);
741 
742 
743 RT_EXPORT extern void rt_optim_tree(union tree *tp,
744  struct resource *resp);
745 
746 
747 
748 
749 
750 /*************************************************************************
751  * Deprecated
752  *************************************************************************/
753 
754 
755 /**
756  * Updates state via *tsp, pushes member's directory entry on *pathp.
757  * (Caller is responsible for popping it).
758  *
759  * Returns -
760  * -1 failure
761  * 0 success, member pushed on path
762  *
763  * DEPRECATED, internal implementation function
764  */
765 RT_EXPORT extern int db_apply_state_from_memb(struct db_tree_state *tsp,
766  struct db_full_path *pathp,
767  const union tree *tp);
768 
769 /**
770  * Returns -
771  * -1 found member, failed to apply state
772  * 0 unable to find member 'cp'
773  * 1 state applied OK
774  *
775  * DEPRECATED, internal implementation function
776  */
777 RT_EXPORT extern int db_apply_state_from_one_member(struct db_tree_state *tsp,
778  struct db_full_path *pathp,
779  const char *cp,
780  int sofar,
781  const union tree *tp);
782 
783 /**
784  * Recurse down the tree, finding all the leaves (or finding just all
785  * the regions).
786  *
787  * ts_region_start_func() is called to permit regions to be skipped.
788  * It is not intended to be used for collecting state.
789  *
790  * DEPRECATED, internal implementation function
791  */
792 RT_EXPORT extern union tree *db_recurse(struct db_tree_state *tsp,
793  struct db_full_path *pathp,
794  struct combined_tree_state **region_start_statepp,
795  void *client_data);
796 
797 
798 
799 __END_DECLS
800 
801 #endif /* RT_TREE_H */
802 
803 /*
804  * Local Variables:
805  * tab-width: 8
806  * mode: C
807  * indent-tabs-mode: t
808  * c-file-style: "stroustrup"
809  * End:
810  * ex: shiftwidth=4 tabstop=8
811  */
Header file for the BRL-CAD common definitions.
fastf_t vect_t[ELEMENTS_PER_VECT]
3-tuple vector
Definition: vmath.h:349
fastf_t mat_t[ELEMENTS_PER_MAT]
4x4 matrix
Definition: vmath.h:370
fastf_t * matp_t
pointer to a 4x4 matrix
Definition: vmath.h:373
Global registry of recognized magic numbers.
Definition: tol.h:72
Definition: vls.h:53
struct db_full_path cts_p
Definition: tree.h:144
struct db_tree_state cts_s
Definition: tree.h:143
uint32_t magic
Definition: tree.h:142
void(* comb_exit_func)(struct db_i *, struct directory *, void *)
Definition: tree.h:124
void * client_data
Definition: tree.h:133
void(* leaf_func)(struct db_i *, struct directory *, void *)
Definition: tree.h:128
uint32_t magic
Definition: tree.h:118
struct db_i * dbip
Definition: tree.h:119
struct resource * resp
Definition: tree.h:132
void(* comb_enter_func)(struct db_i *, struct directory *, void *)
Definition: tree.h:120
int ts_los
equivalent LOS estimate
Definition: tree.h:64
struct mater_info ts_mater
material properties
Definition: tree.h:65
const struct bg_tess_tol * ts_ttol
Tessellation tolerance.
Definition: tree.h:89
int ts_is_fastgen
REGION_NON_FASTGEN/_PLATE/_VOLUME.
Definition: tree.h:70
struct resource * ts_resp
Per-CPU data.
Definition: tree.h:93
struct rt_i * ts_rtip
Helper for rt_gettrees()
Definition: tree.h:92
int ts_sofar
Flag bits.
Definition: tree.h:59
uint32_t magic
Definition: tree.h:57
int ts_regionid
GIFT compat region ID code.
Definition: tree.h:61
struct bu_attribute_value_set ts_attrs
attribute/value structure
Definition: tree.h:71
const struct bn_tol * ts_tol
Math tolerance.
Definition: tree.h:90
struct db_i * ts_dbip
Definition: tree.h:58
struct model ** ts_m
ptr to ptr to NMG "model"
Definition: tree.h:91
int(* ts_region_start_func)(struct db_tree_state *tsp, const struct db_full_path *pathp, const struct rt_comb_internal *comb, void *client_data)
callback during DAG downward traversal called on region nodes
Definition: tree.h:74
int ts_aircode
GIFT compat air code.
Definition: tree.h:62
mat_t ts_mat
transform matrix
Definition: tree.h:69
int ts_stop_at_regions
else stop at solids
Definition: tree.h:73
int ts_gmater
GIFT compat material code.
Definition: tree.h:63
NMG topological model.
Definition: topology.h:289
NMG topological region.
Definition: topology.h:277
Definition: region.h:44
int tl_op
Definition: tree.h:233
union tree * tl_tree
Definition: tree.h:232
Definition: soltab.h:57
int tc_op
leaf, OP_REGION
Definition: tree.h:166
struct region * tc_pad
unused
Definition: tree.h:167
uint32_t magic
Definition: tree.h:165
struct combined_tree_state * tc_ctsp
Definition: tree.h:168
int tl_op
leaf, OP_DB_LEAF
Definition: tree.h:180
uint32_t magic
Definition: tree.h:179
char * tl_name
Name of this leaf (bu_strdup'ed)
Definition: tree.h:182
matp_t tl_mat
xform matp, NULL ==> identity
Definition: tree.h:181
uint32_t magic
Definition: tree.h:159
struct soltab * tu_stp
Definition: tree.h:162
int tu_op
leaf, OP_SOLID
Definition: tree.h:160
struct region * tu_regionp
ptr to containing region
Definition: tree.h:161
union tree * tb_left
Definition: tree.h:155
uint32_t magic
Definition: tree.h:152
int tb_op
non-leaf
Definition: tree.h:153
union tree * tb_right
Definition: tree.h:156
struct region * tb_regionp
ptr to containing region
Definition: tree.h:154
struct rt_db_internal * td_i
For special cases like half spaces.
Definition: tree.h:176
const char * td_name
If non-null, dynamic string describing heritage of this region.
Definition: tree.h:173
void * td_d
tessellation related data
Definition: tree.h:175
struct nmgregion * td_r
ptr to NMG region
Definition: tree.h:174
int td_op
leaf, OP_TESS
Definition: tree.h:172
void db_tree_del_lhs(union tree *tp, struct resource *resp)
int db_follow_path_for_state(struct db_tree_state *tsp, struct db_full_path *pathp, const char *orig_str, int noisy)
int db_walk_tree(struct db_i *dbip, int argc, const char **argv, int ncpu, const struct db_tree_state *init_state, int(*reg_start_func)(struct db_tree_state *, const struct db_full_path *, const struct rt_comb_internal *, void *client_data), union tree *(*reg_end_func)(struct db_tree_state *, const struct db_full_path *, union tree *, void *client_data), union tree *(*leaf_func)(struct db_tree_state *, const struct db_full_path *, struct rt_db_internal *, void *client_data), void *client_data)
struct combined_tree_state * db_dup_combined_tree_state(const struct combined_tree_state *old)
void db_pr_tree_state(const struct db_tree_state *tsp)
int db_apply_state_from_memb(struct db_tree_state *tsp, struct db_full_path *pathp, const union tree *tp)
int db_follow_path(struct db_tree_state *tsp, struct db_full_path *total_path, const struct db_full_path *new_path, int noisy, long pdepth)
union tree * db_find_named_leafs_parent(int *side, union tree *tp, const char *cp)
union tree * db_recurse(struct db_tree_state *tsp, struct db_full_path *pathp, struct combined_tree_state **region_start_statepp, void *client_data)
void rt_pr_tree_val(const union tree *tp, const struct partition *partp, int pr_name, int lvl)
union tree * db_find_named_leaf(union tree *tp, const char *cp)
int db_tally_subtree_regions(union tree *tp, union tree **reg_trees, int cur, int lim, struct resource *resp)
void db_pr_combined_tree_state(const struct combined_tree_state *ctsp)
int db_apply_state_from_one_member(struct db_tree_state *tsp, struct db_full_path *pathp, const char *cp, int sofar, const union tree *tp)
void db_free_combined_tree_state(struct combined_tree_state *ctsp)
struct combined_tree_state * db_new_combined_tree_state(const struct db_tree_state *tsp, const struct db_full_path *pathp)
int db_ck_v4gift_tree(const union tree *tp)
void db_non_union_push(union tree *tp, struct resource *resp)
int db_is_tree_all_unions(const union tree *tp)
union tree * db_mkgift_tree(struct rt_tree_array *trees, size_t subtreecount, struct resource *resp)
void db_tree_flatten_describe(struct bu_vls *vls, const union tree *tp, int indented, int lvl, double mm2local, struct resource *resp)
union tree * db_mkbool_tree(struct rt_tree_array *rt_tree_array, size_t howfar, struct resource *resp)
void db_init_db_tree_state(struct db_tree_state *tsp, struct db_i *dbip, struct resource *resp)
void db_ck_tree(const union tree *tp)
char * rt_pr_tree_str(const union tree *tree)
void rt_pr_tree_vls(struct bu_vls *vls, const union tree *tp)
struct rt_tree_array * db_flatten_tree(struct rt_tree_array *rt_tree_array, union tree *tp, int op, int avail, struct resource *resp)
void db_tree_del_rhs(union tree *tp, struct resource *resp)
int rt_tree_elim_nops(union tree *, struct resource *resp)
union tree * db_tree_parse(struct bu_vls *vls, const char *str, struct resource *resp)
void db_functree(struct db_i *dbip, struct directory *dp, void(*comb_func)(struct db_i *, struct directory *, void *), void(*leaf_func)(struct db_i *, struct directory *, void *), struct resource *resp, void *client_data)
void rt_optim_tree(union tree *tp, struct resource *resp)
void db_free_db_tree_state(struct db_tree_state *tsp)
void db_left_hvy_node(union tree *tp)
int db_tree_del_dbleaf(union tree **tp, const char *cp, struct resource *resp, int nflag)
void db_dup_db_tree_state(struct db_tree_state *otsp, const struct db_tree_state *itsp)
int db_count_tree_nodes(const union tree *tp, int count)
const struct db_tree_state rt_initial_tree_state
int db_apply_state_from_comb(struct db_tree_state *tsp, const struct db_full_path *pathp, const struct rt_comb_internal *comb)
void db_tree_mul_dbleaf(union tree *tp, const mat_t mat)
int rt_bound_tree(const union tree *tp, vect_t tree_min, vect_t tree_max)
union tree * db_dup_subtree(const union tree *tp, struct resource *resp)
size_t db_tree_nleaves(const union tree *tp)
void rt_pr_tree(const union tree *tp, int lvl)
int db_tree_list(struct bu_vls *vls, const union tree *tp)
int db_ck_left_heavy_tree(const union tree *tp, int no_unions)
void db_tree_funcleaf(struct db_i *dbip, struct rt_comb_internal *comb, union tree *comb_tree, void(*leaf_func)(struct db_i *, struct rt_comb_internal *, union tree *, void *, void *, void *, void *), void *user_ptr1, void *user_ptr2, void *user_ptr3, void *user_ptr4)
void db_free_tree(union tree *tp, struct resource *resp)
int db_count_subtree_regions(const union tree *tp)
void db_tree_describe(struct bu_vls *vls, const union tree *tp, int indented, int lvl, double mm2local)
Definition: tree.h:148
struct tree::tree_cts tr_c
struct tree::tree_node tr_b
uint32_t magic
First word: magic number.
Definition: tree.h:149
struct tree::tree_leaf tr_a
struct tree::tree_tessellation tr_d
struct tree::tree_db_leaf tr_l
fundamental vector, matrix, quaternion math macros