BRL-CAD
db5_attr.c
Go to the documentation of this file.
1 /* D B 5 _ A T T R . C
2  * BRL-CAD
3  *
4  * Copyright (c) 2000-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 librt/db5_attr.c
23  *
24  * Properties and functions related to standard DB5 object attributes
25  *
26  */
27 
28 #include "common.h"
29 
30 #include <string.h>
31 #include <math.h>
32 #include "bio.h"
33 
34 
35 #include "bu/parse.h"
36 #include "vmath.h"
37 #include "db5.h"
38 #include "raytrace.h"
39 
40 /* this is the master source of standard and registered attribute information */
41 const struct db5_attr_ctype db5_attr_std[] = {
42  { ATTR_REGION, 0, ATTR_STANDARD,
43  "region",
44  "boolean",
45  "Yes, R, 1, 0", /* example */
46  "", /* aliases, if any */
47  "Region Flag", /* property, if any */
48  /* long_description, if any: */
49  "The Region Flag identifies a particular geometric combination as being a solid material; in other words, any geometry below this combination in the tree can overlap without the overlap being regarded as a non-physical description, since it is the combination of all descriptions in the region object that defines the physical volume in space."
50 
51  },
52  { ATTR_REGION_ID, 0, ATTR_STANDARD,
53  "region_id",
54  "an integer",
55  "0, -1, and positive integers", /* examples */
56  "id", /* aliases, if any */
57  "Region Identifier Number", /* property, if any */
58  /* long_description, if any: */
59  "The Region Identifier Number identifies a particular region with a unique number. This allows multiple region objects to be regarded as being the same type of region, without requiring that they be included in the same combination object."
60  },
61  { ATTR_MATERIAL_ID, 0, ATTR_STANDARD,
62  "material_id",
63  "zero or positive integer (user-defined)",
64  "", /* examples */
65  "giftmater,mat", /* aliases, if any */
66  "Material Identifier Number", /* property, if any */
67  /* long_description, if any: */
68  "The Material ID Number corresponds to an entry in a DENSITIES table, usually contained in a text file. This table associates numbers with material names and density information used by analytical programs such as 'rtweight'."
69  },
70  { ATTR_AIR, 0, ATTR_STANDARD,
71  "aircode",
72  "an integer (application defined)",
73  "'0', '1', or '-2'", /* examples */
74  "air", /* aliases, if any */
75  "Air Code", /* property, if any */
76  /* long_description, if any: */
77  "Any non-zero Air Code alerts the raytracer that the region in question is modeling air which is handled by specialized rules in LIBRT."
78  },
79  { ATTR_LOS, 0, ATTR_STANDARD,
80  "los",
81  "an integer in the inclusive range: 0 to 100",
82  "'24' or '100'", /* examples */
83  "", /* aliases, if any */
84  "Line of Sight Thickness Equivalence", /* property, if any */
85  /* long_description, if any: */
86  ""
87  },
88  { ATTR_COLOR, 0, ATTR_STANDARD,
89  "color",
90  "a 3-tuple of RGB values",
91  "\"0 255 255\"", /* examples */
92  "rgb", /* aliases, if any */
93  "Color", /* property, if any */
94  "" /* long_description, if any */
95  },
96  { ATTR_SHADER, 0, ATTR_STANDARD,
97  "shader",
98  "a string of shader characteristics in a standard format",
99  "", /* examples */
100  "oshader", /* aliases, if any */
101  "Shader Name", /* property, if any */
102  /* long_description, if any: */
103  "LIBRT can use a variety of shaders when rendering. This attribute holds a text string which corresponds to the name and other details of the shader to be used."
104  },
105  { ATTR_INHERIT, 0, ATTR_STANDARD,
106  "inherit",
107  "boolean",
108  "Yes, 1, 0", /* examples */
109  "", /* aliases, if any */
110  "Inherit Properties", /* property, if any */
111  /* long_description, if any: */
112  "The Inherit Properties value, if true, indicates all child objects inherit the attributes of this parent object."
113  },
114  { ATTR_TIMESTAMP, 1, ATTR_STANDARD, /* first binary attribute */
115  "mtime",
116 
117  "a binary time stamp for an object's last mod time (the time is displayed in human-readable form with the 'attr' command)",
118 
119  "", /* examples */
120  "timestamp,time_stamp,modtime,mod_time,mtime", /* aliases, if any */
121  "Time Stamp", /* property, if any */
122  /* long_description, if any: */
123  ""
124  },
125  { ATTR_NULL, 0, ATTR_UNKNOWN_ORIGIN, "", "", "", "", "", "" }
126 };
127 
128 const char *
130 {
131  if (idx >= ATTR_NULL) return NULL;
132  return db5_attr_std[idx].name;
133 }
134 
135 int
136 db5_is_standard_attribute(const char *attr_want)
137 {
138  int i = 0;
139  const char *attr_have = NULL;
140 
141  if (!attr_want) return 0;
142 
143  for (i = 0; (attr_have = db5_standard_attribute(i)) != NULL; i++) {
144  if (BU_STR_EQUIV(attr_want, attr_have)) return 1;
145  }
146 
147  return 0;
148 }
149 
150 
151 int
152 db5_standardize_attribute(const char *attr)
153 {
154  int curr_attr = 0;
155  struct bu_vls alias;
156  const char *curr_pos, *next_pos;
157  if (!attr) return ATTR_NULL;
158  bu_vls_init(&alias);
159  while (db5_attr_std[curr_attr].attr_type != ATTR_NULL) {
160  if (BU_STR_EQUIV(attr, db5_attr_std[curr_attr].name)) {
161  bu_vls_free(&alias);
162  return db5_attr_std[curr_attr].attr_type;
163  }
164  curr_pos = db5_attr_std[curr_attr].aliases;
165  while (curr_pos && strlen(curr_pos) > 0) {
166  next_pos = strchr(curr_pos+1, ',');
167  if (next_pos) {
168  bu_vls_strncpy(&alias, curr_pos, next_pos - curr_pos);
169  if (BU_STR_EQUIV(attr, bu_vls_addr(&alias))) {
170  bu_vls_free(&alias);
171  return db5_attr_std[curr_attr].attr_type;
172  }
173  curr_pos = next_pos + 1;
174  } else {
175  bu_vls_strncpy(&alias, curr_pos, strlen(curr_pos));
176  if (BU_STR_EQUIV(attr, bu_vls_addr(&alias))) {
177  bu_vls_free(&alias);
178  return db5_attr_std[curr_attr].attr_type;
179  }
180  curr_pos = NULL;
181  }
182  }
183  curr_attr++;
184  }
185  bu_vls_free(&alias);
186  return ATTR_NULL;
187 }
188 
189 
190 HIDDEN
191 int
192 boolean_attribute(int attr) {
193  if (attr == ATTR_REGION)
194  return 1;
195  if (attr == ATTR_INHERIT)
196  return 1;
197  return 0;
198 }
199 
200 
201 HIDDEN
202 void
203 attr_add(struct bu_attribute_value_set *newavs, int attr_type, const char *stdattr, const char *value)
204 {
205  if (boolean_attribute(attr_type)) {
206  if (bu_str_true(value)) {
207  /* Use R for region, otherwise go with 1 */
208  if (attr_type == ATTR_REGION) {
209  (void)bu_avs_add(newavs, stdattr, "R\0");
210  } else {
211  (void)bu_avs_add(newavs, stdattr, "1\0");
212  }
213  } else {
214  (void)bu_avs_remove(newavs, stdattr);
215  }
216  } else {
217  (void)bu_avs_add(newavs, stdattr, value);
218  }
219 }
220 
221 
222 size_t
224 {
225  size_t conflict = 0;
226  int attr_type;
227 
228  const char *stdattr;
229  const char *added;
230 
231  struct bu_attribute_value_set newavs;
232  struct bu_attribute_value_pair *avpp;
233 
234  /* check inputs */
235  BU_CK_AVS(avs);
236  if (avs->count <= 0)
237  return 0;
238 
239  bu_avs_init_empty(&newavs);
240 
241  /* FIRST PASS: identify any attributes that are already in
242  * standard form since they take priority if there are duplicates
243  * with different values.
244  */
245  for (BU_AVS_FOR(avpp, avs)) {
246  /* see if this is a standardizable attribute name */
247  attr_type = db5_standardize_attribute(avpp->name);
248 
249  /* get the standard name for this type */
250  stdattr = db5_standard_attribute(attr_type);
251 
252  /* name is already in standard form, add it */
253  if (attr_type != ATTR_NULL && BU_STR_EQUAL(stdattr, avpp->name))
254  (void)attr_add(&newavs, attr_type, stdattr, avpp->value);
255  }
256 
257  /* SECOND PASS: check for duplicates and non-standard
258  * attributes.
259  */
260  for (BU_AVS_FOR(avpp, avs)) {
261  /* see if this is a standardizable attribute name */
262  attr_type = db5_standardize_attribute(avpp->name);
263 
264  /* get the standard name for this type */
265  stdattr = db5_standard_attribute(attr_type);
266 
267  /* see if we already added this attribute */
268  added = bu_avs_get(&newavs, stdattr);
269 
270  if (attr_type != ATTR_NULL && added == NULL) {
271 
272  /* case 1: name is "standardizable" and not added */
273 
274  (void)attr_add(&newavs, attr_type, stdattr, avpp->value);
275  } else if (attr_type != ATTR_NULL && BU_STR_EQUAL(added, avpp->value)) {
276 
277  /* case 2: name is "standardizable", but we already added the same value */
278 
279  /* ignore/skip it (because it's the same value) */
280  } else if (attr_type != ATTR_NULL && !BU_STR_EQUAL(added, avpp->value)) {
281 
282  /* case 3: name is "standardizable", but we already added something else */
283 
284  /* preserve the conflict, keep the old value too */
285  (void)attr_add(&newavs, attr_type, avpp->name, avpp->value);
286  conflict++;
287  } else {
288 
289  /* everything else: add it */
290 
291  (void)attr_add(&newavs, attr_type, avpp->name, avpp->value);
292  }
293  }
294  bu_avs_free(avs);
295  bu_avs_merge(avs, &newavs);
296  bu_avs_free(&newavs);
297 
298  return conflict;
299 }
300 
301 
302 void
303 db5_sync_attr_to_comb(struct rt_comb_internal *comb, const struct bu_attribute_value_set *avs, struct directory *dp)
304 {
305  int ret;
306  size_t i;
307  long int attr_num_val;
308  /*double attr_float_val;*/
309  char *endptr = NULL;
310  int color[3] = {-1, -1, -1};
311  struct bu_vls newval = BU_VLS_INIT_ZERO;
312  char *name = dp->d_namep;
313 
314  /* check inputs */
315  RT_CK_COMB(comb);
316 
317  /* region flag */
318  bu_vls_sprintf(&newval, "%s", bu_avs_get(avs, db5_standard_attribute(ATTR_REGION)));
319  bu_vls_trimspace(&newval);
320  if (bu_str_true(bu_vls_addr(&newval))) {
321  /* set region bit */
322  dp->d_flags |= RT_DIR_REGION;
323  comb->region_flag = 1;
324  } else {
325  /* unset region bit */
326  dp->d_flags &= ~RT_DIR_REGION;
327  comb->region_flag = 0;
328  }
329 
330  /* region_id */
331  bu_vls_sprintf(&newval, "%s", bu_avs_get(avs, db5_standard_attribute(ATTR_REGION_ID)));
332  bu_vls_trimspace(&newval);
333  if (bu_vls_strlen(&newval) != 0 && !BU_STR_EQUAL(bu_vls_addr(&newval), "(null)") && !BU_STR_EQUAL(bu_vls_addr(&newval), "del")) {
334  attr_num_val = strtol(bu_vls_addr(&newval), &endptr, 0);
335  if (endptr == bu_vls_addr(&newval) + strlen(bu_vls_addr(&newval))) {
336  comb->region_id = attr_num_val;
337  } else {
338  bu_log("WARNING: [%s] has invalid region_id value [%s]\nregion_id remains at %ld\n", name, bu_vls_addr(&newval), comb->region_id);
339  }
340  } else {
341  /* remove region_id */
342  comb->region_id = 0;
343  }
344 
345  /* material_id */
346  bu_vls_sprintf(&newval, "%s", bu_avs_get(avs, db5_standard_attribute(ATTR_MATERIAL_ID)));
347  bu_vls_trimspace(&newval);
348  if (bu_vls_strlen(&newval) != 0 && !BU_STR_EQUAL(bu_vls_addr(&newval), "(null)") && !BU_STR_EQUAL(bu_vls_addr(&newval), "del")) {
349  attr_num_val = strtol(bu_vls_addr(&newval), &endptr, 0);
350  if (endptr == bu_vls_addr(&newval) + strlen(bu_vls_addr(&newval))) {
351  comb->GIFTmater = attr_num_val;
352  } else {
353  bu_log("WARNING: [%s] has invalid material_id value [%s]\nmateriel_id remains at %ld\n", name, bu_vls_addr(&newval), comb->GIFTmater);
354  }
355  } else {
356  /* empty - set to zero */
357  comb->GIFTmater = 0;
358  }
359 
360  /* aircode */
361  bu_vls_sprintf(&newval, "%s", bu_avs_get(avs, db5_standard_attribute(ATTR_AIR)));
362  bu_vls_trimspace(&newval);
363  if (bu_vls_strlen(&newval) != 0 && !BU_STR_EQUAL(bu_vls_addr(&newval), "(null)") && !BU_STR_EQUAL(bu_vls_addr(&newval), "del")) {
364  attr_num_val = strtol(bu_vls_addr(&newval), &endptr, 0);
365  if (endptr == bu_vls_addr(&newval) + strlen(bu_vls_addr(&newval))) {
366  comb->aircode = attr_num_val;
367  } else {
368  bu_log("WARNING: [%s] has invalid aircode value [%s]\naircode remains at %ld\n", name, bu_vls_addr(&newval), comb->aircode);
369  }
370  } else {
371  /* not air */
372  comb->aircode = 0;
373  }
374 
375  /* los */
376  bu_vls_sprintf(&newval, "%s", bu_avs_get(avs, db5_standard_attribute(ATTR_LOS)));
377  bu_vls_trimspace(&newval);
378  if (bu_vls_strlen(&newval) != 0
379  && !BU_STR_EQUAL(bu_vls_addr(&newval), "(null)")
380  && !BU_STR_EQUAL(bu_vls_addr(&newval), "del")) {
381  /* Currently, struct rt_comb_internal lists los as a long. Probably should allow
382  * floating point, but as it's DEPRECATED anyway I suppose we can wait for that? */
383  /* attr_float_val = strtod(bu_vls_addr(&newval), &endptr); */
384  attr_num_val = strtol(bu_vls_addr(&newval), &endptr, 0);
385  if (endptr == bu_vls_addr(&newval) + strlen(bu_vls_addr(&newval))) {
386  comb->los = attr_num_val;
387  } else {
388  bu_log("WARNING: [%s] has invalid los value %s\nlos remains at %ld\n",
389  name, bu_vls_addr(&newval), comb->los);
390  }
391  } else {
392  /* no los */
393  comb->los = 0;
394  }
395 
396 
397  /* color */
398  bu_vls_sprintf(&newval, "%s", bu_avs_get(avs, db5_standard_attribute(ATTR_COLOR)));
399  bu_vls_trimspace(&newval);
400  if (bu_vls_strlen(&newval) != 0 && !BU_STR_EQUAL(bu_vls_addr(&newval), "(null)") && !BU_STR_EQUAL(bu_vls_addr(&newval), "del")) {
401  ret = sscanf(bu_vls_addr(&newval), "%3i%*c%3i%*c%3i", color+0, color+1, color+2);
402  if (ret == 3) {
403  if (color[0] < 0 || color[1] < 0 || color[2] < 0) {
404  comb->rgb_valid = 0;
405  } else {
406  for (i = 0; i < 3; i++) {
407  if (color[i] > 255) color[i] = 255;
408  }
409  comb->rgb[0] = color[0];
410  comb->rgb[1] = color[1];
411  comb->rgb[2] = color[2];
412  comb->rgb_valid = 1;
413  }
414  } else if (ret == 1 && color[0] < 0) {
415  comb->rgb_valid = 0;
416  } else {
417  if (comb->rgb_valid) {
418  bu_log("WARNING: [%s] color does not match an R/G/B pattern\nColor remains unchanged at %d/%d/%d\n", name, V3ARGS(comb->rgb));
419  }
420  }
421  } else {
422  comb->rgb_valid = 0;
423  }
424 
425  /* shader */
426  bu_vls_sprintf(&newval, "%s", bu_avs_get(avs, db5_standard_attribute(ATTR_SHADER)));
427  bu_vls_trimspace(&newval);
428  if (bu_vls_strlen(&newval) != 0 && !BU_STR_EQUAL(bu_vls_addr(&newval), "(null)") && !BU_STR_EQUAL(bu_vls_addr(&newval), "del")) {
429  bu_vls_sprintf(&comb->shader, "%s", bu_avs_get(avs, db5_standard_attribute(ATTR_SHADER)));
430  } else {
431  bu_vls_trunc(&comb->shader, 0);
432  }
433 
434  /* inherit */
435  bu_vls_sprintf(&newval, "%s", bu_avs_get(avs, db5_standard_attribute(ATTR_INHERIT)));
436  if (bu_str_true(bu_vls_addr(&newval))) {
437  comb->inherit = 1;
438  } else {
439  comb->inherit = 0;
440  }
441 
442  bu_vls_free(&newval);
443 }
444 
445 
446 void
448 {
449  struct bu_vls newval = BU_VLS_INIT_ZERO;
450 
451  /* check inputs */
452  RT_CK_COMB(comb);
453 
454  /* Region */
455  if (comb->region_flag) {
456  (void)bu_avs_add(avs, db5_standard_attribute(ATTR_REGION), "R");
457  } else {
458  bu_avs_remove(avs, db5_standard_attribute(ATTR_REGION));
459  }
460 
461  /* Region ID */
462  if (comb->region_flag) {
463  bu_vls_sprintf(&newval, "%ld", comb->region_id);
464  (void)bu_avs_add_vls(avs, db5_standard_attribute(ATTR_REGION_ID), &newval);
465  } else {
466  bu_avs_remove(avs, db5_standard_attribute(ATTR_REGION_ID));
467  }
468 
469  /* Material ID */
470  if (comb->GIFTmater != 0) {
471  bu_vls_sprintf(&newval, "%ld", comb->GIFTmater);
472  (void)bu_avs_add_vls(avs, db5_standard_attribute(ATTR_MATERIAL_ID), &newval);
473  } else {
474  bu_avs_remove(avs, db5_standard_attribute(ATTR_MATERIAL_ID));
475  }
476 
477  /* Air */
478  if (comb->aircode) {
479  bu_vls_sprintf(&newval, "%ld", comb->aircode);
480  (void)bu_avs_add_vls(avs, db5_standard_attribute(ATTR_AIR), &newval);
481  } else {
482  bu_avs_remove(avs, db5_standard_attribute(ATTR_AIR));
483  }
484 
485  /* LOS */
486  if (comb->los) {
487  bu_vls_sprintf(&newval, "%ld", comb->los);
488  (void)bu_avs_add_vls(avs, db5_standard_attribute(ATTR_LOS), &newval);
489  } else {
490  bu_avs_remove(avs, db5_standard_attribute(ATTR_LOS));
491  }
492 
493  /* Color */
494  if (comb->rgb_valid) {
495  bu_vls_sprintf(&newval, "%d/%d/%d", comb->rgb[0], comb->rgb[1], comb->rgb[2]);
496  (void)bu_avs_add_vls(avs, db5_standard_attribute(ATTR_COLOR), &newval);
497  } else {
498  bu_avs_remove(avs, db5_standard_attribute(ATTR_COLOR));
499  }
500 
501  /* Shader - may be redundant */
502  if (bu_vls_strlen(&comb->shader) != 0 && !BU_STR_EQUAL(bu_vls_addr(&newval), "(null)")) {
503  bu_vls_sprintf(&newval, "%s", bu_vls_addr(&comb->shader));
504  (void)bu_avs_add_vls(avs, db5_standard_attribute(ATTR_SHADER), &newval);
505  } else {
506  bu_avs_remove(avs, db5_standard_attribute(ATTR_SHADER));
507  }
508 
509  /* Inherit */
510  if (comb->inherit) {
511  bu_vls_sprintf(&newval, "%d", comb->inherit);
512  (void)bu_avs_add_vls(avs, db5_standard_attribute(ATTR_INHERIT), &newval);
513  } else {
514  bu_avs_remove(avs, db5_standard_attribute(ATTR_INHERIT));
515  }
516  bu_vls_free(&newval);
517 }
518 
519 
520 /** @} */
521 /*
522  * Local Variables:
523  * mode: C
524  * tab-width: 8
525  * indent-tabs-mode: t
526  * c-file-style: "stroustrup"
527  * End:
528  * ex: shiftwidth=4 tabstop=8
529  */
void bu_vls_init(struct bu_vls *vp)
Definition: vls.c:56
char * d_namep
pointer to name string
Definition: raytrace.h:859
HIDDEN void attr_add(struct bu_attribute_value_set *newavs, int attr_type, const char *stdattr, const char *value)
Definition: db5_attr.c:203
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
const struct db5_attr_ctype db5_attr_std[]
Definition: db5_attr.c:41
HIDDEN int boolean_attribute(int attr)
Definition: db5_attr.c:192
void bu_avs_init_empty(struct bu_attribute_value_set *avp)
Definition: avs.c:36
char region_flag
!0 ==> this COMB is a REGION
Definition: raytrace.h:939
Definition: clone.c:90
int bu_avs_add(struct bu_attribute_value_set *avp, const char *attribute, const char *value)
Definition: avs.c:78
void bu_avs_merge(struct bu_attribute_value_set *dest, const struct bu_attribute_value_set *src)
Definition: avs.c:154
void bu_vls_trunc(struct bu_vls *vp, int len)
Definition: vls.c:198
#define RT_CK_COMB(_p)
Definition: raytrace.h:955
void bu_vls_strncpy(struct bu_vls *vp, const char *s, size_t n)
Definition: vls.c:339
Header file for the BRL-CAD common definitions.
const char * value
Definition: avs.h:62
#define RT_DIR_REGION
region
Definition: raytrace.h:885
unsigned char rgb[3]
Definition: raytrace.h:948
#define HIDDEN
Definition: common.h:86
const char * bu_avs_get(const struct bu_attribute_value_set *avp, const char *attribute)
Definition: avs.c:172
char * strchr(const char *sp, int c)
void bu_vls_free(struct bu_vls *vp)
Definition: vls.c:248
void db5_sync_attr_to_comb(struct rt_comb_internal *comb, const struct bu_attribute_value_set *avs, struct directory *dp)
Definition: db5_attr.c:303
int bu_avs_remove(struct bu_attribute_value_set *avp, const char *attribute)
Definition: avs.c:195
void bu_vls_sprintf(struct bu_vls *vls, const char *fmt,...) _BU_ATTR_PRINTF23
Definition: vls.c:707
#define V3ARGS(a)
Definition: color.c:56
#define BU_AVS_FOR(_pp, _avp)
Definition: avs.h:141
struct bu_vls shader
Definition: raytrace.h:950
#define BU_STR_EQUIV(s1, s2)
Definition: str.h:135
size_t bu_vls_strlen(const struct bu_vls *vp)
Definition: vls.c:189
char * bu_vls_addr(const struct bu_vls *vp)
Definition: vls.c:111
void db5_sync_comb_to_attr(struct bu_attribute_value_set *avs, const struct rt_comb_internal *comb)
Definition: db5_attr.c:447
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
const char * name
Definition: avs.h:61
char rgb_valid
!0 ==> rgb[] has valid color
Definition: raytrace.h:947
int bu_str_true(const char *str)
Definition: booleanize.c:32
int db5_standardize_attribute(const char *attr)
Definition: db5_attr.c:152
#define BU_VLS_INIT_ZERO
Definition: vls.h:84
int d_flags
flags
Definition: raytrace.h:869
Definition: vls.h:56
#define BU_CK_AVS(_ap)
Definition: avs.h:97
void bu_avs_free(struct bu_attribute_value_set *avp)
Definition: avs.c:235
#define BU_STR_EQUAL(s1, s2)
Definition: str.h:126
int db5_is_standard_attribute(const char *attr_want)
Definition: db5_attr.c:136