Revision: 76328
http://sourceforge.net/p/brlcad/code/76328
Author: starseeker
Date: 2020-07-14 18:48:17 +0000 (Tue, 14 Jul 2020)
Log Message:
-----------
Rename
Modified Paths:
--------------
brlcad/trunk/src/libtclcad/CMakeLists.txt
Added Paths:
-----------
brlcad/trunk/src/libtclcad/rt_funcs.c
Removed Paths:
-------------
brlcad/trunk/src/libtclcad/libfuncs.c
Modified: brlcad/trunk/src/libtclcad/CMakeLists.txt
===================================================================
--- brlcad/trunk/src/libtclcad/CMakeLists.txt 2020-07-14 18:47:49 UTC (rev
76327)
+++ brlcad/trunk/src/libtclcad/CMakeLists.txt 2020-07-14 18:48:17 UTC (rev
76328)
@@ -1,7 +1,7 @@
set(LIBTCLCAD_SRCS
bu_funcs.c
bn_funcs.c
- libfuncs.c
+ rt_funcs.c
tclcad.c
tclcadAutoPath.c
tclcad_obj.c
Deleted: brlcad/trunk/src/libtclcad/libfuncs.c
===================================================================
--- brlcad/trunk/src/libtclcad/libfuncs.c 2020-07-14 18:47:49 UTC (rev
76327)
+++ brlcad/trunk/src/libtclcad/libfuncs.c 2020-07-14 18:48:17 UTC (rev
76328)
@@ -1,845 +0,0 @@
-/* L I B F U N C S . C
- * BRL-CAD
- *
- * Copyright (c) 2004-2020 United States Government as represented by
- * the U.S. Army Research Laboratory.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * version 2.1 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this file; see the file named COPYING for more
- * information.
- *
- */
-/** @file libtclcad/libfuncs.c
- *
- * BRL-CAD's Tcl wrappers for various libraries.
- *
- */
-
-#include "common.h"
-
-#define RESOURCE_INCLUDED 1
-#include <tcl.h>
-#ifdef HAVE_TK
-# include <tk.h>
-#endif
-
-#include "string.h" /* for strchr */
-
-#include "vmath.h"
-#include "dm.h"
-#include "dm.h"
-#include "bu.h"
-#include "bn.h"
-#include "vmath.h"
-#include "raytrace.h"
-#include "tclcad.h"
-
-
-/* Private headers */
-#include "brlcad_version.h"
-#include "tclcad_private.h"
-
-
-#define RT_FUNC_TCL_CAST(_func) ((int (*)(ClientData clientData, Tcl_Interp
*interp, int argc, const char *const *argv))_func)
-
-static int tclcad_rt_shootray(ClientData clientData, Tcl_Interp *interp, int
argc, const char *const *argv);
-static int tclcad_rt_onehit(ClientData clientData, Tcl_Interp *interp, int
argc, const char *const *argv);
-static int tclcad_rt_no_bool(ClientData clientData, Tcl_Interp *interp, int
argc, const char *const *argv);
-static int tclcad_rt_check(ClientData clientData, Tcl_Interp *interp, int
argc, const char *const *argv);
-static int tclcad_rt_prep(ClientData clientData, Tcl_Interp *interp, int argc,
const char *const *argv);
-static int tclcad_rt_set(ClientData clientData, Tcl_Interp *interp, int argc,
const char *const*argv);
-
-
-/************************************************************************
- * *
- * Tcl interface to Ray-tracing *
- * *
- ************************************************************************/
-
-struct dbcmdstruct {
- char *cmdname;
- int (*cmdfunc)(ClientData clientData, Tcl_Interp *interp, int argc, const
char *const *argv);
-};
-
-
-static struct dbcmdstruct tclcad_rt_cmds[] = {
- {"shootray", RT_FUNC_TCL_CAST(tclcad_rt_shootray)},
- {"onehit", RT_FUNC_TCL_CAST(tclcad_rt_onehit)},
- {"no_bool", RT_FUNC_TCL_CAST(tclcad_rt_no_bool)},
- {"check", RT_FUNC_TCL_CAST(tclcad_rt_check)},
- {"prep", RT_FUNC_TCL_CAST(tclcad_rt_prep)},
- {"cutter", RT_FUNC_TCL_CAST(tclcad_rt_cutter)},
- {"set", RT_FUNC_TCL_CAST(tclcad_rt_set)},
- {(char *)0, RT_FUNC_TCL_CAST(0)}
-};
-
-
-int
-tclcad_rt_parse_ray(Tcl_Interp *interp, struct xray *rp, const char
*const*argv)
-{
- if (bn_decode_vect(rp->r_pt, argv[0]) != 3) {
- Tcl_AppendResult(interp,
- "badly formatted point: ", argv[0], (char *)NULL);
- return TCL_ERROR;
- }
- if (bn_decode_vect(rp->r_dir, argv[2]) != 3) {
- Tcl_AppendResult(interp,
- "badly formatted vector: ", argv[2], (char *)NULL);
- return TCL_ERROR;
- }
- switch (argv[1][0]) {
- case 'd':
- /* [2] is direction vector */
- break;
- case 'a':
- /* [2] is target point, build a vector from start pt */
- VSUB2(rp->r_dir, rp->r_dir, rp->r_pt);
- break;
- default:
- Tcl_AppendResult(interp,
- "wrong ray keyword: '", argv[1],
- "', should be one of 'dir' or 'at'",
- (char *)NULL);
- return TCL_ERROR;
- }
- VUNITIZE(rp->r_dir);
- return TCL_OK;
-}
-
-
-void
-tclcad_rt_pr_cutter(Tcl_Interp *interp, const union cutter *cutp)
-{
- static const char xyz[4] = "XYZ";
- struct bu_vls str = BU_VLS_INIT_ZERO;
- size_t i;
-
- switch (cutp->cut_type) {
- case CUT_CUTNODE:
- bu_vls_printf(&str,
- "type cutnode axis %c point %.25G",
- xyz[cutp->cn.cn_axis], cutp->cn.cn_point);
- break;
- case CUT_BOXNODE:
- bu_vls_printf(&str,
- "type boxnode min {%.25G %.25G %.25G}",
- V3ARGS(cutp->bn.bn_min));
- bu_vls_printf(&str,
- " max {%.25G %.25G %.25G}",
- V3ARGS(cutp->bn.bn_max));
- bu_vls_printf(&str, " solids {");
- for (i=0; i < cutp->bn.bn_len; i++) {
- bu_vls_strcat(&str, cutp->bn.bn_list[i]->st_name);
- bu_vls_putc(&str, ' ');
- }
- bu_vls_printf(&str, "} pieces {");
- for (i = 0; i < cutp->bn.bn_piecelen; i++) {
- struct rt_piecelist *plp = &cutp->bn.bn_piecelist[i];
- size_t j;
- RT_CK_PIECELIST(plp);
- /* These can be taken by user positionally */
- bu_vls_printf(&str, "{%s {", plp->stp->st_name);
- for (j=0; j < plp->npieces; j++) {
- bu_vls_printf(&str, "%ld ", plp->pieces[j]);
- }
- bu_vls_strcat(&str, "} } ");
- }
- bu_vls_strcat(&str, "}");
- break;
- default:
- bu_vls_printf(&str, "tclcad_rt_pr_cutter() bad pointer cutp=%p",
- (void *)cutp);
- break;
- }
- Tcl_AppendResult(interp, bu_vls_addr(&str), (char *)NULL);
- bu_vls_free(&str);
-}
-
-
-/**
- * Obtain the 'n'th space partitioning cell along the given ray, and
- * return that to the user.
- *
- * Example -
- * .rt cutter 7 {0 0 0} dir {0 0 -1}
- */
-int
-tclcad_rt_cutter(ClientData clientData, Tcl_Interp *interp, int argc, const
char *const*argv)
-{
- struct application *ap = (struct application *)clientData;
- struct rt_i *rtip;
- const union cutter *cutp;
- int n;
-
- if (argc != 6) {
- Tcl_AppendResult(interp,
- "wrong # args: should be \"",
- argv[0], " ", argv[1], "cutnum {P} dir|at {V}\"",
- (char *)NULL);
- return TCL_ERROR;
- }
-
- RT_CK_APPLICATION(ap);
- rtip = ap->a_rt_i;
- RT_CK_RTI(rtip);
-
- n = atoi(argv[2]);
- if (tclcad_rt_parse_ray(interp, &ap->a_ray, &argv[3]) == TCL_ERROR)
- return TCL_ERROR;
-
- cutp = rt_cell_n_on_ray(ap, n);
- if (cutp == CUTTER_NULL) {
- Tcl_AppendResult(interp, "rt_cell_n_on_ray() failed to find cell ",
argv[2], (char *)NULL);
- return TCL_ERROR;
- }
- tclcad_rt_pr_cutter(interp, cutp);
- return TCL_OK;
-}
-
-
-void
-tclcad_rt_pr_hit(Tcl_Interp *interp, struct hit *hitp, const struct seg *segp,
int flipflag)
-{
- struct bu_vls str = BU_VLS_INIT_ZERO;
- vect_t norm;
- struct soltab *stp;
- const struct directory *dp;
- struct curvature crv = {{0.0, 0.0, 0.0}, 0.0, 0.0};
-
- RT_CK_SEG(segp);
- stp = segp->seg_stp;
- RT_CK_SOLTAB(stp);
- dp = stp->st_dp;
- RT_CK_DIR(dp);
-
- RT_HIT_NORMAL(norm, hitp, stp, rayp, flipflag);
- RT_CURVATURE(&crv, hitp, flipflag, stp);
-
- bu_vls_printf(&str, " {dist %g point {", hitp->hit_dist);
- bn_encode_vect(&str, hitp->hit_point, 1);
- bu_vls_printf(&str, "} normal {");
- bn_encode_vect(&str, norm, 1);
- bu_vls_printf(&str, "} c1 %g c2 %g pdir {",
- crv.crv_c1, crv.crv_c2);
- bn_encode_vect(&str, crv.crv_pdir, 1);
- bu_vls_printf(&str, "} surfno %d", hitp->hit_surfno);
- if (stp->st_path.magic == DB_FULL_PATH_MAGIC) {
- /* Magic is left 0 if the path is not filled in. */
- char *sofar = db_path_to_string(&stp->st_path);
- bu_vls_printf(&str, " path ");
- bu_vls_strcat(&str, sofar);
- bu_free((void *)sofar, "path string");
- }
- bu_vls_printf(&str, " solid %s}", dp->d_namep);
-
- Tcl_AppendResult(interp, bu_vls_addr(&str), (char *)NULL);
- bu_vls_free(&str);
-}
-
-
-int
-tclcad_rt_a_hit(struct application *ap,
- struct partition *PartHeadp,
- struct seg *UNUSED(segHeadp))
-{
- Tcl_Interp *interp = (Tcl_Interp *)ap->a_uptr;
- register struct partition *pp;
-
- RT_CK_PT_HD(PartHeadp);
-
- for (pp=PartHeadp->pt_forw; pp != PartHeadp; pp = pp->pt_forw) {
- RT_CK_PT(pp);
- Tcl_AppendResult(interp, "{in", (char *)NULL);
- tclcad_rt_pr_hit(interp, pp->pt_inhit, pp->pt_inseg, pp->pt_inflip);
- Tcl_AppendResult(interp, "\nout", (char *)NULL);
- tclcad_rt_pr_hit(interp, pp->pt_outhit, pp->pt_outseg, pp->pt_outflip);
- Tcl_AppendResult(interp,
- "\nregion ",
- pp->pt_regionp->reg_name,
- (char *)NULL);
- Tcl_AppendResult(interp, "}\n", (char *)NULL);
- }
-
- return 1;
-}
-
-
-int
-tclcad_rt_a_miss(struct application *ap)
-{
- if (ap) RT_CK_APPLICATION(ap);
- return 0;
-}
-
-
-/**
- * Usage -
- * procname shootray [-R] {P} dir|at {V}
- * -R option specifies no overlap reporting
- *
- * Example -
- * set glob_compat_mode 0
- * .inmem rt_gettrees .rt all.g
- * .rt shootray -R {0 0 0} dir {0 0 -1}
- *
- * set tgt [bu_get_value_by_keyword V [concat type [.inmem get LIGHT]]]
- * .rt shootray {20 -13.5 20} at $tgt
- *
- *
- * Returns -
- * This "shootray" operation returns a nested set of lists. It
- * returns a list of zero or more partitions. Inside each
- * partition is a list containing an in, out, and region keyword,
- * each with an associated value. The associated value for each
- * "inhit" and "outhit" is itself a list containing a dist,
- * point, normal, surfno, and solid keyword, each with an
- * associated value.
- */
-static int
-tclcad_rt_shootray(ClientData clientData, Tcl_Interp *interp, int argc, const
char *const *argv)
-{
- struct application *ap = (struct application *)clientData;
- struct rt_i *rtip;
- int idx;
-
- if ((argc != 5 && argc != 6) || (argc == 6 && !BU_STR_EQUAL(argv[2],
"-R"))) {
- Tcl_AppendResult(interp,
- "wrong # args: should be \"",
- argv[0], " ", argv[1], " [-R] {P} dir|at {V}\"",
- (char *)NULL);
- return TCL_ERROR;
- }
-
- if (argc == 6) {
- ap->a_logoverlap = rt_silent_logoverlap;
- idx = 3;
- } else {
- idx = 2;
- }
-
- RT_CK_APPLICATION(ap);
- rtip = ap->a_rt_i;
- RT_CK_RTI(rtip);
-
- if (tclcad_rt_parse_ray(interp, &ap->a_ray, &argv[idx]) == TCL_ERROR)
- return TCL_ERROR;
- ap->a_hit = tclcad_rt_a_hit;
- ap->a_miss = tclcad_rt_a_miss;
- ap->a_uptr = (void *)interp;
-
- (void)rt_shootray(ap);
-
- return TCL_OK;
-}
-
-
-/**
- * Usage -
- * procname onehit
- * procname onehit #
- */
-static int
-tclcad_rt_onehit(ClientData clientData, Tcl_Interp *interp, int argc, const
char *const *argv)
-{
- struct application *ap = (struct application *)clientData;
- struct rt_i *rtip;
- char buf[64];
-
- if (argc < 2 || argc > 3) {
- Tcl_AppendResult(interp,
- "wrong # args: should be \"",
- argv[0], " ", argv[1], " [#]\"",
- (char *)NULL);
- return TCL_ERROR;
- }
-
- RT_CK_APPLICATION(ap);
- rtip = ap->a_rt_i;
- RT_CK_RTI(rtip);
-
- if (argc == 3) {
- ap->a_onehit = atoi(argv[2]);
- }
- sprintf(buf, "%d", ap->a_onehit);
- Tcl_AppendResult(interp, buf, (char *)NULL);
- return TCL_OK;
-}
-
-
-/**
- * Usage -
- * procname no_bool
- * procname no_bool #
- */
-int
-tclcad_rt_no_bool(ClientData clientData, Tcl_Interp *interp, int argc, const
char *const *argv)
-{
- struct application *ap = (struct application *)clientData;
- struct rt_i *rtip;
- char buf[64];
-
- if (argc < 2 || argc > 3) {
- Tcl_AppendResult(interp,
- "wrong # args: should be \"",
- argv[0], " ", argv[1], " [#]\"",
- (char *)NULL);
- return TCL_ERROR;
- }
-
- RT_CK_APPLICATION(ap);
- rtip = ap->a_rt_i;
- RT_CK_RTI(rtip);
-
- if (argc == 3) {
- ap->a_no_booleans = atoi(argv[2]);
- }
- sprintf(buf, "%d", ap->a_no_booleans);
- Tcl_AppendResult(interp, buf, (char *)NULL);
- return TCL_OK;
-}
-
-
-/**
- * Run some of the internal consistency checkers over the data
- * structures.
- *
- * Usage -
- * procname check
- */
-int
-tclcad_rt_check(ClientData clientData, Tcl_Interp *interp, int argc, const
char *const *argv)
-{
- struct application *ap = (struct application *)clientData;
- struct rt_i *rtip;
-
- if (argc != 2) {
- Tcl_AppendResult(interp,
- "wrong # args: should be \"",
- argv[0], " ", argv[1], "\"",
- (char *)NULL);
- return TCL_ERROR;
- }
-
- RT_CK_APPLICATION(ap);
- rtip = ap->a_rt_i;
- RT_CK_RTI(rtip);
-
- rt_ck(rtip);
-
- return TCL_OK;
-}
-
-
-/**
- * When run with no args, just prints current status of prepping.
- *
- * Usage -
- * procname prep
- * procname prep use_air [hasty_prep]
- */
-int
-tclcad_rt_prep(ClientData clientData, Tcl_Interp *interp, int argc, const char
*const *argv)
-{
- struct application *ap = (struct application *)clientData;
- struct rt_i *rtip;
- struct bu_vls str = BU_VLS_INIT_ZERO;
-
- if (argc < 2 || argc > 4) {
- Tcl_AppendResult(interp,
- "wrong # args: should be \"",
- argv[0], " ", argv[1],
- " [hasty_prep]\"",
- (char *)NULL);
- return TCL_ERROR;
- }
-
- RT_CK_APPLICATION(ap);
- rtip = ap->a_rt_i;
- RT_CK_RTI(rtip);
-
- if (argc >= 3 && !rtip->needprep) {
- Tcl_AppendResult(interp,
- argv[0], " ", argv[1],
- " invoked when model has already been prepped.\n",
- (char *)NULL);
- return TCL_ERROR;
- }
-
- if (argc == 4) rtip->rti_hasty_prep = atoi(argv[3]);
-
- /* If args were given, prep now. */
- if (argc >= 3) rt_prep_parallel(rtip, 1);
-
- /* Now, describe the current state */
- bu_vls_printf(&str, "hasty_prep %d dont_instance %d useair %d needprep %d",
- rtip->rti_hasty_prep,
- rtip->rti_dont_instance,
- rtip->useair,
- rtip->needprep
- );
-
- bu_vls_printf(&str, " space_partition_type %s n_cutnode %d n_boxnode %d
n_empty %ld",
- rtip->rti_space_partition == RT_PART_NUBSPT ?
- "NUBSP" : "unknown",
- rtip->rti_ncut_by_type[CUT_CUTNODE],
- rtip->rti_ncut_by_type[CUT_BOXNODE],
- rtip->nempty_cells);
- bu_vls_printf(&str, " maxdepth %d maxlen %d",
- rtip->rti_cut_maxdepth,
- rtip->rti_cut_maxlen);
- if (rtip->rti_ncut_by_type[CUT_BOXNODE]) bu_vls_printf(&str, " avglen %g",
-
((double)rtip->rti_cut_totobj) /
-
rtip->rti_ncut_by_type[CUT_BOXNODE]);
-
- Tcl_AppendResult(interp, bu_vls_addr(&str), (char *)NULL);
- bu_vls_free(&str);
- return TCL_OK;
-}
-
-
-/**
- * Set/get the rt object's settable variables.
- *
- * This replaces onehit and no_bool.
- *
- * Usage -
- * procname set
- * procname set vname
- * procname set vname val
- */
-int
-tclcad_rt_set(ClientData clientData, Tcl_Interp *interp, int argc, const char
*const *argv)
-{
- struct application *ap = (struct application *)clientData;
- struct rt_i *rtip;
- struct bu_vls str = BU_VLS_INIT_ZERO;
- int val;
- const char *usage = "[vname [val]]";
-
- if (argc < 2 || argc > 4) {
- bu_vls_printf(&str, "%s %s: %s", argv[0], argv[1], usage);
- Tcl_AppendResult(interp, bu_vls_addr(&str), (char *)NULL);
- bu_vls_free(&str);
-
- return TCL_ERROR;
- }
-
- RT_CK_APPLICATION(ap);
- rtip = ap->a_rt_i;
- RT_CK_RTI(rtip);
-
- /* Return a list of the settable variables and their values */
- if (argc == 2) {
- bu_vls_printf(&str, "{onehit %d} ", ap->a_onehit);
- bu_vls_printf(&str, "{no_bool %d} ", ap->a_no_booleans);
- bu_vls_printf(&str, "{bot_reverse_normal_disabled %d}",
ap->a_bot_reverse_normal_disabled);
- Tcl_AppendResult(interp, bu_vls_addr(&str), (char *)NULL);
- bu_vls_free(&str);
-
- return TCL_OK;
- }
-
- if (argc == 4 && sscanf(argv[3], "%d", &val) != 1) {
- bu_vls_printf(&str, "%s %s: bad val - %s, must be an integer", argv[0],
argv[1], argv[3]);
- Tcl_AppendResult(interp, bu_vls_addr(&str), (char *)NULL);
- bu_vls_free(&str);
-
- return TCL_ERROR;
- }
-
- if (argv[2][0] == 'o' && !bu_strncmp(argv[2], "onehit", 6)) {
- if (argc == 3)
- val = ap->a_onehit;
- else
- ap->a_onehit = val;
- } else if (argv[2][0] == 'n' && !bu_strncmp(argv[2], "no_bool", 7)) {
- if (argc == 3)
- val = ap->a_no_booleans;
- else
- ap->a_no_booleans = val;
- } else if (argv[2][0] == 'b' && !bu_strncmp(argv[2],
"bot_reverse_normal_disabled", 27)) {
- if (argc == 3)
- val = ap->a_bot_reverse_normal_disabled;
- else
- ap->a_bot_reverse_normal_disabled = val;
- } else {
- bu_vls_printf(&str, "%s %s: bad val - %s, must be one of the following:
onehit, no_bool, or bot_reverse_normal_disabled",
- argv[0], argv[1], argv[2]);
- Tcl_AppendResult(interp, bu_vls_addr(&str), (char *)NULL);
- bu_vls_free(&str);
-
- return TCL_ERROR;
- }
-
- bu_vls_printf(&str, "%d", val);
- Tcl_AppendResult(interp, bu_vls_addr(&str), (char *)NULL);
- bu_vls_free(&str);
- return TCL_OK;
-}
-
-
-int
-tclcad_rt(ClientData clientData, Tcl_Interp *interp, int argc, const char
**argv)
-{
- struct dbcmdstruct *dbcmd;
-
- if (argc < 2) {
- Tcl_AppendResult(interp,
- "wrong # args: should be \"", argv[0],
- " command [args...]\"",
- (char *)NULL);
- return TCL_ERROR;
- }
-
- for (dbcmd = tclcad_rt_cmds; dbcmd->cmdname != NULL; dbcmd++) {
- if (BU_STR_EQUAL(dbcmd->cmdname, argv[1])) {
- /* need proper cmd func pointer for actual call */
- int (*_cmdfunc)(void*, Tcl_Interp*, int, const char* const*);
- /* cast to the actual caller */
- _cmdfunc = (int (*)(void*, Tcl_Interp*, int, const char*
const*))(*dbcmd->cmdfunc);
- return _cmdfunc(clientData, interp, argc, argv);
- }
- }
-
-
- Tcl_AppendResult(interp, "unknown LIBRT command '",
- argv[1], "'; must be one of:",
- (char *)NULL);
- for (dbcmd = tclcad_rt_cmds; dbcmd->cmdname != NULL; dbcmd++) {
- Tcl_AppendResult(interp, " ", dbcmd->cmdname, (char *)NULL);
- }
- return TCL_ERROR;
-}
-
-
-/************************************************************************
- * *
- * Tcl interface to Combination management *
- * *
- ************************************************************************/
-
-int
-tclcad_rt_import_from_path(Tcl_Interp *interp, struct rt_db_internal *ip,
const char *path, struct rt_wdb *wdb)
-{
- struct db_i *dbip;
- int status;
-
- /* Can't run RT_CK_DB_INTERNAL(ip), it hasn't been filled in yet */
- RT_CK_WDB(wdb);
- dbip = wdb->dbip;
- RT_CK_DBI(dbip);
-
- if (strchr(path, '/')) {
- /* This is a path */
- struct db_tree_state ts;
- struct db_full_path old_path;
- struct db_full_path new_path;
- struct directory *dp_curr;
- int ret;
-
- db_init_db_tree_state(&ts, dbip, &rt_uniresource);
- db_full_path_init(&old_path);
- db_full_path_init(&new_path);
-
- if (db_string_to_path(&new_path, dbip, path) < 0) {
- Tcl_AppendResult(interp, "tclcad_rt_import_from_path: '",
- path, "' contains unknown object names\n", (char
*)NULL);
- return TCL_ERROR;
- }
-
- dp_curr = DB_FULL_PATH_CUR_DIR(&new_path);
- if (!dp_curr)
- return TCL_ERROR;
-
- ret = db_follow_path(&ts, &old_path, &new_path, LOOKUP_NOISY, 0);
- db_free_full_path(&old_path);
- db_free_full_path(&new_path);
-
- if (ret < 0) {
- Tcl_AppendResult(interp, "tclcad_rt_import_from_path: '",
- path, "' is a bad path\n", (char *)NULL);
- return TCL_ERROR;
- }
-
- status = wdb_import(wdb, ip, dp_curr->d_namep, ts.ts_mat);
- if (status == -4) {
- Tcl_AppendResult(interp, dp_curr->d_namep,
- " not found in path ", path, "\n",
- (char *)NULL);
- return TCL_ERROR;
- }
- if (status < 0) {
- Tcl_AppendResult(interp, "wdb_import failure: ",
- dp_curr->d_namep, (char *)NULL);
- return TCL_ERROR;
- }
- } else {
- status = wdb_import(wdb, ip, path, (matp_t)NULL);
- if (status == -4) {
- Tcl_AppendResult(interp, path, ": not found\n",
- (char *)NULL);
- return TCL_ERROR;
- }
- if (status < 0) {
- Tcl_AppendResult(interp, "wdb_import failure: ",
- path, (char *)NULL);
- return TCL_ERROR;
- }
- }
- return TCL_OK;
-}
-
-
-void
-tclcad_rt_setup(Tcl_Interp *interp)
-{
- Tcl_LinkVar(interp, "rt_bot_minpieces", (char *)&rt_bot_minpieces,
TCL_LINK_WIDE_INT);
-
- Tcl_LinkVar(interp, "rt_bot_tri_per_piece",
- (char *)&rt_bot_tri_per_piece, TCL_LINK_WIDE_INT);
-}
-
-
-int
-Rt_Init(Tcl_Interp *interp)
-{
- /*XXX how much will this break? */
- if (!BU_LIST_IS_INITIALIZED(&RTG.rtg_vlfree)) {
- if (bu_avail_cpus() > 1) {
- RTG.rtg_parallel = 1;
- }
-
- /* initialize RT's global state */
- BU_LIST_INIT(&RTG.rtg_vlfree);
- BU_LIST_INIT(&RTG.rtg_headwdb.l);
- if (rt_uniresource.re_magic != RESOURCE_MAGIC) {
- rt_init_resource(&rt_uniresource, 0, NULL);
- }
- }
-
- tclcad_rt_setup(interp);
-
- Tcl_PkgProvide(interp, "Rt", brlcad_version());
-
- return TCL_OK;
-}
-
-
-/* ====================================================================== */
-
-/* TCL-oriented C support for LIBRT */
-
-
-void
-db_full_path_appendresult(Tcl_Interp *interp, const struct db_full_path *pp)
-{
- size_t i;
-
- RT_CK_FULL_PATH(pp);
-
- for (i=0; i<pp->fp_len; i++) {
- Tcl_AppendResult(interp, "/", pp->fp_names[i]->d_namep, (char *)NULL);
- }
-}
-
-
-int
-tcl_obj_to_int_array(Tcl_Interp *interp, Tcl_Obj *list, int **array, int
*array_len)
-{
- Tcl_Obj **obj_array;
- int len, i;
-
- if (Tcl_ListObjGetElements(interp, list, &len, &obj_array) != TCL_OK)
- return 0;
-
- if (len < 1)
- return 0;
-
- if (*array_len < 1) {
- *array = (int *)bu_calloc(len, sizeof(int), "array");
- *array_len = len;
- }
-
- for (i=0; i<len && i<*array_len; i++) {
- (*array)[i] = atoi(Tcl_GetStringFromObj(obj_array[i], NULL));
- Tcl_DecrRefCount(obj_array[i]);
- }
-
- return len < *array_len ? len : *array_len;
-}
-
-
-int
-tcl_list_to_int_array(Tcl_Interp *interp, char *char_list, int **array, int
*array_len)
-{
- Tcl_Obj *obj;
- int ret;
-
- obj = Tcl_NewStringObj(char_list, -1);
-
- ret = tcl_obj_to_int_array(interp, obj, array, array_len);
-
- return ret;
-}
-
-
-int
-tcl_obj_to_fastf_array(Tcl_Interp *interp, Tcl_Obj *list, fastf_t **array, int
*array_len)
-{
- Tcl_Obj **obj_array;
- int len, i;
- int ret;
-
- if ((ret=Tcl_ListObjGetElements(interp, list, &len, &obj_array)) != TCL_OK)
- return ret;
-
- if (len < 1)
- return 0;
-
- if (*array_len < 1) {
- *array = (fastf_t *)bu_calloc(len, sizeof(fastf_t), "array");
- *array_len = len;
- }
-
- for (i=0; i<len && i<*array_len; i++) {
- (*array)[i] = atof(Tcl_GetStringFromObj(obj_array[i], NULL));
- Tcl_DecrRefCount(obj_array[i]);
- }
-
- return len < *array_len ? len : *array_len;
-}
-
-
-int
-tcl_list_to_fastf_array(Tcl_Interp *interp, const char *char_list, fastf_t
**array, int *array_len)
-{
- Tcl_Obj *obj;
- int ret;
-
- obj = Tcl_NewStringObj(char_list, -1);
-
- ret = tcl_obj_to_fastf_array(interp, obj, array, array_len);
-
- return ret;
-}
-
-
-
-/*
- * Local Variables:
- * mode: C
- * tab-width: 8
- * indent-tabs-mode: t
- * c-file-style: "stroustrup"
- * End:
- * ex: shiftwidth=4 tabstop=8
- */
Copied: brlcad/trunk/src/libtclcad/rt_funcs.c (from rev 76327,
brlcad/trunk/src/libtclcad/libfuncs.c)
===================================================================
--- brlcad/trunk/src/libtclcad/rt_funcs.c (rev 0)
+++ brlcad/trunk/src/libtclcad/rt_funcs.c 2020-07-14 18:48:17 UTC (rev
76328)
@@ -0,0 +1,845 @@
+/* L I B F U N C S . C
+ * BRL-CAD
+ *
+ * Copyright (c) 2004-2020 United States Government as represented by
+ * the U.S. Army Research Laboratory.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this file; see the file named COPYING for more
+ * information.
+ *
+ */
+/** @file libtclcad/libfuncs.c
+ *
+ * BRL-CAD's Tcl wrappers for various libraries.
+ *
+ */
+
+#include "common.h"
+
+#define RESOURCE_INCLUDED 1
+#include <tcl.h>
+#ifdef HAVE_TK
+# include <tk.h>
+#endif
+
+#include "string.h" /* for strchr */
+
+#include "vmath.h"
+#include "dm.h"
+#include "dm.h"
+#include "bu.h"
+#include "bn.h"
+#include "vmath.h"
+#include "raytrace.h"
+#include "tclcad.h"
+
+
+/* Private headers */
+#include "brlcad_version.h"
+#include "tclcad_private.h"
+
+
+#define RT_FUNC_TCL_CAST(_func) ((int (*)(ClientData clientData, Tcl_Interp
*interp, int argc, const char *const *argv))_func)
+
+static int tclcad_rt_shootray(ClientData clientData, Tcl_Interp *interp, int
argc, const char *const *argv);
+static int tclcad_rt_onehit(ClientData clientData, Tcl_Interp *interp, int
argc, const char *const *argv);
+static int tclcad_rt_no_bool(ClientData clientData, Tcl_Interp *interp, int
argc, const char *const *argv);
+static int tclcad_rt_check(ClientData clientData, Tcl_Interp *interp, int
argc, const char *const *argv);
+static int tclcad_rt_prep(ClientData clientData, Tcl_Interp *interp, int argc,
const char *const *argv);
+static int tclcad_rt_set(ClientData clientData, Tcl_Interp *interp, int argc,
const char *const*argv);
+
+
+/************************************************************************
+ * *
+ * Tcl interface to Ray-tracing *
+ * *
+ ************************************************************************/
+
+struct dbcmdstruct {
+ char *cmdname;
+ int (*cmdfunc)(ClientData clientData, Tcl_Interp *interp, int argc, const
char *const *argv);
+};
+
+
+static struct dbcmdstruct tclcad_rt_cmds[] = {
+ {"shootray", RT_FUNC_TCL_CAST(tclcad_rt_shootray)},
+ {"onehit", RT_FUNC_TCL_CAST(tclcad_rt_onehit)},
+ {"no_bool", RT_FUNC_TCL_CAST(tclcad_rt_no_bool)},
+ {"check", RT_FUNC_TCL_CAST(tclcad_rt_check)},
+ {"prep", RT_FUNC_TCL_CAST(tclcad_rt_prep)},
+ {"cutter", RT_FUNC_TCL_CAST(tclcad_rt_cutter)},
+ {"set", RT_FUNC_TCL_CAST(tclcad_rt_set)},
+ {(char *)0, RT_FUNC_TCL_CAST(0)}
+};
+
+
+int
+tclcad_rt_parse_ray(Tcl_Interp *interp, struct xray *rp, const char
*const*argv)
+{
+ if (bn_decode_vect(rp->r_pt, argv[0]) != 3) {
+ Tcl_AppendResult(interp,
+ "badly formatted point: ", argv[0], (char *)NULL);
+ return TCL_ERROR;
+ }
+ if (bn_decode_vect(rp->r_dir, argv[2]) != 3) {
+ Tcl_AppendResult(interp,
+ "badly formatted vector: ", argv[2], (char *)NULL);
+ return TCL_ERROR;
+ }
+ switch (argv[1][0]) {
+ case 'd':
+ /* [2] is direction vector */
+ break;
+ case 'a':
+ /* [2] is target point, build a vector from start pt */
+ VSUB2(rp->r_dir, rp->r_dir, rp->r_pt);
+ break;
+ default:
+ Tcl_AppendResult(interp,
+ "wrong ray keyword: '", argv[1],
+ "', should be one of 'dir' or 'at'",
+ (char *)NULL);
+ return TCL_ERROR;
+ }
+ VUNITIZE(rp->r_dir);
+ return TCL_OK;
+}
+
+
+void
+tclcad_rt_pr_cutter(Tcl_Interp *interp, const union cutter *cutp)
+{
+ static const char xyz[4] = "XYZ";
+ struct bu_vls str = BU_VLS_INIT_ZERO;
+ size_t i;
+
+ switch (cutp->cut_type) {
+ case CUT_CUTNODE:
+ bu_vls_printf(&str,
+ "type cutnode axis %c point %.25G",
+ xyz[cutp->cn.cn_axis], cutp->cn.cn_point);
+ break;
+ case CUT_BOXNODE:
+ bu_vls_printf(&str,
+ "type boxnode min {%.25G %.25G %.25G}",
+ V3ARGS(cutp->bn.bn_min));
+ bu_vls_printf(&str,
+ " max {%.25G %.25G %.25G}",
+ V3ARGS(cutp->bn.bn_max));
+ bu_vls_printf(&str, " solids {");
+ for (i=0; i < cutp->bn.bn_len; i++) {
+ bu_vls_strcat(&str, cutp->bn.bn_list[i]->st_name);
+ bu_vls_putc(&str, ' ');
+ }
+ bu_vls_printf(&str, "} pieces {");
+ for (i = 0; i < cutp->bn.bn_piecelen; i++) {
+ struct rt_piecelist *plp = &cutp->bn.bn_piecelist[i];
+ size_t j;
+ RT_CK_PIECELIST(plp);
+ /* These can be taken by user positionally */
+ bu_vls_printf(&str, "{%s {", plp->stp->st_name);
+ for (j=0; j < plp->npieces; j++) {
+ bu_vls_printf(&str, "%ld ", plp->pieces[j]);
+ }
+ bu_vls_strcat(&str, "} } ");
+ }
+ bu_vls_strcat(&str, "}");
+ break;
+ default:
+ bu_vls_printf(&str, "tclcad_rt_pr_cutter() bad pointer cutp=%p",
+ (void *)cutp);
+ break;
+ }
+ Tcl_AppendResult(interp, bu_vls_addr(&str), (char *)NULL);
+ bu_vls_free(&str);
+}
+
+
+/**
+ * Obtain the 'n'th space partitioning cell along the given ray, and
+ * return that to the user.
+ *
+ * Example -
+ * .rt cutter 7 {0 0 0} dir {0 0 -1}
+ */
+int
+tclcad_rt_cutter(ClientData clientData, Tcl_Interp *interp, int argc, const
char *const*argv)
+{
+ struct application *ap = (struct application *)clientData;
+ struct rt_i *rtip;
+ const union cutter *cutp;
+ int n;
+
+ if (argc != 6) {
+ Tcl_AppendResult(interp,
+ "wrong # args: should be \"",
+ argv[0], " ", argv[1], "cutnum {P} dir|at {V}\"",
+ (char *)NULL);
+ return TCL_ERROR;
+ }
+
+ RT_CK_APPLICATION(ap);
+ rtip = ap->a_rt_i;
+ RT_CK_RTI(rtip);
+
+ n = atoi(argv[2]);
+ if (tclcad_rt_parse_ray(interp, &ap->a_ray, &argv[3]) == TCL_ERROR)
+ return TCL_ERROR;
+
+ cutp = rt_cell_n_on_ray(ap, n);
+ if (cutp == CUTTER_NULL) {
+ Tcl_AppendResult(interp, "rt_cell_n_on_ray() failed to find cell ",
argv[2], (char *)NULL);
+ return TCL_ERROR;
+ }
+ tclcad_rt_pr_cutter(interp, cutp);
+ return TCL_OK;
+}
+
+
+void
+tclcad_rt_pr_hit(Tcl_Interp *interp, struct hit *hitp, const struct seg *segp,
int flipflag)
+{
+ struct bu_vls str = BU_VLS_INIT_ZERO;
+ vect_t norm;
+ struct soltab *stp;
+ const struct directory *dp;
+ struct curvature crv = {{0.0, 0.0, 0.0}, 0.0, 0.0};
+
+ RT_CK_SEG(segp);
+ stp = segp->seg_stp;
+ RT_CK_SOLTAB(stp);
+ dp = stp->st_dp;
+ RT_CK_DIR(dp);
+
+ RT_HIT_NORMAL(norm, hitp, stp, rayp, flipflag);
+ RT_CURVATURE(&crv, hitp, flipflag, stp);
+
+ bu_vls_printf(&str, " {dist %g point {", hitp->hit_dist);
+ bn_encode_vect(&str, hitp->hit_point, 1);
+ bu_vls_printf(&str, "} normal {");
+ bn_encode_vect(&str, norm, 1);
+ bu_vls_printf(&str, "} c1 %g c2 %g pdir {",
+ crv.crv_c1, crv.crv_c2);
+ bn_encode_vect(&str, crv.crv_pdir, 1);
+ bu_vls_printf(&str, "} surfno %d", hitp->hit_surfno);
+ if (stp->st_path.magic == DB_FULL_PATH_MAGIC) {
+ /* Magic is left 0 if the path is not filled in. */
+ char *sofar = db_path_to_string(&stp->st_path);
+ bu_vls_printf(&str, " path ");
+ bu_vls_strcat(&str, sofar);
+ bu_free((void *)sofar, "path string");
+ }
+ bu_vls_printf(&str, " solid %s}", dp->d_namep);
+
+ Tcl_AppendResult(interp, bu_vls_addr(&str), (char *)NULL);
+ bu_vls_free(&str);
+}
+
+
+int
+tclcad_rt_a_hit(struct application *ap,
+ struct partition *PartHeadp,
+ struct seg *UNUSED(segHeadp))
+{
+ Tcl_Interp *interp = (Tcl_Interp *)ap->a_uptr;
+ register struct partition *pp;
+
+ RT_CK_PT_HD(PartHeadp);
+
+ for (pp=PartHeadp->pt_forw; pp != PartHeadp; pp = pp->pt_forw) {
+ RT_CK_PT(pp);
+ Tcl_AppendResult(interp, "{in", (char *)NULL);
+ tclcad_rt_pr_hit(interp, pp->pt_inhit, pp->pt_inseg, pp->pt_inflip);
+ Tcl_AppendResult(interp, "\nout", (char *)NULL);
+ tclcad_rt_pr_hit(interp, pp->pt_outhit, pp->pt_outseg, pp->pt_outflip);
+ Tcl_AppendResult(interp,
+ "\nregion ",
+ pp->pt_regionp->reg_name,
+ (char *)NULL);
+ Tcl_AppendResult(interp, "}\n", (char *)NULL);
+ }
+
+ return 1;
+}
+
+
+int
+tclcad_rt_a_miss(struct application *ap)
+{
+ if (ap) RT_CK_APPLICATION(ap);
+ return 0;
+}
+
+
+/**
+ * Usage -
+ * procname shootray [-R] {P} dir|at {V}
+ * -R option specifies no overlap reporting
+ *
+ * Example -
+ * set glob_compat_mode 0
+ * .inmem rt_gettrees .rt all.g
+ * .rt shootray -R {0 0 0} dir {0 0 -1}
+ *
+ * set tgt [bu_get_value_by_keyword V [concat type [.inmem get LIGHT]]]
+ * .rt shootray {20 -13.5 20} at $tgt
+ *
+ *
+ * Returns -
+ * This "shootray" operation returns a nested set of lists. It
+ * returns a list of zero or more partitions. Inside each
+ * partition is a list containing an in, out, and region keyword,
+ * each with an associated value. The associated value for each
+ * "inhit" and "outhit" is itself a list containing a dist,
+ * point, normal, surfno, and solid keyword, each with an
+ * associated value.
+ */
+static int
+tclcad_rt_shootray(ClientData clientData, Tcl_Interp *interp, int argc, const
char *const *argv)
+{
+ struct application *ap = (struct application *)clientData;
+ struct rt_i *rtip;
+ int idx;
+
+ if ((argc != 5 && argc != 6) || (argc == 6 && !BU_STR_EQUAL(argv[2],
"-R"))) {
+ Tcl_AppendResult(interp,
+ "wrong # args: should be \"",
+ argv[0], " ", argv[1], " [-R] {P} dir|at {V}\"",
+ (char *)NULL);
+ return TCL_ERROR;
+ }
+
+ if (argc == 6) {
+ ap->a_logoverlap = rt_silent_logoverlap;
+ idx = 3;
+ } else {
+ idx = 2;
+ }
+
+ RT_CK_APPLICATION(ap);
+ rtip = ap->a_rt_i;
+ RT_CK_RTI(rtip);
+
+ if (tclcad_rt_parse_ray(interp, &ap->a_ray, &argv[idx]) == TCL_ERROR)
+ return TCL_ERROR;
+ ap->a_hit = tclcad_rt_a_hit;
+ ap->a_miss = tclcad_rt_a_miss;
+ ap->a_uptr = (void *)interp;
+
+ (void)rt_shootray(ap);
+
+ return TCL_OK;
+}
+
+
+/**
+ * Usage -
+ * procname onehit
+ * procname onehit #
+ */
+static int
+tclcad_rt_onehit(ClientData clientData, Tcl_Interp *interp, int argc, const
char *const *argv)
+{
+ struct application *ap = (struct application *)clientData;
+ struct rt_i *rtip;
+ char buf[64];
+
+ if (argc < 2 || argc > 3) {
+ Tcl_AppendResult(interp,
+ "wrong # args: should be \"",
+ argv[0], " ", argv[1], " [#]\"",
+ (char *)NULL);
+ return TCL_ERROR;
+ }
+
+ RT_CK_APPLICATION(ap);
+ rtip = ap->a_rt_i;
+ RT_CK_RTI(rtip);
+
+ if (argc == 3) {
+ ap->a_onehit = atoi(argv[2]);
+ }
+ sprintf(buf, "%d", ap->a_onehit);
+ Tcl_AppendResult(interp, buf, (char *)NULL);
+ return TCL_OK;
+}
+
+
+/**
+ * Usage -
+ * procname no_bool
+ * procname no_bool #
+ */
+int
+tclcad_rt_no_bool(ClientData clientData, Tcl_Interp *interp, int argc, const
char *const *argv)
+{
+ struct application *ap = (struct application *)clientData;
+ struct rt_i *rtip;
+ char buf[64];
+
+ if (argc < 2 || argc > 3) {
+ Tcl_AppendResult(interp,
+ "wrong # args: should be \"",
+ argv[0], " ", argv[1], " [#]\"",
+ (char *)NULL);
+ return TCL_ERROR;
+ }
+
+ RT_CK_APPLICATION(ap);
+ rtip = ap->a_rt_i;
+ RT_CK_RTI(rtip);
+
+ if (argc == 3) {
+ ap->a_no_booleans = atoi(argv[2]);
+ }
+ sprintf(buf, "%d", ap->a_no_booleans);
+ Tcl_AppendResult(interp, buf, (char *)NULL);
+ return TCL_OK;
+}
+
+
+/**
+ * Run some of the internal consistency checkers over the data
+ * structures.
+ *
+ * Usage -
+ * procname check
+ */
+int
+tclcad_rt_check(ClientData clientData, Tcl_Interp *interp, int argc, const
char *const *argv)
+{
+ struct application *ap = (struct application *)clientData;
+ struct rt_i *rtip;
+
+ if (argc != 2) {
+ Tcl_AppendResult(interp,
+ "wrong # args: should be \"",
+ argv[0], " ", argv[1], "\"",
+ (char *)NULL);
+ return TCL_ERROR;
+ }
+
+ RT_CK_APPLICATION(ap);
+ rtip = ap->a_rt_i;
+ RT_CK_RTI(rtip);
+
+ rt_ck(rtip);
+
+ return TCL_OK;
+}
+
+
+/**
+ * When run with no args, just prints current status of prepping.
+ *
+ * Usage -
+ * procname prep
+ * procname prep use_air [hasty_prep]
+ */
+int
+tclcad_rt_prep(ClientData clientData, Tcl_Interp *interp, int argc, const char
*const *argv)
+{
+ struct application *ap = (struct application *)clientData;
+ struct rt_i *rtip;
+ struct bu_vls str = BU_VLS_INIT_ZERO;
+
+ if (argc < 2 || argc > 4) {
+ Tcl_AppendResult(interp,
+ "wrong # args: should be \"",
+ argv[0], " ", argv[1],
+ " [hasty_prep]\"",
+ (char *)NULL);
+ return TCL_ERROR;
+ }
+
+ RT_CK_APPLICATION(ap);
+ rtip = ap->a_rt_i;
+ RT_CK_RTI(rtip);
+
+ if (argc >= 3 && !rtip->needprep) {
+ Tcl_AppendResult(interp,
+ argv[0], " ", argv[1],
+ " invoked when model has already been prepped.\n",
+ (char *)NULL);
+ return TCL_ERROR;
+ }
+
+ if (argc == 4) rtip->rti_hasty_prep = atoi(argv[3]);
+
+ /* If args were given, prep now. */
+ if (argc >= 3) rt_prep_parallel(rtip, 1);
+
+ /* Now, describe the current state */
+ bu_vls_printf(&str, "hasty_prep %d dont_instance %d useair %d needprep %d",
+ rtip->rti_hasty_prep,
+ rtip->rti_dont_instance,
+ rtip->useair,
+ rtip->needprep
+ );
+
+ bu_vls_printf(&str, " space_partition_type %s n_cutnode %d n_boxnode %d
n_empty %ld",
+ rtip->rti_space_partition == RT_PART_NUBSPT ?
+ "NUBSP" : "unknown",
+ rtip->rti_ncut_by_type[CUT_CUTNODE],
+ rtip->rti_ncut_by_type[CUT_BOXNODE],
+ rtip->nempty_cells);
+ bu_vls_printf(&str, " maxdepth %d maxlen %d",
+ rtip->rti_cut_maxdepth,
+ rtip->rti_cut_maxlen);
+ if (rtip->rti_ncut_by_type[CUT_BOXNODE]) bu_vls_printf(&str, " avglen %g",
+
((double)rtip->rti_cut_totobj) /
+
rtip->rti_ncut_by_type[CUT_BOXNODE]);
+
+ Tcl_AppendResult(interp, bu_vls_addr(&str), (char *)NULL);
+ bu_vls_free(&str);
+ return TCL_OK;
+}
+
+
+/**
+ * Set/get the rt object's settable variables.
+ *
+ * This replaces onehit and no_bool.
+ *
+ * Usage -
+ * procname set
+ * procname set vname
+ * procname set vname val
+ */
+int
+tclcad_rt_set(ClientData clientData, Tcl_Interp *interp, int argc, const char
*const *argv)
+{
+ struct application *ap = (struct application *)clientData;
+ struct rt_i *rtip;
+ struct bu_vls str = BU_VLS_INIT_ZERO;
+ int val;
+ const char *usage = "[vname [val]]";
+
+ if (argc < 2 || argc > 4) {
+ bu_vls_printf(&str, "%s %s: %s", argv[0], argv[1], usage);
+ Tcl_AppendResult(interp, bu_vls_addr(&str), (char *)NULL);
+ bu_vls_free(&str);
+
+ return TCL_ERROR;
+ }
+
+ RT_CK_APPLICATION(ap);
+ rtip = ap->a_rt_i;
+ RT_CK_RTI(rtip);
+
+ /* Return a list of the settable variables and their values */
+ if (argc == 2) {
+ bu_vls_printf(&str, "{onehit %d} ", ap->a_onehit);
+ bu_vls_printf(&str, "{no_bool %d} ", ap->a_no_booleans);
+ bu_vls_printf(&str, "{bot_reverse_normal_disabled %d}",
ap->a_bot_reverse_normal_disabled);
+ Tcl_AppendResult(interp, bu_vls_addr(&str), (char *)NULL);
+ bu_vls_free(&str);
+
+ return TCL_OK;
+ }
+
+ if (argc == 4 && sscanf(argv[3], "%d", &val) != 1) {
+ bu_vls_printf(&str, "%s %s: bad val - %s, must be an integer", argv[0],
argv[1], argv[3]);
+ Tcl_AppendResult(interp, bu_vls_addr(&str), (char *)NULL);
+ bu_vls_free(&str);
+
+ return TCL_ERROR;
+ }
+
+ if (argv[2][0] == 'o' && !bu_strncmp(argv[2], "onehit", 6)) {
+ if (argc == 3)
+ val = ap->a_onehit;
+ else
+ ap->a_onehit = val;
+ } else if (argv[2][0] == 'n' && !bu_strncmp(argv[2], "no_bool", 7)) {
+ if (argc == 3)
+ val = ap->a_no_booleans;
+ else
+ ap->a_no_booleans = val;
+ } else if (argv[2][0] == 'b' && !bu_strncmp(argv[2],
"bot_reverse_normal_disabled", 27)) {
+ if (argc == 3)
+ val = ap->a_bot_reverse_normal_disabled;
+ else
+ ap->a_bot_reverse_normal_disabled = val;
+ } else {
+ bu_vls_printf(&str, "%s %s: bad val - %s, must be one of the following:
onehit, no_bool, or bot_reverse_normal_disabled",
+ argv[0], argv[1], argv[2]);
+ Tcl_AppendResult(interp, bu_vls_addr(&str), (char *)NULL);
+ bu_vls_free(&str);
+
+ return TCL_ERROR;
+ }
+
+ bu_vls_printf(&str, "%d", val);
+ Tcl_AppendResult(interp, bu_vls_addr(&str), (char *)NULL);
+ bu_vls_free(&str);
+ return TCL_OK;
+}
+
+
+int
+tclcad_rt(ClientData clientData, Tcl_Interp *interp, int argc, const char
**argv)
+{
+ struct dbcmdstruct *dbcmd;
+
+ if (argc < 2) {
+ Tcl_AppendResult(interp,
+ "wrong # args: should be \"", argv[0],
+ " command [args...]\"",
+ (char *)NULL);
+ return TCL_ERROR;
+ }
+
+ for (dbcmd = tclcad_rt_cmds; dbcmd->cmdname != NULL; dbcmd++) {
+ if (BU_STR_EQUAL(dbcmd->cmdname, argv[1])) {
+ /* need proper cmd func pointer for actual call */
+ int (*_cmdfunc)(void*, Tcl_Interp*, int, const char* const*);
+ /* cast to the actual caller */
+ _cmdfunc = (int (*)(void*, Tcl_Interp*, int, const char*
const*))(*dbcmd->cmdfunc);
+ return _cmdfunc(clientData, interp, argc, argv);
+ }
+ }
+
+
+ Tcl_AppendResult(interp, "unknown LIBRT command '",
+ argv[1], "'; must be one of:",
+ (char *)NULL);
+ for (dbcmd = tclcad_rt_cmds; dbcmd->cmdname != NULL; dbcmd++) {
+ Tcl_AppendResult(interp, " ", dbcmd->cmdname, (char *)NULL);
+ }
+ return TCL_ERROR;
+}
+
+
+/************************************************************************
+ * *
+ * Tcl interface to Combination management *
+ * *
+ ************************************************************************/
+
+int
+tclcad_rt_import_from_path(Tcl_Interp *interp, struct rt_db_internal *ip,
const char *path, struct rt_wdb *wdb)
+{
+ struct db_i *dbip;
+ int status;
+
+ /* Can't run RT_CK_DB_INTERNAL(ip), it hasn't been filled in yet */
+ RT_CK_WDB(wdb);
+ dbip = wdb->dbip;
+ RT_CK_DBI(dbip);
+
+ if (strchr(path, '/')) {
+ /* This is a path */
+ struct db_tree_state ts;
+ struct db_full_path old_path;
+ struct db_full_path new_path;
+ struct directory *dp_curr;
+ int ret;
+
+ db_init_db_tree_state(&ts, dbip, &rt_uniresource);
+ db_full_path_init(&old_path);
+ db_full_path_init(&new_path);
+
+ if (db_string_to_path(&new_path, dbip, path) < 0) {
+ Tcl_AppendResult(interp, "tclcad_rt_import_from_path: '",
+ path, "' contains unknown object names\n", (char
*)NULL);
+ return TCL_ERROR;
+ }
+
+ dp_curr = DB_FULL_PATH_CUR_DIR(&new_path);
+ if (!dp_curr)
+ return TCL_ERROR;
+
+ ret = db_follow_path(&ts, &old_path, &new_path, LOOKUP_NOISY, 0);
+ db_free_full_path(&old_path);
+ db_free_full_path(&new_path);
+
+ if (ret < 0) {
+ Tcl_AppendResult(interp, "tclcad_rt_import_from_path: '",
+ path, "' is a bad path\n", (char *)NULL);
+ return TCL_ERROR;
+ }
+
+ status = wdb_import(wdb, ip, dp_curr->d_namep, ts.ts_mat);
+ if (status == -4) {
+ Tcl_AppendResult(interp, dp_curr->d_namep,
+ " not found in path ", path, "\n",
+ (char *)NULL);
+ return TCL_ERROR;
+ }
+ if (status < 0) {
+ Tcl_AppendResult(interp, "wdb_import failure: ",
+ dp_curr->d_namep, (char *)NULL);
+ return TCL_ERROR;
+ }
+ } else {
+ status = wdb_import(wdb, ip, path, (matp_t)NULL);
+ if (status == -4) {
+ Tcl_AppendResult(interp, path, ": not found\n",
+ (char *)NULL);
+ return TCL_ERROR;
+ }
+ if (status < 0) {
+ Tcl_AppendResult(interp, "wdb_import failure: ",
+ path, (char *)NULL);
+ return TCL_ERROR;
+ }
+ }
+ return TCL_OK;
+}
+
+
+void
+tclcad_rt_setup(Tcl_Interp *interp)
+{
+ Tcl_LinkVar(interp, "rt_bot_minpieces", (char *)&rt_bot_minpieces,
TCL_LINK_WIDE_INT);
+
+ Tcl_LinkVar(interp, "rt_bot_tri_per_piece",
+ (char *)&rt_bot_tri_per_piece, TCL_LINK_WIDE_INT);
+}
+
+
+int
+Rt_Init(Tcl_Interp *interp)
+{
+ /*XXX how much will this break? */
+ if (!BU_LIST_IS_INITIALIZED(&RTG.rtg_vlfree)) {
+ if (bu_avail_cpus() > 1) {
+ RTG.rtg_parallel = 1;
+ }
+
+ /* initialize RT's global state */
+ BU_LIST_INIT(&RTG.rtg_vlfree);
+ BU_LIST_INIT(&RTG.rtg_headwdb.l);
+ if (rt_uniresource.re_magic != RESOURCE_MAGIC) {
+ rt_init_resource(&rt_uniresource, 0, NULL);
+ }
+ }
+
+ tclcad_rt_setup(interp);
+
+ Tcl_PkgProvide(interp, "Rt", brlcad_version());
+
+ return TCL_OK;
+}
+
+
+/* ====================================================================== */
+
+/* TCL-oriented C support for LIBRT */
+
+
+void
+db_full_path_appendresult(Tcl_Interp *interp, const struct db_full_path *pp)
+{
+ size_t i;
+
+ RT_CK_FULL_PATH(pp);
+
+ for (i=0; i<pp->fp_len; i++) {
+ Tcl_AppendResult(interp, "/", pp->fp_names[i]->d_namep, (char *)NULL);
+ }
+}
+
+
+int
+tcl_obj_to_int_array(Tcl_Interp *interp, Tcl_Obj *list, int **array, int
*array_len)
+{
+ Tcl_Obj **obj_array;
+ int len, i;
+
+ if (Tcl_ListObjGetElements(interp, list, &len, &obj_array) != TCL_OK)
+ return 0;
+
+ if (len < 1)
+ return 0;
+
+ if (*array_len < 1) {
+ *array = (int *)bu_calloc(len, sizeof(int), "array");
+ *array_len = len;
+ }
+
+ for (i=0; i<len && i<*array_len; i++) {
+ (*array)[i] = atoi(Tcl_GetStringFromObj(obj_array[i], NULL));
+ Tcl_DecrRefCount(obj_array[i]);
+ }
+
+ return len < *array_len ? len : *array_len;
+}
+
+
+int
+tcl_list_to_int_array(Tcl_Interp *interp, char *char_list, int **array, int
*array_len)
+{
+ Tcl_Obj *obj;
+ int ret;
+
+ obj = Tcl_NewStringObj(char_list, -1);
+
+ ret = tcl_obj_to_int_array(interp, obj, array, array_len);
+
+ return ret;
+}
+
+
+int
+tcl_obj_to_fastf_array(Tcl_Interp *interp, Tcl_Obj *list, fastf_t **array, int
*array_len)
+{
+ Tcl_Obj **obj_array;
+ int len, i;
+ int ret;
+
+ if ((ret=Tcl_ListObjGetElements(interp, list, &len, &obj_array)) != TCL_OK)
+ return ret;
+
+ if (len < 1)
+ return 0;
+
+ if (*array_len < 1) {
+ *array = (fastf_t *)bu_calloc(len, sizeof(fastf_t), "array");
+ *array_len = len;
+ }
+
+ for (i=0; i<len && i<*array_len; i++) {
+ (*array)[i] = atof(Tcl_GetStringFromObj(obj_array[i], NULL));
+ Tcl_DecrRefCount(obj_array[i]);
+ }
+
+ return len < *array_len ? len : *array_len;
+}
+
+
+int
+tcl_list_to_fastf_array(Tcl_Interp *interp, const char *char_list, fastf_t
**array, int *array_len)
+{
+ Tcl_Obj *obj;
+ int ret;
+
+ obj = Tcl_NewStringObj(char_list, -1);
+
+ ret = tcl_obj_to_fastf_array(interp, obj, array, array_len);
+
+ return ret;
+}
+
+
+
+/*
+ * Local Variables:
+ * mode: C
+ * tab-width: 8
+ * indent-tabs-mode: t
+ * c-file-style: "stroustrup"
+ * End:
+ * ex: shiftwidth=4 tabstop=8
+ */
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
_______________________________________________
BRL-CAD Source Commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/brlcad-commits