Revision: 76327 http://sourceforge.net/p/brlcad/code/76327 Author: starseeker Date: 2020-07-14 18:47:49 +0000 (Tue, 14 Jul 2020) Log Message: ----------- Group bu and bn lib functions into their own files
Modified Paths: -------------- brlcad/trunk/src/libtclcad/CMakeLists.txt brlcad/trunk/src/libtclcad/libfuncs.c Added Paths: ----------- brlcad/trunk/src/libtclcad/bn_funcs.c brlcad/trunk/src/libtclcad/bu_funcs.c Modified: brlcad/trunk/src/libtclcad/CMakeLists.txt =================================================================== --- brlcad/trunk/src/libtclcad/CMakeLists.txt 2020-07-14 16:34:25 UTC (rev 76326) +++ brlcad/trunk/src/libtclcad/CMakeLists.txt 2020-07-14 18:47:49 UTC (rev 76327) @@ -1,4 +1,6 @@ set(LIBTCLCAD_SRCS + bu_funcs.c + bn_funcs.c libfuncs.c tclcad.c tclcadAutoPath.c Added: brlcad/trunk/src/libtclcad/bn_funcs.c =================================================================== --- brlcad/trunk/src/libtclcad/bn_funcs.c (rev 0) +++ brlcad/trunk/src/libtclcad/bn_funcs.c 2020-07-14 18:47:49 UTC (rev 76327) @@ -0,0 +1,1378 @@ +/* B N _ 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/bn_funcs.c + * + * BRL-CAD's Tcl wrappers for libbn. + * + */ + +#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 "bu.h" +#include "bn.h" +#include "tclcad.h" + + +/* Private headers */ +#include "brlcad_version.h" +#include "tclcad_private.h" + +void +bn_quat_distance_wrapper(double *dp, mat_t q1, mat_t q2) +{ + *dp = quat_distance(q1, q2); +} + + +static void +bn_mat4x3vec(fastf_t *o, mat_t m, vect_t i) +{ + MAT4X3VEC(o, m, i); +} + + +static void +bn_hdivide(fastf_t *o, const mat_t i) +{ + HDIVIDE(o, i); +} + +static int +tclcad_bn_dist_pnt2_lseg2(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) +{ + struct bu_vls result = BU_VLS_INIT_ZERO; + point_t ptA, ptB, pca; + point_t pt; + fastf_t dist; + int ret; + static const struct bn_tol tol = { + BN_TOL_MAGIC, BN_TOL_DIST, BN_TOL_DIST*BN_TOL_DIST, 1e-6, 1-1e-6 + }; + + if (argc != 4) { + bu_vls_printf(&result, + "Usage: bn_dist_pnt2_lseg2 pntA pntB pnt (%d args specified)", argc-1); + goto error; + } + + if (bn_decode_vect(ptA, argv[1]) < 2) { + bu_vls_printf(&result, "bn_dist_pnt2_lseg2 no pntA: %s\n", argv[0]); + goto error; + } + + if (bn_decode_vect(ptB, argv[2]) < 2) { + bu_vls_printf(&result, "bn_dist_pnt2_lseg2 no pntB: %s\n", argv[0]); + goto error; + } + + if (bn_decode_vect(pt, argv[3]) < 2) { + bu_vls_printf(&result, "bn_dist_pnt2_lseg2 no pnt: %s\n", argv[0]); + goto error; + } + + ret = bn_dist_pnt2_lseg2(&dist, pca, ptA, ptB, pt, &tol); + switch (ret) { + case 0: + case 1: + case 2: + dist = 0.0; + break; + default: + break; + } + + bu_vls_printf(&result, "%g", dist); + + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_OK; + +error: + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_ERROR; + +} + +static int +tclcad_bn_isect_line2_line2(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) +{ + struct bu_vls result = BU_VLS_INIT_ZERO; + fastf_t dist[2]; + point_t pt = VINIT_ZERO; + point_t a = VINIT_ZERO; + vect_t dir = VINIT_ZERO; + vect_t c = VINIT_ZERO; + int i; + static const struct bn_tol tol = { + BN_TOL_MAGIC, BN_TOL_DIST, BN_TOL_DIST*BN_TOL_DIST, 1e-6, 1-1e-6 + }; + + if (argc != 5) { + bu_vls_printf(&result, + "Usage: bn_isect_line2_line2 pt dir pt dir (%d args specified)", + argc-1); + goto error; + } + + /* i = bn_isect_line2_line2 {0 0} {1 0} {1 1} {0 -1} */ + + if (bn_decode_vect(pt, argv[1]) < 2) { + bu_vls_printf(&result, "bn_isect_line2_line2 no pt: %s\n", argv[0]); + goto error; + } + if (bn_decode_vect(dir, argv[2]) < 2) { + bu_vls_printf(&result, "bn_isect_line2_line2 no dir: %s\n", argv[0]); + goto error; + } + if (bn_decode_vect(a, argv[3]) < 2) { + bu_vls_printf(&result, "bn_isect_line2_line2 no a pt: %s\n", argv[0]); + goto error; + } + if (bn_decode_vect(c, argv[4]) < 2) { + bu_vls_printf(&result, "bn_isect_line2_line2 no c dir: %s\n", argv[0]); + goto error; + } + i = bn_isect_line2_line2(dist, pt, dir, a, c, &tol); + if (i != 1) { + bu_vls_printf(&result, "bn_isect_line2_line2 no intersection: %s\n", argv[0]); + goto error; + } + + VJOIN1(a, pt, dist[0], dir); + bu_vls_printf(&result, "%g %g", V2INTCLAMPARGS(a)); + + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_OK; + +error: + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_ERROR; +} + +static int +tclcad_bn_isect_line3_line3(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) +{ + struct bu_vls result = BU_VLS_INIT_ZERO; + + fastf_t t, u; + point_t pt, a; + vect_t dir, c; + int i; + static const struct bn_tol tol = { + BN_TOL_MAGIC, BN_TOL_DIST, BN_TOL_DIST*BN_TOL_DIST, 1e-6, 1-1e-6 + }; + if (argc != 5) { + bu_vls_printf(&result, + "Usage: bn_isect_line3_line3 pt dir pt dir (%d args specified)", + argc-1); + goto error; + } + + if (bn_decode_vect(pt, argv[1]) < 3) { + bu_vls_printf(&result, "bn_isect_line3_line3 no pt: %s\n", argv[0]); + goto error; + } + if (bn_decode_vect(dir, argv[2]) < 3) { + bu_vls_printf(&result, "bn_isect_line3_line3 no dir: %s\n", argv[0]); + goto error; + } + if (bn_decode_vect(a, argv[3]) < 3) { + bu_vls_printf(&result, "bn_isect_line3_line3 no a pt: %s\n", argv[0]); + goto error; + } + if (bn_decode_vect(c, argv[4]) < 3) { + bu_vls_printf(&result, "bn_isect_line3_line3 no c dir: %s\n", argv[0]); + goto error; + } + i = bn_isect_line3_line3(&t, &u, pt, dir, a, c, &tol); + if (i != 1) { + bu_vls_printf(&result, "bn_isect_line3_line3 no intersection: %s\n", argv[0]); + goto error; + } + + VJOIN1(a, pt, t, dir); + bn_encode_vect(&result, a, 1); + + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_OK; + +error: + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_ERROR; +} + + +static int +tclcad_bn_mat_inv(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) +{ + struct bu_vls result = BU_VLS_INIT_ZERO; + + mat_t o, a; + + if (argc < 2 || bn_decode_mat(a, argv[1]) < 16) { + bu_vls_printf(&result, "usage: %s mat", argv[0]); + goto error; + } + bn_mat_inv(o, a); + bn_encode_mat(&result, o, 1); + + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_OK; + +error: + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_ERROR; +} + + +static int +tclcad_bn_mat_trn(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) +{ + struct bu_vls result = BU_VLS_INIT_ZERO; + + mat_t o, a; + + if (argc < 2 || bn_decode_mat(a, argv[1]) < 16) { + bu_vls_printf(&result, "usage: %s mat", argv[0]); + goto error; + } + bn_mat_trn(o, a); + bn_encode_mat(&result, o, 1); + + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_OK; + +error: + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_ERROR; +} + + +static int +tclcad_bn_matXvec(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) +{ + struct bu_vls result = BU_VLS_INIT_ZERO; + + mat_t m; + hvect_t i, o; + if (argc < 3 || bn_decode_mat(m, argv[1]) < 16 || + bn_decode_hvect(i, argv[2]) < 4) { + bu_vls_printf(&result, "usage: %s mat hvect", argv[0]); + goto error; + } + bn_matXvec(o, m, i); + bn_encode_hvect(&result, o, 1); + + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_OK; + +error: + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_ERROR; +} + +static int +tclcad_bn_mat4x3vec(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) +{ + struct bu_vls result = BU_VLS_INIT_ZERO; + mat_t m; + vect_t i, o; + MAT_ZERO(m); + if (argc < 3 || bn_decode_mat(m, argv[1]) < 16 || + bn_decode_vect(i, argv[2]) < 3) { + bu_vls_printf(&result, "usage: %s mat vect", argv[0]); + goto error; + } + bn_mat4x3vec(o, m, i); + bn_encode_vect(&result, o, 1); + + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_OK; + +error: + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_ERROR; +} + + +static int +tclcad_bn_hdivide(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) +{ + struct bu_vls result = BU_VLS_INIT_ZERO; + hvect_t i; + vect_t o; + if (argc < 2 || bn_decode_hvect(i, argv[1]) < 4) { + bu_vls_printf(&result, "usage: %s hvect", argv[0]); + goto error; + } + bn_hdivide(o, i); + bn_encode_vect(&result, o, 1); + + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_OK; + +error: + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_ERROR; +} + +static int +tclcad_bn_vjoin1(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) +{ + struct bu_vls result = BU_VLS_INIT_ZERO; + point_t o; + point_t b, d; + double c; + + if (argc < 4) { + bu_vls_printf(&result, "usage: %s pnt scale dir", argv[0]); + goto error; + } + if (bn_decode_vect(b, argv[1]) < 3) goto error; + if (Tcl_GetDouble(interp, argv[2], &c) != TCL_OK) goto error; + if (bn_decode_vect(d, argv[3]) < 3) goto error; + + VJOIN1(o, b, c, d); /* bn_vjoin1(o, b, c, d) */ + bn_encode_vect(&result, o, 1); + + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_OK; + +error: + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_ERROR; +} + +static int +tclcad_bn_vblend(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) +{ + struct bu_vls result = BU_VLS_INIT_ZERO; + point_t a, c, e; + double b, d; + + if (argc < 5) { + bu_vls_printf(&result, "usage: %s scale pnt scale pnt", argv[0]); + goto error; + } + + if (Tcl_GetDouble(interp, argv[1], &b) != TCL_OK) goto error; + if (bn_decode_vect(c, argv[2]) < 3) goto error; + if (Tcl_GetDouble(interp, argv[3], &d) != TCL_OK) goto error; + if (bn_decode_vect(e, argv[4]) < 3) goto error; + + VBLEND2(a, b, c, d, e); + bn_encode_vect(&result, a, 1); + + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_OK; + +error: + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_ERROR; +} + +static int +tclcad_bn_ae_vec(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) +{ + struct bu_vls result = BU_VLS_INIT_ZERO; + fastf_t az, el; + vect_t v; + + if (argc < 2 || bn_decode_vect(v, argv[1]) < 3) { + bu_vls_printf(&result, "usage: %s vect", argv[0]); + goto error; + } + + bn_ae_vec(&az, &el, v); + bu_vls_printf(&result, "%g %g", az, el); + + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_OK; + +error: + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_ERROR; +} + +static int +tclcad_bn_aet_vec(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) +{ + struct bu_vls result = BU_VLS_INIT_ZERO; + double acc; + fastf_t az, el, twist, accuracy; + vect_t vec_ae, vec_twist; + + if (argc < 4 || bn_decode_vect(vec_ae, argv[1]) < 3 || + bn_decode_vect(vec_twist, argv[2]) < 3 || + sscanf(argv[3], "%lf", &acc) < 1) { + bu_vls_printf(&result, "usage: %s vec_ae vec_twist accuracy", + argv[0]); + goto error; + } + accuracy = acc; + + bn_aet_vec(&az, &el, &twist, vec_ae, vec_twist, accuracy); + bu_vls_printf(&result, "%g %g %g", az, el, twist); + + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_OK; + +error: + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_ERROR; +} + +static int +tclcad_bn_mat_angles(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) +{ + struct bu_vls result = BU_VLS_INIT_ZERO; + mat_t o; + double alpha, beta, ggamma; + + if (argc < 4) { + bu_vls_printf(&result, "usage: %s alpha beta gamma", argv[0]); + goto error; + } + if (Tcl_GetDouble(interp, argv[1], &alpha) != TCL_OK) goto error; + if (Tcl_GetDouble(interp, argv[2], &beta) != TCL_OK) goto error; + if (Tcl_GetDouble(interp, argv[3], &ggamma) != TCL_OK) goto error; + + bn_mat_angles(o, alpha, beta, ggamma); + bn_encode_mat(&result, o, 1); + + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_OK; + +error: + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_ERROR; +} + +static int +tclcad_bn_eigen2x2(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) +{ + struct bu_vls result = BU_VLS_INIT_ZERO; + fastf_t val1, val2; + vect_t vec1, vec2; + double a, b, c; + + if (argc < 4) { + bu_vls_printf(&result, "usage: %s a b c", argv[0]); + goto error; + } + if (Tcl_GetDouble(interp, argv[1], &a) != TCL_OK) goto error; + if (Tcl_GetDouble(interp, argv[2], &c) != TCL_OK) goto error; + if (Tcl_GetDouble(interp, argv[3], &b) != TCL_OK) goto error; + + bn_eigen2x2(&val1, &val2, vec1, vec2, (fastf_t)a, (fastf_t)b, + (fastf_t)c); + bu_vls_printf(&result, "%g %g {%g %g %g} {%g %g %g}", INTCLAMP(val1), INTCLAMP(val2), + V3INTCLAMPARGS(vec1), V3INTCLAMPARGS(vec2)); + + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_OK; + +error: + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_ERROR; +} + +static int +tclcad_bn_mat_fromto(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) +{ + struct bu_vls result = BU_VLS_INIT_ZERO; + mat_t o; + vect_t from, to; + static const struct bn_tol tol = { + BN_TOL_MAGIC, BN_TOL_DIST, BN_TOL_DIST*BN_TOL_DIST, 1e-6, 1-1e-6 + }; + + if (argc < 3 || bn_decode_vect(from, argv[1]) < 3 || + bn_decode_vect(to, argv[2]) < 3) { + bu_vls_printf(&result, "usage: %s vecFrom vecTo", argv[0]); + goto error; + } + bn_mat_fromto(o, from, to, &tol); + bn_encode_mat(&result, o, 1); + + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_OK; + +error: + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_ERROR; +} + + +static int +tclcad_bn_mat_xrot(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) +{ + struct bu_vls result = BU_VLS_INIT_ZERO; + mat_t o; + double s, c; + + if (argc < 3) { + bu_vls_printf(&result, "usage: %s sinAngle cosAngle", argv[0]); + goto error; + } + if (Tcl_GetDouble(interp, argv[1], &s) != TCL_OK) goto error; + if (Tcl_GetDouble(interp, argv[2], &c) != TCL_OK) goto error; + + bn_mat_xrot(o, s, c); + bn_encode_mat(&result, o, 1); + + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_OK; + +error: + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_ERROR; +} + + +static int +tclcad_bn_mat_yrot(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) +{ + struct bu_vls result = BU_VLS_INIT_ZERO; + mat_t o; + double s, c; + + if (argc < 3) { + bu_vls_printf(&result, "usage: %s sinAngle cosAngle", argv[0]); + goto error; + } + if (Tcl_GetDouble(interp, argv[1], &s) != TCL_OK) goto error; + if (Tcl_GetDouble(interp, argv[2], &c) != TCL_OK) goto error; + + bn_mat_yrot(o, s, c); + bn_encode_mat(&result, o, 1); + + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_OK; + +error: + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_ERROR; +} + + +static int +tclcad_bn_mat_zrot(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) +{ + struct bu_vls result = BU_VLS_INIT_ZERO; + mat_t o; + double s, c; + + if (argc < 3) { + bu_vls_printf(&result, "usage: %s sinAngle cosAngle", argv[0]); + goto error; + } + if (Tcl_GetDouble(interp, argv[1], &s) != TCL_OK) goto error; + if (Tcl_GetDouble(interp, argv[2], &c) != TCL_OK) goto error; + + bn_mat_zrot(o, s, c); + bn_encode_mat(&result, o, 1); + + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_OK; + +error: + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_ERROR; +} + + +static int +tclcad_bn_mat_lookat(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) +{ + struct bu_vls result = BU_VLS_INIT_ZERO; + mat_t o; + vect_t dir; + int yflip; + if (argc < 3 || bn_decode_vect(dir, argv[1]) < 3) { + bu_vls_printf(&result, "usage: %s dir yflip", argv[0]); + goto error; + } + if (Tcl_GetBoolean(interp, argv[2], &yflip) != TCL_OK) goto error; + + bn_mat_lookat(o, dir, yflip); + bn_encode_mat(&result, o, 1); + + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_OK; + +error: + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_ERROR; +} + + +static int +tclcad_bn_vec_ortho(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) +{ + struct bu_vls result = BU_VLS_INIT_ZERO; + vect_t ov, vec; + + if (argc < 2 || bn_decode_vect(vec, argv[1]) < 3) { + bu_vls_printf(&result, "usage: %s vec", argv[0]); + goto error; + } + + bn_vec_ortho(ov, vec); + bn_encode_vect(&result, ov, 1); + + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_OK; + +error: + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_ERROR; +} + + +static int +tclcad_bn_vec_perp(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) +{ + struct bu_vls result = BU_VLS_INIT_ZERO; + vect_t ov, vec; + + if (argc < 2 || bn_decode_vect(vec, argv[1]) < 3) { + bu_vls_printf(&result, "usage: %s vec", argv[0]); + goto error; + } + + bn_vec_perp(ov, vec); + bn_encode_vect(&result, ov, 1); + + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_OK; + +error: + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_ERROR; +} + + +static int +tclcad_bn_mat_xform_about_pnt(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) +{ + struct bu_vls result = BU_VLS_INIT_ZERO; + mat_t o, xform; + vect_t v; + + if (argc < 3 || bn_decode_mat(xform, argv[1]) < 16 || + bn_decode_vect(v, argv[2]) < 3) { + bu_vls_printf(&result, "usage: %s xform pt", argv[0]); + goto error; + } + + bn_mat_xform_about_pnt(o, xform, v); + bn_encode_mat(&result, o, 1); + + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_OK; + +error: + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_ERROR; +} + + +static int +tclcad_bn_mat_arb_rot(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) +{ + struct bu_vls result = BU_VLS_INIT_ZERO; + mat_t o; + point_t pt; + vect_t dir; + double angle; + + if (argc < 4 || bn_decode_vect(pt, argv[1]) < 3 || + bn_decode_vect(dir, argv[2]) < 3) { + bu_vls_printf(&result, "usage: %s pt dir angle", argv[0]); + goto error; + } + if (Tcl_GetDouble(interp, argv[3], &angle) != TCL_OK) + return TCL_ERROR; + + bn_mat_arb_rot(o, pt, dir, (fastf_t)angle); + bn_encode_mat(&result, o, 1); + + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_OK; + +error: + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_ERROR; +} + + +static int +tclcad_bn_quat_mat2quat(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) +{ + struct bu_vls result = BU_VLS_INIT_ZERO; + mat_t mat; + quat_t quat; + + if (argc < 2 || bn_decode_mat(mat, argv[1]) < 16) { + bu_vls_printf(&result, "usage: %s mat", argv[0]); + goto error; + } + + quat_mat2quat(quat, mat); + bn_encode_quat(&result, quat, 1); + + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_OK; + +error: + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_ERROR; +} + + +static int +tclcad_bn_quat_quat2mat(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) +{ + struct bu_vls result = BU_VLS_INIT_ZERO; + mat_t mat; + quat_t quat; + + if (argc < 2 || bn_decode_quat(quat, argv[1]) < 4) { + bu_vls_printf(&result, "usage: %s quat", argv[0]); + goto error; + } + + quat_quat2mat(mat, quat); + bn_encode_mat(&result, mat, 1); + + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_OK; + +error: + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_ERROR; +} + +static int +tclcad_bn_quat_distance(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) +{ + struct bu_vls result = BU_VLS_INIT_ZERO; + quat_t q1, q2; + double d; + + if (argc < 3 || bn_decode_quat(q1, argv[1]) < 4 || + bn_decode_quat(q2, argv[2]) < 4) { + bu_vls_printf(&result, "usage: %s quatA quatB", argv[0]); + goto error; + } + + bn_quat_distance_wrapper(&d, q1, q2); + bu_vls_printf(&result, "%g", d); + + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_OK; + +error: + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_ERROR; +} + +static int +tclcad_bn_quat_double(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) +{ + struct bu_vls result = BU_VLS_INIT_ZERO; + quat_t oqot, q1, q2; + + if (argc < 3 || bn_decode_quat(q1, argv[1]) < 4 || + bn_decode_quat(q2, argv[2]) < 4) { + bu_vls_printf(&result, "usage: %s quatA quatB", argv[0]); + goto error; + } + + quat_double(oqot, q1, q2); + bn_encode_quat(&result, oqot, 1); + + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_OK; + +error: + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_ERROR; +} + + + +static int +tclcad_bn_quat_bisect(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) +{ + struct bu_vls result = BU_VLS_INIT_ZERO; + quat_t oqot, q1, q2; + + if (argc < 3 || bn_decode_quat(q1, argv[1]) < 4 || + bn_decode_quat(q2, argv[2]) < 4) { + bu_vls_printf(&result, "usage: %s quatA quatB", argv[0]); + goto error; + } + + quat_bisect(oqot, q1, q2); + bn_encode_quat(&result, oqot, 1); + + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_OK; + +error: + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_ERROR; +} + + + +static int +tclcad_bn_quat_make_nearest(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) +{ + struct bu_vls result = BU_VLS_INIT_ZERO; + quat_t oqot, q1; + + if (argc < 2 || bn_decode_quat(oqot, argv[1]) < 4) { + bu_vls_printf(&result, "usage: %s orig_quat", argv[0]); + goto error; + } + + quat_make_nearest(q1, oqot); + bn_encode_quat(&result, q1, 1); + + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_OK; + +error: + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_ERROR; +} + +static int +tclcad_bn_quat_slerp(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) +{ + struct bu_vls result = BU_VLS_INIT_ZERO; + quat_t oq, q1, q2; + double d; + + if (argc < 4 || bn_decode_quat(q1, argv[1]) < 4 || + bn_decode_quat(q2, argv[2]) < 4) { + bu_vls_printf(&result, "usage: %s quat1 quat2 factor", argv[0]); + goto error; + } + if (Tcl_GetDouble(interp, argv[3], &d) != TCL_OK) goto error; + + quat_slerp(oq, q1, q2, d); + bn_encode_quat(&result, oq, 1); + + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_OK; + +error: + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_ERROR; +} + + + +static int +tclcad_bn_quat_sberp(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) +{ + struct bu_vls result = BU_VLS_INIT_ZERO; + quat_t oq, q1, qa, qb, q2; + double d; + + if (argc < 6 || bn_decode_quat(q1, argv[1]) < 4 || + bn_decode_quat(qa, argv[2]) < 4 || bn_decode_quat(qb, argv[3]) < 4 || + bn_decode_quat(q2, argv[4]) < 4) { + bu_vls_printf(&result, "usage: %s quat1 quatA quatB quat2 factor", + argv[0]); + goto error; + } + if (Tcl_GetDouble(interp, argv[5], &d) != TCL_OK) goto error; + + quat_sberp(oq, q1, qa, qb, q2, d); + bn_encode_quat(&result, oq, 1); + + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_OK; + +error: + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_ERROR; +} + + + +static int +tclcad_bn_quat_exp(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) +{ + struct bu_vls result = BU_VLS_INIT_ZERO; + quat_t qout, qin; + + if (argc < 2 || bn_decode_quat(qin, argv[1]) < 4) { + bu_vls_printf(&result, "usage: %s quat", argv[0]); + goto error; + } + + quat_exp(qout, qin); + bn_encode_quat(&result, qout, 1); + + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_OK; + +error: + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_ERROR; +} + + +static int +tclcad_bn_quat_log(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) +{ + struct bu_vls result = BU_VLS_INIT_ZERO; + quat_t qout, qin; + + if (argc < 2 || bn_decode_quat(qin, argv[1]) < 4) { + bu_vls_printf(&result, "usage: %s quat", argv[0]); + goto error; + } + + quat_log(qout, qin); + bn_encode_quat(&result, qout, 1); + + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_OK; + +error: + Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); + bu_vls_free(&result); + return TCL_ERROR; +} + + +#define BN_FUNC_TCL_CAST(_func) ((int (*)(ClientData clientData, Tcl_Interp *interp, int argc, const char *const *argv))_func) + +static struct math_func_link { + const char *name; + int (*func)(ClientData clientData, Tcl_Interp *interp, int argc, const char *const *argv); +} math_funcs[] = { + /* FIXME: migrate these all to libged */ + {"bn_dist_pnt2_lseg2", BN_FUNC_TCL_CAST(tclcad_bn_dist_pnt2_lseg2) }, + {"bn_isect_line2_line2", BN_FUNC_TCL_CAST(tclcad_bn_isect_line2_line2) }, + {"bn_isect_line3_line3", BN_FUNC_TCL_CAST(tclcad_bn_isect_line3_line3) }, + {"mat_inv", BN_FUNC_TCL_CAST(tclcad_bn_mat_inv) }, + {"mat_trn", BN_FUNC_TCL_CAST(tclcad_bn_mat_trn) }, + {"matXvec", BN_FUNC_TCL_CAST(tclcad_bn_matXvec) }, + {"mat4x3vec", BN_FUNC_TCL_CAST(tclcad_bn_mat4x3vec) }, + {"hdivide", BN_FUNC_TCL_CAST(tclcad_bn_hdivide) }, + {"vjoin1", BN_FUNC_TCL_CAST(tclcad_bn_vjoin1) }, + {"vblend", BN_FUNC_TCL_CAST(tclcad_bn_vblend) }, + {"mat_ae_vec", BN_FUNC_TCL_CAST(tclcad_bn_ae_vec) }, + {"mat_aet_vec", BN_FUNC_TCL_CAST(tclcad_bn_aet_vec) }, + {"mat_angles", BN_FUNC_TCL_CAST(tclcad_bn_mat_angles) }, + {"mat_eigen2x2", BN_FUNC_TCL_CAST(tclcad_bn_eigen2x2) }, + {"mat_fromto", BN_FUNC_TCL_CAST(tclcad_bn_mat_fromto) }, + {"mat_xrot", BN_FUNC_TCL_CAST(tclcad_bn_mat_xrot) }, + {"mat_yrot", BN_FUNC_TCL_CAST(tclcad_bn_mat_yrot) }, + {"mat_zrot", BN_FUNC_TCL_CAST(tclcad_bn_mat_zrot) }, + {"mat_lookat", BN_FUNC_TCL_CAST(tclcad_bn_mat_lookat) }, + {"mat_vec_ortho", BN_FUNC_TCL_CAST(tclcad_bn_vec_ortho) }, + {"mat_vec_perp", BN_FUNC_TCL_CAST(tclcad_bn_vec_perp) }, + {"mat_xform_about_pnt", BN_FUNC_TCL_CAST(tclcad_bn_mat_xform_about_pnt) }, + {"mat_arb_rot", BN_FUNC_TCL_CAST(tclcad_bn_mat_arb_rot) }, + {"quat_mat2quat", BN_FUNC_TCL_CAST(tclcad_bn_quat_mat2quat) }, + {"quat_quat2mat", BN_FUNC_TCL_CAST(tclcad_bn_quat_quat2mat) }, + {"quat_distance", BN_FUNC_TCL_CAST(tclcad_bn_quat_distance) }, + {"quat_double", BN_FUNC_TCL_CAST(tclcad_bn_quat_double) }, + {"quat_bisect", BN_FUNC_TCL_CAST(tclcad_bn_quat_bisect) }, + {"quat_make_nearest", BN_FUNC_TCL_CAST(tclcad_bn_quat_make_nearest) }, + {"quat_slerp", BN_FUNC_TCL_CAST(tclcad_bn_quat_slerp) }, + {"quat_sberp", BN_FUNC_TCL_CAST(tclcad_bn_quat_sberp) }, + {"quat_exp", BN_FUNC_TCL_CAST(tclcad_bn_quat_exp) }, + {"quat_log", BN_FUNC_TCL_CAST(tclcad_bn_quat_log) }, + {0, 0} +}; + +int +bn_cmd_noise_perlin(ClientData UNUSED(clientData), + Tcl_Interp *interp, + int argc, + char **argv) +{ + point_t pt; + double v; + + if (argc != 4) { + Tcl_AppendResult(interp, "wrong # args: should be \"", + argv[0], " X Y Z \"", + NULL); + return TCL_ERROR; + } + + pt[X] = atof(argv[1]); + pt[Y] = atof(argv[2]); + pt[Z] = atof(argv[3]); + + v = bn_noise_perlin(pt); + Tcl_SetObjResult(interp, Tcl_NewDoubleObj(v)); + + return TCL_OK; +} + + +/* + * usage: bn_noise_fbm X Y Z h_val lacunarity octaves + * + */ +int +bn_cmd_noise(ClientData UNUSED(clientData), + Tcl_Interp *interp, + int argc, + char **argv) +{ + point_t pt; + double h_val; + double lacunarity; + double octaves; + double val; + + if (argc != 7) { + Tcl_AppendResult(interp, "wrong # args: should be \"", + argv[0], " X Y Z h_val lacunarity octaves\"", + NULL); + return TCL_ERROR; + } + + pt[0] = atof(argv[1]); + pt[1] = atof(argv[2]); + pt[2] = atof(argv[3]); + + h_val = atof(argv[4]); + lacunarity = atof(argv[5]); + octaves = atof(argv[6]); + + + if (BU_STR_EQUAL("bn_noise_turb", argv[0])) { + val = bn_noise_turb(pt, h_val, lacunarity, octaves); + + Tcl_SetObjResult(interp, Tcl_NewDoubleObj(val)); + } else if (BU_STR_EQUAL("bn_noise_fbm", argv[0])) { + val = bn_noise_fbm(pt, h_val, lacunarity, octaves); + Tcl_SetObjResult(interp, Tcl_NewDoubleObj(val)); + } else { + Tcl_AppendResult(interp, "Unknown noise type \"", + argv[0], "\"", NULL); + return TCL_ERROR; + } + return TCL_OK; +} + + +/** + * @brief + * usage: noise_slice xdim ydim inv h_val lac octaves dX dY dZ sX [sY sZ] + * + * The idea here is to get a whole slice of noise at once, thereby + * avoiding the overhead of doing this in Tcl. + */ +int +bn_cmd_noise_slice(ClientData UNUSED(clientData), + Tcl_Interp *interp, + int argc, + char **argv) +{ + double h_val; + double lacunarity; + double octaves; + + vect_t delta; /* translation to noise space */ + vect_t scale; /* scale to noise space */ + unsigned xdim; /* # samples X direction */ + unsigned ydim; /* # samples Y direction */ + unsigned xval, yval; +#define NOISE_FBM 0 +#define NOISE_TURB 1 + +#define COV186_UNUSED_CODE 0 +#if COV186_UNUSED_CODE + int noise_type = NOISE_FBM; +#endif + double val; + point_t pt; + + if (argc != 7) { + Tcl_AppendResult(interp, "wrong # args: should be \"", + argv[0], " Xdim Ydim Zval h_val lacunarity octaves\"", + NULL); + return TCL_ERROR; + } + + xdim = atoi(argv[0]); + ydim = atoi(argv[1]); + VSETALL(delta, 0.0); + VSETALL(scale, 1.); + pt[Z] = delta[Z] = atof(argv[2]); + h_val = atof(argv[3]); + lacunarity = atof(argv[4]); + octaves = atof(argv[5]); + +#define COV186_UNUSED_CODE 0 + /* Only NOISE_FBM is possible at this time, so comment out the switching for + * NOISE_TURB. This may need to be deleted. */ +#if COV186_UNUSED_CODE + switch (noise_type) { + case NOISE_FBM: +#endif + for (yval = 0; yval < ydim; yval++) { + + pt[Y] = yval * scale[Y] + delta[Y]; + + for (xval = 0; xval < xdim; xval++) { + pt[X] = xval * scale[X] + delta[X]; + + bn_noise_fbm(pt, h_val, lacunarity, octaves); + + } + } +#if COV186_UNUSED_CODE + break; + case NOISE_TURB: + for (yval = 0; yval < ydim; yval++) { + + pt[Y] = yval * scale[Y] + delta[Y]; + + for (xval = 0; xval < xdim; xval++) { + pt[X] = xval * scale[X] + delta[X]; + + val = bn_noise_turb(pt, h_val, lacunarity, octaves); + + } + } + break; + } +#endif + + + pt[0] = atof(argv[1]); + pt[1] = atof(argv[2]); + pt[2] = atof(argv[3]); + + h_val = atof(argv[4]); + lacunarity = atof(argv[5]); + octaves = atof(argv[6]); + + + if (BU_STR_EQUAL("bn_noise_turb", argv[0])) { + val = bn_noise_turb(pt, h_val, lacunarity, octaves); + Tcl_SetObjResult(interp, Tcl_NewDoubleObj(val)); + } else if (BU_STR_EQUAL("bn_noise_fbm", argv[0])) { + val = bn_noise_fbm(pt, h_val, lacunarity, octaves); + Tcl_SetObjResult(interp, Tcl_NewDoubleObj(val)); + } else { + Tcl_AppendResult(interp, "Unknown noise type \"", + argv[0], "\"", NULL); + return TCL_ERROR; + } + return TCL_OK; +} + + +int +bn_cmd_random(ClientData UNUSED(clientData), + Tcl_Interp *interp, + int argc, + char **argv) +{ + int val; + const char *str; + double rnd; + char buf[32]; + + if (argc != 2) { + Tcl_AppendResult(interp, "Wrong # args: Should be \"", + argv[0], " varname\"", NULL); + return TCL_ERROR; + } + + str=Tcl_GetVar(interp, argv[1], 0); + if (!str) { + Tcl_AppendResult(interp, "Error getting variable ", + argv[1], NULL); + return TCL_ERROR; + } + val = atoi(str); + + V_MAX(val, 0); + + rnd = BN_RANDOM(val); + + snprintf(buf, 32, "%d", val); + + if (!Tcl_SetVar(interp, argv[1], buf, 0)) { + Tcl_AppendResult(interp, "Error setting variable ", + argv[1], NULL); + return TCL_ERROR; + } + + snprintf(buf, 32, "%g", rnd); + Tcl_AppendResult(interp, buf, NULL); + return TCL_OK; +} + + +void +tclcad_bn_mat_print(Tcl_Interp *interp, + const char *title, + const mat_t m) +{ + char obuf[1024]; /* snprintf may be non-PARALLEL */ + + bn_mat_print_guts(title, m, obuf, 1024); + Tcl_AppendResult(interp, obuf, "\n", (char *)NULL); +} + + +void +tclcad_bn_setup(Tcl_Interp *interp) +{ + struct math_func_link *mp; + + for (mp = math_funcs; mp->name != NULL; mp++) { + (void)Tcl_CreateCommand(interp, mp->name, + (Tcl_CmdProc *)mp->func, + (ClientData)NULL, + (Tcl_CmdDeleteProc *)NULL); + } + + (void)Tcl_CreateCommand(interp, "bn_noise_perlin", + (Tcl_CmdProc *)bn_cmd_noise_perlin, (ClientData)NULL, + (Tcl_CmdDeleteProc *)NULL); + + (void)Tcl_CreateCommand(interp, "bn_noise_turb", + (Tcl_CmdProc *)bn_cmd_noise, (ClientData)NULL, + (Tcl_CmdDeleteProc *)NULL); + + (void)Tcl_CreateCommand(interp, "bn_noise_fbm", + (Tcl_CmdProc *)bn_cmd_noise, (ClientData)NULL, + (Tcl_CmdDeleteProc *)NULL); + + (void)Tcl_CreateCommand(interp, "bn_noise_slice", + (Tcl_CmdProc *)bn_cmd_noise_slice, (ClientData)NULL, + (Tcl_CmdDeleteProc *)NULL); + + (void)Tcl_CreateCommand(interp, "bn_random", + (Tcl_CmdProc *)bn_cmd_random, (ClientData)NULL, + (Tcl_CmdDeleteProc *)NULL); +} + + +int +Bn_Init(Tcl_Interp *interp) +{ + tclcad_bn_setup(interp); + return TCL_OK; +} + +/* + * Local Variables: + * mode: C + * tab-width: 8 + * indent-tabs-mode: t + * c-file-style: "stroustrup" + * End: + * ex: shiftwidth=4 tabstop=8 + */ Property changes on: brlcad/trunk/src/libtclcad/bn_funcs.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Added: brlcad/trunk/src/libtclcad/bu_funcs.c =================================================================== --- brlcad/trunk/src/libtclcad/bu_funcs.c (rev 0) +++ brlcad/trunk/src/libtclcad/bu_funcs.c 2020-07-14 18:47:49 UTC (rev 76327) @@ -0,0 +1,501 @@ +/* B U _ 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/bu_funcs.c + * + * BRL-CAD's Tcl wrappers for libbu. + * + */ + +#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 "bu.h" +#include "vmath.h" +#include "tclcad.h" + + +/* Private headers */ +#include "brlcad_version.h" +#include "tclcad_private.h" + +static int +lwrapper_func(ClientData data, Tcl_Interp *interp, int argc, const char *argv[]) +{ + struct bu_cmdtab *ctp = (struct bu_cmdtab *)data; + + return ctp->ct_func(interp, argc, argv); +} + + + +#define TINYBUFSIZ 32 +#define SMALLBUFSIZ 256 + +/** + * A wrapper for bu_prmem. Prints map of memory currently in use, to + * stderr. + * + * \@param clientData - UNUSED, present for signature matching + * @param argc - number of elements in argv + * @param argv - command name and arguments + * + * @return BRLCAD_OK if successful, otherwise, BRLCAD_ERROR. + */ +HIDDEN int +tcl_bu_prmem(void *UNUSED(clientData), + int argc, + const char **argv) +{ + if (argc != 2) { + bu_log("Usage: bu_prmem title\n"); + return BRLCAD_ERROR; + } + + bu_prmem(argv[1]); + return BRLCAD_OK; +} + + +/** + * Given arguments of alternating keywords and values and a specific + * keyword ("Iwant"), return the value associated with that keyword. + * + * example: bu_get_value_by_keyword Iwant az 35 elev 25 temp 9.6 + * + * If only one argument is given after the search keyword, it is + * interpreted as a list in the same format. + * + * example: bu_get_value_by_keyword Iwant {az 35 elev 25 temp 9.6} + * + * Search order is left-to-right, only first match is returned. + * + * Sample use: + * bu_get_value_by_keyword V8 [concat type [.inmem get box.s]] + * + * @param clientData - associated data/state + * @param argc - number of elements in argv + * @param argv - command name and arguments + * + * @return BRLCAD_OK if successful, otherwise, BRLCAD_ERROR. + */ +HIDDEN int +tcl_bu_get_value_by_keyword(void *clientData, + int argc, + const char **argv) +{ + Tcl_Interp *interp = (Tcl_Interp *)clientData; + int i = 0; + int listc = 0; + const char *iwant = (const char *)NULL; + const char **listv = (const char **)NULL; + const char **tofree = (const char **)NULL; + + if (argc < 3) { + char buf[TINYBUFSIZ]; + snprintf(buf, TINYBUFSIZ, "%d", argc); + bu_log("bu_get_value_by_keyword: wrong # of args (%s).\n" + "Usage: bu_get_value_by_keyword iwant {list}\n" + "Usage: bu_get_value_by_keyword iwant key1 val1 key2 val2 ... keyN valN\n", buf); + return BRLCAD_ERROR; + } + + iwant = argv[1]; + + if (argc == 3) { + if (Tcl_SplitList(interp, argv[2], &listc, (const char ***)&listv) != TCL_OK) { + bu_log("bu_get_value_by_keyword: iwant='%s', unable to split '%s'\n", iwant, argv[2]); + return BRLCAD_ERROR; + } + tofree = listv; + } else { + /* Take search list from remaining arguments */ + listc = argc - 2; + listv = argv + 2; + } + + if ((listc & 1) != 0) { + char buf[TINYBUFSIZ]; + snprintf(buf, TINYBUFSIZ, "%d", listc); + bu_log("bu_get_value_by_keyword: odd # of items in list (%s).\n", buf); + + if (tofree) + Tcl_Free((char *)tofree); /* not bu_free() */ + return BRLCAD_ERROR; + } + + for (i=0; i < listc; i += 2) { + if (BU_STR_EQUAL(iwant, listv[i])) { + /* If value is a list, don't nest it in another list */ + if (listv[i+1][0] == '{') { + struct bu_vls str = BU_VLS_INIT_ZERO; + + /* Skip leading { */ + bu_vls_strcat(&str, &listv[i+1][1]); + /* Trim trailing } */ + bu_vls_trunc(&str, -1); + Tcl_AppendResult(interp, bu_vls_addr(&str), NULL); + bu_vls_free(&str); + } else { + Tcl_AppendResult(interp, listv[i+1], NULL); + } + + if (tofree) + Tcl_Free((char *)tofree); /* not bu_free() */ + return BRLCAD_OK; + } + } + + /* Not found */ + + if (tofree) + Tcl_Free((char *)tofree); /* not bu_free() */ + return BRLCAD_ERROR; +} + + +/** + * A wrapper for bu_rgb_to_hsv. + * + * @param clientData - associated data/state + * @param argc - number of elements in argv + * @param argv - command name and arguments + * + * @return BRLCAD_OK if successful, otherwise, BRLCAD_ERROR. + */ +HIDDEN int +tcl_bu_rgb_to_hsv(void *clientData, + int argc, + const char **argv) +{ + Tcl_Interp *interp = (Tcl_Interp *)clientData; + int rgb_int[3]; + unsigned char rgb[3]; + fastf_t hsv[3]; + struct bu_vls result = BU_VLS_INIT_ZERO; + + if (argc != 4) { + bu_log("Usage: bu_rgb_to_hsv R G B\n"); + return BRLCAD_ERROR; + } + if (sscanf(argv[1], "%d", &rgb_int[0]) != 1 + || sscanf(argv[2], "%d", &rgb_int[1]) != 1 + || sscanf(argv[3], "%d", &rgb_int[2]) != 1 + || (rgb_int[0] < 0) || (rgb_int[0] > 255) + || (rgb_int[1] < 0) || (rgb_int[1] > 255) + || (rgb_int[2] < 0) || (rgb_int[2] > 255)) { + bu_vls_printf(&result, "bu_rgb_to_hsv: Bad RGB (%s, %s, %s)\n", + argv[1], argv[2], argv[3]); + bu_log("ERROR: %s", bu_vls_addr(&result)); + bu_vls_free(&result); + return BRLCAD_ERROR; + } + rgb[0] = rgb_int[0]; + rgb[1] = rgb_int[1]; + rgb[2] = rgb_int[2]; + + bu_rgb_to_hsv(rgb, hsv); + bu_vls_printf(&result, "%g %g %g", hsv[0], hsv[1], hsv[2]); + Tcl_AppendResult(interp, bu_vls_addr(&result), NULL); + bu_vls_free(&result); + return BRLCAD_OK; + +} + + +/** + * A wrapper for bu_hsv_to_rgb. + * + * @param clientData - associated data/state + * @param argc - number of elements in argv + * @param argv - command name and arguments + * + * @return BRLCAD_OK if successful, otherwise, BRLCAD_ERROR. + */ +HIDDEN int +tcl_bu_hsv_to_rgb(void *clientData, + int argc, + const char **argv) +{ + Tcl_Interp *interp = (Tcl_Interp *)clientData; + + double vals[3]; + fastf_t hsv[3]; + unsigned char rgb[3]; + struct bu_vls result = BU_VLS_INIT_ZERO; + + if (argc != 4) { + bu_log("Usage: bu_hsv_to_rgb H S V\n"); + return BRLCAD_ERROR; + } + if (sscanf(argv[1], "%lf", &vals[0]) != 1 + || sscanf(argv[2], "%lf", &vals[1]) != 1 + || sscanf(argv[3], "%lf", &vals[2]) != 1) + { + bu_log("Bad HSV parsing (%s, %s, %s)\n", argv[1], argv[2], argv[3]); + return BRLCAD_ERROR; + } + + VMOVE(hsv, vals); + if (bu_hsv_to_rgb(hsv, rgb) == 0) { + bu_log("HSV to RGB conversion failed (%s, %s, %s)\n", argv[1], argv[2], argv[3]); + return BRLCAD_ERROR; + } + + bu_vls_printf(&result, "%d %d %d", rgb[0], rgb[1], rgb[2]); + Tcl_AppendResult(interp, bu_vls_addr(&result), NULL); + bu_vls_free(&result); + return BRLCAD_OK; + +} + +const char * +_tclcad_bu_dir_print(const char *dirkey, int fail_quietly) +{ + static char result[MAXPATHLEN] = {0}; + if (BU_STR_EQUIV(dirkey, "curr") || BU_STR_EQUIV(dirkey, "cwd") || + BU_STR_EQUAL(dirkey, "BU_DIR_CURR")) { + snprintf(result, MAXPATHLEN, "%s", bu_dir(NULL, 0, BU_DIR_CURR, NULL)); + return result; + } + if (BU_STR_EQUIV(dirkey, "init") || BU_STR_EQUIV(dirkey, "iwd") || + BU_STR_EQUAL(dirkey, "BU_DIR_INIT")) { + snprintf(result, MAXPATHLEN, "%s", bu_dir(NULL, 0, BU_DIR_INIT, NULL)); + return result; + } + if (BU_STR_EQUIV(dirkey, "bin") || BU_STR_EQUAL(dirkey, "BU_DIR_BIN")) { + snprintf(result, MAXPATHLEN, "%s", bu_dir(NULL, 0, BU_DIR_BIN, NULL)); + return result; + } + if (BU_STR_EQUIV(dirkey, "lib") || BU_STR_EQUAL(dirkey, "BU_DIR_LIB")) { + snprintf(result, MAXPATHLEN, "%s", bu_dir(NULL, 0, BU_DIR_LIB, NULL)); + return result; + } + if (BU_STR_EQUIV(dirkey, "libexec") || BU_STR_EQUAL(dirkey, "BU_DIR_LIBEXEC")) { + snprintf(result, MAXPATHLEN, "%s", bu_dir(NULL, 0, BU_DIR_LIBEXEC, NULL)); + return result; + } + if (BU_STR_EQUIV(dirkey, "include") || BU_STR_EQUAL(dirkey, "BU_DIR_INCLUDE")) { + snprintf(result, MAXPATHLEN, "%s", bu_dir(NULL, 0, BU_DIR_INCLUDE, NULL)); + return result; + } + if (BU_STR_EQUIV(dirkey, "data") || BU_STR_EQUIV(dirkey, "share") || + BU_STR_EQUAL(dirkey, "BU_DIR_DATA")) { + snprintf(result, MAXPATHLEN, "%s", bu_dir(NULL, 0, BU_DIR_DATA, NULL)); + return result; + } + if (BU_STR_EQUIV(dirkey, "doc") || BU_STR_EQUAL(dirkey, "BU_DIR_DOC")) { + snprintf(result, MAXPATHLEN, "%s", bu_dir(NULL, 0, BU_DIR_DOC, NULL)); + return result; + } + if (BU_STR_EQUIV(dirkey, "man") || BU_STR_EQUAL(dirkey, "BU_DIR_MAN")) { + snprintf(result, MAXPATHLEN, "%s", bu_dir(NULL, 0, BU_DIR_MAN, NULL)); + return result; + } + if (BU_STR_EQUIV(dirkey, "temp") || BU_STR_EQUAL(dirkey, "BU_DIR_TEMP")) { + snprintf(result, MAXPATHLEN, "%s", bu_dir(NULL, 0, BU_DIR_TEMP, NULL)); + return result; + } + if (BU_STR_EQUIV(dirkey, "home") || BU_STR_EQUAL(dirkey, "BU_DIR_HOME")) { + snprintf(result, MAXPATHLEN, "%s", bu_dir(NULL, 0, BU_DIR_HOME, NULL)); + return result; + } + if (BU_STR_EQUIV(dirkey, "cache") || BU_STR_EQUAL(dirkey, "BU_DIR_CACHE")) { + snprintf(result, MAXPATHLEN, "%s", bu_dir(NULL, 0, BU_DIR_CACHE, NULL)); + return result; + } + if (BU_STR_EQUIV(dirkey, "config") || BU_STR_EQUAL(dirkey, "BU_DIR_CONFIG")) { + snprintf(result, MAXPATHLEN, "%s", bu_dir(NULL, 0, BU_DIR_CONFIG, NULL)); + return result; + } + if (BU_STR_EQUIV(dirkey, "ext") || BU_STR_EQUAL(dirkey, "BU_DIR_EXT")) { + snprintf(result, MAXPATHLEN, "%s", bu_dir(NULL, 0, BU_DIR_EXT, NULL)); + return result; + } + if (BU_STR_EQUIV(dirkey, "libext") || BU_STR_EQUAL(dirkey, "BU_DIR_LIBEXT")) { + snprintf(result, MAXPATHLEN, "%s", bu_dir(NULL, 0, BU_DIR_LIBEXT, NULL)); + return result; + } + if (!fail_quietly) { + snprintf(result, MAXPATHLEN, "Unknown directory key %s", dirkey); + return result; + } + return NULL; +} + +/** + * A wrapper for bu_dir. + * + * @param clientData - associated data/state + * @param argc - number of elements in argv + * @param argv - command name and arguments + * + * @return BRLCAD_OK if successful, otherwise, BRLCAD_ERROR. + */ +HIDDEN int +tcl_bu_dir(void *clientData, + int argc, + const char **argv) +{ + Tcl_Interp *interp = (Tcl_Interp *)clientData; + if (argc != 2) { + bu_log("Usage: bu_dir [curr|init|bin|lib|libexec|include|data|doc|man|temp|home|cache|config|ext|libext]\n"); + return BRLCAD_ERROR; + } + Tcl_AppendResult(interp, _tclcad_bu_dir_print(argv[1],1), NULL); + return BRLCAD_OK; +} + +/** + * A wrapper for bu_brlcad_dir. + * + * @param clientData - associated data/state + * @param argc - number of elements in argv + * @param argv - command name and arguments + * + * @return BRLCAD_OK if successful, otherwise, BRLCAD_ERROR. + */ +HIDDEN int +tcl_bu_brlcad_dir(void *clientData, + int argc, + const char **argv) +{ + Tcl_Interp *interp = (Tcl_Interp *)clientData; + if (argc != 2) { + bu_log("Usage: bu_brlcad_dir dirkey\n"); + return BRLCAD_ERROR; + } + Tcl_AppendResult(interp, bu_brlcad_dir(argv[1], 1), NULL); + return BRLCAD_OK; +} + +/** + * A wrapper for bu_brlcad_root. + * + * @param clientData - associated data/state + * @param argc - number of elements in argv + * @param argv - command name and arguments + * + * @return BRLCAD_OK if successful, otherwise, BRLCAD_ERROR. + */ +HIDDEN int +tcl_bu_brlcad_root(void *clientData, + int argc, + const char **argv) +{ + Tcl_Interp *interp = (Tcl_Interp *)clientData; + if (argc != 2) { + bu_log("Usage: bu_brlcad_root subdir\n"); + return BRLCAD_ERROR; + } + Tcl_AppendResult(interp, bu_brlcad_root(argv[1], 1), NULL); + return BRLCAD_OK; +} + + +/** + * A wrapper for bu_units_conversion. + * + * @param clientData - associated data/state + * @param argc - number of elements in argv + * @param argv - command name and arguments + * + * @return BRLCAD_OK if successful, otherwise, BRLCAD_ERROR. + */ +HIDDEN int +tcl_bu_units_conversion(void *clientData, + int argc, + const char **argv) +{ + Tcl_Interp *interp = (Tcl_Interp *)clientData; + double conv_factor; + struct bu_vls result = BU_VLS_INIT_ZERO; + + if (argc != 2) { + bu_log("Usage: bu_units_conversion units_string\n"); + return BRLCAD_ERROR; + } + + conv_factor = bu_units_conversion(argv[1]); + if (conv_factor <= 0.0) { + bu_log("ERROR: bu_units_conversion: Unrecognized units string: %s\n", argv[1]); + return BRLCAD_ERROR; + } + + bu_vls_printf(&result, "%.12e", conv_factor); + Tcl_AppendResult(interp, bu_vls_addr(&result), NULL); + bu_vls_free(&result); + return BRLCAD_OK; +} + + +static void +register_cmds(Tcl_Interp *interp, struct bu_cmdtab *cmds) +{ + struct bu_cmdtab *ctp = NULL; + + for (ctp = cmds; ctp->ct_name != (char *)NULL; ctp++) { + (void)Tcl_CreateCommand(interp, ctp->ct_name, lwrapper_func, (ClientData)ctp, (Tcl_CmdDeleteProc *)NULL); + } +} + + +int +Bu_Init(void *p) +{ + Tcl_Interp *interp = (Tcl_Interp *)p; + + static struct bu_cmdtab cmds[] = { + {"bu_units_conversion", tcl_bu_units_conversion}, + {"bu_dir", tcl_bu_dir}, + {"bu_brlcad_dir", tcl_bu_brlcad_dir}, + {"bu_brlcad_root", tcl_bu_brlcad_root}, + {"bu_prmem", tcl_bu_prmem}, + {"bu_get_value_by_keyword", tcl_bu_get_value_by_keyword}, + {"bu_rgb_to_hsv", tcl_bu_rgb_to_hsv}, + {"bu_hsv_to_rgb", tcl_bu_hsv_to_rgb}, + {(const char *)NULL, BU_CMD_NULL} + }; + + register_cmds(interp, cmds); + + Tcl_SetVar(interp, "BU_DEBUG_FORMAT", BU_DEBUG_FORMAT, TCL_GLOBAL_ONLY); + Tcl_LinkVar(interp, "bu_debug", (char *)&bu_debug, TCL_LINK_INT); + + return BRLCAD_OK; +} + +/* + * Local Variables: + * mode: C + * tab-width: 8 + * indent-tabs-mode: t + * c-file-style: "stroustrup" + * End: + * ex: shiftwidth=4 tabstop=8 + */ Property changes on: brlcad/trunk/src/libtclcad/bu_funcs.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Modified: brlcad/trunk/src/libtclcad/libfuncs.c =================================================================== --- brlcad/trunk/src/libtclcad/libfuncs.c 2020-07-14 16:34:25 UTC (rev 76326) +++ brlcad/trunk/src/libtclcad/libfuncs.c 2020-07-14 18:47:49 UTC (rev 76327) @@ -48,1777 +48,7 @@ #include "brlcad_version.h" #include "tclcad_private.h" -static int -lwrapper_func(ClientData data, Tcl_Interp *interp, int argc, const char *argv[]) -{ - struct bu_cmdtab *ctp = (struct bu_cmdtab *)data; - return ctp->ct_func(interp, argc, argv); -} - - - -#define TINYBUFSIZ 32 -#define SMALLBUFSIZ 256 - -/** - * A wrapper for bu_prmem. Prints map of memory currently in use, to - * stderr. - * - * \@param clientData - UNUSED, present for signature matching - * @param argc - number of elements in argv - * @param argv - command name and arguments - * - * @return BRLCAD_OK if successful, otherwise, BRLCAD_ERROR. - */ -HIDDEN int -tcl_bu_prmem(void *UNUSED(clientData), - int argc, - const char **argv) -{ - if (argc != 2) { - bu_log("Usage: bu_prmem title\n"); - return BRLCAD_ERROR; - } - - bu_prmem(argv[1]); - return BRLCAD_OK; -} - - -/** - * Given arguments of alternating keywords and values and a specific - * keyword ("Iwant"), return the value associated with that keyword. - * - * example: bu_get_value_by_keyword Iwant az 35 elev 25 temp 9.6 - * - * If only one argument is given after the search keyword, it is - * interpreted as a list in the same format. - * - * example: bu_get_value_by_keyword Iwant {az 35 elev 25 temp 9.6} - * - * Search order is left-to-right, only first match is returned. - * - * Sample use: - * bu_get_value_by_keyword V8 [concat type [.inmem get box.s]] - * - * @param clientData - associated data/state - * @param argc - number of elements in argv - * @param argv - command name and arguments - * - * @return BRLCAD_OK if successful, otherwise, BRLCAD_ERROR. - */ -HIDDEN int -tcl_bu_get_value_by_keyword(void *clientData, - int argc, - const char **argv) -{ - Tcl_Interp *interp = (Tcl_Interp *)clientData; - int i = 0; - int listc = 0; - const char *iwant = (const char *)NULL; - const char **listv = (const char **)NULL; - const char **tofree = (const char **)NULL; - - if (argc < 3) { - char buf[TINYBUFSIZ]; - snprintf(buf, TINYBUFSIZ, "%d", argc); - bu_log("bu_get_value_by_keyword: wrong # of args (%s).\n" - "Usage: bu_get_value_by_keyword iwant {list}\n" - "Usage: bu_get_value_by_keyword iwant key1 val1 key2 val2 ... keyN valN\n", buf); - return BRLCAD_ERROR; - } - - iwant = argv[1]; - - if (argc == 3) { - if (Tcl_SplitList(interp, argv[2], &listc, (const char ***)&listv) != TCL_OK) { - bu_log("bu_get_value_by_keyword: iwant='%s', unable to split '%s'\n", iwant, argv[2]); - return BRLCAD_ERROR; - } - tofree = listv; - } else { - /* Take search list from remaining arguments */ - listc = argc - 2; - listv = argv + 2; - } - - if ((listc & 1) != 0) { - char buf[TINYBUFSIZ]; - snprintf(buf, TINYBUFSIZ, "%d", listc); - bu_log("bu_get_value_by_keyword: odd # of items in list (%s).\n", buf); - - if (tofree) - Tcl_Free((char *)tofree); /* not bu_free() */ - return BRLCAD_ERROR; - } - - for (i=0; i < listc; i += 2) { - if (BU_STR_EQUAL(iwant, listv[i])) { - /* If value is a list, don't nest it in another list */ - if (listv[i+1][0] == '{') { - struct bu_vls str = BU_VLS_INIT_ZERO; - - /* Skip leading { */ - bu_vls_strcat(&str, &listv[i+1][1]); - /* Trim trailing } */ - bu_vls_trunc(&str, -1); - Tcl_AppendResult(interp, bu_vls_addr(&str), NULL); - bu_vls_free(&str); - } else { - Tcl_AppendResult(interp, listv[i+1], NULL); - } - - if (tofree) - Tcl_Free((char *)tofree); /* not bu_free() */ - return BRLCAD_OK; - } - } - - /* Not found */ - - if (tofree) - Tcl_Free((char *)tofree); /* not bu_free() */ - return BRLCAD_ERROR; -} - - -/** - * A wrapper for bu_rgb_to_hsv. - * - * @param clientData - associated data/state - * @param argc - number of elements in argv - * @param argv - command name and arguments - * - * @return BRLCAD_OK if successful, otherwise, BRLCAD_ERROR. - */ -HIDDEN int -tcl_bu_rgb_to_hsv(void *clientData, - int argc, - const char **argv) -{ - Tcl_Interp *interp = (Tcl_Interp *)clientData; - int rgb_int[3]; - unsigned char rgb[3]; - fastf_t hsv[3]; - struct bu_vls result = BU_VLS_INIT_ZERO; - - if (argc != 4) { - bu_log("Usage: bu_rgb_to_hsv R G B\n"); - return BRLCAD_ERROR; - } - if (sscanf(argv[1], "%d", &rgb_int[0]) != 1 - || sscanf(argv[2], "%d", &rgb_int[1]) != 1 - || sscanf(argv[3], "%d", &rgb_int[2]) != 1 - || (rgb_int[0] < 0) || (rgb_int[0] > 255) - || (rgb_int[1] < 0) || (rgb_int[1] > 255) - || (rgb_int[2] < 0) || (rgb_int[2] > 255)) { - bu_vls_printf(&result, "bu_rgb_to_hsv: Bad RGB (%s, %s, %s)\n", - argv[1], argv[2], argv[3]); - bu_log("ERROR: %s", bu_vls_addr(&result)); - bu_vls_free(&result); - return BRLCAD_ERROR; - } - rgb[0] = rgb_int[0]; - rgb[1] = rgb_int[1]; - rgb[2] = rgb_int[2]; - - bu_rgb_to_hsv(rgb, hsv); - bu_vls_printf(&result, "%g %g %g", hsv[0], hsv[1], hsv[2]); - Tcl_AppendResult(interp, bu_vls_addr(&result), NULL); - bu_vls_free(&result); - return BRLCAD_OK; - -} - - -/** - * A wrapper for bu_hsv_to_rgb. - * - * @param clientData - associated data/state - * @param argc - number of elements in argv - * @param argv - command name and arguments - * - * @return BRLCAD_OK if successful, otherwise, BRLCAD_ERROR. - */ -HIDDEN int -tcl_bu_hsv_to_rgb(void *clientData, - int argc, - const char **argv) -{ - Tcl_Interp *interp = (Tcl_Interp *)clientData; - - double vals[3]; - fastf_t hsv[3]; - unsigned char rgb[3]; - struct bu_vls result = BU_VLS_INIT_ZERO; - - if (argc != 4) { - bu_log("Usage: bu_hsv_to_rgb H S V\n"); - return BRLCAD_ERROR; - } - if (sscanf(argv[1], "%lf", &vals[0]) != 1 - || sscanf(argv[2], "%lf", &vals[1]) != 1 - || sscanf(argv[3], "%lf", &vals[2]) != 1) - { - bu_log("Bad HSV parsing (%s, %s, %s)\n", argv[1], argv[2], argv[3]); - return BRLCAD_ERROR; - } - - VMOVE(hsv, vals); - if (bu_hsv_to_rgb(hsv, rgb) == 0) { - bu_log("HSV to RGB conversion failed (%s, %s, %s)\n", argv[1], argv[2], argv[3]); - return BRLCAD_ERROR; - } - - bu_vls_printf(&result, "%d %d %d", rgb[0], rgb[1], rgb[2]); - Tcl_AppendResult(interp, bu_vls_addr(&result), NULL); - bu_vls_free(&result); - return BRLCAD_OK; - -} - -const char * -_tclcad_bu_dir_print(const char *dirkey, int fail_quietly) -{ - static char result[MAXPATHLEN] = {0}; - if (BU_STR_EQUIV(dirkey, "curr") || BU_STR_EQUIV(dirkey, "cwd") || - BU_STR_EQUAL(dirkey, "BU_DIR_CURR")) { - snprintf(result, MAXPATHLEN, "%s", bu_dir(NULL, 0, BU_DIR_CURR, NULL)); - return result; - } - if (BU_STR_EQUIV(dirkey, "init") || BU_STR_EQUIV(dirkey, "iwd") || - BU_STR_EQUAL(dirkey, "BU_DIR_INIT")) { - snprintf(result, MAXPATHLEN, "%s", bu_dir(NULL, 0, BU_DIR_INIT, NULL)); - return result; - } - if (BU_STR_EQUIV(dirkey, "bin") || BU_STR_EQUAL(dirkey, "BU_DIR_BIN")) { - snprintf(result, MAXPATHLEN, "%s", bu_dir(NULL, 0, BU_DIR_BIN, NULL)); - return result; - } - if (BU_STR_EQUIV(dirkey, "lib") || BU_STR_EQUAL(dirkey, "BU_DIR_LIB")) { - snprintf(result, MAXPATHLEN, "%s", bu_dir(NULL, 0, BU_DIR_LIB, NULL)); - return result; - } - if (BU_STR_EQUIV(dirkey, "libexec") || BU_STR_EQUAL(dirkey, "BU_DIR_LIBEXEC")) { - snprintf(result, MAXPATHLEN, "%s", bu_dir(NULL, 0, BU_DIR_LIBEXEC, NULL)); - return result; - } - if (BU_STR_EQUIV(dirkey, "include") || BU_STR_EQUAL(dirkey, "BU_DIR_INCLUDE")) { - snprintf(result, MAXPATHLEN, "%s", bu_dir(NULL, 0, BU_DIR_INCLUDE, NULL)); - return result; - } - if (BU_STR_EQUIV(dirkey, "data") || BU_STR_EQUIV(dirkey, "share") || - BU_STR_EQUAL(dirkey, "BU_DIR_DATA")) { - snprintf(result, MAXPATHLEN, "%s", bu_dir(NULL, 0, BU_DIR_DATA, NULL)); - return result; - } - if (BU_STR_EQUIV(dirkey, "doc") || BU_STR_EQUAL(dirkey, "BU_DIR_DOC")) { - snprintf(result, MAXPATHLEN, "%s", bu_dir(NULL, 0, BU_DIR_DOC, NULL)); - return result; - } - if (BU_STR_EQUIV(dirkey, "man") || BU_STR_EQUAL(dirkey, "BU_DIR_MAN")) { - snprintf(result, MAXPATHLEN, "%s", bu_dir(NULL, 0, BU_DIR_MAN, NULL)); - return result; - } - if (BU_STR_EQUIV(dirkey, "temp") || BU_STR_EQUAL(dirkey, "BU_DIR_TEMP")) { - snprintf(result, MAXPATHLEN, "%s", bu_dir(NULL, 0, BU_DIR_TEMP, NULL)); - return result; - } - if (BU_STR_EQUIV(dirkey, "home") || BU_STR_EQUAL(dirkey, "BU_DIR_HOME")) { - snprintf(result, MAXPATHLEN, "%s", bu_dir(NULL, 0, BU_DIR_HOME, NULL)); - return result; - } - if (BU_STR_EQUIV(dirkey, "cache") || BU_STR_EQUAL(dirkey, "BU_DIR_CACHE")) { - snprintf(result, MAXPATHLEN, "%s", bu_dir(NULL, 0, BU_DIR_CACHE, NULL)); - return result; - } - if (BU_STR_EQUIV(dirkey, "config") || BU_STR_EQUAL(dirkey, "BU_DIR_CONFIG")) { - snprintf(result, MAXPATHLEN, "%s", bu_dir(NULL, 0, BU_DIR_CONFIG, NULL)); - return result; - } - if (BU_STR_EQUIV(dirkey, "ext") || BU_STR_EQUAL(dirkey, "BU_DIR_EXT")) { - snprintf(result, MAXPATHLEN, "%s", bu_dir(NULL, 0, BU_DIR_EXT, NULL)); - return result; - } - if (BU_STR_EQUIV(dirkey, "libext") || BU_STR_EQUAL(dirkey, "BU_DIR_LIBEXT")) { - snprintf(result, MAXPATHLEN, "%s", bu_dir(NULL, 0, BU_DIR_LIBEXT, NULL)); - return result; - } - if (!fail_quietly) { - snprintf(result, MAXPATHLEN, "Unknown directory key %s", dirkey); - return result; - } - return NULL; -} - -/** - * A wrapper for bu_dir. - * - * @param clientData - associated data/state - * @param argc - number of elements in argv - * @param argv - command name and arguments - * - * @return BRLCAD_OK if successful, otherwise, BRLCAD_ERROR. - */ -HIDDEN int -tcl_bu_dir(void *clientData, - int argc, - const char **argv) -{ - Tcl_Interp *interp = (Tcl_Interp *)clientData; - if (argc != 2) { - bu_log("Usage: bu_dir [curr|init|bin|lib|libexec|include|data|doc|man|temp|home|cache|config|ext|libext]\n"); - return BRLCAD_ERROR; - } - Tcl_AppendResult(interp, _tclcad_bu_dir_print(argv[1],1), NULL); - return BRLCAD_OK; -} - -/** - * A wrapper for bu_brlcad_dir. - * - * @param clientData - associated data/state - * @param argc - number of elements in argv - * @param argv - command name and arguments - * - * @return BRLCAD_OK if successful, otherwise, BRLCAD_ERROR. - */ -HIDDEN int -tcl_bu_brlcad_dir(void *clientData, - int argc, - const char **argv) -{ - Tcl_Interp *interp = (Tcl_Interp *)clientData; - if (argc != 2) { - bu_log("Usage: bu_brlcad_dir dirkey\n"); - return BRLCAD_ERROR; - } - Tcl_AppendResult(interp, bu_brlcad_dir(argv[1], 1), NULL); - return BRLCAD_OK; -} - -/** - * A wrapper for bu_brlcad_root. - * - * @param clientData - associated data/state - * @param argc - number of elements in argv - * @param argv - command name and arguments - * - * @return BRLCAD_OK if successful, otherwise, BRLCAD_ERROR. - */ -HIDDEN int -tcl_bu_brlcad_root(void *clientData, - int argc, - const char **argv) -{ - Tcl_Interp *interp = (Tcl_Interp *)clientData; - if (argc != 2) { - bu_log("Usage: bu_brlcad_root subdir\n"); - return BRLCAD_ERROR; - } - Tcl_AppendResult(interp, bu_brlcad_root(argv[1], 1), NULL); - return BRLCAD_OK; -} - - -/** - * A wrapper for bu_units_conversion. - * - * @param clientData - associated data/state - * @param argc - number of elements in argv - * @param argv - command name and arguments - * - * @return BRLCAD_OK if successful, otherwise, BRLCAD_ERROR. - */ -HIDDEN int -tcl_bu_units_conversion(void *clientData, - int argc, - const char **argv) -{ - Tcl_Interp *interp = (Tcl_Interp *)clientData; - double conv_factor; - struct bu_vls result = BU_VLS_INIT_ZERO; - - if (argc != 2) { - bu_log("Usage: bu_units_conversion units_string\n"); - return BRLCAD_ERROR; - } - - conv_factor = bu_units_conversion(argv[1]); - if (conv_factor <= 0.0) { - bu_log("ERROR: bu_units_conversion: Unrecognized units string: %s\n", argv[1]); - return BRLCAD_ERROR; - } - - bu_vls_printf(&result, "%.12e", conv_factor); - Tcl_AppendResult(interp, bu_vls_addr(&result), NULL); - bu_vls_free(&result); - return BRLCAD_OK; -} - - -static void -register_cmds(Tcl_Interp *interp, struct bu_cmdtab *cmds) -{ - struct bu_cmdtab *ctp = NULL; - - for (ctp = cmds; ctp->ct_name != (char *)NULL; ctp++) { - (void)Tcl_CreateCommand(interp, ctp->ct_name, lwrapper_func, (ClientData)ctp, (Tcl_CmdDeleteProc *)NULL); - } -} - - -int -Bu_Init(void *p) -{ - Tcl_Interp *interp = (Tcl_Interp *)p; - - static struct bu_cmdtab cmds[] = { - {"bu_units_conversion", tcl_bu_units_conversion}, - {"bu_dir", tcl_bu_dir}, - {"bu_brlcad_dir", tcl_bu_brlcad_dir}, - {"bu_brlcad_root", tcl_bu_brlcad_root}, - {"bu_prmem", tcl_bu_prmem}, - {"bu_get_value_by_keyword", tcl_bu_get_value_by_keyword}, - {"bu_rgb_to_hsv", tcl_bu_rgb_to_hsv}, - {"bu_hsv_to_rgb", tcl_bu_hsv_to_rgb}, - {(const char *)NULL, BU_CMD_NULL} - }; - - register_cmds(interp, cmds); - - Tcl_SetVar(interp, "BU_DEBUG_FORMAT", BU_DEBUG_FORMAT, TCL_GLOBAL_ONLY); - Tcl_LinkVar(interp, "bu_debug", (char *)&bu_debug, TCL_LINK_INT); - - return BRLCAD_OK; -} - - -void -bn_quat_distance_wrapper(double *dp, mat_t q1, mat_t q2) -{ - *dp = quat_distance(q1, q2); -} - - -static void -bn_mat4x3vec(fastf_t *o, mat_t m, vect_t i) -{ - MAT4X3VEC(o, m, i); -} - - -static void -bn_hdivide(fastf_t *o, const mat_t i) -{ - HDIVIDE(o, i); -} - -static int -tclcad_bn_dist_pnt2_lseg2(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) -{ - struct bu_vls result = BU_VLS_INIT_ZERO; - point_t ptA, ptB, pca; - point_t pt; - fastf_t dist; - int ret; - static const struct bn_tol tol = { - BN_TOL_MAGIC, BN_TOL_DIST, BN_TOL_DIST*BN_TOL_DIST, 1e-6, 1-1e-6 - }; - - if (argc != 4) { - bu_vls_printf(&result, - "Usage: bn_dist_pnt2_lseg2 pntA pntB pnt (%d args specified)", argc-1); - goto error; - } - - if (bn_decode_vect(ptA, argv[1]) < 2) { - bu_vls_printf(&result, "bn_dist_pnt2_lseg2 no pntA: %s\n", argv[0]); - goto error; - } - - if (bn_decode_vect(ptB, argv[2]) < 2) { - bu_vls_printf(&result, "bn_dist_pnt2_lseg2 no pntB: %s\n", argv[0]); - goto error; - } - - if (bn_decode_vect(pt, argv[3]) < 2) { - bu_vls_printf(&result, "bn_dist_pnt2_lseg2 no pnt: %s\n", argv[0]); - goto error; - } - - ret = bn_dist_pnt2_lseg2(&dist, pca, ptA, ptB, pt, &tol); - switch (ret) { - case 0: - case 1: - case 2: - dist = 0.0; - break; - default: - break; - } - - bu_vls_printf(&result, "%g", dist); - - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_OK; - -error: - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_ERROR; - -} - -static int -tclcad_bn_isect_line2_line2(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) -{ - struct bu_vls result = BU_VLS_INIT_ZERO; - fastf_t dist[2]; - point_t pt = VINIT_ZERO; - point_t a = VINIT_ZERO; - vect_t dir = VINIT_ZERO; - vect_t c = VINIT_ZERO; - int i; - static const struct bn_tol tol = { - BN_TOL_MAGIC, BN_TOL_DIST, BN_TOL_DIST*BN_TOL_DIST, 1e-6, 1-1e-6 - }; - - if (argc != 5) { - bu_vls_printf(&result, - "Usage: bn_isect_line2_line2 pt dir pt dir (%d args specified)", - argc-1); - goto error; - } - - /* i = bn_isect_line2_line2 {0 0} {1 0} {1 1} {0 -1} */ - - if (bn_decode_vect(pt, argv[1]) < 2) { - bu_vls_printf(&result, "bn_isect_line2_line2 no pt: %s\n", argv[0]); - goto error; - } - if (bn_decode_vect(dir, argv[2]) < 2) { - bu_vls_printf(&result, "bn_isect_line2_line2 no dir: %s\n", argv[0]); - goto error; - } - if (bn_decode_vect(a, argv[3]) < 2) { - bu_vls_printf(&result, "bn_isect_line2_line2 no a pt: %s\n", argv[0]); - goto error; - } - if (bn_decode_vect(c, argv[4]) < 2) { - bu_vls_printf(&result, "bn_isect_line2_line2 no c dir: %s\n", argv[0]); - goto error; - } - i = bn_isect_line2_line2(dist, pt, dir, a, c, &tol); - if (i != 1) { - bu_vls_printf(&result, "bn_isect_line2_line2 no intersection: %s\n", argv[0]); - goto error; - } - - VJOIN1(a, pt, dist[0], dir); - bu_vls_printf(&result, "%g %g", V2INTCLAMPARGS(a)); - - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_OK; - -error: - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_ERROR; -} - -static int -tclcad_bn_isect_line3_line3(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) -{ - struct bu_vls result = BU_VLS_INIT_ZERO; - - fastf_t t, u; - point_t pt, a; - vect_t dir, c; - int i; - static const struct bn_tol tol = { - BN_TOL_MAGIC, BN_TOL_DIST, BN_TOL_DIST*BN_TOL_DIST, 1e-6, 1-1e-6 - }; - if (argc != 5) { - bu_vls_printf(&result, - "Usage: bn_isect_line3_line3 pt dir pt dir (%d args specified)", - argc-1); - goto error; - } - - if (bn_decode_vect(pt, argv[1]) < 3) { - bu_vls_printf(&result, "bn_isect_line3_line3 no pt: %s\n", argv[0]); - goto error; - } - if (bn_decode_vect(dir, argv[2]) < 3) { - bu_vls_printf(&result, "bn_isect_line3_line3 no dir: %s\n", argv[0]); - goto error; - } - if (bn_decode_vect(a, argv[3]) < 3) { - bu_vls_printf(&result, "bn_isect_line3_line3 no a pt: %s\n", argv[0]); - goto error; - } - if (bn_decode_vect(c, argv[4]) < 3) { - bu_vls_printf(&result, "bn_isect_line3_line3 no c dir: %s\n", argv[0]); - goto error; - } - i = bn_isect_line3_line3(&t, &u, pt, dir, a, c, &tol); - if (i != 1) { - bu_vls_printf(&result, "bn_isect_line3_line3 no intersection: %s\n", argv[0]); - goto error; - } - - VJOIN1(a, pt, t, dir); - bn_encode_vect(&result, a, 1); - - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_OK; - -error: - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_ERROR; -} - - -static int -tclcad_bn_mat_inv(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) -{ - struct bu_vls result = BU_VLS_INIT_ZERO; - - mat_t o, a; - - if (argc < 2 || bn_decode_mat(a, argv[1]) < 16) { - bu_vls_printf(&result, "usage: %s mat", argv[0]); - goto error; - } - bn_mat_inv(o, a); - bn_encode_mat(&result, o, 1); - - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_OK; - -error: - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_ERROR; -} - - -static int -tclcad_bn_mat_trn(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) -{ - struct bu_vls result = BU_VLS_INIT_ZERO; - - mat_t o, a; - - if (argc < 2 || bn_decode_mat(a, argv[1]) < 16) { - bu_vls_printf(&result, "usage: %s mat", argv[0]); - goto error; - } - bn_mat_trn(o, a); - bn_encode_mat(&result, o, 1); - - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_OK; - -error: - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_ERROR; -} - - -static int -tclcad_bn_matXvec(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) -{ - struct bu_vls result = BU_VLS_INIT_ZERO; - - mat_t m; - hvect_t i, o; - if (argc < 3 || bn_decode_mat(m, argv[1]) < 16 || - bn_decode_hvect(i, argv[2]) < 4) { - bu_vls_printf(&result, "usage: %s mat hvect", argv[0]); - goto error; - } - bn_matXvec(o, m, i); - bn_encode_hvect(&result, o, 1); - - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_OK; - -error: - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_ERROR; -} - -static int -tclcad_bn_mat4x3vec(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) -{ - struct bu_vls result = BU_VLS_INIT_ZERO; - mat_t m; - vect_t i, o; - MAT_ZERO(m); - if (argc < 3 || bn_decode_mat(m, argv[1]) < 16 || - bn_decode_vect(i, argv[2]) < 3) { - bu_vls_printf(&result, "usage: %s mat vect", argv[0]); - goto error; - } - bn_mat4x3vec(o, m, i); - bn_encode_vect(&result, o, 1); - - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_OK; - -error: - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_ERROR; -} - - -static int -tclcad_bn_hdivide(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) -{ - struct bu_vls result = BU_VLS_INIT_ZERO; - hvect_t i; - vect_t o; - if (argc < 2 || bn_decode_hvect(i, argv[1]) < 4) { - bu_vls_printf(&result, "usage: %s hvect", argv[0]); - goto error; - } - bn_hdivide(o, i); - bn_encode_vect(&result, o, 1); - - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_OK; - -error: - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_ERROR; -} - -static int -tclcad_bn_vjoin1(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) -{ - struct bu_vls result = BU_VLS_INIT_ZERO; - point_t o; - point_t b, d; - double c; - - if (argc < 4) { - bu_vls_printf(&result, "usage: %s pnt scale dir", argv[0]); - goto error; - } - if (bn_decode_vect(b, argv[1]) < 3) goto error; - if (Tcl_GetDouble(interp, argv[2], &c) != TCL_OK) goto error; - if (bn_decode_vect(d, argv[3]) < 3) goto error; - - VJOIN1(o, b, c, d); /* bn_vjoin1(o, b, c, d) */ - bn_encode_vect(&result, o, 1); - - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_OK; - -error: - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_ERROR; -} - -static int -tclcad_bn_vblend(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) -{ - struct bu_vls result = BU_VLS_INIT_ZERO; - point_t a, c, e; - double b, d; - - if (argc < 5) { - bu_vls_printf(&result, "usage: %s scale pnt scale pnt", argv[0]); - goto error; - } - - if (Tcl_GetDouble(interp, argv[1], &b) != TCL_OK) goto error; - if (bn_decode_vect(c, argv[2]) < 3) goto error; - if (Tcl_GetDouble(interp, argv[3], &d) != TCL_OK) goto error; - if (bn_decode_vect(e, argv[4]) < 3) goto error; - - VBLEND2(a, b, c, d, e); - bn_encode_vect(&result, a, 1); - - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_OK; - -error: - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_ERROR; -} - -static int -tclcad_bn_ae_vec(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) -{ - struct bu_vls result = BU_VLS_INIT_ZERO; - fastf_t az, el; - vect_t v; - - if (argc < 2 || bn_decode_vect(v, argv[1]) < 3) { - bu_vls_printf(&result, "usage: %s vect", argv[0]); - goto error; - } - - bn_ae_vec(&az, &el, v); - bu_vls_printf(&result, "%g %g", az, el); - - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_OK; - -error: - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_ERROR; -} - -static int -tclcad_bn_aet_vec(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) -{ - struct bu_vls result = BU_VLS_INIT_ZERO; - double acc; - fastf_t az, el, twist, accuracy; - vect_t vec_ae, vec_twist; - - if (argc < 4 || bn_decode_vect(vec_ae, argv[1]) < 3 || - bn_decode_vect(vec_twist, argv[2]) < 3 || - sscanf(argv[3], "%lf", &acc) < 1) { - bu_vls_printf(&result, "usage: %s vec_ae vec_twist accuracy", - argv[0]); - goto error; - } - accuracy = acc; - - bn_aet_vec(&az, &el, &twist, vec_ae, vec_twist, accuracy); - bu_vls_printf(&result, "%g %g %g", az, el, twist); - - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_OK; - -error: - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_ERROR; -} - -static int -tclcad_bn_mat_angles(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) -{ - struct bu_vls result = BU_VLS_INIT_ZERO; - mat_t o; - double alpha, beta, ggamma; - - if (argc < 4) { - bu_vls_printf(&result, "usage: %s alpha beta gamma", argv[0]); - goto error; - } - if (Tcl_GetDouble(interp, argv[1], &alpha) != TCL_OK) goto error; - if (Tcl_GetDouble(interp, argv[2], &beta) != TCL_OK) goto error; - if (Tcl_GetDouble(interp, argv[3], &ggamma) != TCL_OK) goto error; - - bn_mat_angles(o, alpha, beta, ggamma); - bn_encode_mat(&result, o, 1); - - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_OK; - -error: - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_ERROR; -} - -static int -tclcad_bn_eigen2x2(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) -{ - struct bu_vls result = BU_VLS_INIT_ZERO; - fastf_t val1, val2; - vect_t vec1, vec2; - double a, b, c; - - if (argc < 4) { - bu_vls_printf(&result, "usage: %s a b c", argv[0]); - goto error; - } - if (Tcl_GetDouble(interp, argv[1], &a) != TCL_OK) goto error; - if (Tcl_GetDouble(interp, argv[2], &c) != TCL_OK) goto error; - if (Tcl_GetDouble(interp, argv[3], &b) != TCL_OK) goto error; - - bn_eigen2x2(&val1, &val2, vec1, vec2, (fastf_t)a, (fastf_t)b, - (fastf_t)c); - bu_vls_printf(&result, "%g %g {%g %g %g} {%g %g %g}", INTCLAMP(val1), INTCLAMP(val2), - V3INTCLAMPARGS(vec1), V3INTCLAMPARGS(vec2)); - - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_OK; - -error: - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_ERROR; -} - -static int -tclcad_bn_mat_fromto(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) -{ - struct bu_vls result = BU_VLS_INIT_ZERO; - mat_t o; - vect_t from, to; - static const struct bn_tol tol = { - BN_TOL_MAGIC, BN_TOL_DIST, BN_TOL_DIST*BN_TOL_DIST, 1e-6, 1-1e-6 - }; - - if (argc < 3 || bn_decode_vect(from, argv[1]) < 3 || - bn_decode_vect(to, argv[2]) < 3) { - bu_vls_printf(&result, "usage: %s vecFrom vecTo", argv[0]); - goto error; - } - bn_mat_fromto(o, from, to, &tol); - bn_encode_mat(&result, o, 1); - - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_OK; - -error: - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_ERROR; -} - - -static int -tclcad_bn_mat_xrot(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) -{ - struct bu_vls result = BU_VLS_INIT_ZERO; - mat_t o; - double s, c; - - if (argc < 3) { - bu_vls_printf(&result, "usage: %s sinAngle cosAngle", argv[0]); - goto error; - } - if (Tcl_GetDouble(interp, argv[1], &s) != TCL_OK) goto error; - if (Tcl_GetDouble(interp, argv[2], &c) != TCL_OK) goto error; - - bn_mat_xrot(o, s, c); - bn_encode_mat(&result, o, 1); - - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_OK; - -error: - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_ERROR; -} - - -static int -tclcad_bn_mat_yrot(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) -{ - struct bu_vls result = BU_VLS_INIT_ZERO; - mat_t o; - double s, c; - - if (argc < 3) { - bu_vls_printf(&result, "usage: %s sinAngle cosAngle", argv[0]); - goto error; - } - if (Tcl_GetDouble(interp, argv[1], &s) != TCL_OK) goto error; - if (Tcl_GetDouble(interp, argv[2], &c) != TCL_OK) goto error; - - bn_mat_yrot(o, s, c); - bn_encode_mat(&result, o, 1); - - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_OK; - -error: - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_ERROR; -} - - -static int -tclcad_bn_mat_zrot(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) -{ - struct bu_vls result = BU_VLS_INIT_ZERO; - mat_t o; - double s, c; - - if (argc < 3) { - bu_vls_printf(&result, "usage: %s sinAngle cosAngle", argv[0]); - goto error; - } - if (Tcl_GetDouble(interp, argv[1], &s) != TCL_OK) goto error; - if (Tcl_GetDouble(interp, argv[2], &c) != TCL_OK) goto error; - - bn_mat_zrot(o, s, c); - bn_encode_mat(&result, o, 1); - - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_OK; - -error: - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_ERROR; -} - - -static int -tclcad_bn_mat_lookat(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) -{ - struct bu_vls result = BU_VLS_INIT_ZERO; - mat_t o; - vect_t dir; - int yflip; - if (argc < 3 || bn_decode_vect(dir, argv[1]) < 3) { - bu_vls_printf(&result, "usage: %s dir yflip", argv[0]); - goto error; - } - if (Tcl_GetBoolean(interp, argv[2], &yflip) != TCL_OK) goto error; - - bn_mat_lookat(o, dir, yflip); - bn_encode_mat(&result, o, 1); - - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_OK; - -error: - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_ERROR; -} - - -static int -tclcad_bn_vec_ortho(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) -{ - struct bu_vls result = BU_VLS_INIT_ZERO; - vect_t ov, vec; - - if (argc < 2 || bn_decode_vect(vec, argv[1]) < 3) { - bu_vls_printf(&result, "usage: %s vec", argv[0]); - goto error; - } - - bn_vec_ortho(ov, vec); - bn_encode_vect(&result, ov, 1); - - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_OK; - -error: - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_ERROR; -} - - -static int -tclcad_bn_vec_perp(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) -{ - struct bu_vls result = BU_VLS_INIT_ZERO; - vect_t ov, vec; - - if (argc < 2 || bn_decode_vect(vec, argv[1]) < 3) { - bu_vls_printf(&result, "usage: %s vec", argv[0]); - goto error; - } - - bn_vec_perp(ov, vec); - bn_encode_vect(&result, ov, 1); - - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_OK; - -error: - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_ERROR; -} - - -static int -tclcad_bn_mat_xform_about_pnt(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) -{ - struct bu_vls result = BU_VLS_INIT_ZERO; - mat_t o, xform; - vect_t v; - - if (argc < 3 || bn_decode_mat(xform, argv[1]) < 16 || - bn_decode_vect(v, argv[2]) < 3) { - bu_vls_printf(&result, "usage: %s xform pt", argv[0]); - goto error; - } - - bn_mat_xform_about_pnt(o, xform, v); - bn_encode_mat(&result, o, 1); - - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_OK; - -error: - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_ERROR; -} - - -static int -tclcad_bn_mat_arb_rot(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) -{ - struct bu_vls result = BU_VLS_INIT_ZERO; - mat_t o; - point_t pt; - vect_t dir; - double angle; - - if (argc < 4 || bn_decode_vect(pt, argv[1]) < 3 || - bn_decode_vect(dir, argv[2]) < 3) { - bu_vls_printf(&result, "usage: %s pt dir angle", argv[0]); - goto error; - } - if (Tcl_GetDouble(interp, argv[3], &angle) != TCL_OK) - return TCL_ERROR; - - bn_mat_arb_rot(o, pt, dir, (fastf_t)angle); - bn_encode_mat(&result, o, 1); - - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_OK; - -error: - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_ERROR; -} - - -static int -tclcad_bn_quat_mat2quat(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) -{ - struct bu_vls result = BU_VLS_INIT_ZERO; - mat_t mat; - quat_t quat; - - if (argc < 2 || bn_decode_mat(mat, argv[1]) < 16) { - bu_vls_printf(&result, "usage: %s mat", argv[0]); - goto error; - } - - quat_mat2quat(quat, mat); - bn_encode_quat(&result, quat, 1); - - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_OK; - -error: - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_ERROR; -} - - -static int -tclcad_bn_quat_quat2mat(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) -{ - struct bu_vls result = BU_VLS_INIT_ZERO; - mat_t mat; - quat_t quat; - - if (argc < 2 || bn_decode_quat(quat, argv[1]) < 4) { - bu_vls_printf(&result, "usage: %s quat", argv[0]); - goto error; - } - - quat_quat2mat(mat, quat); - bn_encode_mat(&result, mat, 1); - - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_OK; - -error: - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_ERROR; -} - -static int -tclcad_bn_quat_distance(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) -{ - struct bu_vls result = BU_VLS_INIT_ZERO; - quat_t q1, q2; - double d; - - if (argc < 3 || bn_decode_quat(q1, argv[1]) < 4 || - bn_decode_quat(q2, argv[2]) < 4) { - bu_vls_printf(&result, "usage: %s quatA quatB", argv[0]); - goto error; - } - - bn_quat_distance_wrapper(&d, q1, q2); - bu_vls_printf(&result, "%g", d); - - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_OK; - -error: - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_ERROR; -} - -static int -tclcad_bn_quat_double(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) -{ - struct bu_vls result = BU_VLS_INIT_ZERO; - quat_t oqot, q1, q2; - - if (argc < 3 || bn_decode_quat(q1, argv[1]) < 4 || - bn_decode_quat(q2, argv[2]) < 4) { - bu_vls_printf(&result, "usage: %s quatA quatB", argv[0]); - goto error; - } - - quat_double(oqot, q1, q2); - bn_encode_quat(&result, oqot, 1); - - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_OK; - -error: - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_ERROR; -} - - - -static int -tclcad_bn_quat_bisect(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) -{ - struct bu_vls result = BU_VLS_INIT_ZERO; - quat_t oqot, q1, q2; - - if (argc < 3 || bn_decode_quat(q1, argv[1]) < 4 || - bn_decode_quat(q2, argv[2]) < 4) { - bu_vls_printf(&result, "usage: %s quatA quatB", argv[0]); - goto error; - } - - quat_bisect(oqot, q1, q2); - bn_encode_quat(&result, oqot, 1); - - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_OK; - -error: - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_ERROR; -} - - - -static int -tclcad_bn_quat_make_nearest(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) -{ - struct bu_vls result = BU_VLS_INIT_ZERO; - quat_t oqot, q1; - - if (argc < 2 || bn_decode_quat(oqot, argv[1]) < 4) { - bu_vls_printf(&result, "usage: %s orig_quat", argv[0]); - goto error; - } - - quat_make_nearest(q1, oqot); - bn_encode_quat(&result, q1, 1); - - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_OK; - -error: - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_ERROR; -} - -static int -tclcad_bn_quat_slerp(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) -{ - struct bu_vls result = BU_VLS_INIT_ZERO; - quat_t oq, q1, q2; - double d; - - if (argc < 4 || bn_decode_quat(q1, argv[1]) < 4 || - bn_decode_quat(q2, argv[2]) < 4) { - bu_vls_printf(&result, "usage: %s quat1 quat2 factor", argv[0]); - goto error; - } - if (Tcl_GetDouble(interp, argv[3], &d) != TCL_OK) goto error; - - quat_slerp(oq, q1, q2, d); - bn_encode_quat(&result, oq, 1); - - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_OK; - -error: - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_ERROR; -} - - - -static int -tclcad_bn_quat_sberp(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) -{ - struct bu_vls result = BU_VLS_INIT_ZERO; - quat_t oq, q1, qa, qb, q2; - double d; - - if (argc < 6 || bn_decode_quat(q1, argv[1]) < 4 || - bn_decode_quat(qa, argv[2]) < 4 || bn_decode_quat(qb, argv[3]) < 4 || - bn_decode_quat(q2, argv[4]) < 4) { - bu_vls_printf(&result, "usage: %s quat1 quatA quatB quat2 factor", - argv[0]); - goto error; - } - if (Tcl_GetDouble(interp, argv[5], &d) != TCL_OK) goto error; - - quat_sberp(oq, q1, qa, qb, q2, d); - bn_encode_quat(&result, oq, 1); - - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_OK; - -error: - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_ERROR; -} - - - -static int -tclcad_bn_quat_exp(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) -{ - struct bu_vls result = BU_VLS_INIT_ZERO; - quat_t qout, qin; - - if (argc < 2 || bn_decode_quat(qin, argv[1]) < 4) { - bu_vls_printf(&result, "usage: %s quat", argv[0]); - goto error; - } - - quat_exp(qout, qin); - bn_encode_quat(&result, qout, 1); - - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_OK; - -error: - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_ERROR; -} - - -static int -tclcad_bn_quat_log(ClientData UNUSED(clientData), Tcl_Interp *interp, int argc, char **argv) -{ - struct bu_vls result = BU_VLS_INIT_ZERO; - quat_t qout, qin; - - if (argc < 2 || bn_decode_quat(qin, argv[1]) < 4) { - bu_vls_printf(&result, "usage: %s quat", argv[0]); - goto error; - } - - quat_log(qout, qin); - bn_encode_quat(&result, qout, 1); - - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_OK; - -error: - Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); - bu_vls_free(&result); - return TCL_ERROR; -} - - -#define BN_FUNC_TCL_CAST(_func) ((int (*)(ClientData clientData, Tcl_Interp *interp, int argc, const char *const *argv))_func) - -static struct math_func_link { - const char *name; - int (*func)(ClientData clientData, Tcl_Interp *interp, int argc, const char *const *argv); -} math_funcs[] = { - /* FIXME: migrate these all to libged */ - {"bn_dist_pnt2_lseg2", BN_FUNC_TCL_CAST(tclcad_bn_dist_pnt2_lseg2) }, - {"bn_isect_line2_line2", BN_FUNC_TCL_CAST(tclcad_bn_isect_line2_line2) }, - {"bn_isect_line3_line3", BN_FUNC_TCL_CAST(tclcad_bn_isect_line3_line3) }, - {"mat_inv", BN_FUNC_TCL_CAST(tclcad_bn_mat_inv) }, - {"mat_trn", BN_FUNC_TCL_CAST(tclcad_bn_mat_trn) }, - {"matXvec", BN_FUNC_TCL_CAST(tclcad_bn_matXvec) }, - {"mat4x3vec", BN_FUNC_TCL_CAST(tclcad_bn_mat4x3vec) }, - {"hdivide", BN_FUNC_TCL_CAST(tclcad_bn_hdivide) }, - {"vjoin1", BN_FUNC_TCL_CAST(tclcad_bn_vjoin1) }, - {"vblend", BN_FUNC_TCL_CAST(tclcad_bn_vblend) }, - {"mat_ae_vec", BN_FUNC_TCL_CAST(tclcad_bn_ae_vec) }, - {"mat_aet_vec", BN_FUNC_TCL_CAST(tclcad_bn_aet_vec) }, - {"mat_angles", BN_FUNC_TCL_CAST(tclcad_bn_mat_angles) }, - {"mat_eigen2x2", BN_FUNC_TCL_CAST(tclcad_bn_eigen2x2) }, - {"mat_fromto", BN_FUNC_TCL_CAST(tclcad_bn_mat_fromto) }, - {"mat_xrot", BN_FUNC_TCL_CAST(tclcad_bn_mat_xrot) }, - {"mat_yrot", BN_FUNC_TCL_CAST(tclcad_bn_mat_yrot) }, - {"mat_zrot", BN_FUNC_TCL_CAST(tclcad_bn_mat_zrot) }, - {"mat_lookat", BN_FUNC_TCL_CAST(tclcad_bn_mat_lookat) }, - {"mat_vec_ortho", BN_FUNC_TCL_CAST(tclcad_bn_vec_ortho) }, - {"mat_vec_perp", BN_FUNC_TCL_CAST(tclcad_bn_vec_perp) }, - {"mat_xform_about_pnt", BN_FUNC_TCL_CAST(tclcad_bn_mat_xform_about_pnt) }, - {"mat_arb_rot", BN_FUNC_TCL_CAST(tclcad_bn_mat_arb_rot) }, - {"quat_mat2quat", BN_FUNC_TCL_CAST(tclcad_bn_quat_mat2quat) }, - {"quat_quat2mat", BN_FUNC_TCL_CAST(tclcad_bn_quat_quat2mat) }, - {"quat_distance", BN_FUNC_TCL_CAST(tclcad_bn_quat_distance) }, - {"quat_double", BN_FUNC_TCL_CAST(tclcad_bn_quat_double) }, - {"quat_bisect", BN_FUNC_TCL_CAST(tclcad_bn_quat_bisect) }, - {"quat_make_nearest", BN_FUNC_TCL_CAST(tclcad_bn_quat_make_nearest) }, - {"quat_slerp", BN_FUNC_TCL_CAST(tclcad_bn_quat_slerp) }, - {"quat_sberp", BN_FUNC_TCL_CAST(tclcad_bn_quat_sberp) }, - {"quat_exp", BN_FUNC_TCL_CAST(tclcad_bn_quat_exp) }, - {"quat_log", BN_FUNC_TCL_CAST(tclcad_bn_quat_log) }, - {0, 0} -}; - -int -bn_cmd_noise_perlin(ClientData UNUSED(clientData), - Tcl_Interp *interp, - int argc, - char **argv) -{ - point_t pt; - double v; - - if (argc != 4) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " X Y Z \"", - NULL); - return TCL_ERROR; - } - - pt[X] = atof(argv[1]); - pt[Y] = atof(argv[2]); - pt[Z] = atof(argv[3]); - - v = bn_noise_perlin(pt); - Tcl_SetObjResult(interp, Tcl_NewDoubleObj(v)); - - return TCL_OK; -} - - -/* - * usage: bn_noise_fbm X Y Z h_val lacunarity octaves - * - */ -int -bn_cmd_noise(ClientData UNUSED(clientData), - Tcl_Interp *interp, - int argc, - char **argv) -{ - point_t pt; - double h_val; - double lacunarity; - double octaves; - double val; - - if (argc != 7) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " X Y Z h_val lacunarity octaves\"", - NULL); - return TCL_ERROR; - } - - pt[0] = atof(argv[1]); - pt[1] = atof(argv[2]); - pt[2] = atof(argv[3]); - - h_val = atof(argv[4]); - lacunarity = atof(argv[5]); - octaves = atof(argv[6]); - - - if (BU_STR_EQUAL("bn_noise_turb", argv[0])) { - val = bn_noise_turb(pt, h_val, lacunarity, octaves); - - Tcl_SetObjResult(interp, Tcl_NewDoubleObj(val)); - } else if (BU_STR_EQUAL("bn_noise_fbm", argv[0])) { - val = bn_noise_fbm(pt, h_val, lacunarity, octaves); - Tcl_SetObjResult(interp, Tcl_NewDoubleObj(val)); - } else { - Tcl_AppendResult(interp, "Unknown noise type \"", - argv[0], "\"", NULL); - return TCL_ERROR; - } - return TCL_OK; -} - - -/** - * @brief - * usage: noise_slice xdim ydim inv h_val lac octaves dX dY dZ sX [sY sZ] - * - * The idea here is to get a whole slice of noise at once, thereby - * avoiding the overhead of doing this in Tcl. - */ -int -bn_cmd_noise_slice(ClientData UNUSED(clientData), - Tcl_Interp *interp, - int argc, - char **argv) -{ - double h_val; - double lacunarity; - double octaves; - - vect_t delta; /* translation to noise space */ - vect_t scale; /* scale to noise space */ - unsigned xdim; /* # samples X direction */ - unsigned ydim; /* # samples Y direction */ - unsigned xval, yval; -#define NOISE_FBM 0 -#define NOISE_TURB 1 - -#define COV186_UNUSED_CODE 0 -#if COV186_UNUSED_CODE - int noise_type = NOISE_FBM; -#endif - double val; - point_t pt; - - if (argc != 7) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " Xdim Ydim Zval h_val lacunarity octaves\"", - NULL); - return TCL_ERROR; - } - - xdim = atoi(argv[0]); - ydim = atoi(argv[1]); - VSETALL(delta, 0.0); - VSETALL(scale, 1.); - pt[Z] = delta[Z] = atof(argv[2]); - h_val = atof(argv[3]); - lacunarity = atof(argv[4]); - octaves = atof(argv[5]); - -#define COV186_UNUSED_CODE 0 - /* Only NOISE_FBM is possible at this time, so comment out the switching for - * NOISE_TURB. This may need to be deleted. */ -#if COV186_UNUSED_CODE - switch (noise_type) { - case NOISE_FBM: -#endif - for (yval = 0; yval < ydim; yval++) { - - pt[Y] = yval * scale[Y] + delta[Y]; - - for (xval = 0; xval < xdim; xval++) { - pt[X] = xval * scale[X] + delta[X]; - - bn_noise_fbm(pt, h_val, lacunarity, octaves); - - } - } -#if COV186_UNUSED_CODE - break; - case NOISE_TURB: - for (yval = 0; yval < ydim; yval++) { - - pt[Y] = yval * scale[Y] + delta[Y]; - - for (xval = 0; xval < xdim; xval++) { - pt[X] = xval * scale[X] + delta[X]; - - val = bn_noise_turb(pt, h_val, lacunarity, octaves); - - } - } - break; - } -#endif - - - pt[0] = atof(argv[1]); - pt[1] = atof(argv[2]); - pt[2] = atof(argv[3]); - - h_val = atof(argv[4]); - lacunarity = atof(argv[5]); - octaves = atof(argv[6]); - - - if (BU_STR_EQUAL("bn_noise_turb", argv[0])) { - val = bn_noise_turb(pt, h_val, lacunarity, octaves); - Tcl_SetObjResult(interp, Tcl_NewDoubleObj(val)); - } else if (BU_STR_EQUAL("bn_noise_fbm", argv[0])) { - val = bn_noise_fbm(pt, h_val, lacunarity, octaves); - Tcl_SetObjResult(interp, Tcl_NewDoubleObj(val)); - } else { - Tcl_AppendResult(interp, "Unknown noise type \"", - argv[0], "\"", NULL); - return TCL_ERROR; - } - return TCL_OK; -} - - -int -bn_cmd_random(ClientData UNUSED(clientData), - Tcl_Interp *interp, - int argc, - char **argv) -{ - int val; - const char *str; - double rnd; - char buf[32]; - - if (argc != 2) { - Tcl_AppendResult(interp, "Wrong # args: Should be \"", - argv[0], " varname\"", NULL); - return TCL_ERROR; - } - - str=Tcl_GetVar(interp, argv[1], 0); - if (!str) { - Tcl_AppendResult(interp, "Error getting variable ", - argv[1], NULL); - return TCL_ERROR; - } - val = atoi(str); - - V_MAX(val, 0); - - rnd = BN_RANDOM(val); - - snprintf(buf, 32, "%d", val); - - if (!Tcl_SetVar(interp, argv[1], buf, 0)) { - Tcl_AppendResult(interp, "Error setting variable ", - argv[1], NULL); - return TCL_ERROR; - } - - snprintf(buf, 32, "%g", rnd); - Tcl_AppendResult(interp, buf, NULL); - return TCL_OK; -} - - -void -tclcad_bn_mat_print(Tcl_Interp *interp, - const char *title, - const mat_t m) -{ - char obuf[1024]; /* snprintf may be non-PARALLEL */ - - bn_mat_print_guts(title, m, obuf, 1024); - Tcl_AppendResult(interp, obuf, "\n", (char *)NULL); -} - - -void -tclcad_bn_setup(Tcl_Interp *interp) -{ - struct math_func_link *mp; - - for (mp = math_funcs; mp->name != NULL; mp++) { - (void)Tcl_CreateCommand(interp, mp->name, - (Tcl_CmdProc *)mp->func, - (ClientData)NULL, - (Tcl_CmdDeleteProc *)NULL); - } - - (void)Tcl_CreateCommand(interp, "bn_noise_perlin", - (Tcl_CmdProc *)bn_cmd_noise_perlin, (ClientData)NULL, - (Tcl_CmdDeleteProc *)NULL); - - (void)Tcl_CreateCommand(interp, "bn_noise_turb", - (Tcl_CmdProc *)bn_cmd_noise, (ClientData)NULL, - (Tcl_CmdDeleteProc *)NULL); - - (void)Tcl_CreateCommand(interp, "bn_noise_fbm", - (Tcl_CmdProc *)bn_cmd_noise, (ClientData)NULL, - (Tcl_CmdDeleteProc *)NULL); - - (void)Tcl_CreateCommand(interp, "bn_noise_slice", - (Tcl_CmdProc *)bn_cmd_noise_slice, (ClientData)NULL, - (Tcl_CmdDeleteProc *)NULL); - - (void)Tcl_CreateCommand(interp, "bn_random", - (Tcl_CmdProc *)bn_cmd_random, (ClientData)NULL, - (Tcl_CmdDeleteProc *)NULL); -} - - -int -Bn_Init(Tcl_Interp *interp) -{ - tclcad_bn_setup(interp); - return TCL_OK; -} - - #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); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. _______________________________________________ BRL-CAD Source Commits mailing list brlcad-commits@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/brlcad-commits