BRL-CAD
tree.c
Go to the documentation of this file.
1 /* T R E E . C
2  * BRL-CAD
3  *
4  * Copyright (c) 1995-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 
21 
22 #include "common.h"
23 
24 #include <stddef.h>
25 #include <math.h>
26 #include <string.h>
27 #include "bio.h"
28 
29 
30 #include "bu/parallel.h"
31 #include "vmath.h"
32 #include "bn.h"
33 #include "db.h"
34 #include "raytrace.h"
35 #include "mater.h"
36 
37 
38 #define ACQUIRE_SEMAPHORE_TREE(_hash) switch ((_hash)&03) { \
39  case 0: \
40  bu_semaphore_acquire(RT_SEM_TREE0); \
41  break; \
42  case 1: \
43  bu_semaphore_acquire(RT_SEM_TREE1); \
44  break; \
45  case 2: \
46  bu_semaphore_acquire(RT_SEM_TREE2); \
47  break; \
48  default: \
49  bu_semaphore_acquire(RT_SEM_TREE3); \
50  break; \
51  }
52 
53 #define RELEASE_SEMAPHORE_TREE(_hash) switch ((_hash)&03) { \
54  case 0: \
55  bu_semaphore_release(RT_SEM_TREE0); \
56  break; \
57  case 1: \
58  bu_semaphore_release(RT_SEM_TREE1); \
59  break; \
60  case 2: \
61  bu_semaphore_release(RT_SEM_TREE2); \
62  break; \
63  default: \
64  bu_semaphore_release(RT_SEM_TREE3); \
65  break; \
66  }
67 
68 
69 HIDDEN void
70 _rt_tree_region_assign(union tree *tp, const struct region *regionp)
71 {
72  RT_CK_TREE(tp);
73  RT_CK_REGION(regionp);
74  switch (tp->tr_op) {
75  case OP_NOP:
76  return;
77 
78  case OP_SOLID:
79  tp->tr_a.tu_regionp = (struct region *)regionp;
80  return;
81 
82  case OP_NOT:
83  case OP_GUARD:
84  case OP_XNOP:
85  tp->tr_b.tb_regionp = (struct region *)regionp;
86  _rt_tree_region_assign(tp->tr_b.tb_left, regionp);
87  return;
88 
89  case OP_UNION:
90  case OP_INTERSECT:
91  case OP_SUBTRACT:
92  case OP_XOR:
93  tp->tr_b.tb_regionp = (struct region *)regionp;
94  _rt_tree_region_assign(tp->tr_b.tb_left, regionp);
95  _rt_tree_region_assign(tp->tr_b.tb_right, regionp);
96  return;
97 
98  default:
99  bu_bomb("_rt_tree_region_assign: bad op\n");
100  }
101 }
102 
103 
104 /**
105  * This routine must be prepared to run in parallel.
106  */
107 HIDDEN int
108 _rt_gettree_region_start(struct db_tree_state *tsp, const struct db_full_path *pathp, const struct rt_comb_internal *combp, void *UNUSED(client_data))
109 {
110  if (tsp) {
111  RT_CK_RTI(tsp->ts_rtip);
112  RT_CK_RESOURCE(tsp->ts_resp);
113  if (pathp) RT_CK_FULL_PATH(pathp);
114  if (combp) RT_CHECK_COMB(combp);
115 
116  /* Ignore "air" regions unless wanted */
117  if (tsp->ts_rtip->useair == 0 && tsp->ts_aircode != 0) {
118  tsp->ts_rtip->rti_air_discards++;
119  return -1; /* drop this region */
120  }
121  }
122  return 0;
123 }
124 
125 
126 /**
127  * This routine will be called by db_walk_tree() once all the solids
128  * in this region have been visited.
129  *
130  * This routine must be prepared to run in parallel. As a result,
131  * note that the details of the solids pointed to by the soltab
132  * pointers in the tree may not be filled in when this routine is
133  * called (due to the way multiple instances of solids are handled).
134  * Therefore, everything which referred to the tree has been moved out
135  * into the serial section. (_rt_tree_region_assign, rt_bound_tree)
136  */
137 HIDDEN union tree *
138 _rt_gettree_region_end(struct db_tree_state *tsp, const struct db_full_path *pathp, union tree *curtree, void *client_data)
139 {
140  struct region *rp;
141  struct directory *dp = NULL;
142  size_t shader_len=0;
143  struct rt_i *rtip;
144  Tcl_HashTable *tbl = (Tcl_HashTable *)client_data;
145  Tcl_HashEntry *entry;
146  matp_t inv_mat;
147  struct bu_attribute_value_set avs;
148  struct bu_attribute_value_pair *avpp;
149 
150  RT_CK_DBI(tsp->ts_dbip);
151  RT_CK_FULL_PATH(pathp);
152  RT_CK_TREE(curtree);
153  rtip = tsp->ts_rtip;
154  RT_CK_RTI(rtip);
155  RT_CK_RESOURCE(tsp->ts_resp);
156 
157  if (curtree->tr_op == OP_NOP) {
158  /* Ignore empty regions */
159  return curtree;
160  }
161 
162  BU_ALLOC(rp, struct region);
163  rp->l.magic = RT_REGION_MAGIC;
164  rp->reg_regionid = tsp->ts_regionid;
165  rp->reg_is_fastgen = tsp->ts_is_fastgen;
166  rp->reg_aircode = tsp->ts_aircode;
167  rp->reg_gmater = tsp->ts_gmater;
168  rp->reg_los = tsp->ts_los;
169 
170  dp = (struct directory *)DB_FULL_PATH_CUR_DIR(pathp);
171  if (!dp)
172  return TREE_NULL;
173 
174  bu_avs_init_empty(&avs);
175  if (db5_get_attributes(tsp->ts_dbip, &avs, dp) == 0) {
176  /* copy avs */
178  for (BU_AVS_FOR(avpp, &(tsp->ts_attrs))) {
179  bu_avs_add(&(rp->attr_values), avpp->name, bu_avs_get(&avs, avpp->name));
180  }
181  }
182  bu_avs_free(&avs);
183 
184  rp->reg_mater = tsp->ts_mater; /* struct copy */
185  if (tsp->ts_mater.ma_shader)
186  shader_len = strlen(tsp->ts_mater.ma_shader);
187  if (shader_len) {
189  } else
190  rp->reg_mater.ma_shader = (char *)NULL;
191 
192  rp->reg_name = db_path_to_string(pathp);
193 
194 
196  bu_log("_rt_gettree_region_end() %s\n", rp->reg_name);
197  rt_pr_tree(curtree, 0);
198  }
199 
200  rp->reg_treetop = curtree;
201  rp->reg_all_unions = db_is_tree_all_unions(curtree);
202 
203  /* Determine material properties */
204  rp->reg_mfuncs = (char *)0;
205  rp->reg_udata = (char *)0;
206  if (rp->reg_mater.ma_color_valid == 0)
208 
209  /* enter critical section */
211 
212  rp->reg_instnum = dp->d_uses++;
213 
214  /*
215  * Add the region to the linked list of regions.
216  * Positions in the region bit vector are established at this time.
217  */
218  BU_LIST_INSERT(&(rtip->HeadRegion), &rp->l);
219 
220  /* Assign bit vector pos. */
221  rp->reg_bit = rtip->nregions++;
222 
223  /* leave critical section */
225 
226  if (tbl && bu_avs_get(&tsp->ts_attrs, "ORCA_Comp")) {
227  int newentry;
228  long int reg_bit = rp->reg_bit;
229  const char *key = (char *)reg_bit;
230 
231  inv_mat = (matp_t)bu_calloc(16, sizeof(fastf_t), "inv_mat");
232  bn_mat_inv(inv_mat, tsp->ts_mat);
233 
234  /* enter critical section */
236 
237  entry = Tcl_CreateHashEntry(tbl, key, &newentry);
238  Tcl_SetHashValue(entry, (ClientData)inv_mat);
239 
240  /* leave critical section */
242  }
243 
244  if (RT_G_DEBUG & DEBUG_REGIONS) {
245  bu_log("Add Region %s instnum %ld\n",
246  rp->reg_name, rp->reg_instnum);
247  }
248 
249  /* Indicate that we have swiped 'curtree' */
250  return TREE_NULL;
251 }
252 
253 
254 /**
255  * See if solid "dp" as transformed by "mat" already exists in the
256  * soltab list. If it does, return the matching stp, otherwise,
257  * create a new soltab structure, enroll it in the list, and return a
258  * pointer to that.
259  *
260  * "mat" will be a null pointer when an identity matrix is signified.
261  * This greatly speeds the comparison process.
262  *
263  * The two cases can be distinguished by the fact that stp->st_id will
264  * be 0 for a new soltab structure, and non-zero for an existing one.
265  *
266  * This routine will run in parallel.
267  *
268  * In order to avoid a race between searching the soltab list and
269  * adding new solids to it, the new solid to be added *must* be
270  * enrolled in the list before exiting the critical section.
271  *
272  * To limit the size of the list to be searched, there are many lists.
273  * The selection of which list is determined by the hash value
274  * computed from the solid's name. This is the same optimization used
275  * in searching the directory lists.
276  *
277  * This subroutine is the critical bottleneck in parallel tree walking.
278  *
279  * It is safe, and much faster, to use several different critical
280  * sections when searching different lists.
281  *
282  * There are only 4 dedicated semaphores defined, TREE0 through TREE3.
283  * This unfortunately limits the code to having only 4 CPUs doing list
284  * searching at any one time. Hopefully, this is enough parallelism
285  * to keep the rest of the CPUs doing I/O and actual solid prepping.
286  *
287  * Since the algorithm has been reduced from an O((nsolid/128)**2)
288  * search on the entire rti_solidheads[hash] list to an O(ninstance)
289  * search on the dp->d_use_head list for this one solid, the critical
290  * section should be relatively short-lived. Having the 3-way split
291  * should provide ample opportunity for parallelism through here,
292  * while still ensuring that the necessary variables are protected.
293  *
294  * There are two critical variables which *both* need to be protected:
295  * the specific rti_solidhead[hash] list head, and the specific
296  * dp->d_use_hd list head. Fortunately, since the selection of
297  * critical section is based upon db_dirhash(dp->d_namep), any other
298  * processor that wants to search this same 'dp' will get the same
299  * hash as the current thread, and will thus wait for the appropriate
300  * semaphore to be released. Similarly, any other thread that wants
301  * to search the same rti_solidhead[hash] list as the current thread
302  * will be using the same hash, and will thus wait for the proper
303  * semaphore.
304  */
305 HIDDEN struct soltab *
306 _rt_find_identical_solid(const matp_t mat, struct directory *dp, struct rt_i *rtip)
307 {
308  struct soltab *stp = RT_SOLTAB_NULL;
309  int hash;
310 
311  RT_CK_DIR(dp);
312  RT_CK_RTI(rtip);
313 
314  hash = db_dirhash(dp->d_namep);
315 
316  /* Enter the appropriate dual critical-section */
318 
319  /*
320  * If solid has not been referenced yet, the search can be
321  * skipped. If solid is being referenced a _lot_, it certainly
322  * isn't all going to be in the same place, so don't bother
323  * searching. Consider the case of a million instances of the
324  * same tree submodel solid.
325  */
326  if (dp->d_uses > 0 && dp->d_uses < 100 &&
327  rtip->rti_dont_instance == 0
328  ) {
329  struct bu_list *mid;
330 
331  /* Search dp->d_use_hd list for other instances */
332  for (BU_LIST_FOR(mid, bu_list, &dp->d_use_hd)) {
333 
334  stp = BU_LIST_MAIN_PTR(soltab, mid, l2);
335  RT_CK_SOLTAB(stp);
336 
337  if (stp->st_matp == (matp_t)0) {
338  if (mat == (matp_t)0) {
339  /* Both have identity matrix */
340  goto more_checks;
341  }
342  continue;
343  }
344  if (mat == (matp_t)0) continue; /* doesn't match */
345 
346  if (!bn_mat_is_equal(mat, stp->st_matp, &rtip->rti_tol))
347  continue;
348 
349  more_checks:
350  /* Don't instance this solid from some other model
351  * instance. As this is nearly always equal, check it
352  * last
353  */
354  if (stp->st_rtip != rtip) continue;
355 
356  /*
357  * stp now points to re-referenced solid. stp->st_id is
358  * non-zero, indicating pre-existing solid.
359  */
360  RT_CK_SOLTAB(stp); /* sanity */
361 
362  /* Only increment use counter for non-dead solids. */
363  if (!(stp->st_aradius <= -1))
364  stp->st_uses++;
365  /* dp->d_uses is NOT incremented, because number of
366  * soltab's using it has not gone up.
367  */
368  if (RT_G_DEBUG & DEBUG_SOLIDS) {
369  bu_log(mat ?
370  "%s re-referenced %ld\n" :
371  "%s re-referenced %ld (identity mat)\n",
372  dp->d_namep, stp->st_uses);
373  }
374 
375  /* Leave the appropriate dual critical-section */
377  return stp;
378  }
379  }
380 
381  /*
382  * Create and link a new solid into the list.
383  *
384  * Ensure the search keys "dp", "st_mat" and "st_rtip" are stored
385  * now, while still inside the critical section, because they are
386  * searched on, above.
387  */
388  BU_ALLOC(stp, struct soltab);
389  stp->l.magic = RT_SOLTAB_MAGIC;
390  stp->l2.magic = RT_SOLTAB2_MAGIC;
391  stp->st_rtip = rtip;
392  stp->st_dp = dp;
393  dp->d_uses++;
394  stp->st_uses = 1;
395  /* stp->st_id is intentionally left zero here, as a flag */
396 
397  if (mat) {
398  stp->st_matp = (matp_t)bu_malloc(sizeof(mat_t), "st_matp");
399  MAT_COPY(stp->st_matp, mat);
400  } else {
401  stp->st_matp = (matp_t)0;
402  }
403 
404  /* Add to the appropriate soltab list head */
405  /* PARALLEL NOTE: Uses critical section on rt_solidheads element */
406  BU_LIST_INSERT(&(rtip->rti_solidheads[hash]), &(stp->l));
407 
408  /* Also add to the directory structure list head */
409  /* PARALLEL NOTE: Uses critical section on this 'dp' */
410  BU_LIST_INSERT(&dp->d_use_hd, &(stp->l2));
411 
412  /*
413  * Leave the 4-way critical-section protecting dp and [hash]
414  */
416 
417  /* Enter an exclusive critical section to protect nsolids.
418  * nsolids++ needs to be locked to a SINGLE thread
419  */
421  stp->st_bit = rtip->nsolids++;
423 
424  /*
425  * Fill in the last little bit of the structure in full parallel
426  * mode, outside of any critical section.
427  */
428 
429  /* Init tables of regions using this solid. Usually small. */
430  bu_ptbl_init(&stp->st_regions, 7, "st_regions ptbl");
431 
432  return stp;
433 }
434 
435 
436 /**
437  * This routine must be prepared to run in parallel.
438  */
439 HIDDEN union tree *
440 _rt_gettree_leaf(struct db_tree_state *tsp, const struct db_full_path *pathp, struct rt_db_internal *ip, void *UNUSED(client_data))
441 {
442  struct soltab *stp;
443  struct directory *dp;
444  matp_t mat;
445  union tree *curtree;
446  struct rt_i *rtip;
447  int ret;
448  int i;
449 
450  RT_CK_DBTS(tsp);
451  RT_CK_DBI(tsp->ts_dbip);
452  RT_CK_FULL_PATH(pathp);
453  RT_CK_DB_INTERNAL(ip);
454  rtip = tsp->ts_rtip;
455  RT_CK_RTI(rtip);
456  RT_CK_RESOURCE(tsp->ts_resp);
457  dp = DB_FULL_PATH_CUR_DIR(pathp);
458  if (!dp)
459  return TREE_NULL;
460 
461  /* Determine if this matrix is an identity matrix */
462 
463  if (!bn_mat_is_equal(tsp->ts_mat, bn_mat_identity, &rtip->rti_tol)) {
464  /* Not identity matrix */
465  mat = (matp_t)tsp->ts_mat;
466  } else {
467  /* Identity matrix */
468  mat = (matp_t)0;
469  }
470 
471  /*
472  * Check to see if this exact solid has already been processed.
473  * Match on leaf name and matrix. Note that there is a race here
474  * between having st_id filled in a few lines below (which is
475  * necessary for calling ft_prep), and ft_prep filling in
476  * st_aradius. Fortunately, st_aradius starts out as zero, and
477  * will never go down to -1 unless this soltab structure has
478  * become a dead solid, so by testing against -1 (instead of <= 0,
479  * like before, oops), it isn't a problem.
480  */
481  stp = _rt_find_identical_solid(mat, dp, rtip);
482  if (stp->st_id != 0) {
483  /* stp is an instance of a pre-existing solid */
484  if (stp->st_aradius <= -1) {
485  /* It's dead, Jim. st_uses was not incremented. */
486  return TREE_NULL; /* BAD: instance of dead solid */
487  }
488  goto found_it;
489  }
490 
491  if (rtip->rti_add_to_new_solids_list) {
492  bu_ptbl_ins(&rtip->rti_new_solids, (long *)stp);
493  }
494 
495  stp->st_id = ip->idb_type;
496  stp->st_meth = &OBJ[ip->idb_type];
497  if (mat) {
498  mat = stp->st_matp;
499  } else {
500  mat = (matp_t)bn_mat_identity;
501  }
502 
503  RT_CK_DB_INTERNAL(ip);
504 
505  /* init solid's maxima and minima */
506  VSETALL(stp->st_max, -INFINITY);
507  VSETALL(stp->st_min, INFINITY);
508 
509  /*
510  * If the ft_prep routine wants to keep the internal structure,
511  * that is OK, as long as idb_ptr is set to null. Note that the
512  * prep routine may have changed st_id.
513  */
514  ret = -1;
515  if (stp->st_meth->ft_prep) {
516  ret = stp->st_meth->ft_prep(stp, ip, rtip);
517  }
518  if (ret != 0) {
519  int hash;
520  /* Error, solid no good */
521  bu_log("_rt_gettree_leaf(%s): prep failure\n", dp->d_namep);
522  /* Too late to delete soltab entry; mark it as "dead" */
523  hash = db_dirhash(dp->d_namep);
525  stp->st_aradius = -1;
526  stp->st_uses--;
528  return TREE_NULL; /* BAD */
529  }
530 
531  if (rtip->rti_dont_instance) {
532  /*
533  * If instanced solid refs are not being compressed, then
534  * memory isn't an issue, and the application (such as
535  * solids_on_ray) probably cares about the full path of this
536  * solid, from root to leaf. So make it available here.
537  * (stp->st_dp->d_uses could be the way to discriminate
538  * references uniquely, if the path isn't enough. To locate
539  * given dp and d_uses, search dp->d_use_hd list. Question
540  * is, where to stash current val of d_uses?)
541  */
542  db_full_path_init(&stp->st_path);
543  db_dup_full_path(&stp->st_path, pathp);
544  } else {
545  /*
546  * If there is more than just a direct reference to this leaf
547  * from its containing region, copy that below-region path
548  * into st_path. Otherwise, leave st_path's magic number 0.
549  *
550  * XXX nothing depends on this behavior yet, and this whole
551  * XXX 'else' clause might well be deleted. -Mike
552  */
553  i = pathp->fp_len-1;
554  if (i > 0 && !(pathp->fp_names[i-1]->d_flags & RT_DIR_REGION)) {
555  /* Search backwards for region. If no region, use whole path */
556  for (--i; i > 0; i--) {
557  if (pathp->fp_names[i-1]->d_flags & RT_DIR_REGION) break;
558  }
559  if (i < 0) i = 0;
560  db_full_path_init(&stp->st_path);
561  db_dup_path_tail(&stp->st_path, pathp, i);
562  }
563  }
565  char *sofar = db_path_to_string(&stp->st_path);
566  bu_log("_rt_gettree_leaf() st_path=%s\n", sofar);
567  bu_free(sofar, "path string");
568  }
569 
570  if (RT_G_DEBUG&DEBUG_SOLIDS) {
571  struct bu_vls str = BU_VLS_INIT_ZERO;
572  bu_log("\n---Primitive %ld: %s\n", stp->st_bit, dp->d_namep);
573 
574  /* verbose=1, mm2local=1.0 */
575  ret = -1;
576  if (stp->st_meth->ft_describe) {
577  ret = stp->st_meth->ft_describe(&str, ip, 1, 1.0, tsp->ts_resp, tsp->ts_dbip);
578  }
579  if (ret < 0) {
580  bu_log("_rt_gettree_leaf(%s): solid describe failure\n",
581  dp->d_namep);
582  }
583  bu_log("%s: %s", dp->d_namep, bu_vls_addr(&str));
584  bu_vls_free(&str);
585  }
586 
587 found_it:
588  RT_GET_TREE(curtree, tsp->ts_resp);
589  curtree->tr_op = OP_SOLID;
590  curtree->tr_a.tu_stp = stp;
591  /* regionp will be filled in later by _rt_tree_region_assign() */
592  curtree->tr_a.tu_regionp = (struct region *)0;
593 
595  char *sofar = db_path_to_string(pathp);
596  bu_log("_rt_gettree_leaf() %s\n", sofar);
597  bu_free(sofar, "path string");
598  }
599 
600  return curtree;
601 }
602 
603 
604 void
605 rt_free_soltab(struct soltab *stp)
606 {
607  int hash = 0;
608 
609  RT_CK_SOLTAB(stp);
610  if (stp->st_id < 0)
611  bu_bomb("rt_free_soltab: bad st_id");
612 
613  if (stp->st_dp && stp->st_dp->d_namep)
614  hash = db_dirhash(stp->st_dp->d_namep);
615 
616  ACQUIRE_SEMAPHORE_TREE(hash); /* start critical section */
617  if (--(stp->st_uses) > 0) {
619  return;
620  }
621  BU_LIST_DEQUEUE(&(stp->l2)); /* remove from st_dp->d_use_hd list */
622  BU_LIST_DEQUEUE(&(stp->l)); /* uses rti_solidheads[] */
623 
624  RELEASE_SEMAPHORE_TREE(hash); /* end critical section */
625 
626  if (stp->st_aradius > 0) {
627  if (stp->st_meth->ft_free)
628  stp->st_meth->ft_free(stp);
629  stp->st_aradius = 0;
630  }
631  if (stp->st_matp) bu_free((char *)stp->st_matp, "st_matp");
632  stp->st_matp = (matp_t)0; /* Sanity */
633 
634  bu_ptbl_free(&stp->st_regions);
635 
636  stp->st_dp = RT_DIR_NULL; /* Sanity */
637 
638  if (stp->st_path.magic) {
639  RT_CK_FULL_PATH(&stp->st_path);
640  db_free_full_path(&stp->st_path);
641  }
642 
643  bu_free((char *)stp, "struct soltab");
644 }
645 
646 
647 /**
648  * Convert any references to "dead" solids into NOP nodes.
649  */
650 void
652 {
653 
654  RT_CK_TREE(tp);
655 
656  switch (tp->tr_op) {
657 
658  case OP_SOLID:
659  {
660  struct soltab *stp;
661 
662  stp = tp->tr_a.tu_stp;
663  RT_CK_SOLTAB(stp);
664  if (stp->st_aradius <= 0) {
666  bu_log("encountered dead solid '%s' stp=%p, tp=%p\n",
667  stp->st_dp->d_namep, (void *)stp, (void *)tp);
668  rt_free_soltab(stp);
669  tp->tr_a.tu_stp = SOLTAB_NULL;
670  tp->tr_op = OP_NOP; /* Convert to NOP */
671  }
672  return;
673  }
674 
675  default:
676  bu_log("_rt_tree_kill_dead_solid_refs(%p): unknown op=%x\n",
677  (void *)tp, tp->tr_op);
678  return;
679 
680  case OP_XOR:
681  case OP_UNION:
682  case OP_INTERSECT:
683  case OP_SUBTRACT:
684  /* BINARY */
687  break;
688  case OP_NOT:
689  case OP_GUARD:
690  case OP_XNOP:
691  /* UNARY tree -- for completeness only, should never be seen */
693  break;
694  case OP_NOP:
695  /* This sub-tree has nothing further in it */
696  return;
697  }
698  return;
699 }
700 
701 
702 int
703 rt_gettrees_muves(struct rt_i *rtip, const char **attrs, int argc, const char **argv, int ncpus)
704 {
705  struct soltab *stp;
706  struct region *regp;
707  Tcl_HashTable *tbl;
708  size_t prev_sol_count;
709  int i;
710  int num_attrs=0;
711  point_t region_min, region_max;
712 
713  RT_CHECK_RTI(rtip);
714  RT_CK_DBI(rtip->rti_dbip);
715 
716  if (!rtip->needprep) {
717  bu_log("ERROR: rt_gettree() called again after rt_prep!\n");
718  return -1; /* FAIL */
719  }
720 
721  if (argc <= 0) return -1; /* FAIL */
722 
723  BU_ALLOC(tbl, Tcl_HashTable);
724  Tcl_InitHashTable(tbl, TCL_ONE_WORD_KEYS);
725  rtip->Orca_hash_tbl = (void *)tbl;
726 
727  prev_sol_count = rtip->nsolids;
728 
729  {
730  struct db_tree_state tree_state;
731 
732  tree_state = rt_initial_tree_state; /* struct copy */
733  tree_state.ts_dbip = rtip->rti_dbip;
734  tree_state.ts_rtip = rtip;
735  tree_state.ts_resp = NULL; /* sanity. Needs to be updated */
736 
737 
738  if (attrs) {
739  if (db_version(rtip->rti_dbip) < 5) {
740  bu_log("WARNING: requesting attributes from an old database version (ignored)\n");
741  bu_avs_init_empty(&tree_state.ts_attrs);
742  } else {
743  while (attrs[num_attrs]) {
744  num_attrs++;
745  }
746  if (num_attrs) {
747  bu_avs_init(&tree_state.ts_attrs,
748  num_attrs,
749  "avs in tree_state");
750  num_attrs = 0;
751  while (attrs[num_attrs]) {
752  bu_avs_add(&tree_state.ts_attrs,
753  attrs[num_attrs],
754  NULL);
755  num_attrs++;
756  }
757  } else {
758  bu_avs_init_empty(&tree_state.ts_attrs);
759  }
760  }
761  } else {
762  bu_avs_init_empty(&tree_state.ts_attrs);
763  }
764 
765  i = db_walk_tree(rtip->rti_dbip, argc, argv, ncpus,
766  &tree_state,
769  _rt_gettree_leaf, (void *)tbl);
770  bu_avs_free(&tree_state.ts_attrs);
771  }
772 
773  /* DEBUG: Ensure that all region trees are valid */
774  for (BU_LIST_FOR(regp, region, &(rtip->HeadRegion))) {
775  RT_CK_REGION(regp);
776  db_ck_tree(regp->reg_treetop);
777  }
778 
779  /*
780  * Eliminate any "dead" solids that parallel code couldn't change.
781  * First remove any references from the region tree, then remove
782  * actual soltab structs from the soltab list.
783  */
784  for (BU_LIST_FOR(regp, region, &(rtip->HeadRegion))) {
785  RT_CK_REGION(regp);
788  }
789 again:
790  RT_VISIT_ALL_SOLTABS_START(stp, rtip) {
791  RT_CK_SOLTAB(stp);
792  if (stp->st_aradius <= 0) {
793  bu_log("rt_gettrees() cleaning up dead solid '%s'\n",
794  stp->st_dp->d_namep);
795  rt_free_soltab(stp);
796  /* Can't do rtip->nsolids--, that doubles as max bit number! */
797  /* The macro makes it hard to regain place, punt */
798  goto again;
799  }
801 
802  /*
803  * Another pass, no restarting. Assign "piecestate" indices
804  * for those solids which contain pieces.
805  */
806  RT_VISIT_ALL_SOLTABS_START(stp, rtip) {
807  if (stp->st_npieces > 1) {
808  /* all pieces must be within model bounding box for pieces
809  * to work correctly.
810  */
811  VMINMAX(rtip->mdl_min, rtip->mdl_max, stp->st_min);
812  VMINMAX(rtip->mdl_min, rtip->mdl_max, stp->st_max);
814  }
816  rt_pr_soltab(stp);
818 
819  /* Handle finishing touches on the trees that needed soltab
820  * structs that the parallel code couldn't look at yet.
821  */
822  for (BU_LIST_FOR(regp, region, &(rtip->HeadRegion))) {
823  RT_CK_REGION(regp);
824 
825  /* The region and the entire tree are cross-referenced */
826  _rt_tree_region_assign(regp->reg_treetop, regp);
827 
828  /*
829  * Find region RPP, and update the model maxima and
830  * minima.
831  *
832  * Don't update min & max for halfspaces; instead, add
833  * them to the list of infinite solids, for special
834  * handling.
835  */
836  if (rt_bound_tree(regp->reg_treetop, region_min, region_max) < 0) {
837  bu_log("rt_gettrees() %s\n", regp->reg_name);
838  bu_bomb("rt_gettrees(): rt_bound_tree() fail\n");
839  }
840  if (region_max[X] < INFINITY) {
841  /* infinite regions are exempted from this */
842  VMINMAX(rtip->mdl_min, rtip->mdl_max, region_min);
843  VMINMAX(rtip->mdl_min, rtip->mdl_max, region_max);
844  }
845  }
846 
847  /* DEBUG: Ensure that all region trees are valid */
848  for (BU_LIST_FOR(regp, region, &(rtip->HeadRegion))) {
849  RT_CK_REGION(regp);
850  db_ck_tree(regp->reg_treetop);
851  }
852 
853  if (i < 0) return i;
854 
855  if (rtip->nsolids <= prev_sol_count)
856  bu_log("rt_gettrees(%s) warning: no primitives found\n", argv[0]);
857  return 0; /* OK */
858 }
859 
860 
861 int
862 rt_gettrees_and_attrs(struct rt_i *rtip, const char **attrs, int argc, const char **argv, int ncpus)
863 {
864  return rt_gettrees_muves(rtip, attrs, argc, argv, ncpus);
865 }
866 
867 
868 int
869 rt_gettree(struct rt_i *rtip, const char *node)
870 {
871  int rv;
872  const char *argv[2];
873 
874  argv[0] = node;
875  argv[1] = (const char *)NULL;
876 
877  rv = rt_gettrees_and_attrs(rtip, NULL, 1, argv, 1);
878 
879  if (rv == 0 || rv == -2) {
880  return 0;
881  } else {
882  return -1;
883  }
884 }
885 
886 
887 int
888 rt_gettrees(struct rt_i *rtip, int argc, const char **argv, int ncpus)
889 {
890  int rv;
891  rv = rt_gettrees_and_attrs(rtip, NULL, argc, argv, ncpus);
892 
893  if (rv == 0 || rv == -2) {
894  return 0;
895  } else {
896  return -1;
897  }
898 }
899 
900 
901 int
902 rt_tree_elim_nops(union tree *tp, struct resource *resp)
903 {
904  union tree *left, *right;
905 
906  RT_CK_RESOURCE(resp);
907 top:
908  RT_CK_TREE(tp);
909 
910  switch (tp->tr_op) {
911 
912  case OP_SOLID:
913  return 0; /* Retain */
914 
915  default:
916  bu_log("rt_tree_elim_nops(%p): unknown op=%x\n",
917  (void *)tp, tp->tr_op);
918  return -1;
919 
920  case OP_XOR:
921  case OP_UNION:
922  /* BINARY type -- rewrite tp as surviving side */
923  left = tp->tr_b.tb_left;
924  right = tp->tr_b.tb_right;
925  if (rt_tree_elim_nops(left, resp) < 0) {
926  *tp = *right; /* struct copy */
927  RT_FREE_TREE(left, resp);
928  RT_FREE_TREE(right, resp);
929  goto top;
930  }
931  if (rt_tree_elim_nops(right, resp) < 0) {
932  *tp = *left; /* struct copy */
933  RT_FREE_TREE(left, resp);
934  RT_FREE_TREE(right, resp);
935  goto top;
936  }
937  break;
938  case OP_INTERSECT:
939  /* BINARY type -- if either side fails, nuke subtree */
940  left = tp->tr_b.tb_left;
941  right = tp->tr_b.tb_right;
942  if (rt_tree_elim_nops(left, resp) < 0 ||
943  rt_tree_elim_nops(right, resp) < 0) {
944  db_free_tree(left, resp);
945  db_free_tree(right, resp);
946  tp->tr_op = OP_NOP;
947  return -1; /* eliminate reference to tp */
948  }
949  break;
950  case OP_SUBTRACT:
951  /* BINARY type -- if right fails, rewrite (X - 0 = X).
952  * If left fails, nuke entire subtree (0 - X = 0).
953  */
954  left = tp->tr_b.tb_left;
955  right = tp->tr_b.tb_right;
956  if (rt_tree_elim_nops(left, resp) < 0) {
957  db_free_tree(left, resp);
958  db_free_tree(right, resp);
959  tp->tr_op = OP_NOP;
960  return -1; /* eliminate reference to tp */
961  }
962  if (rt_tree_elim_nops(right, resp) < 0) {
963  *tp = *left; /* struct copy */
964  RT_FREE_TREE(left, resp);
965  RT_FREE_TREE(right, resp);
966  goto top;
967  }
968  break;
969  case OP_NOT:
970  case OP_GUARD:
971  case OP_XNOP:
972  /* UNARY tree -- for completeness only, should never be seen */
973  left = tp->tr_b.tb_left;
974  if (rt_tree_elim_nops(left, resp) < 0) {
975  RT_FREE_TREE(left, resp);
976  tp->tr_op = OP_NOP;
977  return -1; /* Kill ref to unary op, too */
978  }
979  break;
980  case OP_NOP:
981  /* Implies that this tree has nothing in it */
982  return -1; /* Kill ref to this NOP */
983  }
984  return 0;
985 }
986 
987 
988 struct soltab *
989 rt_find_solid(const struct rt_i *rtip, const char *name)
990 {
991  struct soltab *stp;
992  struct directory *dp;
993 
994  RT_CHECK_RTI(rtip);
995  if ((dp = db_lookup((struct db_i *)rtip->rti_dbip, (char *)name,
997  return RT_SOLTAB_NULL;
998 
999  RT_VISIT_ALL_SOLTABS_START(stp, (struct rt_i *)rtip) {
1000  if (stp->st_dp == dp)
1001  return stp;
1003  return RT_SOLTAB_NULL;
1004 }
1005 
1006 
1007 void
1008 rt_optim_tree(union tree *tp, struct resource *resp)
1009 {
1010  union tree **sp;
1011  union tree *low;
1012  union tree **stackend;
1013 
1014  RT_CK_TREE(tp);
1015  while ((sp = resp->re_boolstack) == (union tree **)0)
1016  rt_grow_boolstack(resp);
1017  stackend = &(resp->re_boolstack[resp->re_boolslen-1]);
1018  *sp++ = TREE_NULL;
1019  *sp++ = tp;
1020  while ((tp = *--sp) != TREE_NULL) {
1021  switch (tp->tr_op) {
1022  case OP_NOP:
1023  /* XXX Consider eliminating nodes of form (A op NOP) */
1024  /* XXX Needs to be detected in previous iteration */
1025  break;
1026  case OP_SOLID:
1027  break;
1028  case OP_SUBTRACT:
1029  while ((low=tp->tr_b.tb_left)->tr_op == OP_SUBTRACT) {
1030  /* Rewrite X - A - B as X - (A union B) */
1031  tp->tr_b.tb_left = low->tr_b.tb_left;
1032  low->tr_op = OP_UNION;
1033  low->tr_b.tb_left = low->tr_b.tb_right;
1034  low->tr_b.tb_right = tp->tr_b.tb_right;
1035  tp->tr_b.tb_right = low;
1036  }
1037  /* push both nodes - search left first */
1038  *sp++ = tp->tr_b.tb_right;
1039  *sp++ = tp->tr_b.tb_left;
1040  if (sp >= stackend) {
1041  int off = sp - resp->re_boolstack;
1042  rt_grow_boolstack(resp);
1043  sp = &(resp->re_boolstack[off]);
1044  stackend = &(resp->re_boolstack[resp->re_boolslen-1]);
1045  }
1046  break;
1047  case OP_UNION:
1048  case OP_INTERSECT:
1049  case OP_XOR:
1050  /* Need to look at 3-level optimizations here, both sides */
1051  /* push both nodes - search left first */
1052  *sp++ = tp->tr_b.tb_right;
1053  *sp++ = tp->tr_b.tb_left;
1054  if (sp >= stackend) {
1055  int off = sp - resp->re_boolstack;
1056  rt_grow_boolstack(resp);
1057  sp = &(resp->re_boolstack[off]);
1058  stackend = &(resp->re_boolstack[resp->re_boolslen-1]);
1059  }
1060  break;
1061  default:
1062  bu_log("rt_optim_tree: bad op x%x\n", tp->tr_op);
1063  break;
1064  }
1065  }
1066 }
1067 
1068 
1069 /*
1070  * Local Variables:
1071  * mode: C
1072  * tab-width: 8
1073  * indent-tabs-mode: t
1074  * c-file-style: "stroustrup"
1075  * End:
1076  * ex: shiftwidth=4 tabstop=8
1077  */
void rt_pr_soltab(const struct soltab *stp)
char * d_namep
pointer to name string
Definition: raytrace.h:859
struct bu_attribute_value_set attr_values
Attribute/value set.
Definition: raytrace.h:556
#define DEBUG_REGIONS
7 Print regions & boolean trees
Definition: raytrace.h:90
int reg_bit
constant index into Regions[]
Definition: raytrace.h:541
#define BU_LIST_FOR(p, structure, hp)
Definition: list.h:365
Definition: raytrace.h:800
void bu_log(const char *,...) _BU_ATTR_PRINTF12
Definition: log.c:176
#define BU_LIST_INSERT(old, new)
Definition: list.h:183
const struct db_tree_state rt_initial_tree_state
Definition: globals.c:90
void bu_avs_init_empty(struct bu_attribute_value_set *avp)
Definition: avs.c:36
struct mater_info ts_mater
material properties
Definition: raytrace.h:1047
Definition: list.h:118
#define RT_CHECK_COMB(_p)
Definition: raytrace.h:954
const struct directory * st_dp
Directory entry of solid.
Definition: raytrace.h:436
point_t mdl_min
min corner of model bounding RPP
Definition: raytrace.h:1769
size_t fp_len
Definition: db_fullpath.h:44
int rti_air_discards
of air regions discarded
Definition: raytrace.h:1805
void db_dup_full_path(struct db_full_path *newp, const struct db_full_path *oldp)
Definition: db_fullpath.c:87
#define RT_CK_RTI(_p)
Definition: raytrace.h:1833
void db_dup_path_tail(struct db_full_path *newp, const struct db_full_path *oldp, off_t start)
Definition: db_fullpath.c:165
#define RT_SOLTAB_NULL
Definition: raytrace.h:449
int ts_gmater
GIFT compat material code.
Definition: raytrace.h:1045
#define OP_NOP
Leaf with no effect.
Definition: raytrace.h:1132
void rt_region_color_map(register struct region *regp)
Definition: mater.c:196
const mat_t bn_mat_identity
Matrix and vector functionality.
Definition: mat.c:46
union tree ** re_boolstack
Stack for rt_booleval()
Definition: raytrace.h:1455
Definition: clone.c:90
int useair
1="air" regions are retained while prepping
Definition: raytrace.h:1756
void bu_ptbl_init(struct bu_ptbl *b, size_t len, const char *str)
Definition: ptbl.c:32
int rt_bound_tree(const union tree *tp, vect_t tree_min, vect_t tree_max)
#define RT_SOLTAB2_MAGIC
Definition: magic.h:168
void rt_grow_boolstack(struct resource *res)
int rti_add_to_new_solids_list
Definition: raytrace.h:1821
#define VSETALL(a, s)
Definition: color.c:54
int db_is_tree_all_unions(const union tree *tp)
Definition: db_tree.c:1670
#define OP_XOR
Binary: L xor R, not both.
Definition: raytrace.h:1130
struct bu_list HeadRegion
ptr of list of regions in model
Definition: raytrace.h:1778
int bu_avs_add(struct bu_attribute_value_set *avp, const char *attribute, const char *value)
Definition: avs.c:78
short reg_all_unions
1=boolean tree is all unions
Definition: raytrace.h:551
void bu_semaphore_acquire(unsigned int i)
Definition: semaphore.c:180
struct directory * db_lookup(const struct db_i *, const char *name, int noisy)
Definition: db_lookup.c:153
long d_uses
uses, from instancing
Definition: raytrace.h:866
size_t nregions
total # of regions participating
Definition: raytrace.h:1782
struct db_full_path st_path
path from region to leaf
Definition: raytrace.h:442
void _rt_tree_kill_dead_solid_refs(union tree *tp)
Definition: tree.c:651
int db_version(struct db_i *dbip)
Definition: db5_scan.c:414
struct region * tb_regionp
ptr to containing region
Definition: raytrace.h:1148
void db_ck_tree(const union tree *tp)
Definition: db_tree.c:1255
fastf_t st_aradius
Radius of APPROXIMATING sphere.
Definition: raytrace.h:433
Header file for the BRL-CAD common definitions.
#define OP_XNOP
Unary: L, mark region.
Definition: raytrace.h:1136
int ts_los
equivalent LOS estimate
Definition: raytrace.h:1046
#define DB_FULL_PATH_CUR_DIR(_pp)
Definition: db_fullpath.h:51
matp_t st_matp
solid coords to model space, NULL=identity
Definition: raytrace.h:441
#define RT_DIR_REGION
region
Definition: raytrace.h:885
const char * reg_name
Identifying string.
Definition: raytrace.h:539
#define RT_REGION_MAGIC
Definition: magic.h:166
char ma_color_valid
non-0 ==> ma_color is non-default
Definition: raytrace.h:524
int bu_ptbl_ins(struct bu_ptbl *b, long *p)
int rt_tree_elim_nops(union tree *tp, struct resource *resp)
Definition: tree.c:902
void db_full_path_init(struct db_full_path *pathp)
Definition: db_fullpath.c:40
#define RT_CK_REGION(_p)
Definition: raytrace.h:559
struct bu_list l
links, headed by rti_headsolid
Definition: raytrace.h:426
void rt_pr_tree(const union tree *tp, int lvl)
void rt_free_soltab(struct soltab *stp)
Definition: tree.c:605
int ts_aircode
GIFT compat air code.
Definition: raytrace.h:1044
#define HIDDEN
Definition: common.h:86
union tree * tb_left
Definition: raytrace.h:1149
struct soltab * tu_stp
Definition: raytrace.h:1156
int rt_gettrees_and_attrs(struct rt_i *rtip, const char **attrs, int argc, const char **argv, int ncpus)
Definition: tree.c:862
void * bu_malloc(size_t siz, const char *str)
Definition: malloc.c:314
const char * bu_avs_get(const struct bu_attribute_value_set *avp, const char *attribute)
Definition: avs.c:172
long st_bit
solids bit vector index (const)
Definition: raytrace.h:439
struct region * tu_regionp
ptr to containing region
Definition: raytrace.h:1155
void bu_vls_free(struct bu_vls *vp)
Definition: vls.c:248
int bn_mat_is_equal(const mat_t a, const mat_t b, const struct bn_tol *tol)
Definition: mat.c:925
#define OP_SUBTRACT
Binary: L subtract R.
Definition: raytrace.h:1129
HIDDEN union tree * _rt_gettree_leaf(struct db_tree_state *tsp, const struct db_full_path *pathp, struct rt_db_internal *ip, void *client_data)
Definition: tree.c:440
#define RT_SEM_STATS
Definition: raytrace.h:1731
Definition: color.c:49
struct bu_attribute_value_set ts_attrs
attribute/value structure
Definition: raytrace.h:1052
short reg_is_fastgen
FASTGEN-compatibility mode?
Definition: raytrace.h:552
#define RT_FREE_TREE(_tp, _res)
Definition: raytrace.h:1232
struct resource rt_uniresource
default. Defined in librt/globals.c
Definition: globals.c:41
#define OP_INTERSECT
Binary: L intersect R.
Definition: raytrace.h:1128
#define RT_G_DEBUG
Definition: raytrace.h:1718
int reg_los
approximate line-of-sight thickness equivalence
Definition: raytrace.h:545
#define RT_CK_DB_INTERNAL(_p)
Definition: raytrace.h:207
struct bu_ptbl rti_new_solids
Definition: raytrace.h:1822
struct soltab * rt_find_solid(const struct rt_i *rtip, const char *name)
Definition: tree.c:989
#define BU_ALLOC(_ptr, _type)
Definition: malloc.h:223
void * bu_calloc(size_t nelem, size_t elsize, const char *str)
Definition: malloc.c:321
#define RT_CK_DIR(_dp)
Definition: raytrace.h:876
size_t rti_nsolids_with_pieces
solids using pieces
Definition: raytrace.h:1819
int reg_regionid
Region ID code. If <=0, use reg_aircode.
Definition: raytrace.h:542
struct db_i * ts_dbip
Definition: raytrace.h:1040
#define RT_CHECK_RTI(_p)
Definition: raytrace.h:1832
#define LOOKUP_QUIET
Definition: raytrace.h:893
void bn_mat_inv(mat_t output, const mat_t input)
#define TREE_NULL
Definition: raytrace.h:1181
void db_free_full_path(struct db_full_path *pp)
Definition: db_fullpath.c:473
mat_t ts_mat
transform matrix
Definition: raytrace.h:1050
void db_free_tree(union tree *tp, struct resource *resp)
Definition: db_tree.c:1296
static void top()
point_t st_max
max X, Y, Z of bounding RPP
Definition: raytrace.h:438
int(* ft_prep)(struct soltab *stp, struct rt_db_internal *ip, struct rt_i *rtip)
Definition: raytrace.h:2047
#define BU_AVS_FOR(_pp, _avp)
Definition: avs.h:141
int reg_gmater
GIFT Material code.
Definition: raytrace.h:544
char * ma_shader
shader name & parms
Definition: raytrace.h:527
struct tree::tree_node tr_b
#define RT_SOLTAB_MAGIC
Definition: magic.h:169
uint32_t magic
Definition: db_fullpath.h:43
#define UNUSED(parameter)
Definition: common.h:239
#define OP_GUARD
Unary: not L, or else!
Definition: raytrace.h:1135
void bu_avs_init(struct bu_attribute_value_set *avp, size_t len, const char *str)
Definition: avs.c:47
struct directory ** fp_names
array of dir pointers
Definition: db_fullpath.h:46
char * db_path_to_string(const struct db_full_path *pp)
Definition: db_fullpath.c:191
char * bu_vls_addr(const struct bu_vls *vp)
Definition: vls.c:111
int rt_gettrees_muves(struct rt_i *rtip, const char **attrs, int argc, const char **argv, int ncpus)
Definition: tree.c:703
struct resource * ts_resp
Per-CPU data.
Definition: raytrace.h:1074
struct bu_list d_use_hd
heads list of uses (struct soltab l2)
Definition: raytrace.h:872
uint32_t magic
Magic # for mem id/check.
Definition: list.h:119
struct bu_ptbl st_regions
ptrs to regions using this solid (const)
Definition: raytrace.h:440
long st_piecestate_num
re_pieces[] subscript
Definition: raytrace.h:445
#define BU_LIST_MAIN_PTR(_type, _ptr2, _name2)
Definition: list.h:470
void bu_semaphore_release(unsigned int i)
Definition: semaphore.c:218
void bu_ptbl_free(struct bu_ptbl *b)
Definition: ptbl.c:226
struct bn_tol rti_tol
Math tolerances for this model.
Definition: raytrace.h:1765
int rt_gettree(struct rt_i *rtip, const char *node)
Definition: tree.c:869
#define RT_CK_DBI(_p)
Definition: raytrace.h:829
#define RT_CK_FULL_PATH(_p)
Definition: db_fullpath.h:59
struct mater_info reg_mater
Real material information.
Definition: raytrace.h:546
union tree * tb_right
Definition: raytrace.h:1150
#define RT_VISIT_ALL_SOLTABS_END
Definition: raytrace.h:1850
point_t st_min
min X, Y, Z of bounding RPP
Definition: raytrace.h:437
long reg_instnum
instance number, from d_uses
Definition: raytrace.h:550
int reg_aircode
Region ID AIR code.
Definition: raytrace.h:543
const struct rt_functab OBJ[]
Definition: table.c:159
#define RT_CK_RESOURCE(_p)
Definition: raytrace.h:1490
#define RT_VISIT_ALL_SOLTABS_START(_s, _rti)
Definition: raytrace.h:1845
#define RT_CK_DBTS(_p)
Definition: raytrace.h:1084
struct db_i * rti_dbip
prt to Database instance struct
Definition: raytrace.h:1774
size_t nsolids
total # of solids participating
Definition: raytrace.h:1783
point_t mdl_max
max corner of model bounding RPP
Definition: raytrace.h:1770
#define RT_GET_TREE(_tp, _res)
Definition: raytrace.h:1210
struct bu_list l2
links, headed by st_dp->d_use_hd
Definition: raytrace.h:427
HIDDEN int _rt_gettree_region_start(struct db_tree_state *tsp, const struct db_full_path *pathp, const struct rt_comb_internal *combp, void *client_data)
Definition: tree.c:108
#define RT_CK_SOLTAB(_p)
Definition: raytrace.h:453
#define DB_FULL_PATH_MAGIC
Definition: magic.h:203
struct bu_list rti_solidheads[RT_DBNHASH]
active solid lists
Definition: raytrace.h:1810
#define RT_DIR_NULL
Definition: raytrace.h:875
int ts_is_fastgen
REGION_NON_FASTGEN/_PLATE/_VOLUME.
Definition: raytrace.h:1051
long re_boolslen
elements in re_boolstack[]
Definition: raytrace.h:1456
int(* ft_describe)(struct bu_vls *, const struct rt_db_internal *, int, double, struct resource *, struct db_i *)
Definition: raytrace.h:2162
union tree * reg_treetop
Pointer to boolean tree.
Definition: raytrace.h:540
struct rt_i * ts_rtip
Helper for rt_gettrees()
Definition: raytrace.h:1073
int rti_dont_instance
1=Don't compress instances of solids into 1 while prepping
Definition: raytrace.h:1758
void(* ft_free)(struct soltab *)
Definition: raytrace.h:2093
const char * name
Definition: avs.h:61
#define ACQUIRE_SEMAPHORE_TREE(_hash)
Definition: tree.c:38
int rt_gettrees(struct rt_i *rtip, int argc, const char **argv, int ncpus)
Definition: tree.c:888
struct rt_i * st_rtip
"up" pointer to rt_i
Definition: raytrace.h:429
void bu_free(void *ptr, const char *str)
Definition: malloc.c:328
long st_uses
Usage count, for instanced solids.
Definition: raytrace.h:430
#define SOLTAB_NULL
backwards compat
Definition: raytrace.h:450
#define RT_CK_TREE(_p)
Definition: raytrace.h:1182
int ts_regionid
GIFT compat region ID code.
Definition: raytrace.h:1043
void * reg_udata
User appl. data for material.
Definition: raytrace.h:548
#define OP_SOLID
Leaf: tr_stp -> solid.
Definition: raytrace.h:1126
const struct rt_functab * st_meth
pointer to per-solid methods
Definition: raytrace.h:428
void rt_optim_tree(union tree *tp, struct resource *resp)
Definition: tree.c:1008
#define BU_VLS_INIT_ZERO
Definition: vls.h:84
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)
int st_id
Solid ident.
Definition: raytrace.h:431
#define BU_LIST_DEQUEUE(cur)
Definition: list.h:209
HIDDEN void _rt_tree_region_assign(union tree *tp, const struct region *regionp)
Definition: tree.c:70
#define DEBUG_TREEWALK
22 Database tree traversal
Definition: raytrace.h:107
int db5_get_attributes(const struct db_i *dbip, struct bu_attribute_value_set *avs, const struct directory *dp)
Definition: db5_io.c:1027
int d_flags
flags
Definition: raytrace.h:869
Definition: vls.h:56
void bu_bomb(const char *str) _BU_ATTR_NORETURN
Definition: bomb.c:91
HIDDEN struct soltab * _rt_find_identical_solid(const matp_t mat, struct directory *dp, struct rt_i *rtip)
Definition: tree.c:306
double fastf_t
Definition: defines.h:300
#define OP_UNION
Binary: L union R.
Definition: raytrace.h:1127
void * reg_mfuncs
User appl. funcs for material.
Definition: raytrace.h:547
#define RT_SEM_RESULTS
Definition: raytrace.h:1732
int db_dirhash(const char *str)
Definition: db_lookup.c:86
void bu_avs_free(struct bu_attribute_value_set *avp)
Definition: avs.c:235
#define DEBUG_SOLIDS
6 Print prep'ed solids
Definition: raytrace.h:89
#define OP_NOT
Unary: not L.
Definition: raytrace.h:1134
void * Orca_hash_tbl
Hash table in matrices for ORCA.
Definition: raytrace.h:1779
struct bu_list l
magic # and doubly linked list
Definition: raytrace.h:538
struct tree::tree_leaf tr_a
HIDDEN union tree * _rt_gettree_region_end(struct db_tree_state *tsp, const struct db_full_path *pathp, union tree *curtree, void *client_data)
Definition: tree.c:138
int needprep
needs rt_prep
Definition: raytrace.h:1776
#define RELEASE_SEMAPHORE_TREE(_hash)
Definition: tree.c:53
#define bu_strdup(s)
Definition: str.h:71
long st_npieces
pieces used by this solid
Definition: raytrace.h:444