BRL-CAD
put_comb.c
Go to the documentation of this file.
1 /* P U T _ C O M B . C
2  * BRL-CAD
3  *
4  * Copyright (c) 2008-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 /** @file libged/put_comb.c
21  *
22  * The put_comb command.
23  *
24  */
25 
26 #include "common.h"
27 
28 #include <stdlib.h>
29 #include <ctype.h>
30 #include <string.h>
31 
32 #include "./ged_private.h"
33 
34 
35 /* allowable delimiters */
36 static const char _delims[] = " \t/";
37 
38 static const char tmpcomb[16] = { 'g', 'e', 'd', '_', 't', 'm', 'p', '.', 'a', 'X', 'X', 'X', 'X', 'X', '\0' };
39 
40 
41 static int
42 make_tree(struct ged *gedp, struct rt_comb_internal *comb, struct directory *dp, size_t node_count, const char *old_name, const char *new_name, struct rt_tree_array *rt_tree_array, int tree_index)
43 {
44  struct rt_db_internal intern;
45  union tree *final_tree;
46 
47  if (tree_index)
48  final_tree = (union tree *)db_mkgift_tree(rt_tree_array, node_count, &rt_uniresource);
49  else
50  final_tree = (union tree *)NULL;
51 
52  RT_DB_INTERNAL_INIT(&intern);
53  intern.idb_major_type = DB5_MAJORTYPE_BRLCAD;
54  intern.idb_type = ID_COMBINATION;
55  intern.idb_meth = &OBJ[ID_COMBINATION];
56  intern.idb_ptr = (void *)comb;
57  comb->tree = final_tree;
58 
59  if (!BU_STR_EQUAL(new_name, old_name)) {
60  int flags;
61 
62  if (comb->region_flag)
63  flags = RT_DIR_COMB | RT_DIR_REGION;
64  else
65  flags = RT_DIR_COMB;
66 
67  if (dp != RT_DIR_NULL) {
68  if (db_delete(gedp->ged_wdbp->dbip, dp) || db_dirdelete(gedp->ged_wdbp->dbip, dp)) {
69  bu_vls_printf(gedp->ged_result_str, "make_tree: Unable to delete directory entry for %s\n", old_name);
70  intern.idb_meth->ft_ifree(&intern);
71  return GED_ERROR;
72  }
73  }
74 
75  if ((dp=db_diradd(gedp->ged_wdbp->dbip, new_name, RT_DIR_PHONY_ADDR, 0, flags, (void *)&intern.idb_type)) == RT_DIR_NULL) {
76  bu_vls_printf(gedp->ged_result_str, "make_tree: Cannot add %s to directory, no changes made\n", new_name);
77  intern.idb_meth->ft_ifree(&intern);
78  return 1;
79  }
80  } else if (dp == RT_DIR_NULL) {
81  int flags;
82 
83  if (comb->region_flag)
84  flags = RT_DIR_COMB | RT_DIR_REGION;
85  else
86  flags = RT_DIR_COMB;
87 
88  if ((dp=db_diradd(gedp->ged_wdbp->dbip, new_name, RT_DIR_PHONY_ADDR, 0, flags, (void *)&intern.idb_type)) == RT_DIR_NULL) {
89  bu_vls_printf(gedp->ged_result_str, "make_tree: Cannot add %s to directory, no changes made\n", new_name);
90  intern.idb_meth->ft_ifree(&intern);
91  return GED_ERROR;
92  }
93  } else {
94  if (comb->region_flag)
95  dp->d_flags |= RT_DIR_REGION;
96  else
97  dp->d_flags &= ~RT_DIR_REGION;
98  }
99 
100  if (rt_db_put_internal(dp, gedp->ged_wdbp->dbip, &intern, &rt_uniresource) < 0) {
101  bu_vls_printf(gedp->ged_result_str, "make_tree: Unable to write new combination into database.\n");
102  return GED_ERROR;
103  }
104 
105  return GED_OK;
106 }
107 
108 
109 static const char *
110 mktemp_comb(struct ged *gedp, const char *str)
111 {
112  /* Make a temporary name for a combination
113  a template name is expected as in "mk_temp()" with
114  5 trailing X's */
115 
116  int counter, done;
117  char *ptr;
118  static char name[NAMESIZE] = {0};
119 
120  if (gedp->ged_wdbp->dbip == DBI_NULL)
121  return NULL;
122 
123  /* leave room for 5 digits */
124  bu_strlcpy(name, str, NAMESIZE - 5);
125 
126  ptr = name;
127  while (*ptr != '\0')
128  ptr++;
129 
130  while (*(--ptr) == 'X')
131  ;
132  ptr++;
133 
134  counter = 1;
135  done = 0;
136  while (!done && counter < 99999) {
137  sprintf(ptr, "%d", counter);
138  if (db_lookup(gedp->ged_wdbp->dbip, str, LOOKUP_QUIET) == RT_DIR_NULL)
139  done = 1;
140  else
141  counter++;
142  }
143 
144  return name;
145 }
146 
147 
148 static const char *
149 save_comb(struct ged *gedp, struct directory *dpold)
150 {
151  /* Save a combination under a temporary name */
152 
153  struct directory *dp;
154  struct rt_db_internal intern;
155 
156  /* Make a new name */
157  const char *name = mktemp_comb(gedp, tmpcomb);
158 
159  if (rt_db_get_internal(&intern, dpold, gedp->ged_wdbp->dbip, (fastf_t *)NULL, &rt_uniresource) < 0) {
160  bu_vls_printf(gedp->ged_result_str, "save_comb: Database read error, aborting\n");
161  return NULL;
162  }
163 
164  if ((dp = db_diradd(gedp->ged_wdbp->dbip, name, RT_DIR_PHONY_ADDR, 0, dpold->d_flags, (void *)&intern.idb_type)) == RT_DIR_NULL) {
165  bu_vls_printf(gedp->ged_result_str, "save_comb: Cannot save copy of %s, no changed made\n", dpold->d_namep);
166  return NULL;
167  }
168 
169  if (rt_db_put_internal(dp, gedp->ged_wdbp->dbip, &intern, &rt_uniresource) < 0) {
170  bu_vls_printf(gedp->ged_result_str, "save_comb: Cannot save copy of %s, no changed made\n", dpold->d_namep);
171  return NULL;
172  }
173 
174  return name;
175 }
176 
177 
178 /* restore a combination that was created during save_comb() */
179 static void
180 restore_comb(struct ged *gedp, struct directory *dp, const char *oldname)
181 {
182  const char *av[4];
183  char *name;
184 
185  if (!gedp || !dp || !oldname)
186  return;
187 
188  /* get rid of previous comb */
189  name = bu_strdup(dp->d_namep);
190 
191  av[0] = "kill";
192  av[1] = name;
193  av[2] = NULL;
194  av[3] = NULL;
195  (void)ged_kill(gedp, 2, (const char **)av);
196 
197  av[0] = "mv";
198  av[1] = oldname;
199  av[2] = name;
200 
201  (void)ged_move(gedp, 3, (const char **)av);
202 
203  bu_free(name, "bu_strdup'd name");
204 }
205 
206 
207 struct line_list{
208  struct bu_list l;
209  char *line;
210 };
211 
212 
213 static struct line_list HeadLines;
214 
215 
216 static int
217 count_nodes(struct ged *gedp, char *line)
218 {
219  char *ptr;
220  char *name;
221  char relation;
222  int node_count=0;
223 
224  /* sanity */
225  if (line == NULL)
226  return 0;
227 
228  ptr = strtok(line, _delims);
229 
230  while (ptr) {
231  /* First non-white is the relation operator */
232  relation = (*ptr);
233 
234  if (relation != '+' && relation != 'u' && relation != '-') {
235  bu_vls_printf(gedp->ged_result_str, " %c is not a legal operator\n", relation);
236  return -1;
237  }
238 
239  /* Next must be the member name */
240  name = strtok((char *)NULL, _delims);
241 
242  if (name == NULL) {
243  bu_vls_printf(gedp->ged_result_str, " operand name missing\n");
244  return -1;
245  }
246 
247  ptr = strtok((char *)NULL, _delims);
248  /*
249  * If this token is not a boolean operator, then it must be the start
250  * of a matrix which we will skip.
251  */
252  if (ptr && !((*ptr == 'u' || *ptr == '-' || *ptr == '+') &&
253  *(ptr+1) == '\0')) {
254  int k;
255 
256  /* skip past matrix, k = 1 because we already have the first value */
257  for (k = 1; k < 16; k++) {
258  ptr = strtok((char *)NULL, _delims);
259  if (!ptr) {
260  bu_vls_printf(gedp->ged_result_str, "expecting a matrix\n");
261  return -1;
262  }
263  }
264 
265  /* get the next relational operator on the current line */
266  ptr = strtok((char *)NULL, _delims);
267  }
268 
269  node_count++;
270  }
271 
272  return node_count;
273 }
274 
275 
276 static int
277 put_tree_into_comb(struct ged *gedp, struct rt_comb_internal *comb, struct directory *dp, const char *old_name, const char *new_name, const char *imstr)
278 {
279  int i;
280  int done;
281  char *line;
282  char *ptr;
283  char relation;
284  char *name;
285  struct rt_tree_array *rt_tree_array;
286  struct line_list *llp;
287  int node_count = 0;
288  int tree_index = 0;
289  union tree *tp;
290  matp_t matrix;
291  struct bu_vls vls = BU_VLS_INIT_ZERO;
292  char *str;
293 
294  if (imstr == (char *)NULL)
295  return GED_ERROR;
296 
297  BU_LIST_INIT(&HeadLines.l);
298 
299  /* duplicate the immutable str (from argv) for strtok style mutation */
300  str = bu_strdup(imstr);
301 
302  /* break str into lines */
303  line = str;
304  ptr = strchr(str, '\n');
305  if (ptr != NULL)
306  *ptr = '\0';
307 
308  while (line != (char *)NULL) {
309  int n;
310 
311  bu_vls_strcpy(&vls, line);
312 
313  if ((n = count_nodes(gedp, bu_vls_addr(&vls))) < 0) {
314  bu_vls_free(&vls);
315  bu_list_free(&HeadLines.l);
316  bu_free(str, "dealloc bu_strdup str");
317  return GED_ERROR;
318  } else if (n > 0) {
319  BU_ALLOC(llp, struct line_list);
320  BU_LIST_INSERT(&HeadLines.l, &llp->l);
321  llp->line = line;
322 
323  node_count += n;
324  } /* else blank line */
325 
326  if (ptr != NULL && *(ptr+1) != '\0') {
327  /* leap frog past EOS */
328  line = ptr + 1;
329 
330  ptr = strchr(line, '\n');
331  if (ptr != NULL)
332  *ptr = '\0';
333  } else {
334  line = NULL;
335  }
336  }
337  bu_vls_free(&vls);
338 
339  /* build tree list */
340  if (node_count)
341  rt_tree_array = (struct rt_tree_array *)bu_calloc(node_count, sizeof(struct rt_tree_array), "tree list");
342  else
343  rt_tree_array = (struct rt_tree_array *)NULL;
344 
345  for (BU_LIST_FOR (llp, line_list, &HeadLines.l)) {
346  done = 0;
347  ptr = strtok(llp->line, _delims);
348  while (!done) {
349  if (!ptr)
350  break;
351 
352  /* First non-white is the relation operator */
353  relation = (*ptr);
354  if (relation == '\0')
355  break;
356 
357  /* Next must be the member name */
358  ptr = strtok((char *)NULL, _delims);
359  if (ptr == (char *)NULL) {
360  bu_list_free(&HeadLines.l);
361  if (rt_tree_array)
362  bu_free((char *)rt_tree_array, "red: tree list");
363  bu_log("no name specified\n");
364  bu_free(str, "dealloc bu_strdup str");
365  return GED_ERROR;
366  }
367  name = ptr;
368 
369  /* Eliminate trailing white space from name */
370  i = (int)strlen(ptr);
371  while (isspace((int)name[--i]))
372  name[i] = '\0';
373 
374  /* Check for existence of member */
375  if ((db_lookup(gedp->ged_wdbp->dbip, name, LOOKUP_QUIET)) == RT_DIR_NULL)
376  bu_log("\tWARNING: ' %s ' does not exist\n", name);
377 
378  /* get matrix */
379  ptr = strtok((char *)NULL, _delims);
380  if (ptr == (char *)NULL) {
381  matrix = (matp_t)NULL;
382  done = 1;
383  } else if (*ptr == 'u' ||
384  (*ptr == '-' && *(ptr+1) == '\0') ||
385  (*ptr == '+' && *(ptr+1) == '\0')) {
386  /* assume another relational operator */
387  matrix = (matp_t)NULL;
388  } else {
389  int k;
390 
391  matrix = (matp_t)bu_calloc(16, sizeof(fastf_t), "red: matrix");
392  matrix[0] = atof(ptr);
393  for (k = 1; k < 16; k++) {
394  ptr = strtok((char *)NULL, _delims);
395  if (!ptr) {
396  bu_log("incomplete matrix for member %s - No changes made\n", name);
397  bu_free((char *)matrix, "red: matrix");
398  if (rt_tree_array)
399  bu_free((char *)rt_tree_array, "red: tree list");
400  bu_list_free(&HeadLines.l);
401  bu_free(str, "dealloc bu_strdup str");
402  return GED_ERROR;
403  }
404  matrix[k] = atof(ptr);
405  }
406  if (bn_mat_is_identity(matrix)) {
407  bu_free((char *)matrix, "red: matrix");
408  matrix = (matp_t)NULL;
409  }
410 
411  ptr = strtok((char *)NULL, _delims);
412  if (ptr == (char *)NULL)
413  done = 1;
414  }
415 
416  /* Add it to the combination */
417  switch (relation) {
418  case DB_OP_INTERSECT:
419  rt_tree_array[tree_index].tl_op = OP_INTERSECT;
420  break;
421  case DB_OP_SUBTRACT:
422  rt_tree_array[tree_index].tl_op = OP_SUBTRACT;
423  break;
424  default:
425  if (relation != DB_OP_UNION) {
426  bu_log("unrecognized relation (assume UNION)\n");
427  }
428  rt_tree_array[tree_index].tl_op = OP_UNION;
429  break;
430  }
431 
432  BU_ALLOC(tp, union tree);
433  RT_TREE_INIT(tp);
434  rt_tree_array[tree_index].tl_tree = tp;
435  tp->tr_l.tl_op = OP_DB_LEAF;
436  tp->tr_l.tl_name = bu_strdup(name);
437  tp->tr_l.tl_mat = matrix;
438  tree_index++;
439  }
440  }
441 
442  bu_list_free(&HeadLines.l);
443  i = make_tree(gedp, comb, dp, node_count, old_name, new_name, rt_tree_array, tree_index);
444 
445  bu_free(str, "dealloc bu_strdup str");
446 
447  return i;
448 }
449 
450 
451 void
452 put_rgb_into_comb(struct rt_comb_internal *comb, const char *str)
453 {
454  int r, g, b;
455 
456  if (sscanf(str, "%d%*c%d%*c%d", &r, &g, &b) != 3) {
457  comb->rgb_valid = 0;
458  return;
459  }
460 
461  /* clamp the RGB values to [0, 255] */
462  if (r < 0)
463  r = 0;
464  else if (r > 255)
465  r = 255;
466 
467  if (g < 0)
468  g = 0;
469  else if (g > 255)
470  g = 255;
471 
472  if (b < 0)
473  b = 0;
474  else if (b > 255)
475  b = 255;
476 
477  comb->rgb[0] = (unsigned char)r;
478  comb->rgb[1] = (unsigned char)g;
479  comb->rgb[2] = (unsigned char)b;
480  comb->rgb_valid = 1;
481 }
482 
483 
484 int
485 ged_put_comb(struct ged *gedp, int argc, const char *argv[])
486 {
487  struct directory *dp;
488  struct rt_db_internal intern;
489  struct rt_comb_internal *comb;
490  char new_name_v4[NAMESIZE+1];
491  char *new_name;
492  int offset;
493  int save_comb_flag = 0;
494  static const char *usage = "comb_name is_Region id air material los color shader inherit boolean_expr";
495  static const char *noregionusage = "comb_name n color shader inherit boolean_expr";
496  static const char *regionusage = "comb_name y id air material los color shader inherit boolean_expr";
497  const char *saved_name = NULL;
498 
501  GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
502 
503  /* initialize result */
504  bu_vls_trunc(gedp->ged_result_str, 0);
505 
506  /* must be wanting help */
507  if (argc == 1) {
508  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
509  return GED_HELP;
510  }
511 
512  if (argc < 7 || 11 < argc) {
513  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
514  return GED_ERROR;
515  }
516 
517  comb = (struct rt_comb_internal *)NULL;
518  dp = db_lookup(gedp->ged_wdbp->dbip, argv[1], LOOKUP_QUIET);
519  if (dp != RT_DIR_NULL) {
520  if (!(dp->d_flags & RT_DIR_COMB)) {
521  bu_vls_printf(gedp->ged_result_str, "%s: %s is not a combination, so cannot be edited this way\n", argv[0], argv[1]);
522  return GED_ERROR;
523  }
524 
525  if (rt_db_get_internal(&intern, dp, gedp->ged_wdbp->dbip, (fastf_t *)NULL, &rt_uniresource) < 0) {
526  bu_vls_printf(gedp->ged_result_str, "%s: Database read error, aborting\n", argv[0]);
527  return GED_ERROR;
528  }
529 
530  comb = (struct rt_comb_internal *)intern.idb_ptr;
531  saved_name = save_comb(gedp, dp); /* Save combination to a temp name */
532  save_comb_flag = 1;
533  }
534 
535  /* empty the existing combination */
536  if (comb) {
538  comb->tree = NULL;
539  } else {
540  /* make an empty combination structure */
541  BU_ALLOC(comb, struct rt_comb_internal);
542  if (comb == NULL)
543  bu_bomb("Unable to allocate comb memory");
544  RT_COMB_INTERNAL_INIT(comb);
545  }
546 
547  if (db_version(gedp->ged_wdbp->dbip) < 5) {
548  new_name = new_name_v4;
549  if (dp == RT_DIR_NULL)
550  NAMEMOVE(argv[1], new_name_v4);
551  else
552  NAMEMOVE(dp->d_namep, new_name_v4);
553  } else {
554  if (dp == RT_DIR_NULL)
555  new_name = (char *)argv[1];
556  else
557  new_name = dp->d_namep;
558  }
559 
560  if (*argv[2] == 'y' || *argv[2] == 'Y')
561  comb->region_flag = 1;
562  else
563  comb->region_flag = 0;
564 
565  if (comb->region_flag) {
566  if (argc != 11) {
567  bu_vls_printf(gedp->ged_result_str, "region_flag is set, incorrect number of arguments supplied.\n");
568  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], regionusage);
569  return GED_ERROR;
570  }
571 
572  comb->region_id = atoi(argv[3]);
573  comb->aircode = atoi(argv[4]);
574  comb->GIFTmater = atoi(argv[5]);
575  comb->los = atoi(argv[6]);
576 
577  offset = 6;
578  } else {
579  if (argc != 7) {
580  bu_vls_printf(gedp->ged_result_str, "region_flag is not set, incorrect number of arguments supplied.\n");
581  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], noregionusage);
582  return GED_ERROR;
583  }
584  offset = 2;
585  }
586 
587  put_rgb_into_comb(comb, argv[offset + 1]);
588  bu_vls_strcpy(&comb->shader, argv[offset +2]);
589 
590  if (*argv[offset + 3] == 'y' || *argv[offset + 3] == 'Y')
591  comb->inherit = 1;
592  else
593  comb->inherit = 0;
594 
595  if (put_tree_into_comb(gedp, comb, dp, argv[1], new_name, argv[offset + 4]) == GED_ERROR) {
596  if (comb && dp) {
597  restore_comb(gedp, dp, saved_name);
598  bu_vls_printf(gedp->ged_result_str, "%s: \toriginal restored\n", argv[0]);
599  }
601  return GED_ERROR;
602  } else if (save_comb_flag) {
603  /* eliminate the temporary combination */
604  const char *av[3];
605 
606  av[0] = "kill";
607  av[1] = saved_name;
608  av[2] = NULL;
609  (void)ged_kill(gedp, 2, (const char **)av);
610  }
611 
613  return GED_OK;
614 }
615 
616 
617 /*
618  * Local Variables:
619  * tab-width: 8
620  * mode: C
621  * indent-tabs-mode: t
622  * c-file-style: "stroustrup"
623  * End:
624  * ex: shiftwidth=4 tabstop=8
625  */
void usage(struct ged *gedp)
Definition: coil.c:315
#define GED_OK
Definition: ged.h:55
char * d_namep
pointer to name string
Definition: raytrace.h:859
#define BU_LIST_FOR(p, structure, hp)
Definition: list.h:365
int db_dirdelete(struct db_i *, struct directory *dp)
Definition: db_lookup.c:262
void bu_log(const char *,...) _BU_ATTR_PRINTF12
Definition: log.c:176
#define BU_LIST_INSERT(old, new)
Definition: list.h:183
int rt_db_get_internal(struct rt_db_internal *ip, const struct directory *dp, const struct db_i *dbip, const mat_t mat, struct resource *resp)
Definition: dir.c:76
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
Definition: list.h:118
int rt_db_put_internal(struct directory *dp, struct db_i *dbip, struct rt_db_internal *ip, struct resource *resp)
Definition: dir.c:136
Definition: ged.h:338
struct db_i * dbip
Definition: raytrace.h:1266
Definition: clone.c:90
void bu_vls_trunc(struct bu_vls *vp, int len)
Definition: vls.c:198
#define GED_CHECK_ARGC_GT_0(_gedp, _argc, _flags)
Definition: ged.h:202
struct directory * db_lookup(const struct db_i *, const char *name, int noisy)
Definition: db_lookup.c:153
int db_version(struct db_i *dbip)
Definition: db5_scan.c:414
union tree * tl_tree
Definition: raytrace.h:1247
struct rt_wdb * ged_wdbp
Definition: ged.h:340
Header file for the BRL-CAD common definitions.
#define RT_DIR_REGION
region
Definition: raytrace.h:885
union tree * db_mkgift_tree(struct rt_tree_array *trees, size_t subtreecount, struct resource *resp)
Definition: db_comb.c:1016
unsigned char rgb[3]
Definition: raytrace.h:948
#define ID_COMBINATION
Combination Record.
Definition: raytrace.h:499
char * line
Definition: put_comb.c:209
#define GED_ERROR
Definition: ged.h:61
char _ged_tmpfil[MAXPATHLEN]
Definition: red.c:40
#define RT_TREE_INIT(_p)
Definition: raytrace.h:1189
size_t counter[MAX_PSW]
Definition: bu_parallel.c:42
char * strchr(const char *sp, int c)
void bu_vls_free(struct bu_vls *vp)
Definition: vls.c:248
#define OP_SUBTRACT
Binary: L subtract R.
Definition: raytrace.h:1129
#define OP_INTERSECT
Binary: L intersect R.
Definition: raytrace.h:1128
struct resource rt_uniresource
default. Defined in librt/globals.c
Definition: globals.c:41
#define GED_CHECK_DATABASE_OPEN(_gedp, _flags)
Definition: ged.h:114
#define OP_DB_LEAF
Leaf of combination, db fmt.
Definition: raytrace.h:1139
#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_DB_INTERNAL_INIT(_p)
Definition: raytrace.h:199
#define LOOKUP_QUIET
Definition: raytrace.h:893
#define bu_strlcpy(dst, src, size)
Definition: str.h:60
char * strtok(char *s, const char *delim)
void db_free_tree(union tree *tp, struct resource *resp)
Definition: db_tree.c:1296
int ged_kill(struct ged *gedp, int argc, const char *argv[])
Definition: kill.c:37
matp_t tl_mat
xform matp, NULL ==> identity
Definition: raytrace.h:1173
#define RT_DIR_PHONY_ADDR
Special marker for d_addr field.
Definition: raytrace.h:879
struct bu_vls shader
Definition: raytrace.h:950
char * tl_name
Name of this leaf (bu_strdup'ed)
Definition: raytrace.h:1174
struct bu_list l
Definition: put_comb.c:208
char * bu_vls_addr(const struct bu_vls *vp)
Definition: vls.c:111
struct bu_vls * ged_result_str
Definition: ged.h:357
int ged_move(struct ged *gedp, int argc, const char *argv[])
Definition: move.c:37
void put_rgb_into_comb(struct rt_comb_internal *comb, const char *str)
Definition: put_comb.c:452
int ged_put_comb(struct ged *gedp, int argc, const char *argv[])
Definition: put_comb.c:485
struct directory * db_diradd(struct db_i *, const char *name, off_t laddr, size_t len, int flags, void *ptr)
Definition: db_lookup.c:190
struct tree::tree_db_leaf tr_l
#define BU_LIST_INIT(_hp)
Definition: list.h:148
void * idb_ptr
Definition: raytrace.h:195
#define RT_DIR_COMB
combination
Definition: raytrace.h:884
const struct rt_functab OBJ[]
Definition: table.c:159
Definition: op.h:35
#define DBI_NULL
Definition: raytrace.h:827
#define RT_COMB_INTERNAL_INIT(_p)
Definition: raytrace.h:960
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 RT_DIR_NULL
Definition: raytrace.h:875
#define GED_HELP
Definition: ged.h:62
void bu_vls_strcpy(struct bu_vls *vp, const char *s)
Definition: vls.c:310
void bu_free(void *ptr, const char *str)
Definition: malloc.c:328
char rgb_valid
!0 ==> rgb[] has valid color
Definition: raytrace.h:947
#define BU_VLS_INIT_ZERO
Definition: vls.h:84
int tl_op
leaf, OP_DB_LEAF
Definition: raytrace.h:1172
void bu_list_free(struct bu_list *hd)
Definition: list.c:79
#define GED_CHECK_READ_ONLY(_gedp, _flags)
Definition: ged.h:181
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
double fastf_t
Definition: defines.h:300
#define OP_UNION
Binary: L union R.
Definition: raytrace.h:1127
int db_delete(struct db_i *, struct directory *dp)
Definition: db_alloc.c:132
#define bu_strdup(s)
Definition: str.h:71
int bu_file_delete(const char *path)
Definition: file.c:278
#define BU_STR_EQUAL(s1, s2)
Definition: str.h:126