BRL-CAD
comb.c
Go to the documentation of this file.
1 /* C O M B . C
2  * BRL-CAD
3  *
4  * Copyright (c) 2004-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 db5 */
21 /** @{ */
22 /** @file comb.c
23  *
24  * Implement support for combinations in v5 format.
25  *
26  * The on-disk record looks like this:
27  * width byte
28  * n matrices (only non-identity matrices stored).
29  * n leaves
30  * len of RPN expression. (len=0 signals all-union expression)
31  * depth of stack
32  * Section 1: matrices
33  * Section 2: leaves
34  * Section 3: (Optional) RPN expression.
35  *
36  * Encoding of a matrix is (ELEMENTS_PER_MAT * SIZEOF_NETWORK_DOUBLE)
37  * bytes, in network order (big-Endian, IEEE double precision).
38  *
39  */
40 /** @} */
41 
42 #include "common.h"
43 
44 #include <stdlib.h>
45 #include <string.h>
46 #include <ctype.h>
47 #include "bio.h"
48 
49 
50 #include "bu/parse.h"
51 #include "bu/cv.h"
52 #include "vmath.h"
53 #include "bn.h"
54 #include "db5.h"
55 #include "raytrace.h"
56 
57 
59  uint32_t magic;
60  size_t n_mat; /* # leaves with non-identity matrices */
61  size_t n_leaf; /* # leaf nodes */
62  size_t n_oper; /* # operator nodes */
63  size_t leafbytes; /* # bytes for name section */
64  int non_union_seen; /* boolean, 1 = non-unions seen */
65 };
66 #define DB_TREE_COUNTER_STATE_MAGIC 0x64546373 /* dTcs */
67 #define DB_CK_TREE_COUNTER_STATE(_p) BU_CKMAG(_p, DB_TREE_COUNTER_STATE_MAGIC, "db_tree_counter_state");
68 
69 
70 /**
71  * Count number of non-identity matrices, number of leaf nodes,
72  * number of operator nodes, etc.
73  *
74  * Returns - maximum depth of stack needed to unpack this tree, if
75  * serialized.
76  *
77  * Notes - We over-estimate the size of the width fields used for
78  * holding the matrix subscripts. The caller is responsible for
79  * correcting by saying:
80  *
81  * tcsp->leafbytes -= tcsp->n_leaf * (8 - DB5_ENC_LEN(wid));
82  */
83 size_t
84 db_tree_counter(const union tree *tp, struct db_tree_counter_state *tcsp)
85 {
86  size_t ldepth, rdepth;
87 
88  RT_CK_TREE(tp);
90 
91  switch (tp->tr_op) {
92  case OP_DB_LEAF:
93  tcsp->n_leaf++;
94  if (tp->tr_l.tl_mat && !bn_mat_is_identity(tp->tr_l.tl_mat)) tcsp->n_mat++;
95  /* Over-estimate storage requirement for matrix # */
96  tcsp->leafbytes += strlen(tp->tr_l.tl_name) + 1 + 8;
97  return 1;
98 
99  case OP_NOT:
100  /* Unary ops */
101  tcsp->n_oper++;
102  tcsp->non_union_seen = 1;
103  return 1 + db_tree_counter(tp->tr_b.tb_left, tcsp);
104 
105  case OP_UNION:
106  /* This node is known to be a binary op */
107  tcsp->n_oper++;
108  ldepth = db_tree_counter(tp->tr_b.tb_left, tcsp);
109  rdepth = db_tree_counter(tp->tr_b.tb_right, tcsp);
110  if (ldepth > rdepth) return ldepth;
111  return rdepth;
112 
113  case OP_INTERSECT:
114  case OP_SUBTRACT:
115  case OP_XOR:
116  /* This node is known to be a binary op */
117  tcsp->n_oper++;
118  tcsp->non_union_seen = 1;
119  ldepth = db_tree_counter(tp->tr_b.tb_left, tcsp);
120  rdepth = db_tree_counter(tp->tr_b.tb_right, tcsp);
121  if (ldepth > rdepth) return ldepth;
122  return rdepth;
123 
124  default:
125  bu_log("db_tree_counter: bad op %d\n", tp->tr_op);
126  bu_bomb("db_tree_counter\n");
127  /* NOTREACHED */
128  }
129  /* NOTREACHED */
130  return 0;
131 }
132 
133 
134 #define DB5COMB_TOKEN_LEAF 1
135 #define DB5COMB_TOKEN_UNION 2
136 #define DB5COMB_TOKEN_INTERSECT 3
137 #define DB5COMB_TOKEN_SUBTRACT 4
138 #define DB5COMB_TOKEN_XOR 5
139 #define DB5COMB_TOKEN_NOT 6
140 
142  uint32_t magic;
143  size_t mat_num; /* current matrix number */
144  size_t nmat; /* # matrices, total */
145  unsigned char *matp;
146  unsigned char *leafp;
147  unsigned char *exprp;
148  int wid;
149 };
150 #define RT_COMB_V5_SERIALIZE_STATE_MAGIC 0x43357373 /* C5ss */
151 #define RT_CK_COMB_V5_SERIALIZE_STATE(_p) BU_CKMAG(_p, RT_COMB_V5_SERIALIZE_STATE_MAGIC, "rt_comb_v5_serialize_state")
152 
153 
154 /**
155  * In one single pass through the tree, serialize out all three output
156  * sections at once.
157  */
158 void
160  const union tree *tp,
161  struct rt_comb_v5_serialize_state *ssp)
162 {
163  size_t n;
164  ssize_t mi;
165 
166  RT_CK_TREE(tp);
168 
169  switch (tp->tr_op) {
170  case OP_DB_LEAF:
171  /*
172  * Encoding of the leaf: A null-terminated name string,
173  *and the matrix subscript. -1 == identity.
174  */
175  n = strlen(tp->tr_l.tl_name) + 1;
176  memcpy(ssp->leafp, tp->tr_l.tl_name, n);
177  ssp->leafp += n;
178 
179  if (tp->tr_l.tl_mat && !bn_mat_is_identity(tp->tr_l.tl_mat)) {
180  mi = ssp->mat_num++;
181  } else {
182  mi = (ssize_t)-1;
183  }
184 
185  BU_ASSERT_SSIZE_T(mi, <, (ssize_t)ssp->nmat);
186 
187  /* there should be a better way than casting
188  * 'mi' from ssize_t to size_t
189  */
190  n = (size_t)mi;
191  ssp->leafp = db5_encode_length(ssp->leafp, n, ssp->wid);
192 
193  /* Encoding of the matrix */
194  if (mi != (ssize_t)-1) {
195  /* must be double for import and export */
196  double scanmat[ELEMENTS_PER_MAT];
197 
198  MAT_COPY(scanmat, tp->tr_l.tl_mat); /* convert fastf_t to double */
199  bu_cv_htond(ssp->matp, (const unsigned char *)scanmat, ELEMENTS_PER_MAT);
200  ssp->matp += ELEMENTS_PER_MAT * SIZEOF_NETWORK_DOUBLE;
201  }
202 
203  /* Encoding of the "leaf" operator */
204  if (ssp->exprp)
205  *ssp->exprp++ = DB5COMB_TOKEN_LEAF;
206  return;
207 
208  case OP_NOT:
209  /* Unary ops */
211  if (ssp->exprp)
212  *ssp->exprp++ = DB5COMB_TOKEN_NOT;
213  return;
214 
215  case OP_UNION:
216  /* This node is known to be a binary op */
219  if (ssp->exprp)
220  *ssp->exprp++ = DB5COMB_TOKEN_UNION;
221  return;
222  case OP_INTERSECT:
223  /* This node is known to be a binary op */
226  if (ssp->exprp)
227  *ssp->exprp++ = DB5COMB_TOKEN_INTERSECT;
228  return;
229  case OP_SUBTRACT:
230  /* This node is known to be a binary op */
233  if (ssp->exprp)
234  *ssp->exprp++ = DB5COMB_TOKEN_SUBTRACT;
235  return;
236  case OP_XOR:
237  /* This node is known to be a binary op */
240  if (ssp->exprp)
241  *ssp->exprp++ = DB5COMB_TOKEN_XOR;
242  return;
243 
244  default:
245  bu_log("rt_comb_v5_serialize: bad op %d\n", tp->tr_op);
246  bu_bomb("rt_comb_v5_serialize\n");
247  }
248 }
249 
250 
251 int
253  struct bu_external *ep,
254  const struct rt_db_internal *ip,
255  double UNUSED(local2mm),
256  const struct db_i *dbip,
257  struct resource *resp)
258 {
259  struct rt_comb_internal *comb;
260  struct db_tree_counter_state tcs;
261  struct rt_comb_v5_serialize_state ss;
262  long max_stack_depth;
263  size_t need;
264  size_t rpn_len = 0; /* # items in RPN expression */
265  int wid; /* encode format */
266  unsigned char *cp;
267  unsigned char *leafp_end;
268  struct bu_attribute_value_set *avsp;
269  struct bu_vls value = BU_VLS_INIT_ZERO;
270 
271  /* check inputs */
272  RT_CK_DB_INTERNAL(ip);
273  if (dbip) RT_CK_DBI(dbip);
274  if (resp) RT_CK_RESOURCE(resp);
275 
276  /* validate it's a comb */
277  if (ip->idb_type != ID_COMBINATION) bu_bomb("rt_comb_export5() type not ID_COMBINATION");
278  comb = (struct rt_comb_internal *)ip->idb_ptr;
279  RT_CK_COMB(comb);
280 
281  /* First pass -- count number of non-identity matrices, number of
282  * leaf nodes, number of operator nodes.
283  */
284  memset((char *)&tcs, 0, sizeof(tcs));
286  if (comb->tree)
287  max_stack_depth = db_tree_counter(comb->tree, &tcs);
288  else
289  max_stack_depth = 0; /* some combinations have no tree */
290 
291  if (tcs.non_union_seen) {
292  /* RPN expression needs one byte for each leaf or operator node */
293  rpn_len = tcs.n_leaf + tcs.n_oper;
294  } else {
295  rpn_len = 0;
296  }
297 
299  tcs.n_mat | tcs.n_leaf | tcs.leafbytes |
300  rpn_len | max_stack_depth);
301 
302  /* Apply correction factor to tcs.leafbytes now that we know
303  * 'wid'. Ignore the slight chance that a smaller 'wid' might now
304  * be possible.
305  */
306  tcs.leafbytes -= tcs.n_leaf * (8 - DB5_ENC_LEN(wid));
307 
308  /* Second pass -- determine amount of on-disk storage needed */
309  need = 1 + /* width code */
310  DB5_ENC_LEN(wid) + /* size for nmatrices */
311  DB5_ENC_LEN(wid) + /* size for nleaves */
312  DB5_ENC_LEN(wid) + /* size for leafbytes */
313  DB5_ENC_LEN(wid) + /* size for len of RPN */
314  DB5_ENC_LEN(wid) + /* size for max_stack_depth */
315  tcs.n_mat * (ELEMENTS_PER_MAT * SIZEOF_NETWORK_DOUBLE) + /* sizeof matrix array */
316  tcs.leafbytes + /* size for leaf nodes */
317  rpn_len; /* storage for RPN expression */
318 
319  BU_EXTERNAL_INIT(ep);
320  ep->ext_nbytes = need;
321  ep->ext_buf = (uint8_t *)bu_calloc(1, need, "rt_comb_export5 ext_buf");
322 
323  /* Build combination's on-disk header section */
324  cp = (unsigned char *)ep->ext_buf;
325  *cp++ = wid;
326  cp = db5_encode_length(cp, tcs.n_mat, wid);
327  cp = db5_encode_length(cp, tcs.n_leaf, wid);
328  cp = db5_encode_length(cp, tcs.leafbytes, wid);
329  cp = db5_encode_length(cp, rpn_len, wid);
330  cp = db5_encode_length(cp, max_stack_depth, wid);
331 
332  /*
333  * The output format has three sections:
334  * Section 1: matrices
335  * Section 2: leaf nodes
336  * Section 3: Optional RPN expression
337  *
338  * We have pre-computed the exact size of all three sections, so
339  * they can all be serialized together in one pass. Establish
340  * pointers to the start of each section.
341  */
343  ss.wid = wid;
344  ss.mat_num = 0;
345  ss.nmat = tcs.n_mat;
346  ss.matp = cp;
347  ss.leafp = cp + tcs.n_mat * (ELEMENTS_PER_MAT * SIZEOF_NETWORK_DOUBLE);
348  leafp_end = ss.leafp + tcs.leafbytes;
349  if (rpn_len)
350  ss.exprp = leafp_end;
351  else
352  ss.exprp = NULL;
353 
354  if (comb->tree)
355  rt_comb_v5_serialize(comb->tree, &ss);
356 
357  BU_ASSERT_SIZE_T(ss.mat_num, ==, tcs.n_mat);
358  BU_ASSERT_PTR(ss.matp, ==, cp + tcs.n_mat * (ELEMENTS_PER_MAT * SIZEOF_NETWORK_DOUBLE));
359  BU_ASSERT_PTR(ss.leafp, ==, leafp_end);
360  if (rpn_len)
361  BU_ASSERT_PTR(ss.exprp, <=, ((unsigned char *)ep->ext_buf) + ep->ext_nbytes);
362 
363  /* Encode all the other stuff as attributes. */
364  /* WARNING: We remove const from the ip pointer!!! */
365  avsp = (struct bu_attribute_value_set *)&ip->idb_avs;
366  if (avsp->magic != BU_AVS_MAGIC)
367  bu_avs_init(avsp, 32, "rt_comb v5 attributes");
368  if (comb->region_flag) {
369  /* Presence of this attribute means this comb is a region.
370  * Current code values are 0, 1, and 2; all are regions. See
371  * raytrace.h for meanings of different values
372  */
373  bu_vls_trunc(&value, 0);
374  switch (comb->is_fastgen) {
376  bu_vls_printf(&value, "P");
377  break;
379  bu_vls_printf(&value, "V");
380  break;
381  case REGION_NON_FASTGEN: /* fallthrough */
382  default:
383  bu_vls_printf(&value, "R");
384  break;
385  }
386  bu_avs_add_vls(avsp, "region", &value);
387  } else
388  bu_avs_remove(avsp, "region");
389 
390  if (comb->inherit)
391  bu_avs_add(avsp, "inherit", "1");
392  else
393  bu_avs_remove(avsp, "inherit");
394 
395  if (comb->rgb_valid) {
396  bu_vls_trunc(&value, 0);
397  bu_vls_printf(&value, "%d/%d/%d", V3ARGS(comb->rgb));
398  bu_avs_add_vls(avsp, "rgb", &value);
399  } else
400  bu_avs_remove(avsp, "rgb");
401 
402  /* optical shader string goes in an attribute */
403  if (bu_vls_strlen(&comb->shader) > 0) {
404  /* NOTE: still writing out an 'oshader' attribute in addition
405  * to a 'shader' attribute so that older versions of BRL-CAD
406  * will find the shader information correctly.
407  */
408  bu_avs_add_vls(avsp, "oshader", &comb->shader);
409  bu_avs_add_vls(avsp, "shader", &comb->shader);
410  } else {
411  /* see NOTE above */
412  bu_avs_remove(avsp, "oshader");
413  bu_avs_remove(avsp, "shader");
414  }
415 
416  /* GIFT compatibility */
417  if (comb->region_id != 0) {
418  bu_vls_trunc(&value, 0);
419  bu_vls_printf(&value, "%ld", comb->region_id);
420  bu_avs_add_vls(avsp, "region_id", &value);
421  } else
422  bu_avs_remove(avsp, "region_id");
423 
424  if (comb->aircode != 0) {
425  bu_vls_trunc(&value, 0);
426  bu_vls_printf(&value, "%ld", comb->aircode);
427  bu_avs_add_vls(avsp, "aircode", &value);
428  } else
429  bu_avs_remove(avsp, "aircode");
430 
431  if (comb->GIFTmater != 0) {
432  bu_vls_trunc(&value, 0);
433  bu_vls_printf(&value, "%ld", comb->GIFTmater);
434  bu_avs_add_vls(avsp, "material_id", &value);
435  } else
436  bu_avs_remove(avsp, "material_id");
437 
438  if (comb->los != 0) {
439  bu_vls_trunc(&value, 0);
440  bu_vls_printf(&value, "%ld", comb->los);
441  bu_avs_add_vls(avsp, "los", &value);
442  } else
443  bu_avs_remove(avsp, "los");
444 
445  bu_vls_free(&value);
446  return 0; /* OK */
447 }
448 
449 
450 int
451 rt_comb_import5(struct rt_db_internal *ip, const struct bu_external *ep,
452  const mat_t mat, const struct db_i *dbip, struct resource *resp)
453 {
454  struct rt_comb_internal *comb;
455  unsigned char *cp;
456  int wid;
457  size_t nmat, nleaf, rpn_len, max_stack_depth;
458  size_t leafbytes;
459  unsigned char *matp;
460  unsigned char *leafp;
461  unsigned char *leafp_end;
462  unsigned char *exprp;
463 #define MAX_V5_STACK 8000
464  union tree *stack[MAX_V5_STACK];
465  union tree **sp; /* stack pointer */
466  const char *ap;
467  size_t ius;
468 
469  RT_CK_DB_INTERNAL(ip);
470  BU_CK_EXTERNAL(ep);
471  RT_CK_DBI(dbip);
472  RT_CK_RESOURCE(resp);
473 
474  ip->idb_major_type = DB5_MAJORTYPE_BRLCAD;
475  ip->idb_type = ID_COMBINATION;
476  ip->idb_meth = &OBJ[ID_COMBINATION];
477 
478  BU_ALLOC(comb, struct rt_comb_internal);
479  RT_COMB_INTERNAL_INIT(comb);
480 
481  ip->idb_ptr = (void *)comb;
482 
483  cp = ep->ext_buf;
484  wid = *cp++;
485  cp += db5_decode_length(&nmat, cp, wid);
486  cp += db5_decode_length(&nleaf, cp, wid);
487  cp += db5_decode_length(&leafbytes, cp, wid);
488  cp += db5_decode_length(&rpn_len, cp, wid);
489  cp += db5_decode_length(&max_stack_depth, cp, wid);
490  matp = cp;
491  leafp = cp + nmat * (ELEMENTS_PER_MAT * SIZEOF_NETWORK_DOUBLE);
492  exprp = leafp + leafbytes;
493  leafp_end = exprp;
494 
495  if (rpn_len == 0) {
496  ssize_t is;
497 
498  /* This tree is all union operators, import it as a balanced tree */
499  struct bu_ptbl *tbl1, *tbl2;
500 
501  BU_ALLOC(tbl1, struct bu_ptbl);
502  BU_ALLOC(tbl2, struct bu_ptbl);
503 
504  /* insert all the leaf nodes into a bu_ptbl */
505  bu_ptbl_init(tbl1, nleaf, "rt_comb_import5: tbl");
506  for (is = nleaf-1; is >= 0; is--) {
507  union tree *tp;
508  size_t mi;
509 
510  RT_GET_TREE(tp, resp);
511  tp->tr_l.tl_op = OP_DB_LEAF;
512  tp->tr_l.tl_name = bu_strdup((const char *)leafp);
513  leafp += strlen((const char *)leafp) + 1;
514 
515  /* Get matrix index */
516  mi = 4095; /* sanity */
517  leafp += db5_decode_signed(&mi, leafp, wid);
518 
519  if (mi == (size_t)-1) {
520  /* Signal identity matrix */
521  if (!mat || bn_mat_is_identity(mat)) {
522  tp->tr_l.tl_mat = (matp_t)NULL;
523  } else
524  tp->tr_l.tl_mat = bn_mat_dup(mat);
525  } else {
526  mat_t diskmat;
527 
528  /* must be double for import and export */
529  double scanmat[16];
530 
531  /* Unpack indicated matrix mi */
532  BU_ASSERT_SIZE_T(mi, <, nmat);
533 
534  /* read matrix */
535  bu_cv_ntohd((unsigned char *)scanmat, &matp[mi*ELEMENTS_PER_MAT*SIZEOF_NETWORK_DOUBLE], ELEMENTS_PER_MAT);
536  MAT_COPY(diskmat, scanmat); /* convert double to fastf_t */
537 
538  if (!mat || bn_mat_is_identity(mat)) {
539  tp->tr_l.tl_mat = bn_mat_dup(diskmat);
540  } else {
541  tp->tr_l.tl_mat = (matp_t)bu_malloc(
542  sizeof(mat_t), "v5comb mat");
543  bn_mat_mul(tp->tr_l.tl_mat, mat, diskmat);
544  if (bn_mat_is_identity(tp->tr_l.tl_mat)) {
545  bu_free((char *)tp->tr_l.tl_mat, "tl_mat");
546  tp->tr_l.tl_mat = (matp_t)NULL;
547  }
548  }
549  }
550  bu_ptbl_ins(tbl1, (long *)tp);
551  }
552 
553  /* use a second bu_ptbl to help build a balanced tree
554  * 1 - pick off pairs of pointers from tbl1
555  * 2 - make a small tree that unions the pair
556  * 3 - insert that tree into tbl2
557  * 4 - insert any leftover pointer from tbl1 into tbl2
558  * 5 - swap tbl1 and tbl2
559  * 6 - truncate tbl2 and go to step 1
560  * stop when tbl2 has less than 2 members
561  */
562  bu_ptbl_init(tbl2, (BU_PTBL_LEN(tbl1) + 1)/2, "rt_comb_import5: tbl1");
563  while (1) {
564  struct bu_ptbl *tmp;
565 
566  for (ius = 0; ius < BU_PTBL_LEN(tbl1); ius += 2) {
567  union tree *tp1, *tp2, *unionp;
568  size_t j;
569 
570  j = ius + 1;
571  tp1 = (union tree *)BU_PTBL_GET(tbl1, ius);
572  if (j < BU_PTBL_LEN(tbl1)) {
573  tp2 = (union tree *)BU_PTBL_GET(tbl1, j);
574  } else {
575  tp2 = (union tree *)NULL;
576  }
577 
578  if (tp2) {
579  RT_GET_TREE(unionp, resp);
580  unionp->tr_b.tb_op = OP_UNION;
581  unionp->tr_b.tb_left = tp1;
582  unionp->tr_b.tb_right = tp2;
583  bu_ptbl_ins(tbl2, (long *)unionp);
584  } else {
585  bu_ptbl_ins(tbl2, (long *)tp1);
586  }
587 
588  }
589 
590  if (BU_PTBL_LEN(tbl2) == 0) {
591  comb->tree = (union tree *)NULL;
592  bu_ptbl_free(tbl1);
593  bu_ptbl_free(tbl2);
594  bu_free((char *)tbl1, "rt_comb_import5: tbl1");
595  bu_free((char *)tbl2, "rt_comb_import5: tbl2");
596  break;
597  } else if (BU_PTBL_LEN(tbl2) == 1) {
598  comb->tree = (union tree *)BU_PTBL_GET(tbl2, 0);
599  bu_ptbl_free(tbl1);
600  bu_ptbl_free(tbl2);
601  bu_free((char *)tbl1, "rt_comb_import5: tbl1");
602  bu_free((char *)tbl2, "rt_comb_import5: tbl2");
603  break;
604  }
605 
606  tmp = tbl2;
607  tbl2 = tbl1;
608  tbl1 = tmp;
609  bu_ptbl_trunc(tbl2, 0);
610  }
611  BU_ASSERT_PTR(leafp, ==, leafp_end);
612  goto finish;
613  }
614 
615  /*
616  * Bring the RPN expression back from the disk, populating leaves
617  * and matrices in the order they are encountered.
618  */
619  if (max_stack_depth > MAX_V5_STACK) {
620  bu_log("Combination needs stack depth %zu, only have %d, aborted\n",
621  max_stack_depth, MAX_V5_STACK);
622  return -1;
623  }
624  sp = &stack[0];
625 
626  for (ius = 0; ius < rpn_len; ius++, exprp++) {
627  union tree *tp;
628  size_t mi;
629 
630  RT_GET_TREE(tp, resp);
631 
632  switch (*exprp) {
633  case DB5COMB_TOKEN_LEAF:
634  tp->tr_l.tl_op = OP_DB_LEAF;
635  tp->tr_l.tl_name = bu_strdup((const char *)leafp);
636  leafp += strlen((const char *)leafp) + 1;
637 
638  /* Get matrix index */
639  mi = 4095; /* sanity */
640  leafp += db5_decode_signed(&mi, leafp, wid);
641 
642  if ((ssize_t)mi < 0) {
643  /* Signal identity matrix */
644  if (!mat || bn_mat_is_identity(mat)) {
645  tp->tr_l.tl_mat = (matp_t)NULL;
646  } else
647  tp->tr_l.tl_mat = bn_mat_dup(mat);
648  } else {
649  mat_t diskmat;
650 
651  /* must be double for import and export */
652  double scanmat[16];
653 
654  /* Unpack indicated matrix mi */
655  BU_ASSERT_SIZE_T(mi, <, nmat);
656 
657  /* read matrix */
658  bu_cv_ntohd((unsigned char *)scanmat, &matp[mi*ELEMENTS_PER_MAT*SIZEOF_NETWORK_DOUBLE], ELEMENTS_PER_MAT);
659  MAT_COPY(diskmat, scanmat); /* convert double to fastf_t */
660 
661  if (!mat || bn_mat_is_identity(mat)) {
662  tp->tr_l.tl_mat = bn_mat_dup(diskmat);
663  } else {
664  tp->tr_l.tl_mat = (matp_t)bu_malloc(
665  sizeof(mat_t), "v5comb mat");
666  bn_mat_mul(tp->tr_l.tl_mat, mat, diskmat);
667  if (bn_mat_is_identity(tp->tr_l.tl_mat)) {
668  bu_free((char *)tp->tr_l.tl_mat, "tl_mat");
669  tp->tr_l.tl_mat = (matp_t)NULL;
670  }
671  }
672  }
673  break;
674 
675  case DB5COMB_TOKEN_UNION:
678  case DB5COMB_TOKEN_XOR:
679  /* These are all binary operators */
681  tp->tr_b.tb_right = *--sp;
682  RT_CK_TREE(tp->tr_b.tb_right);
683  tp->tr_b.tb_left = *--sp;
684  RT_CK_TREE(tp->tr_b.tb_left);
685  switch (*exprp) {
686  case DB5COMB_TOKEN_UNION:
687  tp->tr_b.tb_op = OP_UNION;
688  break;
690  tp->tr_b.tb_op = OP_INTERSECT;
691  break;
693  tp->tr_b.tb_op = OP_SUBTRACT;
694  break;
695  case DB5COMB_TOKEN_XOR:
696  tp->tr_b.tb_op = OP_XOR;
697  break;
698  }
699  break;
700 
701  case DB5COMB_TOKEN_NOT:
702  /* This is a unary operator */
704  tp->tr_b.tb_left = *--sp;
705  RT_CK_TREE(tp->tr_b.tb_left);
706  tp->tr_b.tb_right = TREE_NULL;
707  tp->tr_b.tb_op = OP_NOT;
708  break;
709  default:
710  bu_log("rt_comb_import5() unknown RPN expression token=%d, import aborted\n", *exprp);
711  return -1;
712  }
713 
714  /* Push this node on the stack */
715  *sp++ = tp;
716  }
717  BU_ASSERT_PTR(leafp, ==, leafp_end);
718 
719  /* There should only be one thing left on the stack, the result */
720  BU_ASSERT_PTR(sp, ==, &stack[1]);
721 
722  comb->tree = stack[0];
723  RT_CK_TREE(comb->tree);
724 
725 finish:
726  if (ip->idb_avs.magic != BU_AVS_MAGIC) return 0; /* OK */
727 
728  /* Unpack the attributes */
729  comb->rgb_valid = 0;
730 
731  if ((ap = bu_avs_get(&ip->idb_avs, db5_standard_attribute(ATTR_COLOR))) != NULL) {
732  int ibuf[3];
733  if (sscanf(ap, "%d/%d/%d", ibuf, ibuf+1, ibuf+2) == 3) {
734  VMOVE(comb->rgb, ibuf);
735  comb->rgb_valid = 1;
736  } else {
737  bu_log("unable to parse 'rgb' attribute '%s'\n", ap);
738  }
739  }
740  if ((ap = bu_avs_get(&ip->idb_avs, db5_standard_attribute(ATTR_INHERIT))) != NULL) {
741  comb->inherit = atoi(ap);
742  }
743  if ((ap = bu_avs_get(&ip->idb_avs, db5_standard_attribute(ATTR_REGION))) != NULL) {
744  /* Presence of this attribute implies it is a region */
745  comb->region_flag = 1;
746 
747  /* Determine if this is a FASTGEN region */
748  switch (*ap) {
749  case 'V' : /* fallthrough */
750  case '2' :
752  break;
753  case 'P' : /* fallthrough */
754  case '1' :
756  break;
757  case 'R' : /* fallthrough */
758  case '0' :
760  break;
761  default:
762  bu_log("unable to parse 'region' attribute '%s'\n", ap);
763  break;
764  }
765 
766  /* get the other GIFT "region" attributes */
767  if ((ap = bu_avs_get(&ip->idb_avs, db5_standard_attribute(ATTR_REGION_ID))) != NULL) {
768  comb->region_id = atol(ap);
769  }
770  if ((ap = bu_avs_get(&ip->idb_avs, db5_standard_attribute(ATTR_AIR))) != NULL) {
771  comb->aircode = atol(ap);
772  }
773  if ((ap = bu_avs_get(&ip->idb_avs, db5_standard_attribute(ATTR_MATERIAL_ID))) != NULL) {
774  comb->GIFTmater = atol(ap);
775  }
776  if ((ap = bu_avs_get(&ip->idb_avs, db5_standard_attribute(ATTR_LOS))) != NULL) {
777  comb->los = atol(ap);
778  }
779  }
780  if ((ap = bu_avs_get(&ip->idb_avs, db5_standard_attribute(ATTR_SHADER))) != NULL) {
781  bu_vls_strcat(&comb->shader, ap);
782  }
783 
784  return 0; /* OK */
785 }
786 
787 
788 /**
789  * Sets the result string to a description of the given combination.
790  * Entered via OBJ[].ft_get().
791  */
792 int
793 rt_comb_get(struct bu_vls *logstr, const struct rt_db_internal *intern, const char *item)
794 {
795  const struct rt_comb_internal *comb;
796  char buf[128];
797 
798  RT_CK_DB_INTERNAL(intern);
799  comb = (struct rt_comb_internal *)intern->idb_ptr;
800  RT_CK_COMB(comb);
801 
802  if (item == 0) {
803  /* Print out the whole combination. */
804 
805  bu_vls_printf(logstr, "comb region ");
806  if (comb->region_flag) {
807  bu_vls_printf(logstr, "yes id %ld ", comb->region_id);
808 
809  if (comb->aircode) {
810  bu_vls_printf(logstr, "air %ld ", comb->aircode);
811  }
812  if (comb->los) {
813  bu_vls_printf(logstr, "los %ld ", comb->los);
814  }
815 
816  if (comb->GIFTmater) {
817  bu_vls_printf(logstr, "GIFTmater %ld ", comb->GIFTmater);
818  }
819  } else {
820  bu_vls_printf(logstr, "no ");
821  }
822 
823  if (comb->rgb_valid) {
824  bu_vls_printf(logstr, "rgb {%d %d %d} ", V3ARGS(comb->rgb));
825  }
826 
827  if (bu_vls_strlen(&comb->shader) > 0) {
828  bu_vls_printf(logstr, "shader {%s} ", bu_vls_addr(&comb->shader));
829  }
830 
831  if (bu_vls_strlen(&comb->material) > 0) {
832  bu_vls_printf(logstr, "material %s ", bu_vls_addr(&comb->material));
833  }
834 
835  if (comb->inherit) {
836  bu_vls_printf(logstr, "inherit yes ");
837  }
838 
839  bu_vls_printf(logstr, "tree {");
840  db_tree_list(logstr, comb->tree);
841  bu_vls_putc(logstr, '}');
842 
843  return BRLCAD_OK;
844  } else {
845  /* Print out only the requested item. */
846  register int i;
847  char itemlwr[128];
848 
849  for (i = 0; i < 127 && item[i]; i++) {
850  itemlwr[i] = (isupper((int)item[i]) ? tolower((int)item[i]) :
851  item[i]);
852  }
853  itemlwr[i] = '\0';
854 
855  if (BU_STR_EQUAL(itemlwr, "region")) {
856  snprintf(buf, 128, "%s", comb->region_flag ? "yes" : "no");
857  } else if (BU_STR_EQUAL(itemlwr, "id")) {
858  if (!comb->region_flag) goto not_region;
859  snprintf(buf, 128, "%ld", comb->region_id);
860  } else if (BU_STR_EQUAL(itemlwr, "air")) {
861  if (!comb->region_flag) goto not_region;
862  snprintf(buf, 128, "%ld", comb->aircode);
863  } else if (BU_STR_EQUAL(itemlwr, "los")) {
864  if (!comb->region_flag) goto not_region;
865  snprintf(buf, 128, "%ld", comb->los);
866  } else if (BU_STR_EQUAL(itemlwr, "giftmater")) {
867  if (!comb->region_flag) goto not_region;
868  snprintf(buf, 128, "%ld", comb->GIFTmater);
869  } else if (BU_STR_EQUAL(itemlwr, "rgb")) {
870  if (comb->rgb_valid)
871  snprintf(buf, 128, "%d %d %d", V3ARGS(comb->rgb));
872  else
873  snprintf(buf, 128, "invalid");
874  } else if (BU_STR_EQUAL(itemlwr, "shader")) {
875  bu_vls_printf(logstr, "%s", bu_vls_addr(&comb->shader));
876  return BRLCAD_OK;
877  } else if (BU_STR_EQUAL(itemlwr, "material")) {
878  bu_vls_printf(logstr, "%s", bu_vls_addr(&comb->material));
879  return BRLCAD_OK;
880  } else if (BU_STR_EQUAL(itemlwr, "inherit")) {
881  snprintf(buf, 128, "%s", comb->inherit ? "yes" : "no");
882  } else if (BU_STR_EQUAL(itemlwr, "tree")) {
883  db_tree_list(logstr, comb->tree);
884  return BRLCAD_OK;
885  } else {
886  bu_vls_printf(logstr, "no such attribute");
887  return BRLCAD_ERROR;
888  }
889 
890  bu_vls_printf(logstr, "%s", buf);
891  return BRLCAD_OK;
892 
893  not_region:
894  bu_vls_printf(logstr, "item not valid for non-region");
895  return BRLCAD_ERROR;
896  }
897 }
898 
899 
900 /**
901  * Example -
902  * rgb "1 2 3" ...
903  *
904  * Invoked via OBJ[ID_COMBINATION].ft_adjust()
905  */
906 int
907 rt_comb_adjust(struct bu_vls *logstr, struct rt_db_internal *intern, int argc, char **argv)
908 {
909  struct rt_comb_internal *comb;
910  char buf[1024] = {'\0'};
911  int i;
912  double d;
913 
914  RT_CK_DB_INTERNAL(intern);
915  comb = (struct rt_comb_internal *)intern->idb_ptr;
916  RT_CK_COMB(comb);
917 
918  while (argc >= 2) {
919  /* Force to lower case */
920  for (i = 0; i < 1023 && argv[0][i] != '\0'; i++) {
921  buf[i] = tolower((int)argv[0][i]);
922  }
923  buf[i] = '\0';
924 
925  if (BU_STR_EQUAL(buf, "region")) {
926  if (BU_STR_EQUAL(argv[1], "none")) {
927  comb->region_flag = 0;
928  } else if (BU_STR_EQUAL(argv[1], "no")) {
929  comb->region_flag = 0;
930  } else if (BU_STR_EQUAL(argv[1], "yes")) {
931  comb->region_flag = 1;
932  } else {
933  if (sscanf(argv[1], "%d", &i) != 1)
934  return BRLCAD_ERROR;
935 
936  if (i != 0)
937  i = 1;
938 
939  comb->region_flag = (char)i;
940  }
941  } else if (BU_STR_EQUAL(buf, "temp")) {
942  if (!comb->region_flag) goto not_region;
943  if (BU_STR_EQUAL(argv[1], "none")) {
944  comb->temperature = 0.0;
945  } else {
946  if (sscanf(argv[1], "%lf", &d) != 1)
947  return BRLCAD_ERROR;
948  comb->temperature = (float)d;
949  }
950  } else if (BU_STR_EQUAL(buf, "id")) {
951  if (!comb->region_flag) goto not_region;
952  if (BU_STR_EQUAL(argv[1], "none")) {
953  comb->region_id = 0;
954  } else {
955  if (sscanf(argv[1], "%d", &i) != 1)
956  return BRLCAD_ERROR;
957  comb->region_id = i;
958  }
959  } else if (BU_STR_EQUAL(buf, "air")) {
960  if (!comb->region_flag) goto not_region;
961  if (BU_STR_EQUAL(argv[1], "none")) {
962  comb->aircode = 0;
963  } else {
964  if (sscanf(argv[1], "%d", &i) != 1)
965  return BRLCAD_ERROR;
966  comb->aircode = i;
967  }
968  } else if (BU_STR_EQUAL(buf, "los")) {
969  if (!comb->region_flag) goto not_region;
970  if (BU_STR_EQUAL(argv[1], "none")) {
971  comb->los = 0;
972  } else {
973  if (sscanf(argv[1], "%d", &i) != 1)
974  return BRLCAD_ERROR;
975  comb->los = i;
976  }
977  } else if (BU_STR_EQUAL(buf, "giftmater")) {
978  if (!comb->region_flag) goto not_region;
979  if (BU_STR_EQUAL(argv[1], "none")) {
980  comb->GIFTmater = 0;
981  } else {
982  if (sscanf(argv[1], "%d", &i) != 1)
983  return BRLCAD_ERROR;
984  comb->GIFTmater = i;
985  }
986  } else if (db5_standardize_attribute(buf) == ATTR_COLOR) {
987  if (BU_STR_EQUAL(argv[1], "invalid") || BU_STR_EQUAL(argv[1], "none")) {
988  comb->rgb[0] = comb->rgb[1] =
989  comb->rgb[2] = 0;
990  comb->rgb_valid = 0;
991  } else {
992  unsigned int r, g, b;
993  i = sscanf(argv[1], "%u %u %u",
994  &r, &g, &b);
995  if (i != 3) {
996  bu_vls_printf(logstr, "adjust %s: not valid rgb 3-tuple\n", argv[1]);
997  return BRLCAD_ERROR;
998  }
999  comb->rgb[0] = (unsigned char)r;
1000  comb->rgb[1] = (unsigned char)g;
1001  comb->rgb[2] = (unsigned char)b;
1002  comb->rgb_valid = 1;
1003  }
1004  } else if (BU_STR_EQUAL(buf, "shader")) {
1005  bu_vls_trunc(&comb->shader, 0);
1006  if (!BU_STR_EQUAL(argv[1], "none")) {
1007  bu_vls_strcat(&comb->shader, argv[1]);
1008  /* Leading spaces boggle the combination exporter */
1009  bu_vls_trimspace(&comb->shader);
1010  }
1011  } else if (BU_STR_EQUAL(buf, "material")) {
1012  bu_vls_trunc(&comb->material, 0);
1013  if (!BU_STR_EQUAL(argv[1], "none")) {
1014  bu_vls_strcat(&comb->material, argv[1]);
1015  bu_vls_trimspace(&comb->material);
1016  }
1017  } else if (BU_STR_EQUAL(buf, "inherit")) {
1018  if (BU_STR_EQUAL(argv[1], "none")) {
1019  comb->inherit = 0;
1020  } else if (BU_STR_EQUAL(argv[1], "no")) {
1021  comb->inherit = 0;
1022  } else if (BU_STR_EQUAL(argv[1], "yes")) {
1023  comb->inherit = 1;
1024  } else {
1025  if (sscanf(argv[1], "%d", &i) != 1)
1026  return BRLCAD_ERROR;
1027 
1028  if (i != 0)
1029  i = 1;
1030 
1031  comb->inherit = (char)i;
1032  }
1033  } else if (BU_STR_EQUAL(buf, "tree")) {
1034  union tree *newtree;
1035 
1036  if (*argv[1] == '\0' || BU_STR_EQUAL(argv[1], "none")) {
1037  db_free_tree(comb->tree, &rt_uniresource);
1038  comb->tree = TREE_NULL;
1039  } else {
1040  newtree = db_tree_parse(logstr, argv[1], &rt_uniresource);
1041  if (newtree == TREE_NULL) {
1042  bu_vls_printf(logstr, "db adjust tree: bad tree '%s'\n", argv[1]);
1043  return BRLCAD_ERROR;
1044  }
1045  db_free_tree(comb->tree, &rt_uniresource);
1046  comb->tree = newtree;
1047  }
1048  } else {
1049  bu_vls_printf(logstr, "db adjust %s : no such attribute", buf);
1050  return BRLCAD_ERROR;
1051  }
1052  argc -= 2;
1053  argv += 2;
1054  }
1055 
1056  /* Make sure the attributes have gotten the message */
1057  db5_sync_comb_to_attr(&intern->idb_avs, comb);
1058  db5_standardize_avs(&intern->idb_avs);
1059 
1060  return BRLCAD_OK;
1061 
1062 not_region:
1063  bu_vls_printf(logstr, "adjusting attribute %s is not valid for a non-region combination.", buf);
1064  return BRLCAD_ERROR;
1065 }
1066 
1067 
1068 int
1069 rt_comb_form(struct bu_vls *logstr, const struct rt_functab *ftp)
1070 {
1071  RT_CK_FUNCTAB(ftp);
1072 
1073  bu_vls_printf(logstr, "region {%%s} id {%%d} air {%%d} los {%%d} GIFTmater {%%d} rgb {%%d %%d %%d} shader {%%s} material {%%s} inherit {%%s} tree {%%s}");
1074 
1075  return BRLCAD_OK;
1076 }
1077 
1078 
1079 /**
1080  * Create a blank combination with appropriate values. Called via
1081  * OBJ[ID_COMBINATION].ft_make().
1082  */
1083 void
1084 rt_comb_make(const struct rt_functab *UNUSED(ftp), struct rt_db_internal *intern)
1085 {
1086  struct rt_comb_internal *comb;
1087 
1088  intern->idb_major_type = DB5_MAJORTYPE_BRLCAD;
1089  intern->idb_type = ID_COMBINATION;
1090  intern->idb_meth = &OBJ[ID_COMBINATION];
1091  BU_ALLOC(intern->idb_ptr, struct rt_comb_internal);
1092 
1093  comb = (struct rt_comb_internal *)intern->idb_ptr;
1094  RT_COMB_INTERNAL_INIT(comb);
1095  bu_vls_init(&comb->shader);
1096  bu_vls_init(&comb->material);
1097 }
1098 
1099 
1100 /*
1101  * Local Variables:
1102  * mode: C
1103  * tab-width: 8
1104  * indent-tabs-mode: t
1105  * c-file-style: "stroustrup"
1106  * End:
1107  * ex: shiftwidth=4 tabstop=8
1108  */
ptrdiff_t ssize_t
Definition: common.h:119
void bu_vls_init(struct bu_vls *vp)
Definition: vls.c:56
Definition: raytrace.h:800
#define RT_CK_FUNCTAB(_p)
Definition: raytrace.h:2242
const char * db5_standard_attribute(int idx)
Definition: db5_attr.c:129
void bu_log(const char *,...) _BU_ATTR_PRINTF12
Definition: log.c:176
size_t db5_standardize_avs(struct bu_attribute_value_set *avs)
Definition: db5_attr.c:223
#define SIZEOF_NETWORK_DOUBLE
Definition: cv.h:48
#define BU_AVS_MAGIC
Definition: magic.h:46
int bn_mat_is_identity(const mat_t m)
Definition: mat.c:980
char region_flag
!0 ==> this COMB is a REGION
Definition: raytrace.h:939
#define REGION_FASTGEN_PLATE
Definition: raytrace.h:554
int tb_op
non-leaf
Definition: raytrace.h:1147
void bu_ptbl_init(struct bu_ptbl *b, size_t len, const char *str)
Definition: ptbl.c:32
void bu_vls_strcat(struct bu_vls *vp, const char *s)
Definition: vls.c:368
#define OP_XOR
Binary: L xor R, not both.
Definition: raytrace.h:1130
int bu_avs_add(struct bu_attribute_value_set *avp, const char *attribute, const char *value)
Definition: avs.c:78
void bu_vls_trunc(struct bu_vls *vp, int len)
Definition: vls.c:198
#define DB5COMB_TOKEN_INTERSECT
Definition: comb.c:136
#define BU_ASSERT_SSIZE_T(_lhs, _relation, _rhs)
Definition: defines.h:266
#define RT_CK_COMB(_p)
Definition: raytrace.h:955
struct region * tb_regionp
ptr to containing region
Definition: raytrace.h:1148
int db_tree_list(struct bu_vls *vls, const union tree *tp)
Definition: db_tree.c:2489
Header file for the BRL-CAD common definitions.
void rt_comb_v5_serialize(const union tree *tp, struct rt_comb_v5_serialize_state *ssp)
Definition: comb.c:159
unsigned char rgb[3]
Definition: raytrace.h:948
#define DB5COMB_TOKEN_NOT
Definition: comb.c:139
int bu_ptbl_ins(struct bu_ptbl *b, long *p)
#define ID_COMBINATION
Combination Record.
Definition: raytrace.h:499
#define RT_CK_COMB_V5_SERIALIZE_STATE(_p)
Definition: comb.c:151
void bu_cv_htond(unsigned char *out, const unsigned char *in, size_t count)
union tree * tb_left
Definition: raytrace.h:1149
void * bu_malloc(size_t siz, const char *str)
Definition: malloc.c:314
Definition: ptbl.h:62
const char * bu_avs_get(const struct bu_attribute_value_set *avp, const char *attribute)
Definition: avs.c:172
if(share_geom)
Definition: nmg_mod.c:3829
int idb_major_type
Definition: raytrace.h:192
void bu_vls_free(struct bu_vls *vp)
Definition: vls.c:248
size_t db5_decode_length(size_t *lenp, const unsigned char *cp, int format)
Definition: db5_io.c:94
#define OP_SUBTRACT
Binary: L subtract R.
Definition: raytrace.h:1129
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)
Definition: comb.c:451
void * memset(void *s, int c, size_t n)
#define DB5COMB_TOKEN_SUBTRACT
Definition: comb.c:137
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 OP_DB_LEAF
Leaf of combination, db fmt.
Definition: raytrace.h:1139
#define RT_CK_DB_INTERNAL(_p)
Definition: raytrace.h:207
#define DB_TREE_COUNTER_STATE_MAGIC
Definition: comb.c:66
unsigned char * matp
Definition: comb.c:145
int rt_comb_form(struct bu_vls *logstr, const struct rt_functab *ftp)
Definition: comb.c:1069
#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
size_t leafbytes
Definition: comb.c:63
int bu_avs_remove(struct bu_attribute_value_set *avp, const char *attribute)
Definition: avs.c:195
#define BU_PTBL_GET(ptbl, i)
Definition: ptbl.h:108
const struct rt_functab * idb_meth
for ft_ifree(), etc.
Definition: raytrace.h:194
#define TREE_NULL
Definition: raytrace.h:1181
#define V3ARGS(a)
Definition: color.c:56
uint32_t magic
Definition: comb.c:59
#define BRLCAD_OK
Definition: defines.h:71
uint8_t * ext_buf
Definition: parse.h:216
void db_free_tree(union tree *tp, struct resource *resp)
Definition: db_tree.c:1296
unsigned char * leafp
Definition: comb.c:146
matp_t tl_mat
xform matp, NULL ==> identity
Definition: raytrace.h:1173
void rt_comb_make(const struct rt_functab *ftp, struct rt_db_internal *intern)
Definition: comb.c:1084
struct bu_vls shader
Definition: raytrace.h:950
int rt_comb_get(struct bu_vls *logstr, const struct rt_db_internal *intern, const char *item)
Definition: comb.c:793
struct bu_attribute_value_set idb_avs
Definition: raytrace.h:196
#define DB_CK_TREE_COUNTER_STATE(_p)
Definition: comb.c:67
void bu_ptbl_trunc(struct bu_ptbl *tbl, int end)
Definition: ptbl.c:267
size_t bu_vls_strlen(const struct bu_vls *vp)
Definition: vls.c:189
char * tl_name
Name of this leaf (bu_strdup'ed)
Definition: raytrace.h:1174
#define REGION_FASTGEN_VOLUME
Definition: raytrace.h:555
struct tree::tree_node tr_b
matp_t bn_mat_dup(const mat_t in)
Definition: mat.c:1046
int db5_select_length_encoding(size_t len)
Definition: db5_io.c:84
#define UNUSED(parameter)
Definition: common.h:239
uint32_t magic
Definition: avs.h:84
void bn_mat_mul(mat_t o, const mat_t a, const mat_t b)
#define DB5COMB_TOKEN_XOR
Definition: comb.c:138
void bu_avs_init(struct bu_attribute_value_set *avp, size_t len, const char *str)
Definition: avs.c:47
size_t db_tree_counter(const union tree *tp, struct db_tree_counter_state *tcsp)
Definition: comb.c:84
char * bu_vls_addr(const struct bu_vls *vp)
Definition: vls.c:111
int db5_decode_signed(size_t *lenp, const unsigned char *cp, int format)
Definition: db5_io.c:119
#define DB5COMB_TOKEN_LEAF
Definition: comb.c:134
struct bu_vls material
Definition: raytrace.h:951
#define BU_PTBL_LEN(ptbl)
Definition: ptbl.h:107
void bu_ptbl_free(struct bu_ptbl *b)
Definition: ptbl.c:226
#define MAX_V5_STACK
#define RT_CK_DBI(_p)
Definition: raytrace.h:829
void db5_sync_comb_to_attr(struct bu_attribute_value_set *avs, const struct rt_comb_internal *comb)
Definition: db5_attr.c:447
struct tree::tree_db_leaf tr_l
union tree * tb_right
Definition: raytrace.h:1150
void * idb_ptr
Definition: raytrace.h:195
int rt_comb_adjust(struct bu_vls *logstr, struct rt_db_internal *intern, int argc, char **argv)
Definition: comb.c:907
#define REGION_NON_FASTGEN
Definition: raytrace.h:553
void bu_cv_ntohd(unsigned char *out, const unsigned char *in, size_t count)
const struct rt_functab OBJ[]
Definition: table.c:159
#define RT_CK_RESOURCE(_p)
Definition: raytrace.h:1490
#define BU_ASSERT_PTR(_lhs, _relation, _rhs)
Definition: defines.h:227
#define RT_GET_TREE(_tp, _res)
Definition: raytrace.h:1210
#define RT_COMB_INTERNAL_INIT(_p)
Definition: raytrace.h:960
#define DB5COMB_TOKEN_UNION
Definition: comb.c:135
union tree * tree
Leading to tree_db_leaf leaves.
Definition: raytrace.h:938
void bu_vls_printf(struct bu_vls *vls, const char *fmt,...) _BU_ATTR_PRINTF23
Definition: vls.c:694
#define BU_EXTERNAL_INIT(_p)
Definition: parse.h:229
#define REGION_NULL
Definition: raytrace.h:558
unsigned char * exprp
Definition: comb.c:147
char is_fastgen
REGION_NON_FASTGEN/_PLATE/_VOLUME.
Definition: raytrace.h:940
void bu_vls_trimspace(struct bu_vls *vp)
Definition: vls.c:678
int bu_avs_add_vls(struct bu_attribute_value_set *avp, const char *attribute, const struct bu_vls *value_vls)
Definition: avs.c:144
#define BU_ASSERT_SIZE_T(_lhs, _relation, _rhs)
Definition: defines.h:253
unsigned char * db5_encode_length(unsigned char *cp, size_t val, int format)
Definition: db5_io.c:152
void bu_free(void *ptr, const char *str)
Definition: malloc.c:328
#define RT_CK_TREE(_p)
Definition: raytrace.h:1182
char rgb_valid
!0 ==> rgb[] has valid color
Definition: raytrace.h:947
#define BU_CK_EXTERNAL(_p)
Definition: parse.h:224
#define RT_COMB_V5_SERIALIZE_STATE_MAGIC
Definition: comb.c:150
int db5_standardize_attribute(const char *attr)
Definition: db5_attr.c:152
#define BU_VLS_INIT_ZERO
Definition: vls.h:84
int tl_op
leaf, OP_DB_LEAF
Definition: raytrace.h:1172
size_t ext_nbytes
Definition: parse.h:210
union tree * db_tree_parse(struct bu_vls *vls, const char *str, struct resource *resp)
Definition: db_tree.c:2560
Definition: vls.h:56
#define BRLCAD_ERROR
Definition: defines.h:72
void bu_bomb(const char *str) _BU_ATTR_NORETURN
Definition: bomb.c:91
float temperature
0 ==> region temperature
Definition: raytrace.h:949
#define OP_UNION
Binary: L union R.
Definition: raytrace.h:1127
void bu_vls_putc(struct bu_vls *vp, int c)
Definition: vls.c:666
#define OP_NOT
Unary: not L.
Definition: raytrace.h:1134
#define bu_strdup(s)
Definition: str.h:71
int rt_comb_export5(struct bu_external *ep, const struct rt_db_internal *ip, double local2mm, const struct db_i *dbip, struct resource *resp)
Definition: comb.c:252
#define BU_STR_EQUAL(s1, s2)
Definition: str.h:126