BRL-CAD
track.c
Go to the documentation of this file.
1 /* T R A C K . C
2  * BRL-CAD
3  *
4  * Copyright (c) 1994-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 librt */
21 /** @{ */
22 /** @file libged/track.c
23  *
24  * Adds "tracks" to the data file given the required info
25  *
26  * Acknowledgements:
27  * Modifications by Bob Parker (SURVICE Engineering):
28  * *- adapt for use in LIBRT's database object
29  * *- removed prompting for input
30  * *- removed signal catching
31  * *- added basename parameter
32  */
33 /** @} */
34 
35 #include "common.h"
36 
37 #include <stdlib.h>
38 #include <math.h>
39 #include <string.h>
40 
41 
42 #include "vmath.h"
43 #include "bn.h"
44 #include "rtgeom.h"
45 #include "raytrace.h"
46 #include "wdb.h"
47 #include "ged.h"
48 
49 static int Trackpos = 0;
50 static int mat_default = 1;
51 static int los_default = 50;
52 static int item_default = 500;
53 static fastf_t plano[4], plant[4];
54 static int grpname_len;
55 static int extraTypeChars = 3;
56 static int extraChars = 4;
57 
58 static struct track_solid {
59  int s_type;
60  char *s_name;
61  fastf_t s_values[24];
62 } sol;
63 
64 static int wrobj();
65 static void slope(), crdummy(), trcurve();
66 static void bottom(), top();
67 
68 static void track_mk_tree_pure();
69 static int track_mk_tree_gift();
70 static struct wmember *track_mk_addmember();
71 static void track_mk_freemembers();
72 static int track_mk_comb();
73 
74 
75 /*
76  * convert integer to ascii wd format
77  */
78 static void
79 itoa(struct bu_vls *log_str,
80  int n,
81  char s[],
82  int w) {
83  int c, i, j, sign;
84 
85  if ((sign = n) < 0) n = -n;
86  i = 0;
87  do s[i++] = n % 10 + '0'; while ((n /= 10) > 0);
88  if (sign < 0) s[i++] = '-';
89 
90  /* blank fill array
91  */
92  for (j = i; j < w; j++) s[j] = ' ';
93  if (i > w)
94  bu_vls_printf(log_str, "itoa: field length too small\n");
95  s[w] = '\0';
96  /* reverse the array
97  */
98  for (i = 0, j = w - 1; i < j; i++, j--) {
99  c = s[i];
100  s[i] = s[j];
101  s[j] = c;
102  }
103 }
104 
105 
106 static void
107 crname(struct bu_vls *log_str,
108  char name[],
109  int pos,
110  int maxlen)
111 {
112  char temp[4];
113 
114  itoa(log_str, pos, temp, 1);
115  bu_strlcat(name, temp, maxlen);
116 }
117 
118 
119 static void
120 crregion(struct bu_vls *log_str,
121  struct rt_wdb *wdbp,
122  char region[],
123  char op[],
124  int members[],
125  int number,
126  char solidname[],
127  int maxlen)
128 {
129  int i;
130  struct bu_list head;
131 
132  if (wdbp->dbip == DBI_NULL)
133  return;
134 
135  BU_LIST_INIT(&head);
136 
137  for (i = 0; i < number; i++) {
138  solidname[grpname_len + extraTypeChars] = '\0';
139  crname(log_str, solidname, members[i], maxlen);
140  if (db_lookup(wdbp->dbip, solidname, LOOKUP_QUIET) == RT_DIR_NULL) {
141  bu_vls_printf(log_str, "region: %s will skip member: %s\n", region, solidname);
142  continue;
143  }
144  track_mk_addmember(solidname, &head, NULL, op[i]);
145  }
146  (void)track_mk_comb(wdbp, region, &head,
147  1, NULL, NULL, NULL,
148  500+Trackpos+i, 0, mat_default, los_default,
149  0, 1, 1);
150 }
151 
152 
153 /*
154  *
155  * Adds track given "wheel" info. This only needs a logging VLS and a
156  * database, so it can be used as a replacement for wdb_track_cmd when
157  * no struct ged is available.
158  *
159  */
160 int
161 ged_track2(struct bu_vls *log_str, struct rt_wdb *wdbp, const char *argv[])
162 {
163  fastf_t fw[3], lw[3], iw[3], dw[3], tr[3];
164  char *solname = NULL;
165  char *regname = NULL;
166  char *grpname = NULL;
167  char oper[3];
168  int i, memb[4];
169  vect_t temp1, temp2;
170  int item, mat, los;
171  int arg;
172  int edit_result = GED_OK;
173  struct bu_list head;
174  int len;
175 
176  BU_LIST_INIT(&head);
177 
178  oper[0] = oper[2] = WMOP_INTERSECT;
179  oper[1] = WMOP_SUBTRACT;
180 
181  /* base name */
182  arg = 1;
183  grpname = bu_strdup(argv[arg]);
184  grpname_len = (int)strlen(grpname);
185  len = grpname_len + 1 + extraChars;
186  solname = (char *)bu_malloc(len, "solid name");
187  regname = (char *)bu_malloc(len, "region name");
188  sol.s_name = (char *)bu_malloc(len, "sol.s_name");
189 
190  /* first road wheel X */
191  ++arg;
192  fw[0] = atof(argv[arg]) * wdbp->dbip->dbi_local2base;
193 
194  /* last road wheel X */
195  ++arg;
196  lw[0] = atof(argv[arg]) * wdbp->dbip->dbi_local2base;
197 
198  if (fw[0] <= lw[0]) {
199  bu_vls_printf(log_str, "First wheel after last wheel - STOP\n");
200  edit_result = GED_ERROR;
201  goto end;
202  }
203 
204  /* road wheel Z */
205  ++arg;
206  fw[1] = lw[1] = atof(argv[arg]) * wdbp->dbip->dbi_local2base;
207 
208  /* roadwheel radius */
209  ++arg;
210  fw[2] = lw[2] = atof(argv[arg]) * wdbp->dbip->dbi_local2base;
211 
212  if (fw[2] <= 0) {
213  bu_vls_printf(log_str, "Radius <= 0 - STOP\n");
214  edit_result = GED_ERROR;
215  goto end;
216  }
217 
218  /* drive sprocket X */
219  ++arg;
220  dw[0] = atof(argv[arg]) * wdbp->dbip->dbi_local2base;
221 
222  if (dw[0] >= lw[0]) {
223  bu_vls_printf(log_str, "DRIVE wheel not in the rear - STOP \n");
224  edit_result = GED_ERROR;
225  goto end;
226  }
227 
228  /* drive sprocket Z */
229  ++arg;
230  dw[1] = atof(argv[arg]) * wdbp->dbip->dbi_local2base;
231 
232  /* drive sprocket radius */
233  ++arg;
234  dw[2] = atof(argv[arg]) * wdbp->dbip->dbi_local2base;
235 
236  if (dw[2] <= 0) {
237  bu_vls_printf(log_str, "Radius <= 0 - STOP\n");
238  edit_result = GED_ERROR;
239  goto end;
240  }
241 
242  /* idler wheel X */
243  ++arg;
244  iw[0] = atof(argv[arg]) * wdbp->dbip->dbi_local2base;
245 
246  if (iw[0] <= fw[0]) {
247  bu_vls_printf(log_str, "IDLER wheel not in the front - STOP \n");
248  edit_result = GED_ERROR;
249  goto end;
250  }
251 
252  /* idler wheel Z */
253  ++arg;
254  iw[1] = atof(argv[arg]) * wdbp->dbip->dbi_local2base;
255 
256  /* idler wheel radius */
257  ++arg;
258  iw[2] = atof(argv[arg]) * wdbp->dbip->dbi_local2base;
259 
260  if (iw[2] <= 0) {
261  bu_vls_printf(log_str, "Radius <= 0 - STOP\n");
262  edit_result = GED_ERROR;
263  goto end;
264  }
265 
266  /* track MIN Y */
267  ++arg;
268  tr[2] = tr[0] = atof(argv[arg]) * wdbp->dbip->dbi_local2base;
269 
270  /* track MAX Y */
271  ++arg;
272  tr[1] = atof(argv[arg]) * wdbp->dbip->dbi_local2base;
273 
274  if (EQUAL(tr[0], tr[1])) {
275  bu_vls_printf(log_str, "MIN == MAX ... STOP\n");
276  edit_result = GED_ERROR;
277  goto end;
278  }
279  if (tr[0] > tr[1]) {
280  bu_vls_printf(log_str, "MIN > MAX .... will switch\n");
281  tr[1] = tr[0];
282  tr[0] = tr[2];
283  }
284 
285  /* track thickness */
286  ++arg;
287  tr[2] = atof(argv[arg]) * wdbp->dbip->dbi_local2base;
288 
289  if (tr[2] <= 0) {
290  bu_vls_printf(log_str, "Track thickness <= 0 - STOP\n");
291  edit_result = GED_ERROR;
292  goto end;
293  }
294 
295  for (i = 0; i < grpname_len; ++i) {
296  solname[i] = grpname[i];
297  regname[i] = grpname[i];
298  }
299 
300  solname[i] = regname[i] = '.';
301  ++i;
302  solname[i] = 's';
303  regname[i] = 'r';
304  ++i;
305  solname[i] = regname[i] = '.';
306  ++i;
307  solname[i] = regname[i] = '\0';
308 /*
309  bu_log("\nX of first road wheel %10.4f\n", fw[0]);
310  bu_log("X of last road wheel %10.4f\n", lw[0]);
311  bu_log("Z of road wheels %10.4f\n", fw[1]);
312  bu_log("radius of road wheels %10.4f\n", fw[2]);
313  bu_log("\nX of drive wheel %10.4f\n", dw[0]);
314  bu_log("Z of drive wheel %10.4f\n", dw[1]);
315  bu_log("radius of drive wheel %10.4f\n", dw[2]);
316  bu_log("\nX of idler wheel %10.4f\n", iw[0]);
317  bu_log("Z of idler wheel %10.4f\n", iw[1]);
318  bu_log("radius of idler wheel %10.4f\n", iw[2]);
319  bu_log("\nY MIN of track %10.4f\n", tr[0]);
320  bu_log("Y MAX of track %10.4f\n", tr[1]);
321  bu_log("thickness of track %10.4f\n", tr[2]);
322 */
323 
324 /* Check for names to use:
325  * grpname.s.0->9 and grpname.r.0->9
326  */
327 
328  for (i = 0; i < 10; i++) {
329  crname(log_str, solname, i, len);
330  crname(log_str, regname, i, len);
331  if ((db_lookup(wdbp->dbip, solname, LOOKUP_QUIET) != RT_DIR_NULL) ||
332  (db_lookup(wdbp->dbip, regname, LOOKUP_QUIET) != RT_DIR_NULL)) {
333  /* name already exists */
334  bu_vls_printf(log_str, "Track: naming error -- STOP\n");
335  edit_result = GED_ERROR;
336  goto end;
337  }
338 
339  solname[grpname_len + extraTypeChars] = '\0';
340  regname[grpname_len + extraTypeChars] = '\0';
341  }
342 
343  /* find the front track slope to the idler */
344  for (i = 0; i < 24; i++)
345  sol.s_values[i] = 0.0;
346 
347  /* add the solids */
348  /* solid 0 */
349  slope(log_str, fw, iw, tr);
350  VMOVE(temp2, &sol.s_values[0]);
351  crname(log_str, solname, 0, len);
352  bu_strlcpy(sol.s_name, solname, len);
353 
354  sol.s_type = ID_ARB8;
355  if (wrobj(log_str, wdbp, solname, RT_DIR_SOLID))
356  return GED_ERROR;
357 
358  solname[grpname_len + extraTypeChars] = '\0';
359 
360  /* solid 1 */
361  /* find track around idler */
362  for (i = 0; i < 24; i++)
363  sol.s_values[i] = 0.0;
364  sol.s_type = ID_TGC;
365  trcurve(iw, tr);
366  crname(log_str, solname, 1, len);
367  bu_strlcpy(sol.s_name, solname, len);
368  if (wrobj(log_str, wdbp, solname, RT_DIR_SOLID))
369  return GED_ERROR;
370  solname[grpname_len + extraTypeChars] = '\0';
371  /* idler dummy rcc */
372  sol.s_values[6] = iw[2];
373  sol.s_values[11] = iw[2];
374  VMOVE(&sol.s_values[12], &sol.s_values[6]);
375  VMOVE(&sol.s_values[15], &sol.s_values[9]);
376  /* solid 2 */
377  crname(log_str, solname, 2, len);
378  bu_strlcpy(sol.s_name, solname, len);
379  if (wrobj(log_str, wdbp, solname, RT_DIR_SOLID))
380  return GED_ERROR;
381  solname[grpname_len + extraTypeChars] = '\0';
382 
383  /* solid 3 */
384  /* find idler track dummy arb8 */
385  for (i = 0; i < 24; i++)
386  sol.s_values[i] = 0.0;
387  crname(log_str, solname, 3, len);
388  bu_strlcpy(sol.s_name, solname, len);
389  sol.s_type = ID_ARB8;
390  crdummy(iw, tr, 1);
391  if (wrobj(log_str, wdbp, solname, RT_DIR_SOLID))
392  return GED_ERROR;
393  solname[grpname_len + extraTypeChars] = '\0';
394 
395  /* solid 4 */
396  /* track slope to drive */
397  for (i = 0; i < 24; i++)
398  sol.s_values[i] = 0.0;
399  slope(log_str, lw, dw, tr);
400  VMOVE(temp1, &sol.s_values[0]);
401  crname(log_str, solname, 4, len);
402  bu_strlcpy(sol.s_name, solname, len);
403  if (wrobj(log_str, wdbp, solname, RT_DIR_SOLID))
404  return GED_ERROR;
405  solname[grpname_len + extraTypeChars] = '\0';
406 
407  /* solid 5 */
408  /* track around drive */
409  for (i = 0; i < 24; i++)
410  sol.s_values[i] = 0.0;
411  sol.s_type = ID_TGC;
412  trcurve(dw, tr);
413  crname(log_str, solname, 5, len);
414  bu_strlcpy(sol.s_name, solname, len);
415  if (wrobj(log_str, wdbp, solname, RT_DIR_SOLID))
416  return GED_ERROR;
417  solname[grpname_len + extraTypeChars] = '\0';
418 
419  /* solid 6 */
420  /* drive dummy rcc */
421  sol.s_values[6] = dw[2];
422  sol.s_values[11] = dw[2];
423  VMOVE(&sol.s_values[12], &sol.s_values[6]);
424  VMOVE(&sol.s_values[15], &sol.s_values[9]);
425  crname(log_str, solname, 6, len);
426  bu_strlcpy(sol.s_name, solname, len);
427  if (wrobj(log_str, wdbp, solname, RT_DIR_SOLID))
428  return GED_ERROR;
429  solname[grpname_len + extraTypeChars] = '\0';
430 
431  /* solid 7 */
432  /* drive dummy arb8 */
433  for (i = 0; i < 24; i++)
434  sol.s_values[i] = 0.0;
435  crname(log_str, solname, 7, len);
436  bu_strlcpy(sol.s_name, solname, len);
437  sol.s_type = ID_ARB8;
438  crdummy(dw, tr, 2);
439  if (wrobj(log_str, wdbp, solname, RT_DIR_SOLID))
440  return GED_ERROR;
441  solname[grpname_len + extraTypeChars] = '\0';
442 
443  /* solid 8 */
444  /* track bottom */
445  temp1[1] = temp2[1] = tr[0];
446  bottom(temp1, temp2, tr);
447  crname(log_str, solname, 8, len);
448  bu_strlcpy(sol.s_name, solname, len);
449  if (wrobj(log_str, wdbp, solname, RT_DIR_SOLID))
450  return GED_ERROR;
451  solname[grpname_len + extraTypeChars] = '\0';
452 
453  /* solid 9 */
454  /* track top */
455  temp1[0] = dw[0];
456  temp1[1] = temp2[1] = tr[0];
457  temp1[2] = dw[1] + dw[2];
458  temp2[0] = iw[0];
459  temp2[2] = iw[1] + iw[2];
460  top(temp1, temp2, tr);
461  crname(log_str, solname, 9, len);
462  bu_strlcpy(sol.s_name, solname, len);
463  if (wrobj(log_str, wdbp, solname, RT_DIR_SOLID))
464  return GED_ERROR;
465  solname[grpname_len + extraTypeChars] = '\0';
466 
467  /* add the regions */
468  /* region 0 */
469  item = item_default;
470  mat = mat_default;
471  los = los_default;
472  item_default = 500;
473  mat_default = 1;
474  los_default = 50;
475  /* region 1 */
476  memb[0] = 0;
477  memb[1] = 3;
478  crname(log_str, regname, 0, len);
479  crregion(log_str, wdbp, regname, oper, memb, 2, solname, len);
480  solname[grpname_len + extraTypeChars] = '\0';
481  regname[grpname_len + extraTypeChars] = '\0';
482 
483  /* region 1 */
484  crname(log_str, regname, 1, len);
485  memb[0] = 1;
486  memb[1] = 2;
487  memb[2] = 3;
488  crregion(log_str, wdbp, regname, oper, memb, 3, solname, len);
489  solname[grpname_len + extraTypeChars] = '\0';
490  regname[grpname_len + extraTypeChars] = '\0';
491 
492  /* region 4 */
493  crname(log_str, regname, 4, len);
494  memb[0] = 4;
495  memb[1] = 7;
496  crregion(log_str, wdbp, regname, oper, memb, 2, solname, len);
497  solname[grpname_len + extraTypeChars] = '\0';
498  regname[grpname_len + extraTypeChars] = '\0';
499 
500  /* region 5 */
501  crname(log_str, regname, 5, len);
502  memb[0] = 5;
503  memb[1] = 6;
504  memb[2] = 7;
505  crregion(log_str, wdbp, regname, oper, memb, 3, solname, len);
506  solname[grpname_len + extraTypeChars] = '\0';
507  regname[grpname_len + extraTypeChars] = '\0';
508 
509  /* region 8 */
510  crname(log_str, regname, 8, len);
511  memb[0] = 8;
512  memb[1] = 0;
513  memb[2] = 4;
514  oper[2] = WMOP_SUBTRACT;
515  crregion(log_str, wdbp, regname, oper, memb, 3, solname, len);
516  solname[grpname_len + extraTypeChars] = '\0';
517  regname[grpname_len + extraTypeChars] = '\0';
518 
519  /* region 9 */
520  crname(log_str, regname, 9, len);
521  memb[0] = 9;
522  memb[1] = 3;
523  memb[2] = 7;
524  crregion(log_str, wdbp, regname, oper, memb, 3, solname, len);
525  solname[grpname_len + extraTypeChars] = '\0';
526  regname[grpname_len + extraTypeChars] = '\0';
527 
528  /* group all the track regions */
529  for (i = 0; i < 10; i++) {
530  if (i == 2 || i == 3 || i == 6 || i == 7)
531  continue;
532  regname[grpname_len + extraTypeChars] = '\0';
533  crname(log_str, regname, i, len);
534  if (db_lookup(wdbp->dbip, regname, LOOKUP_QUIET) == RT_DIR_NULL) {
535  bu_vls_printf(log_str, "group: %s will skip member: %s\n", grpname, regname);
536  continue;
537  }
538  track_mk_addmember(regname, &head, NULL, WMOP_UNION);
539  }
540 
541  /* Add them all at once */
542  if (track_mk_comb(wdbp, grpname, &head,
543  0, NULL, NULL, NULL,
544  0, 0, 0, 0,
545  0, 1, 1) < 0) {
546  bu_vls_printf(log_str, "An error has occurred while adding '%s' to the database.\n", grpname);
547  }
548 
549  Trackpos += 10;
550  item_default = item;
551  mat_default = mat;
552  los_default = los;
553 
554  bu_free((void *)solname, "solid name");
555  bu_free((void *)regname, "region name");
556  bu_free((void *)grpname, "group name");
557  bu_free((void *)sol.s_name, "sol.s_name");
558 
559  return edit_result;
560 
561 end:
562  bu_free((void *)solname, "solid name");
563  bu_free((void *)regname, "region name");
564  bu_free((void *)grpname, "group name");
565  bu_free((void *)sol.s_name, "sol.s_name");
566 
567  return edit_result;
568 }
569 
570 
571 /*
572  *
573  * Adds track given "wheel" info.
574  *
575  */
576 int
577 ged_track(struct ged *gedp, int argc, const char *argv[])
578 {
579  static const char *usage = "basename rX1 rX2 rZ rR dX dZ dR iX iZ iR minX minY th";
580 
583  GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
584 
585  /* initialize result */
586  bu_vls_trunc(gedp->ged_result_str, 0);
587 
588  /* must be wanting help */
589  if (argc == 1) {
590  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
591  return GED_HELP;
592  }
593 
594  if (argc != 15) {
595  bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
596  return GED_ERROR;
597  }
598 
599  return ged_track2(gedp->ged_result_str, gedp->ged_wdbp, argv);
600 }
601 
602 static int
603 wrobj(struct bu_vls *log_str,
604  struct rt_wdb *wdbp,
605  const char name[],
606  int flags)
607 {
608  struct directory *tdp;
609  struct rt_db_internal intern;
610  int i;
611 
612  if (wdbp->dbip == DBI_NULL)
613  return GED_OK;
614 
615  if (db_lookup(wdbp->dbip, name, LOOKUP_QUIET) != RT_DIR_NULL) {
616  bu_vls_printf(log_str, "track naming error: %s already exists\n", name);
617  return -1;
618  }
619 
620  if (flags != RT_DIR_SOLID) {
621  bu_vls_printf(log_str, "wrobj can only write solids, aborting\n");
622  return -1;
623  }
624 
625  RT_DB_INTERNAL_INIT(&intern);
626  switch (sol.s_type) {
627  case ID_ARB8: {
628  struct rt_arb_internal *arb;
629 
630  BU_ALLOC(arb, struct rt_arb_internal);
631 
632  arb->magic = RT_ARB_INTERNAL_MAGIC;
633 
634  VMOVE(arb->pt[0], &sol.s_values[0]);
635  for (i = 1; i < 8; i++)
636  VADD2(arb->pt[i], &sol.s_values[i*3], arb->pt[0]);
637 
638  intern.idb_ptr = (void *)arb;
639  intern.idb_major_type = DB5_MAJORTYPE_BRLCAD;
640  intern.idb_type = ID_ARB8;
641  intern.idb_meth = &OBJ[ID_ARB8];
642  }
643  break;
644  case ID_TGC: {
645  struct rt_tgc_internal *tgc;
646 
647  BU_ALLOC(tgc, struct rt_tgc_internal);
648 
649  tgc->magic = RT_TGC_INTERNAL_MAGIC;
650 
651  VMOVE(tgc->v, &sol.s_values[0]);
652  VMOVE(tgc->h, &sol.s_values[3]);
653  VMOVE(tgc->a, &sol.s_values[6]);
654  VMOVE(tgc->b, &sol.s_values[9]);
655  VMOVE(tgc->c, &sol.s_values[12]);
656  VMOVE(tgc->d, &sol.s_values[15]);
657 
658  intern.idb_ptr = (void *)tgc;
659  intern.idb_major_type = DB5_MAJORTYPE_BRLCAD;
660  intern.idb_type = ID_TGC;
661  intern.idb_meth = &OBJ[ID_TGC];
662  }
663  break;
664  default:
665  bu_vls_printf(log_str, "Unrecognized solid type in 'wrobj', aborting\n");
666  return GED_ERROR;
667  }
668 
669  if ((tdp = db_diradd(wdbp->dbip, name, RT_DIR_PHONY_ADDR, 0, flags, (void *)&intern.idb_type)) == RT_DIR_NULL) {
670  rt_db_free_internal(&intern);
671  bu_vls_printf(log_str, "Cannot add '%s' to directory, aborting\n", name);
672  return GED_ERROR;
673  }
674 
675  if (rt_db_put_internal(tdp, wdbp->dbip, &intern, &rt_uniresource) < 0) {
676  rt_db_free_internal(&intern);
677  bu_vls_printf(log_str, "write error\n");
678  bu_vls_printf(log_str, "The in-memory table of contents may not match the status of the on-disk\ndatabase. The on-disk database should still be intact. For safety, \nyou should exit now, and resolve the I/O problem, before continuing.\n");
679  return GED_ERROR;
680  }
681  return GED_OK;
682 }
683 
684 static void
685 tancir(struct bu_vls *log_str,
686  fastf_t cir1[],
687  fastf_t cir2[]) {
688  static fastf_t mag;
689  vect_t work;
690  fastf_t f;
691  static fastf_t temp, tempp, ang, angc;
692 
693  work[0] = cir2[0] - cir1[0];
694  work[2] = cir2[1] - cir1[1];
695  work[1] = 0.0;
696  mag = MAGNITUDE(work);
697  if (mag > 1.0e-20 || mag < -1.0e-20) {
698  f = 1.0/mag;
699  } else {
700  bu_vls_printf(log_str, "tancir(): 0-length vector!\n");
701  return;
702  }
703  VSCALE(work, work, f);
704  temp = acos(work[0]);
705  if (work[2] < 0.0)
706  temp = 6.28318512717958646 - temp;
707  tempp = acos((cir1[2] - cir2[2]) * f);
708  ang = temp + tempp;
709  angc = temp - tempp;
710  if ((cir1[1] + cir1[2] * sin(ang)) >
711  (cir1[1] + cir1[2] * sin(angc)))
712  ang = angc;
713  plano[0] = cir1[0] + cir1[2] * cos(ang);
714  plano[1] = cir1[1] + cir1[2] * sin(ang);
715  plant[0] = cir2[0] + cir2[2] * cos(ang);
716  plant[1] = cir2[1] + cir2[2] * sin(ang);
717 
718  return;
719 }
720 
721 
722 static void
723 slope(struct bu_vls *log_str,
724  fastf_t wh1[],
725  fastf_t wh2[],
726  fastf_t t[]) {
727  int i, j, switchs;
728  fastf_t temp;
729  fastf_t mag;
730  fastf_t z, r, b;
731  vect_t del, work;
732 
733  switchs = 0;
734  if (wh1[2] < wh2[2]) {
735  switchs++;
736  for (i = 0; i < 3; i++) {
737  temp = wh1[i];
738  wh1[i] = wh2[i];
739  wh2[i] = temp;
740  }
741  }
742  tancir(log_str, wh1, wh2);
743  if (switchs) {
744  for (i = 0; i < 3; i++) {
745  temp = wh1[i];
746  wh1[i] = wh2[i];
747  wh2[i] = temp;
748  }
749  }
750  if (plano[1] <= plant[1]) {
751  for (i = 0; i < 2; i++) {
752  temp = plano[i];
753  plano[i] = plant[i];
754  plant[i] = temp;
755  }
756  }
757  del[1] = 0.0;
758  del[0] = plano[0] - plant[0];
759  del[2] = plano[1] - plant[1];
760  mag = MAGNITUDE(del);
761  work[0] = -1.0 * t[2] * del[2] / mag;
762  if (del[0] < 0.0)
763  work[0] *= -1.0;
764  work[1] = 0.0;
765  work[2] = t[2] * fabs(del[0]) / mag;
766  b = (plano[1] - work[2]) - (del[2]/del[0]*(plano[0] - work[0]));
767  z = wh1[1];
768  r = wh1[2];
769  if (wh1[1] >= wh2[1]) {
770  z = wh2[1];
771  r = wh2[2];
772  }
773  sol.s_values[2] = z - r - t[2];
774  sol.s_values[1] = t[0];
775  sol.s_values[0] = (sol.s_values[2] - b) / (del[2] / del[0]);
776  sol.s_values[3] = plano[0] + (del[0]/mag) - work[0] - sol.s_values[0];
777  sol.s_values[4] = 0.0;
778  sol.s_values[5] = plano[1] + (del[2]/mag) - work[2] - sol.s_values[2];
779  VADD2(&sol.s_values[6], &sol.s_values[3], work);
780  VMOVE(&sol.s_values[9], work);
781  work[0] = work[2] = 0.0;
782  work[1] = t[1] - t[0];
783  VMOVE(&sol.s_values[12], work);
784  for (i = 3; i <= 9; i += 3) {
785  j = i + 12;
786  VADD2(&sol.s_values[j], &sol.s_values[i], work);
787  }
788 
789  return;
790 }
791 
792 
793 static void
794 crdummy(fastf_t w[3], fastf_t t[3], int flag)
795 {
796  fastf_t temp;
797  vect_t vec;
798  int i, j;
799 
800  vec[1] = 0.0;
801  if (plano[1] <= plant[1]) {
802  for (i = 0; i < 2; i++) {
803  temp = plano[i];
804  plano[i] = plant[i];
805  plant[i] = temp;
806  }
807  }
808 
809  vec[0] = w[2] + t[2] + 1.0;
810  vec[2] = ((plano[1] - w[1]) * vec[0]) / (plano[0] - w[0]);
811  if (flag > 1)
812  vec[0] *= -1.0;
813  if (vec[2] >= 0.0)
814  vec[2] *= -1.0;
815  sol.s_values[0] = w[0];
816  sol.s_values[1] = t[0] -1.0;
817  sol.s_values[2] = w[1];
818  VMOVE(&sol.s_values[3], vec);
819  vec[2] = w[2] + t[2] + 1.0;
820  VMOVE(&sol.s_values[6], vec);
821  vec[0] = 0.0;
822  VMOVE(&sol.s_values[9], vec);
823  vec[2] = 0.0;
824  vec[1] = t[1] - t[0] + 2.0;
825  VMOVE(&sol.s_values[12], vec);
826  for (i = 3; i <=9; i += 3) {
827  j = i + 12;
828  VADD2(&sol.s_values[j], &sol.s_values[i], vec);
829  }
830 
831  return;
832 
833 }
834 
835 
836 static void
837 trcurve(fastf_t wh[], fastf_t t[])
838 {
839  sol.s_values[0] = wh[0];
840  sol.s_values[1] = t[0];
841  sol.s_values[2] = wh[1];
842  sol.s_values[4] = t[1] - t[0];
843  sol.s_values[6] = wh[2] + t[2];
844  sol.s_values[11] = wh[2] + t[2];
845  VMOVE(&sol.s_values[12], &sol.s_values[6]);
846  VMOVE(&sol.s_values[15], &sol.s_values[9]);
847 }
848 
849 
850 static void
851 bottom(vect_t vec1, vect_t vec2, fastf_t t[])
852 {
853  vect_t tvec;
854  int i, j;
855 
856  VMOVE(&sol.s_values[0], vec1);
857  tvec[0] = vec2[0] - vec1[0];
858  tvec[1] = tvec[2] = 0.0;
859  VMOVE(&sol.s_values[3], tvec);
860  tvec[0] = tvec[1] = 0.0;
861  tvec[2] = t[2];
862  VADD2(&sol.s_values[6], &sol.s_values[3], tvec);
863  VMOVE(&sol.s_values[9], tvec);
864  tvec[0] = tvec[2] = 0.0;
865  tvec[1] = t[1] - t[0];
866  VMOVE(&sol.s_values[12], tvec);
867 
868  for (i = 3; i <=9; i += 3) {
869  j = i + 12;
870  VADD2(&sol.s_values[j], &sol.s_values[i], tvec);
871  }
872 }
873 
874 
875 static void
876 top(vect_t vec1, vect_t vec2, fastf_t t[])
877 {
878  fastf_t tooch, mag;
879  vect_t del, tvec;
880  int i, j;
881 
882  tooch = t[2] * .25;
883  del[0] = vec2[0] - vec1[0];
884  del[1] = 0.0;
885  del[2] = vec2[2] - vec1[2];
886  mag = MAGNITUDE(del);
887  VSCALE(tvec, del, tooch/mag);
888  VSUB2(&sol.s_values[0], vec1, tvec);
889  VADD2(del, del, tvec);
890  VADD2(&sol.s_values[3], del, tvec);
891  tvec[0] = tvec[2] = 0.0;
892  tvec[1] = t[1] - t[0];
893  VCROSS(del, tvec, &sol.s_values[3]);
894  mag = MAGNITUDE(del);
895  if (del[2] < 0)
896  mag *= -1.0;
897  VSCALE(&sol.s_values[9], del, t[2]/mag);
898  VADD2(&sol.s_values[6], &sol.s_values[3], &sol.s_values[9]);
899  VMOVE(&sol.s_values[12], tvec);
900 
901  for (i = 3; i <= 9; i += 3) {
902  j = i + 12;
903  VADD2(&sol.s_values[j], &sol.s_values[i], tvec);
904  }
905 }
906 
907 
908 /*
909  * The following functions were pulled in from libwdb
910  * to prevent creating a new dependency.
911  */
912 
913 /*
914  * Given a list of wmember structures, build a tree that performs
915  * the boolean operations in the given sequence.
916  * No GIFT semantics or precedence is provided.
917  * For that, use mk_tree_gift().
918  */
919 static void
920 track_mk_tree_pure(struct rt_comb_internal *comb, struct bu_list *member_hd)
921 {
922  struct wmember *wp;
923 
924  for (BU_LIST_FOR(wp, wmember, member_hd)) {
925  union tree *leafp, *nodep;
926 
927  WDB_CK_WMEMBER(wp);
928 
929  BU_ALLOC(leafp, union tree);
930  RT_TREE_INIT(leafp);
931  leafp->tr_l.tl_op = OP_DB_LEAF;
932  leafp->tr_l.tl_name = bu_strdup(wp->wm_name);
933  if (!bn_mat_is_identity(wp->wm_mat)) {
934  leafp->tr_l.tl_mat = bn_mat_dup(wp->wm_mat);
935  }
936 
937  if (!comb->tree) {
938  comb->tree = leafp;
939  continue;
940  }
941  /* Build a left-heavy tree */
942  BU_ALLOC(nodep, union tree);
943  RT_TREE_INIT(nodep);
944  switch (wp->wm_op) {
945  case WMOP_UNION:
946  nodep->tr_b.tb_op = OP_UNION;
947  break;
948  case WMOP_INTERSECT:
949  nodep->tr_b.tb_op = OP_INTERSECT;
950  break;
951  case WMOP_SUBTRACT:
952  nodep->tr_b.tb_op = OP_SUBTRACT;
953  break;
954  default:
955  bu_bomb("track_mk_tree_pure() bad wm_op");
956  }
957  nodep->tr_b.tb_left = comb->tree;
958  nodep->tr_b.tb_right = leafp;
959  comb->tree = nodep;
960  }
961 }
962 
963 
964 /*
965  * Add some nodes to a new or existing combination's tree,
966  * with GIFT precedence and semantics.
967  *
968  * NON-PARALLEL due to rt_uniresource
969  *
970  * Returns -
971  * -1 ERROR
972  * 0 OK
973  */
974 static int
975 track_mk_tree_gift(struct rt_comb_internal *comb, struct bu_list *member_hd)
976 {
977  struct wmember *wp;
978  union tree *tp;
979  struct rt_tree_array *tree_list;
980  size_t node_count;
981  size_t actual_count;
982  int new_nodes;
983 
984  if ((new_nodes = bu_list_len(member_hd)) <= 0)
985  return 0; /* OK, nothing to do */
986 
987  if (comb->tree && db_ck_v4gift_tree(comb->tree) < 0) {
989  if (db_ck_v4gift_tree(comb->tree) < 0) {
990  bu_log("track_mk_tree_gift() Cannot flatten tree for editing\n");
991  return -1;
992  }
993  }
994 
995  /* make space for an extra leaf */
996  node_count = db_tree_nleaves(comb->tree);
997  tree_list = (struct rt_tree_array *)bu_calloc(node_count + (size_t)new_nodes, sizeof(struct rt_tree_array), "tree list");
998 
999  /* flatten tree */
1000  if (comb->tree) {
1001  /* Release storage for non-leaf nodes, steal leaves */
1002  actual_count = (struct rt_tree_array *)db_flatten_tree(
1003  tree_list, comb->tree, OP_UNION,
1004  1, &rt_uniresource) - tree_list;
1005  BU_ASSERT_SIZE_T(actual_count, ==, node_count);
1006  comb->tree = TREE_NULL;
1007  } else {
1008  actual_count = 0;
1009  }
1010 
1011  /* Add new members to the array */
1012  for (BU_LIST_FOR(wp, wmember, member_hd)) {
1013  WDB_CK_WMEMBER(wp);
1014 
1015  switch (wp->wm_op) {
1016  case WMOP_INTERSECT:
1017  tree_list[node_count].tl_op = OP_INTERSECT;
1018  break;
1019  case WMOP_SUBTRACT:
1020  tree_list[node_count].tl_op = OP_SUBTRACT;
1021  break;
1022  default:
1023  bu_log("track_mk_tree_gift() unrecognized relation %c (assuming UNION)\n", wp->wm_op);
1024  /* Fall through */
1025  case WMOP_UNION:
1026  tree_list[node_count].tl_op = OP_UNION;
1027  break;
1028  }
1029 
1030  /* make new leaf node, and insert at end of array */
1031  BU_ALLOC(tp, union tree);
1032  RT_TREE_INIT(tp);
1033  tree_list[node_count++].tl_tree = tp;
1034  tp->tr_l.tl_op = OP_DB_LEAF;
1035  tp->tr_l.tl_name = bu_strdup(wp->wm_name);
1036  if (!bn_mat_is_identity(wp->wm_mat)) {
1037  tp->tr_l.tl_mat = bn_mat_dup(wp->wm_mat);
1038  } else {
1039  tp->tr_l.tl_mat = (matp_t)NULL;
1040  }
1041  }
1042  BU_ASSERT_SIZE_T(node_count, ==, actual_count + (size_t)new_nodes);
1043 
1044  /* rebuild the tree with GIFT semantics */
1045  comb->tree = (union tree *)db_mkgift_tree(tree_list, node_count, &rt_uniresource);
1046 
1047  bu_free((char *)tree_list, "track_mk_tree_gift: tree_list");
1048 
1049  return 0; /* OK */
1050 }
1051 
1052 
1053 /*
1054  * Obtain dynamic storage for a new wmember structure, fill in the
1055  * name, default the operation and matrix, and add to doubly linked
1056  * list. In typical use, a one-line call is sufficient. To change
1057  * the defaults, catch the pointer that is returned, and adjust the
1058  * structure to taste.
1059  *
1060  * The caller is responsible for initializing the header structures
1061  * forward and backward links.
1062  */
1063 static struct wmember *
1064 track_mk_addmember(
1065  const char *name,
1066  struct bu_list *headp,
1067  mat_t mat,
1068  int op)
1069 {
1070  struct wmember *wp;
1071 
1072  BU_GET(wp, struct wmember);
1073  wp->l.magic = WMEMBER_MAGIC;
1074  wp->wm_name = bu_strdup(name);
1075  switch (op) {
1076  case WMOP_UNION:
1077  case WMOP_INTERSECT:
1078  case WMOP_SUBTRACT:
1079  wp->wm_op = op;
1080  break;
1081  default:
1082  bu_log("mk_addmember() op=x%x is bad\n", op);
1083  return WMEMBER_NULL;
1084  }
1085 
1086  /* if the user gave a matrix, use it. otherwise use identity matrix*/
1087  if (mat) {
1088  MAT_COPY(wp->wm_mat, mat);
1089  } else {
1090  MAT_IDN(wp->wm_mat);
1091  }
1092 
1093  /* Append to end of doubly linked list */
1094  BU_LIST_INSERT(headp, &wp->l);
1095  return wp;
1096 }
1097 
1098 
1099 static void
1100 track_mk_freemembers(struct bu_list *headp)
1101 {
1102  struct wmember *wp;
1103 
1104  while (BU_LIST_WHILE(wp, wmember, headp)) {
1105  WDB_CK_WMEMBER(wp);
1106  BU_LIST_DEQUEUE(&wp->l);
1107  bu_free((char *)wp->wm_name, "wm_name");
1108  BU_PUT(wp, struct wmember);
1109  }
1110 }
1111 
1112 
1113 /*
1114  * Make a combination, where the
1115  * members are described by a linked list of wmember structs.
1116  *
1117  * The linked list is freed when it has been output.
1118  *
1119  * Has many operating modes.
1120  *
1121  * Returns -
1122  * -1 ERROR
1123  * 0 OK
1124  */
1125 static int
1126 track_mk_comb(
1127  struct rt_wdb *wdbp,
1128  const char *combname,
1129  struct bu_list *headp, /* Made by mk_addmember() */
1130  int region_kind, /* 1 => region. 'P' and 'V' for FASTGEN */
1131  const char *shadername, /* shader name, or NULL */
1132  const char *shaderargs, /* shader args, or NULL */
1133  const unsigned char *rgb, /* NULL => no color */
1134  int id, /* region_id */
1135  int air, /* aircode */
1136  int material, /* GIFTmater */
1137  int los,
1138  int inherit,
1139  int append_ok, /* 0 = obj must not exit */
1140  int gift_semantics) /* 0 = pure, 1 = gift */
1141 {
1142  struct rt_db_internal intern;
1143  struct rt_comb_internal *comb;
1144  int fresh_combination;
1145 
1146  RT_CK_WDB(wdbp);
1147 
1148  RT_DB_INTERNAL_INIT(&intern);
1149 
1150  if (append_ok &&
1151  wdb_import(wdbp, &intern, combname, (matp_t)NULL) >= 0) {
1152  /* We retrieved an existing object, append to it */
1153  comb = (struct rt_comb_internal *)intern.idb_ptr;
1154  RT_CK_COMB(comb);
1155 
1156  fresh_combination = 0;
1157  } else {
1158  /* Create a fresh new object for export */
1159  BU_ALLOC(comb, struct rt_comb_internal);
1160  RT_COMB_INTERNAL_INIT(comb);
1161 
1162  intern.idb_major_type = DB5_MAJORTYPE_BRLCAD;
1163  intern.idb_type = ID_COMBINATION;
1164  intern.idb_ptr = (void *)comb;
1165  intern.idb_meth = &OBJ[ID_COMBINATION];
1166 
1167  fresh_combination = 1;
1168  }
1169 
1170  if (gift_semantics)
1171  track_mk_tree_gift(comb, headp);
1172  else
1173  track_mk_tree_pure(comb, headp);
1174 
1175  /* Release the wmember list dynamic storage */
1176  track_mk_freemembers(headp);
1177 
1178  /* Don't change these things when appending to existing combination */
1179  if (fresh_combination) {
1180  if (region_kind) {
1181  comb->region_flag = 1;
1182  switch (region_kind) {
1183  case 'P':
1185  break;
1186  case 'V':
1188  break;
1189  case 'R':
1190  case 1:
1191  /* Regular non-FASTGEN Region */
1192  break;
1193  default:
1194  bu_log("mk_comb(%s) unknown region_kind=%d (%c), assuming normal non-FASTGEN\n",
1195  combname, region_kind, region_kind);
1196  }
1197  }
1198  if (shadername) bu_vls_strcat(&comb->shader, shadername);
1199  if (shaderargs) {
1200  bu_vls_strcat(&comb->shader, " ");
1201  bu_vls_strcat(&comb->shader, shaderargs);
1202  /* Convert to Tcl form if necessary. Use heuristics */
1203  if (strchr(shaderargs, '=') != NULL &&
1204  strchr(shaderargs, '{') == NULL)
1205  {
1206  struct bu_vls old = BU_VLS_INIT_ZERO;
1207  bu_vls_vlscatzap(&old, &comb->shader);
1208  if (bu_shader_to_list(bu_vls_addr(&old), &comb->shader))
1209  bu_log("Unable to convert shader string '%s %s'\n", shadername, shaderargs);
1210  bu_vls_free(&old);
1211  }
1212  }
1213 
1214  if (rgb) {
1215  comb->rgb_valid = 1;
1216  comb->rgb[0] = rgb[0];
1217  comb->rgb[1] = rgb[1];
1218  comb->rgb[2] = rgb[2];
1219  }
1220 
1221  comb->region_id = id;
1222  comb->aircode = air;
1223  comb->GIFTmater = material;
1224  comb->los = los;
1225 
1226  comb->inherit = inherit;
1227  }
1228 
1229  /* The internal representation will be freed */
1230  return wdb_put_internal(wdbp, combname, &intern, 1.0);
1231 }
1232 
1233 
1234 /*
1235  * Local Variables:
1236  * mode: C
1237  * tab-width: 8
1238  * indent-tabs-mode: t
1239  * c-file-style: "stroustrup"
1240  * End:
1241  * ex: shiftwidth=4 tabstop=8
1242  */
HIDDEN int sign(double val)
Definition: brep.cpp:1145
void usage(struct ged *gedp)
Definition: coil.c:315
#define GED_OK
Definition: ged.h:55
#define RT_TGC_INTERNAL_MAGIC
Definition: magic.h:111
#define BU_LIST_FOR(p, structure, hp)
Definition: list.h:365
void bu_log(const char *,...) _BU_ATTR_PRINTF12
Definition: log.c:176
#define BU_LIST_INSERT(old, new)
Definition: list.h:183
#define WDB_CK_WMEMBER(_p)
Definition: wdb.h:74
int bn_mat_is_identity(const mat_t m)
Definition: mat.c:980
int bu_shader_to_list(const char *in, struct bu_vls *vls)
Definition: parse.c:1933
char region_flag
!0 ==> this COMB is a REGION
Definition: raytrace.h:939
Definition: list.h:118
#define REGION_FASTGEN_PLATE
Definition: raytrace.h:554
int rt_db_put_internal(struct directory *dp, struct db_i *dbip, struct rt_db_internal *ip, struct resource *resp)
Definition: dir.c:136
int tb_op
non-leaf
Definition: raytrace.h:1147
size_t db_tree_nleaves(const union tree *tp)
Definition: db_comb.c:99
Definition: ged.h:338
struct db_i * dbip
Definition: raytrace.h:1266
#define ID_ARB8
Generalized ARB. V + 7 vectors.
Definition: raytrace.h:462
if lu s
Definition: nmg_mod.c:3860
Definition: clone.c:90
void bu_vls_strcat(struct bu_vls *vp, const char *s)
Definition: vls.c:368
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
#define RT_CK_COMB(_p)
Definition: raytrace.h:955
union tree * tl_tree
Definition: raytrace.h:1247
struct rt_wdb * ged_wdbp
Definition: ged.h:340
Definition: wdb.h:64
Header file for the BRL-CAD common definitions.
#define WMOP_SUBTRACT
Definition: wdb.h:886
static void crdummy()
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 WMOP_UNION
Definition: wdb.h:887
#define ID_COMBINATION
Combination Record.
Definition: raytrace.h:499
struct bu_list l
Definition: wdb.h:65
#define GED_ERROR
Definition: ged.h:61
#define RT_TREE_INIT(_p)
Definition: raytrace.h:1189
int wdb_put_internal(struct rt_wdb *wdbp, const char *name, struct rt_db_internal *ip, double local2mm)
Definition: wdb.c:218
union tree * tb_left
Definition: raytrace.h:1149
void * bu_malloc(size_t siz, const char *str)
Definition: malloc.c:314
#define RT_CK_WDB(_p)
Definition: raytrace.h:1292
Definition: sh_grass.c:82
struct rt_tree_array * db_flatten_tree(struct rt_tree_array *rt_tree_array, union tree *tp, int op, int avail, struct resource *resp)
Definition: db_comb.c:138
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
void db_non_union_push(union tree *tp, struct resource *resp)
Definition: db_tree.c:1426
#define WMEMBER_NULL
Definition: wdb.h:73
#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
int ged_track2(struct bu_vls *log_str, struct rt_wdb *wdbp, const char *argv[])
Definition: track.c:161
#define GED_CHECK_DATABASE_OPEN(_gedp, _flags)
Definition: ged.h:114
#define WMOP_INTERSECT
Definition: wdb.h:885
#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_DIR_SOLID
this name is a solid
Definition: raytrace.h:883
#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
#define TREE_NULL
Definition: raytrace.h:1181
static void top()
#define BU_GET(_ptr, _type)
Definition: malloc.h:201
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
#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 ged_track(struct ged *gedp, int argc, const char *argv[])
Definition: track.c:577
#define BU_PUT(_ptr, _type)
Definition: malloc.h:215
char * wm_name
Definition: wdb.h:68
char * bu_vls_addr(const struct bu_vls *vp)
Definition: vls.c:111
struct bu_vls * ged_result_str
Definition: ged.h:357
uint32_t magic
Magic # for mem id/check.
Definition: list.h:119
#define BU_LIST_WHILE(p, structure, hp)
Definition: list.h:410
int wm_op
Boolean operation.
Definition: wdb.h:66
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
union tree * tb_right
Definition: raytrace.h:1150
#define BU_LIST_INIT(_hp)
Definition: list.h:148
const struct rt_functab OBJ[]
Definition: table.c:159
#define WMEMBER_MAGIC
Definition: magic.h:215
#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
int wdb_import(struct rt_wdb *wdbp, struct rt_db_internal *internp, const char *name, const mat_t mat)
Definition: wdb.c:92
int bu_list_len(const struct bu_list *hd)
#define GED_HELP
Definition: ged.h:62
char is_fastgen
REGION_NON_FASTGEN/_PLATE/_VOLUME.
Definition: raytrace.h:940
#define BU_ASSERT_SIZE_T(_lhs, _relation, _rhs)
Definition: defines.h:253
void bu_free(void *ptr, const char *str)
Definition: malloc.c:328
char rgb_valid
!0 ==> rgb[] has valid color
Definition: raytrace.h:947
double dbi_local2base
local2mm
Definition: raytrace.h:807
#define BU_VLS_INIT_ZERO
Definition: vls.h:84
int tl_op
leaf, OP_DB_LEAF
Definition: raytrace.h:1172
#define BU_LIST_DEQUEUE(cur)
Definition: list.h:209
mat_t wm_mat
FIXME: Should be a matp_t.
Definition: wdb.h:67
#define ID_TGC
Generalized Truncated General Cone.
Definition: raytrace.h:460
#define GED_CHECK_READ_ONLY(_gedp, _flags)
Definition: ged.h:181
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_ck_v4gift_tree(const union tree *tp)
Definition: db_comb.c:927
#define RT_ARB_INTERNAL_MAGIC
Definition: magic.h:82
void rt_db_free_internal(struct rt_db_internal *ip)
Definition: dir.c:216
static void trcurve()
void bu_vls_vlscatzap(struct bu_vls *dest, struct bu_vls *src)
Definition: vls.c:433
#define bu_strlcat(dst, src, size)
Definition: str.h:50
#define bu_strdup(s)
Definition: str.h:71