BRL-CAD
tcl.c
Go to the documentation of this file.
1 /* T C L . C
2  * BRL-CAD
3  *
4  * Copyright (c) 1997-2014 United States Government as represented by
5  * the U.S. Army Research Laboratory.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * version 2.1 as published by the Free Software Foundation.
10  *
11  * This library is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this file; see the file named COPYING for more
18  * information.
19  */
20 
21 
22 #include "common.h"
23 
24 #include <stdlib.h>
25 #include <ctype.h>
26 #include <math.h>
27 #include <string.h>
28 #include "bio.h"
29 
30 #include "tcl.h"
31 
32 
33 #include "bu/parallel.h"
34 #include "vmath.h"
35 #include "bn.h"
36 #include "rtgeom.h"
37 #include "raytrace.h"
38 
39 /* private headers */
40 #include "brlcad_version.h"
41 
42 #define RT_FUNC_TCL_CAST(_func) ((int (*)(ClientData clientData, Tcl_Interp *interp, int argc, const char *const *argv))_func)
43 
44 static int rt_tcl_rt_shootray(ClientData clientData, Tcl_Interp *interp, int argc, const char *const *argv);
45 static int rt_tcl_rt_onehit(ClientData clientData, Tcl_Interp *interp, int argc, const char *const *argv);
46 static int rt_tcl_rt_no_bool(ClientData clientData, Tcl_Interp *interp, int argc, const char *const *argv);
47 static int rt_tcl_rt_check(ClientData clientData, Tcl_Interp *interp, int argc, const char *const *argv);
48 static int rt_tcl_rt_prep(ClientData clientData, Tcl_Interp *interp, int argc, const char *const *argv);
49 static int rt_tcl_rt_cutter(ClientData clientData, Tcl_Interp *interp, int argc, const char *const*argv);
50 static int rt_tcl_rt_set(ClientData clientData, Tcl_Interp *interp, int argc, const char *const*argv);
51 
52 
53 /************************************************************************
54  * *
55  * Tcl interface to Ray-tracing *
56  * *
57  ************************************************************************/
58 
59 struct dbcmdstruct {
60  char *cmdname;
61  int (*cmdfunc)(ClientData clientData, Tcl_Interp *interp, int argc, const char *const *argv);
62 };
63 
64 
65 static struct dbcmdstruct rt_tcl_rt_cmds[] = {
66  {"shootray", RT_FUNC_TCL_CAST(rt_tcl_rt_shootray)},
67  {"onehit", RT_FUNC_TCL_CAST(rt_tcl_rt_onehit)},
68  {"no_bool", RT_FUNC_TCL_CAST(rt_tcl_rt_no_bool)},
69  {"check", RT_FUNC_TCL_CAST(rt_tcl_rt_check)},
70  {"prep", RT_FUNC_TCL_CAST(rt_tcl_rt_prep)},
71  {"cutter", RT_FUNC_TCL_CAST(rt_tcl_rt_cutter)},
72  {"set", RT_FUNC_TCL_CAST(rt_tcl_rt_set)},
73  {(char *)0, RT_FUNC_TCL_CAST(0)}
74 };
75 
76 
77 int
78 rt_tcl_parse_ray(Tcl_Interp *interp, struct xray *rp, const char *const*argv)
79 {
80  if (bn_decode_vect(rp->r_pt, argv[0]) != 3) {
81  Tcl_AppendResult(interp,
82  "badly formatted point: ", argv[0], (char *)NULL);
83  return TCL_ERROR;
84  }
85  if (bn_decode_vect(rp->r_dir, argv[2]) != 3) {
86  Tcl_AppendResult(interp,
87  "badly formatted vector: ", argv[2], (char *)NULL);
88  return TCL_ERROR;
89  }
90  switch (argv[1][0]) {
91  case 'd':
92  /* [2] is direction vector */
93  break;
94  case 'a':
95  /* [2] is target point, build a vector from start pt */
96  VSUB2(rp->r_dir, rp->r_dir, rp->r_pt);
97  break;
98  default:
99  Tcl_AppendResult(interp,
100  "wrong ray keyword: '", argv[1],
101  "', should be one of 'dir' or 'at'",
102  (char *)NULL);
103  return TCL_ERROR;
104  }
105  VUNITIZE(rp->r_dir);
106  return TCL_OK;
107 }
108 
109 
110 void
111 rt_tcl_pr_cutter(Tcl_Interp *interp, const union cutter *cutp)
112 {
113  static const char xyz[4] = "XYZ";
114  struct bu_vls str = BU_VLS_INIT_ZERO;
115  size_t i;
116 
117  switch (cutp->cut_type) {
118  case CUT_CUTNODE:
119  bu_vls_printf(&str,
120  "type cutnode axis %c point %.25G",
121  xyz[cutp->cn.cn_axis], cutp->cn.cn_point);
122  break;
123  case CUT_BOXNODE:
124  bu_vls_printf(&str,
125  "type boxnode min {%.25G %.25G %.25G}",
126  V3ARGS(cutp->bn.bn_min));
127  bu_vls_printf(&str,
128  " max {%.25G %.25G %.25G}",
129  V3ARGS(cutp->bn.bn_max));
130  bu_vls_printf(&str, " solids {");
131  for (i=0; i < cutp->bn.bn_len; i++) {
132  bu_vls_strcat(&str, cutp->bn.bn_list[i]->st_name);
133  bu_vls_putc(&str, ' ');
134  }
135  bu_vls_printf(&str, "} pieces {");
136  for (i = 0; i < cutp->bn.bn_piecelen; i++) {
137  struct rt_piecelist *plp = &cutp->bn.bn_piecelist[i];
138  size_t j;
139  RT_CK_PIECELIST(plp);
140  /* These can be taken by user positionally */
141  bu_vls_printf(&str, "{%s {", plp->stp->st_name);
142  for (j=0; j < plp->npieces; j++) {
143  bu_vls_printf(&str, "%ld ", plp->pieces[j]);
144  }
145  bu_vls_strcat(&str, "} } ");
146  }
147  bu_vls_strcat(&str, "}");
148  break;
149  case CUT_NUGRIDNODE:
150  bu_vls_printf(&str, "type nugridnode");
151  for (i = 0; i < 3; i++) {
152  bu_vls_printf(&str, " %c {", xyz[i]);
153  bu_vls_printf(&str, "spos %.25G epos %.25G width %.25g",
154  cutp->nugn.nu_axis[i]->nu_spos,
155  cutp->nugn.nu_axis[i]->nu_epos,
156  cutp->nugn.nu_axis[i]->nu_width);
157  bu_vls_printf(&str, " cells_per_axis %d",
158  cutp->nugn.nu_cells_per_axis[i]);
159  bu_vls_printf(&str, " stepsize %d}",
160  cutp->nugn.nu_stepsize[i]);
161  }
162  break;
163  default:
164  bu_vls_printf(&str, "rt_tcl_pr_cutter() bad pointer cutp=%p",
165  (void *)cutp);
166  break;
167  }
168  Tcl_AppendResult(interp, bu_vls_addr(&str), (char *)NULL);
169  bu_vls_free(&str);
170 }
171 
172 
173 /**
174  * Obtain the 'n'th space partitioning cell along the given ray, and
175  * return that to the user.
176  *
177  * Example -
178  * .rt cutter 7 {0 0 0} dir {0 0 -1}
179  */
180 static int
181 rt_tcl_rt_cutter(ClientData clientData, Tcl_Interp *interp, int argc, const char *const*argv)
182 {
183  struct application *ap = (struct application *)clientData;
184  struct rt_i *rtip;
185  const union cutter *cutp;
186  int n;
187 
188  if (argc != 6) {
189  Tcl_AppendResult(interp,
190  "wrong # args: should be \"",
191  argv[0], " ", argv[1], "cutnum {P} dir|at {V}\"",
192  (char *)NULL);
193  return TCL_ERROR;
194  }
195 
196  RT_CK_APPLICATION(ap);
197  rtip = ap->a_rt_i;
198  RT_CK_RTI(rtip);
199 
200  n = atoi(argv[2]);
201  if (rt_tcl_parse_ray(interp, &ap->a_ray, &argv[3]) == TCL_ERROR)
202  return TCL_ERROR;
203 
204  cutp = rt_cell_n_on_ray(ap, n);
205  if (cutp == CUTTER_NULL) {
206  Tcl_AppendResult(interp, "rt_cell_n_on_ray() failed to find cell ", argv[2], (char *)NULL);
207  return TCL_ERROR;
208  }
209  rt_tcl_pr_cutter(interp, cutp);
210  return TCL_OK;
211 }
212 
213 
214 void
215 rt_tcl_pr_hit(Tcl_Interp *interp, struct hit *hitp, const struct seg *segp, int flipflag)
216 {
217  struct bu_vls str = BU_VLS_INIT_ZERO;
218  vect_t norm;
219  struct soltab *stp;
220  const struct directory *dp;
221  struct curvature crv = {{0.0, 0.0, 0.0}, 0.0, 0.0};
222 
223  RT_CK_SEG(segp);
224  stp = segp->seg_stp;
225  RT_CK_SOLTAB(stp);
226  dp = stp->st_dp;
227  RT_CK_DIR(dp);
228 
229  RT_HIT_NORMAL(norm, hitp, stp, rayp, flipflag);
230  RT_CURVATURE(&crv, hitp, flipflag, stp);
231 
232  bu_vls_printf(&str, " {dist %g point {", hitp->hit_dist);
233  bn_encode_vect(&str, hitp->hit_point);
234  bu_vls_printf(&str, "} normal {");
235  bn_encode_vect(&str, norm);
236  bu_vls_printf(&str, "} c1 %g c2 %g pdir {",
237  crv.crv_c1, crv.crv_c2);
238  bn_encode_vect(&str, crv.crv_pdir);
239  bu_vls_printf(&str, "} surfno %d", hitp->hit_surfno);
240  if (stp->st_path.magic == DB_FULL_PATH_MAGIC) {
241  /* Magic is left 0 if the path is not filled in. */
242  char *sofar = db_path_to_string(&stp->st_path);
243  bu_vls_printf(&str, " path ");
244  bu_vls_strcat(&str, sofar);
245  bu_free((void *)sofar, "path string");
246  }
247  bu_vls_printf(&str, " solid %s}", dp->d_namep);
248 
249  Tcl_AppendResult(interp, bu_vls_addr(&str), (char *)NULL);
250  bu_vls_free(&str);
251 }
252 
253 
254 int
256  struct partition *PartHeadp,
257  struct seg *UNUSED(segHeadp))
258 {
259  Tcl_Interp *interp = (Tcl_Interp *)ap->a_uptr;
260  register struct partition *pp;
261 
262  RT_CK_PT_HD(PartHeadp);
263 
264  for (pp=PartHeadp->pt_forw; pp != PartHeadp; pp = pp->pt_forw) {
265  RT_CK_PT(pp);
266  Tcl_AppendResult(interp, "{in", (char *)NULL);
267  rt_tcl_pr_hit(interp, pp->pt_inhit, pp->pt_inseg, pp->pt_inflip);
268  Tcl_AppendResult(interp, "\nout", (char *)NULL);
269  rt_tcl_pr_hit(interp, pp->pt_outhit, pp->pt_outseg, pp->pt_outflip);
270  Tcl_AppendResult(interp,
271  "\nregion ",
272  pp->pt_regionp->reg_name,
273  (char *)NULL);
274  Tcl_AppendResult(interp, "}\n", (char *)NULL);
275  }
276 
277  return 1;
278 }
279 
280 
281 int
283 {
284  if (ap) RT_CK_APPLICATION(ap);
285  return 0;
286 }
287 
288 
289 /**
290  * Usage -
291  * procname shootray [-R] {P} dir|at {V}
292  * -R option specifies no overlap reporting
293  *
294  * Example -
295  * set glob_compat_mode 0
296  * .inmem rt_gettrees .rt all.g
297  * .rt shootray -R {0 0 0} dir {0 0 -1}
298  *
299  * set tgt [bu_get_value_by_keyword V [concat type [.inmem get LIGHT]]]
300  * .rt shootray {20 -13.5 20} at $tgt
301  *
302  *
303  * Returns -
304  * This "shootray" operation returns a nested set of lists. It
305  * returns a list of zero or more partitions. Inside each
306  * partition is a list containing an in, out, and region keyword,
307  * each with an associated value. The associated value for each
308  * "inhit" and "outhit" is itself a list containing a dist,
309  * point, normal, surfno, and solid keyword, each with an
310  * associated value.
311  */
312 static int
313 rt_tcl_rt_shootray(ClientData clientData, Tcl_Interp *interp, int argc, const char *const *argv)
314 {
315  struct application *ap = (struct application *)clientData;
316  struct rt_i *rtip;
317  int idx;
318 
319  if ((argc != 5 && argc != 6) || (argc == 6 && !BU_STR_EQUAL(argv[2], "-R"))) {
320  Tcl_AppendResult(interp,
321  "wrong # args: should be \"",
322  argv[0], " ", argv[1], " [-R] {P} dir|at {V}\"",
323  (char *)NULL);
324  return TCL_ERROR;
325  }
326 
327  if (argc == 6) {
329  idx = 3;
330  } else {
331  idx = 2;
332  }
333 
334  RT_CK_APPLICATION(ap);
335  rtip = ap->a_rt_i;
336  RT_CK_RTI(rtip);
337 
338  if (rt_tcl_parse_ray(interp, &ap->a_ray, &argv[idx]) == TCL_ERROR)
339  return TCL_ERROR;
340  ap->a_hit = rt_tcl_a_hit;
341  ap->a_miss = rt_tcl_a_miss;
342  ap->a_uptr = (void *)interp;
343 
344  (void)rt_shootray(ap);
345 
346  return TCL_OK;
347 }
348 
349 
350 /**
351  * Usage -
352  * procname onehit
353  * procname onehit #
354  */
355 static int
356 rt_tcl_rt_onehit(ClientData clientData, Tcl_Interp *interp, int argc, const char *const *argv)
357 {
358  struct application *ap = (struct application *)clientData;
359  struct rt_i *rtip;
360  char buf[64];
361 
362  if (argc < 2 || argc > 3) {
363  Tcl_AppendResult(interp,
364  "wrong # args: should be \"",
365  argv[0], " ", argv[1], " [#]\"",
366  (char *)NULL);
367  return TCL_ERROR;
368  }
369 
370  RT_CK_APPLICATION(ap);
371  rtip = ap->a_rt_i;
372  RT_CK_RTI(rtip);
373 
374  if (argc == 3) {
375  ap->a_onehit = atoi(argv[2]);
376  }
377  sprintf(buf, "%d", ap->a_onehit);
378  Tcl_AppendResult(interp, buf, (char *)NULL);
379  return TCL_OK;
380 }
381 
382 
383 /**
384  * Usage -
385  * procname no_bool
386  * procname no_bool #
387  */
388 int
389 rt_tcl_rt_no_bool(ClientData clientData, Tcl_Interp *interp, int argc, const char *const *argv)
390 {
391  struct application *ap = (struct application *)clientData;
392  struct rt_i *rtip;
393  char buf[64];
394 
395  if (argc < 2 || argc > 3) {
396  Tcl_AppendResult(interp,
397  "wrong # args: should be \"",
398  argv[0], " ", argv[1], " [#]\"",
399  (char *)NULL);
400  return TCL_ERROR;
401  }
402 
403  RT_CK_APPLICATION(ap);
404  rtip = ap->a_rt_i;
405  RT_CK_RTI(rtip);
406 
407  if (argc == 3) {
408  ap->a_no_booleans = atoi(argv[2]);
409  }
410  sprintf(buf, "%d", ap->a_no_booleans);
411  Tcl_AppendResult(interp, buf, (char *)NULL);
412  return TCL_OK;
413 }
414 
415 
416 /**
417  * Run some of the internal consistency checkers over the data
418  * structures.
419  *
420  * Usage -
421  * procname check
422  */
423 int
424 rt_tcl_rt_check(ClientData clientData, Tcl_Interp *interp, int argc, const char *const *argv)
425 {
426  struct application *ap = (struct application *)clientData;
427  struct rt_i *rtip;
428 
429  if (argc != 2) {
430  Tcl_AppendResult(interp,
431  "wrong # args: should be \"",
432  argv[0], " ", argv[1], "\"",
433  (char *)NULL);
434  return TCL_ERROR;
435  }
436 
437  RT_CK_APPLICATION(ap);
438  rtip = ap->a_rt_i;
439  RT_CK_RTI(rtip);
440 
441  rt_ck(rtip);
442 
443  return TCL_OK;
444 }
445 
446 
447 /**
448  * When run with no args, just prints current status of prepping.
449  *
450  * Usage -
451  * procname prep
452  * procname prep use_air [hasty_prep]
453  */
454 int
455 rt_tcl_rt_prep(ClientData clientData, Tcl_Interp *interp, int argc, const char *const *argv)
456 {
457  struct application *ap = (struct application *)clientData;
458  struct rt_i *rtip;
459  struct bu_vls str = BU_VLS_INIT_ZERO;
460 
461  if (argc < 2 || argc > 4) {
462  Tcl_AppendResult(interp,
463  "wrong # args: should be \"",
464  argv[0], " ", argv[1],
465  " [hasty_prep]\"",
466  (char *)NULL);
467  return TCL_ERROR;
468  }
469 
470  RT_CK_APPLICATION(ap);
471  rtip = ap->a_rt_i;
472  RT_CK_RTI(rtip);
473 
474  if (argc >= 3 && !rtip->needprep) {
475  Tcl_AppendResult(interp,
476  argv[0], " ", argv[1],
477  " invoked when model has already been prepped.\n",
478  (char *)NULL);
479  return TCL_ERROR;
480  }
481 
482  if (argc == 4) rtip->rti_hasty_prep = atoi(argv[3]);
483 
484  /* If args were given, prep now. */
485  if (argc >= 3) rt_prep_parallel(rtip, 1);
486 
487  /* Now, describe the current state */
488  bu_vls_printf(&str, "hasty_prep %d dont_instance %d useair %d needprep %d",
489  rtip->rti_hasty_prep,
490  rtip->rti_dont_instance,
491  rtip->useair,
492  rtip->needprep
493  );
494 
495  bu_vls_printf(&str, " space_partition_type %s n_nugridnode %d n_cutnode %d n_boxnode %d n_empty %ld",
497  "NUGrid" : "NUBSP",
501  rtip->nempty_cells);
502  bu_vls_printf(&str, " maxdepth %d maxlen %d",
503  rtip->rti_cut_maxdepth,
504  rtip->rti_cut_maxlen);
505  if (rtip->rti_ncut_by_type[CUT_BOXNODE]) bu_vls_printf(&str, " avglen %g",
506  ((double)rtip->rti_cut_totobj) /
508 
509  Tcl_AppendResult(interp, bu_vls_addr(&str), (char *)NULL);
510  bu_vls_free(&str);
511  return TCL_OK;
512 }
513 
514 
515 /**
516  * Set/get the rt object's settable variables.
517  *
518  * This replaces onehit and no_bool.
519  *
520  * Usage -
521  * procname set
522  * procname set vname
523  * procname set vname val
524  */
525 int
526 rt_tcl_rt_set(ClientData clientData, Tcl_Interp *interp, int argc, const char *const *argv)
527 {
528  struct application *ap = (struct application *)clientData;
529  struct rt_i *rtip;
530  struct bu_vls str = BU_VLS_INIT_ZERO;
531  int val;
532  const char *usage = "[vname [val]]";
533 
534  if (argc < 2 || argc > 4) {
535  bu_vls_printf(&str, "%s %s: %s", argv[0], argv[1], usage);
536  Tcl_AppendResult(interp, bu_vls_addr(&str), (char *)NULL);
537  bu_vls_free(&str);
538 
539  return TCL_ERROR;
540  }
541 
542  RT_CK_APPLICATION(ap);
543  rtip = ap->a_rt_i;
544  RT_CK_RTI(rtip);
545 
546  /* Return a list of the settable variables and their values */
547  if (argc == 2) {
548  bu_vls_printf(&str, "{onehit %d} ", ap->a_onehit);
549  bu_vls_printf(&str, "{no_bool %d} ", ap->a_no_booleans);
550  bu_vls_printf(&str, "{bot_reverse_normal_disabled %d}", ap->a_bot_reverse_normal_disabled);
551  Tcl_AppendResult(interp, bu_vls_addr(&str), (char *)NULL);
552  bu_vls_free(&str);
553 
554  return TCL_OK;
555  }
556 
557  if (argc == 4 && sscanf(argv[3], "%d", &val) != 1) {
558  bu_vls_printf(&str, "%s %s: bad val - %s, must be an integer", argv[0], argv[1], argv[3]);
559  Tcl_AppendResult(interp, bu_vls_addr(&str), (char *)NULL);
560  bu_vls_free(&str);
561 
562  return TCL_ERROR;
563  }
564 
565  if (argv[2][0] == 'o' && !bu_strncmp(argv[2], "onehit", 6)) {
566  if (argc == 3)
567  val = ap->a_onehit;
568  else
569  ap->a_onehit = val;
570  } else if (argv[2][0] == 'n' && !bu_strncmp(argv[2], "no_bool", 7)) {
571  if (argc == 3)
572  val = ap->a_no_booleans;
573  else
574  ap->a_no_booleans = val;
575  } else if (argv[2][0] == 'b' && !bu_strncmp(argv[2], "bot_reverse_normal_disabled", 27)) {
576  if (argc == 3)
578  else
580  } else {
581  bu_vls_printf(&str, "%s %s: bad val - %s, must be one of the following: onehit, no_bool, or bot_reverse_normal_disabled",
582  argv[0], argv[1], argv[2]);
583  Tcl_AppendResult(interp, bu_vls_addr(&str), (char *)NULL);
584  bu_vls_free(&str);
585 
586  return TCL_ERROR;
587  }
588 
589  bu_vls_printf(&str, "%d", val);
590  Tcl_AppendResult(interp, bu_vls_addr(&str), (char *)NULL);
591  bu_vls_free(&str);
592  return TCL_OK;
593 }
594 
595 
596 int
597 rt_tcl_rt(ClientData clientData, Tcl_Interp *interp, int argc, const char **argv)
598 {
599  struct dbcmdstruct *dbcmd;
600 
601  if (argc < 2) {
602  Tcl_AppendResult(interp,
603  "wrong # args: should be \"", argv[0],
604  " command [args...]\"",
605  (char *)NULL);
606  return TCL_ERROR;
607  }
608 
609  for (dbcmd = rt_tcl_rt_cmds; dbcmd->cmdname != NULL; dbcmd++) {
610  if (BU_STR_EQUAL(dbcmd->cmdname, argv[1])) {
611  /* need proper cmd func pointer for actual call */
612  int (*_cmdfunc)(void*, Tcl_Interp*, int, const char* const*);
613  /* cast to the actual caller */
614  _cmdfunc = (int (*)(void*, Tcl_Interp*, int, const char* const*))(*dbcmd->cmdfunc);
615  return _cmdfunc(clientData, interp, argc, argv);
616  }
617  }
618 
619 
620  Tcl_AppendResult(interp, "unknown LIBRT command '",
621  argv[1], "'; must be one of:",
622  (char *)NULL);
623  for (dbcmd = rt_tcl_rt_cmds; dbcmd->cmdname != NULL; dbcmd++) {
624  Tcl_AppendResult(interp, " ", dbcmd->cmdname, (char *)NULL);
625  }
626  return TCL_ERROR;
627 }
628 
629 
630 /************************************************************************
631  * *
632  * Tcl interface to Combination management *
633  * *
634  ************************************************************************/
635 
636 int
637 rt_tcl_import_from_path(Tcl_Interp *interp, struct rt_db_internal *ip, const char *path, struct rt_wdb *wdb)
638 {
639  struct db_i *dbip;
640  int status;
641 
642  /* Can't run RT_CK_DB_INTERNAL(ip), it hasn't been filled in yet */
643  RT_CK_WDB(wdb);
644  dbip = wdb->dbip;
645  RT_CK_DBI(dbip);
646 
647  if (strchr(path, '/')) {
648  /* This is a path */
649  struct db_tree_state ts;
650  struct db_full_path old_path;
651  struct db_full_path new_path;
652  struct directory *dp_curr;
653  int ret;
654 
656  db_full_path_init(&old_path);
657  db_full_path_init(&new_path);
658 
659  if (db_string_to_path(&new_path, dbip, path) < 0) {
660  Tcl_AppendResult(interp, "rt_tcl_import_from_path: '",
661  path, "' contains unknown object names\n", (char *)NULL);
662  return TCL_ERROR;
663  }
664 
665  dp_curr = DB_FULL_PATH_CUR_DIR(&new_path);
666  if (!dp_curr)
667  return TCL_ERROR;
668 
669  ret = db_follow_path(&ts, &old_path, &new_path, LOOKUP_NOISY, 0);
670  db_free_full_path(&old_path);
671  db_free_full_path(&new_path);
672 
673  if (ret < 0) {
674  Tcl_AppendResult(interp, "rt_tcl_import_from_path: '",
675  path, "' is a bad path\n", (char *)NULL);
676  return TCL_ERROR;
677  }
678 
679  status = wdb_import(wdb, ip, dp_curr->d_namep, ts.ts_mat);
680  if (status == -4) {
681  Tcl_AppendResult(interp, dp_curr->d_namep,
682  " not found in path ", path, "\n",
683  (char *)NULL);
684  return TCL_ERROR;
685  }
686  if (status < 0) {
687  Tcl_AppendResult(interp, "wdb_import failure: ",
688  dp_curr->d_namep, (char *)NULL);
689  return TCL_ERROR;
690  }
691  } else {
692  status = wdb_import(wdb, ip, path, (matp_t)NULL);
693  if (status == -4) {
694  Tcl_AppendResult(interp, path, ": not found\n",
695  (char *)NULL);
696  return TCL_ERROR;
697  }
698  if (status < 0) {
699  Tcl_AppendResult(interp, "wdb_import failure: ",
700  path, (char *)NULL);
701  return TCL_ERROR;
702  }
703  }
704  return TCL_OK;
705 }
706 
707 
708 void
709 rt_tcl_setup(Tcl_Interp *interp)
710 {
711  Tcl_LinkVar(interp, "rt_bot_minpieces", (char *)&rt_bot_minpieces, TCL_LINK_WIDE_INT);
712 
713  Tcl_LinkVar(interp, "rt_bot_tri_per_piece",
714  (char *)&rt_bot_tri_per_piece, TCL_LINK_WIDE_INT);
715 }
716 
717 
718 int
719 Rt_Init(Tcl_Interp *interp)
720 {
721  /*XXX how much will this break? */
723  if (bu_avail_cpus() > 1) {
724  RTG.rtg_parallel = 1;
725  }
726 
727  /* initialize RT's global state */
731  rt_init_resource(&rt_uniresource, 0, NULL);
732  }
733  }
734 
735  rt_tcl_setup(interp);
736 
737  Tcl_PkgProvide(interp, "Rt", brlcad_version());
738 
739  return TCL_OK;
740 }
741 
742 
743 /* ====================================================================== */
744 
745 /* TCL-oriented C support for LIBRT */
746 
747 
748 void
749 db_full_path_appendresult(Tcl_Interp *interp, const struct db_full_path *pp)
750 {
751  size_t i;
752 
753  RT_CK_FULL_PATH(pp);
754 
755  for (i=0; i<pp->fp_len; i++) {
756  Tcl_AppendResult(interp, "/", pp->fp_names[i]->d_namep, (char *)NULL);
757  }
758 }
759 
760 
761 int
762 tcl_obj_to_int_array(Tcl_Interp *interp, Tcl_Obj *list, int **array, int *array_len)
763 {
764  Tcl_Obj **obj_array;
765  int len, i;
766 
767  if (Tcl_ListObjGetElements(interp, list, &len, &obj_array) != TCL_OK)
768  return 0;
769 
770  if (len < 1)
771  return 0;
772 
773  if (*array_len < 1) {
774  *array = (int *)bu_calloc(len, sizeof(int), "array");
775  *array_len = len;
776  }
777 
778  for (i=0; i<len && i<*array_len; i++) {
779  (*array)[i] = atoi(Tcl_GetStringFromObj(obj_array[i], NULL));
780  Tcl_DecrRefCount(obj_array[i]);
781  }
782 
783  return len < *array_len ? len : *array_len;
784 }
785 
786 
787 int
788 tcl_list_to_int_array(Tcl_Interp *interp, char *char_list, int **array, int *array_len)
789 {
790  Tcl_Obj *obj;
791  int ret;
792 
793  obj = Tcl_NewStringObj(char_list, -1);
794 
795  ret = tcl_obj_to_int_array(interp, obj, array, array_len);
796 
797  return ret;
798 }
799 
800 
801 int
802 tcl_obj_to_fastf_array(Tcl_Interp *interp, Tcl_Obj *list, fastf_t **array, int *array_len)
803 {
804  Tcl_Obj **obj_array;
805  int len, i;
806  int ret;
807 
808  if ((ret=Tcl_ListObjGetElements(interp, list, &len, &obj_array)) != TCL_OK)
809  return ret;
810 
811  if (len < 1)
812  return 0;
813 
814  if (*array_len < 1) {
815  *array = (fastf_t *)bu_calloc(len, sizeof(fastf_t), "array");
816  *array_len = len;
817  }
818 
819  for (i=0; i<len && i<*array_len; i++) {
820  (*array)[i] = atof(Tcl_GetStringFromObj(obj_array[i], NULL));
821  Tcl_DecrRefCount(obj_array[i]);
822  }
823 
824  return len < *array_len ? len : *array_len;
825 }
826 
827 
828 int
829 tcl_list_to_fastf_array(Tcl_Interp *interp, const char *char_list, fastf_t **array, int *array_len)
830 {
831  Tcl_Obj *obj;
832  int ret;
833 
834  obj = Tcl_NewStringObj(char_list, -1);
835 
836  ret = tcl_obj_to_fastf_array(interp, obj, array, array_len);
837 
838  return ret;
839 }
840 
841 
842 /*
843  * Local Variables:
844  * mode: C
845  * tab-width: 8
846  * indent-tabs-mode: t
847  * c-file-style: "stroustrup"
848  * End:
849  * ex: shiftwidth=4 tabstop=8
850  */
Definition: db_flip.c:35
void usage(struct ged *gedp)
Definition: coil.c:315
int db_follow_path(struct db_tree_state *tsp, struct db_full_path *total_path, const struct db_full_path *new_path, int noisy, long pdepth)
Definition: db_tree.c:682
char * d_namep
pointer to name string
Definition: raytrace.h:859
struct xray a_ray
Actual ray to be shot.
Definition: raytrace.h:1583
Definition: raytrace.h:800
fastf_t bn_min[3]
Definition: raytrace.h:694
const struct directory * st_dp
Directory entry of solid.
Definition: raytrace.h:436
ustring interp
struct soltab ** bn_list
bn_list[bn_len]
Definition: raytrace.h:696
size_t fp_len
Definition: db_fullpath.h:44
#define RT_CK_APPLICATION(_p)
Definition: raytrace.h:1675
#define RT_CK_PIECELIST(_p)
Definition: raytrace.h:1410
#define RT_CK_RTI(_p)
Definition: raytrace.h:1833
void rt_silent_logoverlap(struct application *ap, const struct partition *pp, const struct bu_ptbl *regiontable, const struct partition *InputHdp)
Definition: bool.c:1122
vect_t crv_pdir
Principle direction.
Definition: raytrace.h:307
struct db_i * dbip
Definition: raytrace.h:1266
struct soltab * seg_stp
pointer back to soltab
Definition: raytrace.h:372
struct bu_list rtg_vlfree
head of bn_vlist freelist
Definition: raytrace.h:1698
int useair
1="air" regions are retained while prepping
Definition: raytrace.h:1756
#define CUT_CUTNODE
Definition: raytrace.h:718
void bu_vls_strcat(struct bu_vls *vp, const char *s)
Definition: vls.c:368
Definition: raytrace.h:215
#define RT_CK_SEG(_p)
Definition: raytrace.h:377
Definition: raytrace.h:368
#define BU_LIST_IS_INITIALIZED(_hp)
Definition: list.h:175
fastf_t bn_max[3]
Definition: raytrace.h:695
struct db_full_path st_path
path from region to leaf
Definition: raytrace.h:442
int8_t rtg_parallel
!0 = trying to use multi CPUs
Definition: raytrace.h:1697
Definition: raytrace.h:248
int tcl_list_to_int_array(Tcl_Interp *interp, char *char_list, int **array, int *array_len)
Definition: tcl.c:788
void rt_tcl_pr_cutter(Tcl_Interp *interp, const union cutter *cutp)
Definition: tcl.c:111
Header file for the BRL-CAD common definitions.
#define DB_FULL_PATH_CUR_DIR(_pp)
Definition: db_fullpath.h:51
struct nu_axis * nu_axis[3]
Definition: raytrace.h:712
void db_full_path_init(struct db_full_path *pathp)
Definition: db_fullpath.c:40
int a_onehit
flag to stop on first hit
Definition: raytrace.h:1586
int rt_tcl_import_from_path(Tcl_Interp *interp, struct rt_db_internal *ip, const char *path, struct rt_wdb *wdb)
Definition: tcl.c:637
int(* a_hit)(struct application *, struct partition *, struct seg *)
called when shot hits model
Definition: raytrace.h:1584
fastf_t nu_spos
cell start position
Definition: raytrace.h:705
int rti_space_partition
space partitioning method
Definition: raytrace.h:1763
void rt_tcl_setup(Tcl_Interp *interp)
Definition: tcl.c:709
size_t rt_bot_minpieces
Definition: globals.c:83
size_t nempty_cells
number of empty NUgrid cells
Definition: raytrace.h:1792
#define RT_CK_WDB(_p)
Definition: raytrace.h:1292
void db_full_path_appendresult(Tcl_Interp *interp, const struct db_full_path *pp)
Definition: tcl.c:749
void rt_init_resource(struct resource *resp, int cpu_num, struct rt_i *rtip)
Definition: prep.c:585
char * strchr(const char *sp, int c)
void bu_vls_free(struct bu_vls *vp)
Definition: vls.c:248
int bu_strncmp(const char *string1, const char *string2, size_t n)
Definition: str.c:191
uint32_t re_magic
Magic number.
Definition: raytrace.h:1441
struct rt_i * a_rt_i
this librt instance
Definition: raytrace.h:1588
long * pieces
pieces[npieces], piece indices
Definition: raytrace.h:1407
struct resource rt_uniresource
default. Defined in librt/globals.c
Definition: globals.c:41
int rt_tcl_rt(ClientData clientData, Tcl_Interp *interp, int argc, const char **argv)
Definition: tcl.c:597
size_t bn_len
of solids in list
Definition: raytrace.h:697
#define RESOURCE_MAGIC
Definition: magic.h:210
void db_init_db_tree_state(struct db_tree_state *tsp, struct db_i *dbip, struct resource *resp)
Definition: db_tree.c:93
void * bu_calloc(size_t nelem, size_t elsize, const char *str)
Definition: malloc.c:321
#define RT_CK_DIR(_dp)
Definition: raytrace.h:876
fastf_t crv_c2
curvature in other direction
Definition: raytrace.h:309
#define CUT_NUGRIDNODE
Definition: raytrace.h:720
int(* cmdfunc)(ClientData clientData, Tcl_Interp *interp, int argc, const char *const *argv)
Definition: tcl.c:61
int db_string_to_path(struct db_full_path *pp, const struct db_i *dbip, const char *str)
Definition: db_fullpath.c:361
int nu_stepsize[3]
number of cells to jump for one step in each axis
Definition: raytrace.h:714
void rt_tcl_pr_hit(Tcl_Interp *interp, struct hit *hitp, const struct seg *segp, int flipflag)
Definition: tcl.c:215
#define V3ARGS(a)
Definition: color.c:56
void db_free_full_path(struct db_full_path *pp)
Definition: db_fullpath.c:473
mat_t ts_mat
transform matrix
Definition: raytrace.h:1050
point_t hit_point
DEPRECATED: Intersection point, use VJOIN1 hit_dist.
Definition: raytrace.h:251
char * cmdname
Definition: tcl.c:60
struct rt_piecelist * bn_piecelist
[] solids with pieces
Definition: raytrace.h:699
int a_bot_reverse_normal_disabled
1= no bot normals get reversed in BOT_UNORIENTED_NORM
Definition: raytrace.h:1606
int rt_tcl_parse_ray(Tcl_Interp *interp, struct xray *rp, const char *const *argv)
Definition: tcl.c:78
#define RT_CURVATURE(_curvp, _hitp, _flipflag, _stp)
Definition: raytrace.h:321
uint32_t magic
Definition: db_fullpath.h:43
#define UNUSED(parameter)
Definition: common.h:239
int rti_cut_maxlen
max len RPP list in 1 cut bin
Definition: raytrace.h:1798
struct directory ** fp_names
array of dir pointers
Definition: db_fullpath.h:46
char * db_path_to_string(const struct db_full_path *pp)
Definition: db_fullpath.c:191
char * bu_vls_addr(const struct bu_vls *vp)
Definition: vls.c:111
fastf_t nu_epos
cell end position
Definition: raytrace.h:706
size_t bn_piecelen
of piecelists used
Definition: raytrace.h:700
size_t bu_avail_cpus(void)
Definition: parallel.c:193
vect_t r_dir
Direction of ray (UNIT Length)
Definition: raytrace.h:219
int rti_hasty_prep
1=hasty prep, slower ray-trace
Definition: raytrace.h:1759
#define RT_CK_DBI(_p)
Definition: raytrace.h:829
#define RT_CK_FULL_PATH(_p)
Definition: db_fullpath.h:59
int tcl_obj_to_fastf_array(Tcl_Interp *interp, Tcl_Obj *list, fastf_t **array, int *array_len)
Definition: tcl.c:802
#define RT_FUNC_TCL_CAST(_func)
Definition: tcl.c:42
int rt_tcl_a_miss(struct application *ap)
Definition: tcl.c:282
struct cutnode cn
Definition: raytrace.h:725
#define BU_LIST_INIT(_hp)
Definition: list.h:148
void(* a_logoverlap)(struct application *, const struct partition *, const struct bu_ptbl *, const struct partition *)
called to log overlaps
Definition: raytrace.h:1594
point_t r_pt
Point at which ray starts.
Definition: raytrace.h:218
#define RT_PART_NUGRID
Definition: raytrace.h:1836
size_t npieces
number of pieces in pieces[] array
Definition: raytrace.h:1406
int rti_ncut_by_type[CUT_MAXIMUM+1]
number of cuts by type
Definition: raytrace.h:1799
int bn_decode_vect(fastf_t *vec, const char *str)
Definition: tcl.c:87
int rti_cut_maxdepth
max depth of cut tree
Definition: raytrace.h:1801
#define RT_CK_PT(_p)
Definition: raytrace.h:589
#define RT_CK_PT_HD(_p)
Definition: raytrace.h:591
#define RT_CK_SOLTAB(_p)
Definition: raytrace.h:453
#define DB_FULL_PATH_MAGIC
Definition: magic.h:203
int a_no_booleans
1= partitions==segs, no booleans
Definition: raytrace.h:1602
void bu_vls_printf(struct bu_vls *vls, const char *fmt,...) _BU_ATTR_PRINTF23
Definition: vls.c:694
#define LOOKUP_NOISY
Definition: raytrace.h:892
int cut_type
Definition: raytrace.h:723
int wdb_import(struct rt_wdb *wdbp, struct rt_db_internal *internp, const char *name, const mat_t mat)
Definition: wdb.c:92
int tcl_list_to_fastf_array(Tcl_Interp *interp, const char *char_list, fastf_t **array, int *array_len)
Definition: tcl.c:829
int rti_dont_instance
1=Don't compress instances of solids into 1 while prepping
Definition: raytrace.h:1758
const union cutter * rt_cell_n_on_ray(struct application *ap, int n)
void rt_ck(struct rt_i *rtip)
fastf_t crv_c1
curvature in principle dir
Definition: raytrace.h:308
int Rt_Init(Tcl_Interp *interp)
Definition: tcl.c:719
void rt_prep_parallel(struct rt_i *rtip, int ncpu)
int rt_shootray(struct application *ap)
void * a_uptr
application-specific pointer
Definition: raytrace.h:1618
int rti_cut_totobj
objs in all bins, total
Definition: raytrace.h:1800
struct boxnode bn
Definition: raytrace.h:726
int hit_surfno
solid-specific surface indicator
Definition: raytrace.h:255
struct nugridnode nugn
Definition: raytrace.h:727
#define CUTTER_NULL
Definition: raytrace.h:731
fastf_t nu_width
voxel size (end - start)
Definition: raytrace.h:707
void bu_free(void *ptr, const char *str)
Definition: malloc.c:328
int(* a_miss)(struct application *)
called when shot misses
Definition: raytrace.h:1585
int cn_axis
0, 1, 2 = cut along X, Y, Z
Definition: raytrace.h:686
int rt_tcl_a_hit(struct application *ap, struct partition *PartHeadp, struct seg *segHeadp)
Definition: tcl.c:255
#define BU_VLS_INIT_ZERO
Definition: vls.h:84
#define RT_HIT_NORMAL(_normal, _hitp, _stp, _unused, _flipflag)
Definition: raytrace.h:273
struct soltab * stp
ref back to solid
Definition: raytrace.h:1408
int nu_cells_per_axis[3]
number of slabs
Definition: raytrace.h:713
#define CUT_BOXNODE
Definition: raytrace.h:719
size_t rt_bot_tri_per_piece
Definition: globals.c:88
struct partition * pt_forw
forwards link
Definition: raytrace.h:574
fastf_t hit_dist
dist from r_pt to hit_point
Definition: raytrace.h:250
Definition: vls.h:56
double fastf_t
Definition: defines.h:300
void bu_vls_putc(struct bu_vls *vp, int c)
Definition: vls.c:666
struct rt_wdb rtg_headwdb
head of database object list
Definition: raytrace.h:1700
int tcl_obj_to_int_array(Tcl_Interp *interp, Tcl_Obj *list, int **array, int *array_len)
Definition: tcl.c:762
struct bu_list l
Definition: raytrace.h:1264
int needprep
needs rt_prep
Definition: raytrace.h:1776
fastf_t cn_point
cut through axis==point
Definition: raytrace.h:687
void bn_encode_vect(struct bu_vls *vp, const mat_t v)
Definition: tcl.c:131
#define BU_STR_EQUAL(s1, s2)
Definition: str.h:126
struct rt_g RTG
Definition: globals.c:39