00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #ifndef lint
00044 static const char RCSid[] = "@(#)$Header: /cvsroot/brlcad/brlcad/src/librt/tcl.c,v 14.17 2006/09/16 02:04:26 lbutler Exp $ (ARL)";
00045 #endif
00046
00047 #include "common.h"
00048
00049 #include <stdlib.h>
00050 #include <stdio.h>
00051 #include <ctype.h>
00052 #include <math.h>
00053 #ifdef HAVE_STRING_H
00054 # include <string.h>
00055 #else
00056 # include <strings.h>
00057 #endif
00058
00059 #include "tcl.h"
00060
00061 #include "machine.h"
00062 #include "bu.h"
00063 #include "vmath.h"
00064 #include "bn.h"
00065 #include "rtgeom.h"
00066 #include "raytrace.h"
00067
00068 #include "./debug.h"
00069
00070
00071 extern int Wdb_Init(Tcl_Interp *interp);
00072
00073
00074 extern int Dgo_Init(Tcl_Interp *interp);
00075
00076
00077 extern int Vo_Init(Tcl_Interp *interp);
00078
00079
00080
00081
00082
00083
00084
00085 struct dbcmdstruct {
00086 char *cmdname;
00087 int (*cmdfunc)();
00088 };
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099 int
00100 rt_tcl_parse_ray( Tcl_Interp *interp, struct xray *rp, const char *const*argv )
00101 {
00102 if( bn_decode_vect( rp->r_pt, argv[0] ) != 3 ) {
00103 Tcl_AppendResult( interp,
00104 "badly formatted point: ", argv[0], (char *)NULL );
00105 return TCL_ERROR;
00106 }
00107 if( bn_decode_vect( rp->r_dir, argv[2] ) != 3 ) {
00108 Tcl_AppendResult( interp,
00109 "badly formatted vector: ", argv[2], (char *)NULL );
00110 return TCL_ERROR;
00111 }
00112 switch( argv[1][0] ) {
00113 case 'd':
00114
00115 break;
00116 case 'a':
00117
00118 VSUB2( rp->r_dir, rp->r_dir, rp->r_pt );
00119 break;
00120 default:
00121 Tcl_AppendResult( interp,
00122 "wrong ray keyword: '", argv[1],
00123 "', should be one of 'dir' or 'at'",
00124 (char *)NULL );
00125 return TCL_ERROR;
00126 }
00127 VUNITIZE( rp->r_dir );
00128 return TCL_OK;
00129 }
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142 void
00143 rt_tcl_pr_cutter( Tcl_Interp *interp, const union cutter *cutp )
00144 {
00145 static const char xyz[4] = "XYZ";
00146 struct bu_vls str;
00147 int i;
00148
00149 bu_vls_init(&str);
00150
00151 switch( cutp->cut_type ) {
00152 case CUT_CUTNODE:
00153 bu_vls_printf( &str,
00154 "type cutnode axis %c point %.25G",
00155 xyz[cutp->cn.cn_axis], cutp->cn.cn_point );
00156 break;
00157 case CUT_BOXNODE:
00158 bu_vls_printf( &str,
00159 "type boxnode min {%.25G %.25G %.25G}",
00160 V3ARGS(cutp->bn.bn_min) );
00161 bu_vls_printf( &str,
00162 " max {%.25G %.25G %.25G}",
00163 V3ARGS(cutp->bn.bn_max) );
00164 bu_vls_printf( &str, " solids {");
00165 for( i=0; i < cutp->bn.bn_len; i++ ) {
00166 bu_vls_strcat( &str, cutp->bn.bn_list[i]->st_name );
00167 bu_vls_putc( &str, ' ' );
00168 }
00169 bu_vls_printf( &str, "} pieces {");
00170 for( i = 0; i < cutp->bn.bn_piecelen; i++ ) {
00171 struct rt_piecelist *plp = &cutp->bn.bn_piecelist[i];
00172 int j;
00173 RT_CK_PIECELIST(plp);
00174
00175 bu_vls_printf( &str, "{%s {", plp->stp->st_name );
00176 for( j=0; j < plp->npieces; j++ ) {
00177 bu_vls_printf( &str, "%ld ", plp->pieces[j] );
00178 }
00179 bu_vls_strcat( &str, "} } " );
00180 }
00181 bu_vls_strcat( &str, "}" );
00182 break;
00183 case CUT_NUGRIDNODE:
00184 bu_vls_printf( &str, "type nugridnode" );
00185 for( i = 0; i < 3; i++ ) {
00186 bu_vls_printf( &str, " %c {", xyz[i] );
00187 bu_vls_printf( &str, "spos %.25G epos %.25G width %.25g",
00188 cutp->nugn.nu_axis[i]->nu_spos,
00189 cutp->nugn.nu_axis[i]->nu_epos,
00190 cutp->nugn.nu_axis[i]->nu_width );
00191 bu_vls_printf( &str, " cells_per_axis %ld",
00192 cutp->nugn.nu_cells_per_axis );
00193 bu_vls_printf( &str, " stepsize %ld}",
00194 cutp->nugn.nu_stepsize );
00195 }
00196 break;
00197 default:
00198 bu_vls_printf( &str, "rt_tcl_pr_cutter() bad pointer cutp=x%lx",
00199 (long)cutp);
00200 break;
00201 }
00202 Tcl_AppendResult( interp, bu_vls_addr(&str), (char *)NULL );
00203 bu_vls_free( &str );
00204 }
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215 int
00216 rt_tcl_cutter( ClientData clientData, Tcl_Interp *interp, int argc, const char *const*argv )
00217 {
00218 struct application *ap = (struct application *)clientData;
00219 struct rt_i *rtip;
00220 const union cutter *cutp;
00221 int n;
00222
00223 if( argc != 6 ) {
00224 Tcl_AppendResult( interp,
00225 "wrong # args: should be \"",
00226 argv[0], " ", argv[1], "cutnum {P} dir|at {V}\"",
00227 (char *)NULL );
00228 return TCL_ERROR;
00229 }
00230
00231 RT_CK_AP_TCL(interp, ap);
00232 rtip = ap->a_rt_i;
00233 RT_CK_RTI_TCL(interp,rtip);
00234
00235 n = atoi(argv[2]);
00236 if( rt_tcl_parse_ray( interp, &ap->a_ray, &argv[3] ) == TCL_ERROR )
00237 return TCL_ERROR;
00238
00239 cutp = rt_cell_n_on_ray( ap, n );
00240 if( cutp == CUTTER_NULL ) {
00241 Tcl_AppendResult( interp, "rt_cell_n_on_ray() failed to find cell ", argv[2], (char *)NULL );
00242 return TCL_ERROR;
00243 }
00244 rt_tcl_pr_cutter( interp, cutp );
00245 return TCL_OK;
00246 }
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260 void
00261 rt_tcl_pr_hit( Tcl_Interp *interp, struct hit *hitp, const struct seg *segp, const struct xray *rayp, int flipflag )
00262 {
00263 struct bu_vls str;
00264 vect_t norm;
00265 struct soltab *stp;
00266 const struct directory *dp;
00267 struct curvature crv;
00268
00269 RT_CK_SEG(segp);
00270 stp = segp->seg_stp;
00271 RT_CK_SOLTAB(stp);
00272 dp = stp->st_dp;
00273 RT_CK_DIR(dp);
00274
00275 RT_HIT_NORMAL( norm, hitp, stp, rayp, flipflag );
00276 RT_CURVATURE( &crv, hitp, flipflag, stp );
00277
00278 bu_vls_init(&str);
00279 bu_vls_printf( &str, " {dist %g point {", hitp->hit_dist);
00280 bn_encode_vect( &str, hitp->hit_point );
00281 bu_vls_printf( &str, "} normal {" );
00282 bn_encode_vect( &str, norm );
00283 bu_vls_printf( &str, "} c1 %g c2 %g pdir {",
00284 crv.crv_c1, crv.crv_c2 );
00285 bn_encode_vect( &str, crv.crv_pdir );
00286 bu_vls_printf( &str, "} surfno %d", hitp->hit_surfno );
00287 if( stp->st_path.magic == DB_FULL_PATH_MAGIC ) {
00288
00289 char *sofar = db_path_to_string(&stp->st_path);
00290 bu_vls_printf( &str, " path ");
00291 bu_vls_strcat( &str, sofar );
00292 bu_free( (genptr_t)sofar, "path string" );
00293 }
00294 bu_vls_printf( &str, " solid %s}", dp->d_namep );
00295
00296 Tcl_AppendResult( interp, bu_vls_addr( &str ), (char *)NULL );
00297 bu_vls_free( &str );
00298 }
00299
00300
00301
00302
00303 int
00304 rt_tcl_a_hit( struct application *ap,
00305 struct partition *PartHeadp,
00306 struct seg *segHeadp )
00307 {
00308 Tcl_Interp *interp = (Tcl_Interp *)ap->a_uptr;
00309 register struct partition *pp;
00310
00311 RT_CK_PT_HD(PartHeadp);
00312
00313 for( pp=PartHeadp->pt_forw; pp != PartHeadp; pp = pp->pt_forw ) {
00314 RT_CK_PT(pp);
00315 Tcl_AppendResult( interp, "{in", (char *)NULL );
00316 rt_tcl_pr_hit( interp, pp->pt_inhit, pp->pt_inseg,
00317 &ap->a_ray, pp->pt_inflip );
00318 Tcl_AppendResult( interp, "\nout", (char *)NULL );
00319 rt_tcl_pr_hit( interp, pp->pt_outhit, pp->pt_outseg,
00320 &ap->a_ray, pp->pt_outflip );
00321 Tcl_AppendResult( interp,
00322 "\nregion ",
00323 pp->pt_regionp->reg_name,
00324 (char *)NULL );
00325 Tcl_AppendResult( interp, "}\n", (char *)NULL );
00326 }
00327
00328 return 1;
00329 }
00330
00331
00332
00333
00334 int
00335 rt_tcl_a_miss( struct application *ap )
00336 {
00337 return 0;
00338 }
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364 int
00365 rt_tcl_rt_shootray(ClientData clientData, Tcl_Interp *interp, int argc, const char *const *argv)
00366 {
00367 struct application *ap = (struct application *)clientData;
00368 struct rt_i *rtip;
00369 int index;
00370
00371 if( (argc != 5 && argc != 6) || (argc == 6 && strcmp( argv[2], "-R")) ) {
00372 Tcl_AppendResult( interp,
00373 "wrong # args: should be \"",
00374 argv[0], " ", argv[1], " [-R] {P} dir|at {V}\"",
00375 (char *)NULL );
00376 return TCL_ERROR;
00377 }
00378
00379 if( argc == 6 ) {
00380 ap->a_logoverlap = rt_silent_logoverlap;
00381 index = 3;
00382 } else {
00383 index = 2;
00384 }
00385
00386 RT_CK_AP_TCL(interp, ap);
00387 rtip = ap->a_rt_i;
00388 RT_CK_RTI_TCL(interp,rtip);
00389
00390 if( rt_tcl_parse_ray( interp, &ap->a_ray, &argv[index] ) == TCL_ERROR )
00391 return TCL_ERROR;
00392 ap->a_hit = rt_tcl_a_hit;
00393 ap->a_miss = rt_tcl_a_miss;
00394 ap->a_uptr = (genptr_t)interp;
00395
00396 (void)rt_shootray( ap );
00397
00398 return TCL_OK;
00399 }
00400
00401
00402
00403
00404
00405
00406
00407 int
00408 rt_tcl_rt_onehit(ClientData clientData, Tcl_Interp *interp, int argc, const char *const *argv)
00409 {
00410 struct application *ap = (struct application *)clientData;
00411 struct rt_i *rtip;
00412 char buf[64];
00413
00414 if( argc < 2 || argc > 3 ) {
00415 Tcl_AppendResult( interp,
00416 "wrong # args: should be \"",
00417 argv[0], " ", argv[1], " [#]\"",
00418 (char *)NULL );
00419 return TCL_ERROR;
00420 }
00421
00422 RT_CK_AP_TCL(interp, ap);
00423 rtip = ap->a_rt_i;
00424 RT_CK_RTI_TCL(interp,rtip);
00425
00426 if( argc == 3 ) {
00427 ap->a_onehit = atoi(argv[2]);
00428 }
00429 sprintf(buf, "%d", ap->a_onehit );
00430 Tcl_AppendResult( interp, buf, (char *)NULL );
00431 return TCL_OK;
00432 }
00433
00434
00435
00436
00437
00438
00439
00440 int
00441 rt_tcl_rt_no_bool(ClientData clientData, Tcl_Interp *interp, int argc, const char *const *argv)
00442 {
00443 struct application *ap = (struct application *)clientData;
00444 struct rt_i *rtip;
00445 char buf[64];
00446
00447 if( argc < 2 || argc > 3 ) {
00448 Tcl_AppendResult( interp,
00449 "wrong # args: should be \"",
00450 argv[0], " ", argv[1], " [#]\"",
00451 (char *)NULL );
00452 return TCL_ERROR;
00453 }
00454
00455 RT_CK_AP_TCL(interp, ap);
00456 rtip = ap->a_rt_i;
00457 RT_CK_RTI_TCL(interp,rtip);
00458
00459 if( argc == 3 ) {
00460 ap->a_no_booleans = atoi(argv[2]);
00461 }
00462 sprintf(buf, "%d", ap->a_no_booleans );
00463 Tcl_AppendResult( interp, buf, (char *)NULL );
00464 return TCL_OK;
00465 }
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475 int
00476 rt_tcl_rt_check(ClientData clientData, Tcl_Interp *interp, int argc, const char *const *argv)
00477 {
00478 struct application *ap = (struct application *)clientData;
00479 struct rt_i *rtip;
00480
00481 if( argc != 2 ) {
00482 Tcl_AppendResult( interp,
00483 "wrong # args: should be \"",
00484 argv[0], " ", argv[1], "\"",
00485 (char *)NULL );
00486 return TCL_ERROR;
00487 }
00488
00489 RT_CK_AP_TCL(interp, ap);
00490 rtip = ap->a_rt_i;
00491 RT_CK_RTI_TCL(interp,rtip);
00492
00493 rt_ck(rtip);
00494
00495 return TCL_OK;
00496 }
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507 int
00508 rt_tcl_rt_prep(ClientData clientData, Tcl_Interp *interp, int argc, const char *const *argv)
00509 {
00510 struct application *ap = (struct application *)clientData;
00511 struct rt_i *rtip;
00512 struct bu_vls str;
00513
00514 if( argc < 2 || argc > 4 ) {
00515 Tcl_AppendResult( interp,
00516 "wrong # args: should be \"",
00517 argv[0], " ", argv[1],
00518 " [hasty_prep]\"",
00519 (char *)NULL );
00520 return TCL_ERROR;
00521 }
00522
00523 RT_CK_AP_TCL(interp, ap);
00524 rtip = ap->a_rt_i;
00525 RT_CK_RTI_TCL(interp,rtip);
00526
00527 if( argc >= 3 && !rtip->needprep ) {
00528 Tcl_AppendResult( interp,
00529 argv[0], " ", argv[1],
00530 " invoked when model has already been prepped.\n",
00531 (char *)NULL );
00532 return TCL_ERROR;
00533 }
00534
00535 if( argc == 4 ) rtip->rti_hasty_prep = atoi(argv[3]);
00536
00537
00538 if( argc >= 3 ) rt_prep_parallel( rtip, 1 );
00539
00540
00541 bu_vls_init( &str );
00542 bu_vls_printf( &str, "hasty_prep %d dont_instance %d useair %d needprep %d",
00543 rtip->rti_hasty_prep,
00544 rtip->rti_dont_instance,
00545 rtip->useair,
00546 rtip->needprep
00547 );
00548
00549 bu_vls_printf( &str, " space_partition_type %s n_nugridnode %d n_cutnode %d n_boxnode %d n_empty %ld",
00550 rtip->rti_space_partition == RT_PART_NUGRID ?
00551 "NUGrid" : "NUBSP",
00552 rtip->rti_ncut_by_type[CUT_NUGRIDNODE],
00553 rtip->rti_ncut_by_type[CUT_CUTNODE],
00554 rtip->rti_ncut_by_type[CUT_BOXNODE],
00555 rtip->nempty_cells );
00556 bu_vls_printf( &str, " maxdepth %d maxlen %d",
00557 rtip->rti_cut_maxdepth,
00558 rtip->rti_cut_maxlen );
00559 if( rtip->rti_ncut_by_type[CUT_BOXNODE] ) bu_vls_printf( &str, " avglen %g",
00560 ((double)rtip->rti_cut_totobj) /
00561 rtip->rti_ncut_by_type[CUT_BOXNODE] );
00562
00563 Tcl_AppendResult( interp, bu_vls_addr(&str), (char *)NULL );
00564 bu_vls_free( &str );
00565 return TCL_OK;
00566 }
00567
00568 static struct dbcmdstruct rt_tcl_rt_cmds[] = {
00569 {"shootray", rt_tcl_rt_shootray},
00570 {"onehit", rt_tcl_rt_onehit},
00571 {"no_bool", rt_tcl_rt_no_bool},
00572 {"check", rt_tcl_rt_check},
00573 {"prep", rt_tcl_rt_prep},
00574 {"cutter", rt_tcl_cutter},
00575 {(char *)0, (int (*)())0}
00576 };
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593 int
00594 rt_tcl_rt(ClientData clientData, Tcl_Interp *interp, int argc, const char **argv)
00595 {
00596 struct dbcmdstruct *dbcmd;
00597
00598 if( argc < 2 ) {
00599 Tcl_AppendResult( interp,
00600 "wrong # args: should be \"", argv[0],
00601 " command [args...]\"",
00602 (char *)NULL );
00603 return TCL_ERROR;
00604 }
00605
00606 for( dbcmd = rt_tcl_rt_cmds; dbcmd->cmdname != NULL; dbcmd++ ) {
00607 if( strcmp(dbcmd->cmdname, argv[1]) == 0 ) {
00608 return (*dbcmd->cmdfunc)( clientData, interp,
00609 argc, argv );
00610 }
00611 }
00612
00613
00614 Tcl_AppendResult( interp, "unknown LIBRT command '",
00615 argv[1], "'; must be one of:",
00616 (char *)NULL );
00617 for( dbcmd = rt_tcl_rt_cmds; dbcmd->cmdname != NULL; dbcmd++ ) {
00618 Tcl_AppendResult( interp, " ", dbcmd->cmdname, (char *)NULL );
00619 }
00620 return TCL_ERROR;
00621 }
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658 void
00659 db_tcl_tree_describe(Tcl_DString *dsp, const union tree *tp)
00660 {
00661 if( !tp ) return;
00662
00663 RT_CK_TREE(tp);
00664 switch( tp->tr_op ) {
00665 case OP_DB_LEAF:
00666 Tcl_DStringAppendElement( dsp, "l" );
00667 Tcl_DStringAppendElement( dsp, tp->tr_l.tl_name );
00668 if( tp->tr_l.tl_mat ) {
00669 struct bu_vls vls;
00670 bu_vls_init( &vls );
00671 bn_encode_mat( &vls, tp->tr_l.tl_mat );
00672 Tcl_DStringAppendElement( dsp, bu_vls_addr(&vls) );
00673 bu_vls_free( &vls );
00674 }
00675 break;
00676
00677
00678 case OP_UNION:
00679 Tcl_DStringAppendElement( dsp, "u" );
00680 goto bin;
00681 case OP_INTERSECT:
00682 Tcl_DStringAppendElement( dsp, "n" );
00683 goto bin;
00684 case OP_SUBTRACT:
00685 Tcl_DStringAppendElement( dsp, "-" );
00686 goto bin;
00687 case OP_XOR:
00688 Tcl_DStringAppendElement( dsp, "^" );
00689 bin:
00690 Tcl_DStringStartSublist( dsp );
00691 db_tcl_tree_describe( dsp, tp->tr_b.tb_left );
00692 Tcl_DStringEndSublist( dsp );
00693
00694 Tcl_DStringStartSublist( dsp );
00695 db_tcl_tree_describe( dsp, tp->tr_b.tb_right );
00696 Tcl_DStringEndSublist( dsp );
00697
00698 break;
00699
00700
00701 case OP_NOT:
00702 Tcl_DStringAppendElement( dsp, "!" );
00703 goto unary;
00704 case OP_GUARD:
00705 Tcl_DStringAppendElement( dsp, "G" );
00706 goto unary;
00707 case OP_XNOP:
00708 Tcl_DStringAppendElement( dsp, "X" );
00709 unary:
00710 Tcl_DStringStartSublist( dsp );
00711 db_tcl_tree_describe( dsp, tp->tr_b.tb_left );
00712 Tcl_DStringEndSublist( dsp );
00713 break;
00714
00715 case OP_NOP:
00716 Tcl_DStringAppendElement( dsp, "N" );
00717 break;
00718
00719 default:
00720 bu_log("db_tcl_tree_describe: bad op %d\n", tp->tr_op);
00721 bu_bomb("db_tcl_tree_describe\n");
00722 }
00723 }
00724
00725
00726
00727
00728
00729
00730
00731
00732 union tree *
00733 db_tcl_tree_parse( Tcl_Interp *interp, const char *str, struct resource *resp )
00734 {
00735 int argc;
00736 char **argv;
00737 union tree *tp = TREE_NULL;
00738
00739
00740 while( *str && isspace(*str) ) str++;
00741
00742 if( Tcl_SplitList( interp, str, &argc, (const char ***)&argv ) != TCL_OK )
00743 return TREE_NULL;
00744
00745 if( argc <= 0 || argc > 3 ) {
00746 Tcl_AppendResult( interp, "db_tcl_tree_parse: tree node does not have 1, 2 or 2 elements: ",
00747 str, "\n", (char *)NULL );
00748 goto out;
00749 }
00750
00751 #if 0
00752 Tcl_AppendResult( interp, "\n\ndb_tcl_tree_parse(): ", str, "\n", NULL );
00753
00754 Tcl_AppendResult( interp, "db_tcl_tree_parse() arg0=", argv[0], NULL );
00755 if(argc > 1 ) Tcl_AppendResult( interp, "\n\targ1=", argv[1], NULL );
00756 if(argc > 2 ) Tcl_AppendResult( interp, "\n\targ2=", argv[2], NULL );
00757 Tcl_AppendResult( interp, "\n\n", NULL);
00758 #endif
00759
00760 if( argv[0][1] != '\0' ) {
00761 Tcl_AppendResult( interp, "db_tcl_tree_parse() operator is not single character: ",
00762 argv[0], (char *)NULL );
00763 goto out;
00764 }
00765
00766 switch( argv[0][0] ) {
00767 case 'l':
00768
00769 RT_GET_TREE( tp, resp );
00770 tp->tr_l.magic = RT_TREE_MAGIC;
00771 tp->tr_op = OP_DB_LEAF;
00772 tp->tr_l.tl_name = bu_strdup( argv[1] );
00773
00774 tp->tr_l.tl_mat = NULL;
00775 if( argc == 3 ) {
00776 mat_t m;
00777
00778 if( bn_decode_mat( m, argv[2] ) != 16 ) {
00779 Tcl_AppendResult( interp, "db_tcl_tree_parse: unable to parse matrix '",
00780 argv[2], "', using identity", (char *)NULL );
00781 break;
00782 }
00783 if( bn_mat_is_identity(m) )
00784 break;
00785 if( bn_mat_ck( "db_tcl_tree_parse", m ) ) {
00786 Tcl_AppendResult( interp, "db_tcl_tree_parse: matrix '",
00787 argv[2],
00788 "', does not preserve axis perpendicularity, using identity", (char *)NULL );
00789 break;
00790 }
00791
00792 tp->tr_l.tl_mat = bn_mat_dup(m);
00793 }
00794 break;
00795
00796 case 'u':
00797
00798 RT_GET_TREE( tp, resp );
00799 tp->tr_b.tb_op = OP_UNION;
00800 goto binary;
00801 case 'n':
00802
00803 RT_GET_TREE( tp, resp );
00804 tp->tr_b.tb_op = OP_INTERSECT;
00805 goto binary;
00806 case '-':
00807
00808 RT_GET_TREE( tp, resp );
00809 tp->tr_b.tb_op = OP_SUBTRACT;
00810 goto binary;
00811 case '^':
00812
00813 RT_GET_TREE( tp, resp );
00814 tp->tr_b.tb_op = OP_XOR;
00815 goto binary;
00816 binary:
00817 tp->tr_b.magic = RT_TREE_MAGIC;
00818 if( argv[1] == (char *)NULL || argv[2] == (char *)NULL ) {
00819 Tcl_AppendResult( interp, "db_tcl_tree_parse: binary operator ",
00820 argv[0], " has insufficient operands in ",
00821 str, (char *)NULL );
00822 RT_FREE_TREE( tp, resp );
00823 tp = TREE_NULL;
00824 goto out;
00825 }
00826 tp->tr_b.tb_left = db_tcl_tree_parse( interp, argv[1], resp );
00827 if( tp->tr_b.tb_left == TREE_NULL ) {
00828 RT_FREE_TREE( tp, resp );
00829 tp = TREE_NULL;
00830 goto out;
00831 }
00832 tp->tr_b.tb_right = db_tcl_tree_parse( interp, argv[2], resp );
00833 if( tp->tr_b.tb_left == TREE_NULL ) {
00834 db_free_tree( tp->tr_b.tb_left, resp );
00835 RT_FREE_TREE( tp, resp );
00836 tp = TREE_NULL;
00837 goto out;
00838 }
00839 break;
00840
00841 case '!':
00842
00843 RT_GET_TREE( tp, resp );
00844 tp->tr_b.tb_op = OP_NOT;
00845 goto unary;
00846 case 'G':
00847
00848 RT_GET_TREE( tp, resp );
00849 tp->tr_b.tb_op = OP_GUARD;
00850 goto unary;
00851 case 'X':
00852
00853 RT_GET_TREE( tp, resp );
00854 tp->tr_b.tb_op = OP_XNOP;
00855 goto unary;
00856 unary:
00857 tp->tr_b.magic = RT_TREE_MAGIC;
00858 if( argv[1] == (char *)NULL ) {
00859 Tcl_AppendResult( interp, "db_tcl_tree_parse: unary operator ",
00860 argv[0], " has insufficient operands in ",
00861 str, "\n", (char *)NULL );
00862 bu_free( (char *)tp, "union tree" );
00863 tp = TREE_NULL;
00864 goto out;
00865 }
00866 tp->tr_b.tb_left = db_tcl_tree_parse( interp, argv[1], resp );
00867 if( tp->tr_b.tb_left == TREE_NULL ) {
00868 bu_free( (char *)tp, "union tree" );
00869 tp = TREE_NULL;
00870 goto out;
00871 }
00872 break;
00873
00874 case 'N':
00875
00876 RT_GET_TREE( tp, resp );
00877 tp->tr_b.tb_op = OP_XNOP;
00878 tp->tr_b.magic = RT_TREE_MAGIC;
00879 break;
00880
00881 default:
00882 Tcl_AppendResult( interp, "db_tcl_tree_parse: unable to interpret operator '",
00883 argv[1], "'\n", (char *)NULL );
00884 }
00885
00886 out:
00887 Tcl_Free( (char *)argv);
00888 return tp;
00889 }
00890
00891
00892
00893
00894
00895
00896
00897 int
00898 rt_comb_tclget(Tcl_Interp *interp, const struct rt_db_internal *intern, const char *item)
00899 {
00900 const struct rt_comb_internal *comb;
00901 char buf[128];
00902 Tcl_DString ds;
00903
00904 RT_CK_DB_INTERNAL(intern);
00905 comb = (struct rt_comb_internal *)intern->idb_ptr;
00906 RT_CK_COMB_TCL(interp,comb);
00907
00908 if( item==0 ) {
00909
00910 Tcl_DStringInit( &ds );
00911
00912 Tcl_DStringAppendElement( &ds, "comb" );
00913 Tcl_DStringAppendElement( &ds, "region" );
00914 if( comb->region_flag ) {
00915 Tcl_DStringAppendElement( &ds, "yes" );
00916
00917 Tcl_DStringAppendElement( &ds, "id" );
00918 sprintf( buf, "%d", comb->region_id );
00919 Tcl_DStringAppendElement( &ds, buf );
00920
00921 if( comb->aircode ) {
00922 Tcl_DStringAppendElement( &ds, "air" );
00923 sprintf( buf, "%d", comb->aircode );
00924 Tcl_DStringAppendElement( &ds, buf );
00925 }
00926 if( comb->los ) {
00927 Tcl_DStringAppendElement( &ds, "los" );
00928 sprintf( buf, "%d", comb->los );
00929 Tcl_DStringAppendElement( &ds, buf );
00930 }
00931
00932 if( comb->GIFTmater ) {
00933 Tcl_DStringAppendElement( &ds, "GIFTmater" );
00934 sprintf( buf, "%d", comb->GIFTmater );
00935 Tcl_DStringAppendElement( &ds, buf );
00936 }
00937 } else {
00938 Tcl_DStringAppendElement( &ds, "no" );
00939 }
00940
00941 if( comb->rgb_valid ) {
00942 Tcl_DStringAppendElement( &ds, "rgb" );
00943 sprintf( buf, "%d %d %d", V3ARGS(comb->rgb) );
00944 Tcl_DStringAppendElement( &ds, buf );
00945 }
00946
00947 if( bu_vls_strlen(&comb->shader) > 0 ) {
00948 Tcl_DStringAppendElement( &ds, "shader" );
00949 Tcl_DStringAppendElement( &ds, bu_vls_addr(&comb->shader) );
00950 }
00951
00952 if( bu_vls_strlen(&comb->material) > 0 ) {
00953 Tcl_DStringAppendElement( &ds, "material" );
00954 Tcl_DStringAppendElement( &ds, bu_vls_addr(&comb->material) );
00955 }
00956
00957 if( comb->inherit ) {
00958 Tcl_DStringAppendElement( &ds, "inherit" );
00959 Tcl_DStringAppendElement( &ds, "yes" );
00960 }
00961
00962 Tcl_DStringAppendElement( &ds, "tree" );
00963 Tcl_DStringStartSublist( &ds );
00964 db_tcl_tree_describe( &ds, comb->tree );
00965 Tcl_DStringEndSublist( &ds );
00966
00967 Tcl_DStringResult( interp, &ds );
00968 Tcl_DStringFree( &ds );
00969
00970 return TCL_OK;
00971 } else {
00972
00973 register int i;
00974 char itemlwr[128];
00975
00976 for( i = 0; i < 128 && item[i]; i++ ) {
00977 itemlwr[i] = (isupper(item[i]) ? tolower(item[i]) :
00978 item[i]);
00979 }
00980 itemlwr[i] = 0;
00981
00982 if( strcmp(itemlwr, "region")==0 ) {
00983 strcpy( buf, comb->region_flag ? "yes" : "no" );
00984 } else if( strcmp(itemlwr, "id")==0 ) {
00985 if( !comb->region_flag ) goto not_region;
00986 sprintf( buf, "%d", comb->region_id );
00987 } else if( strcmp(itemlwr, "air")==0 ) {
00988 if( !comb->region_flag ) goto not_region;
00989 sprintf( buf, "%d", comb->aircode );
00990 } else if( strcmp(itemlwr, "los")==0 ) {
00991 if( !comb->region_flag ) goto not_region;
00992 sprintf( buf, "%d", comb->los );
00993 } else if( strcmp(itemlwr, "giftmater")==0 ) {
00994 if( !comb->region_flag ) goto not_region;
00995 sprintf( buf, "%d", comb->GIFTmater );
00996 } else if( strcmp(itemlwr, "rgb")==0 ) {
00997 if( comb->rgb_valid )
00998 sprintf( buf, "%d %d %d", V3ARGS(comb->rgb) );
00999 else
01000 strcpy( buf, "invalid" );
01001 } else if( strcmp(itemlwr, "shader")==0 ) {
01002 Tcl_AppendResult( interp, bu_vls_addr(&comb->shader),
01003 (char *)NULL );
01004 return TCL_OK;
01005 } else if( strcmp(itemlwr, "material")==0 ) {
01006 Tcl_AppendResult( interp, bu_vls_addr(&comb->material),
01007 (char *)NULL );
01008 return TCL_OK;
01009 } else if( strcmp(itemlwr, "inherit")==0 ) {
01010 strcpy( buf, comb->inherit ? "yes" : "no" );
01011 } else if( strcmp(itemlwr, "tree")==0 ) {
01012 Tcl_DStringInit( &ds );
01013 db_tcl_tree_describe( &ds, comb->tree );
01014 Tcl_DStringResult( interp, &ds );
01015 Tcl_DStringFree( &ds );
01016 return TCL_OK;
01017 } else {
01018 Tcl_AppendResult( interp, "no such attribute",
01019 (char *)NULL );
01020 return TCL_ERROR;
01021 }
01022
01023 Tcl_AppendResult( interp, buf, (char *)NULL );
01024 return TCL_OK;
01025
01026 not_region:
01027 Tcl_AppendResult( interp, "item not valid for non-region",
01028 (char *)NULL );
01029 return TCL_ERROR;
01030 }
01031 }
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042 int
01043 rt_comb_tcladjust(
01044 Tcl_Interp *interp,
01045 struct rt_db_internal *intern,
01046 int argc,
01047 char **argv,
01048 struct resource *resp )
01049 {
01050 struct rt_comb_internal *comb;
01051 char buf[128];
01052 int i;
01053 double d;
01054
01055 RT_CK_DB_INTERNAL(intern);
01056 RT_CK_RESOURCE(resp);
01057 comb = (struct rt_comb_internal *)intern->idb_ptr;
01058 RT_CK_COMB(comb);
01059
01060 while( argc >= 2 ) {
01061
01062 for( i=0; i<128 && argv[0][i]!='\0'; i++ )
01063 buf[i] = isupper(argv[0][i])?tolower(argv[0][i]):argv[0][i];
01064 buf[i] = 0;
01065
01066 if( strcmp(buf, "region")==0 ) {
01067 if( strcmp( argv[1], "none" ) == 0 )
01068 comb->region_flag = 0;
01069 else
01070 {
01071 if( Tcl_GetBoolean( interp, argv[1], &i )!= TCL_OK )
01072 return TCL_ERROR;
01073 comb->region_flag = (char)i;
01074 }
01075 } else if( strcmp(buf, "temp")==0 ) {
01076 if( !comb->region_flag ) goto not_region;
01077 if( strcmp( argv[1], "none" ) == 0 )
01078 comb->temperature = 0.0;
01079 else
01080 {
01081 if( Tcl_GetDouble( interp, argv[1], &d ) != TCL_OK )
01082 return TCL_ERROR;
01083 comb->temperature = (float)d;
01084 }
01085 } else if( strcmp(buf, "id")==0 ) {
01086 if( !comb->region_flag ) goto not_region;
01087 if( strcmp( argv[1], "none" ) == 0 )
01088 comb->region_id = 0;
01089 else
01090 {
01091 if( Tcl_GetInt( interp, argv[1], &i ) != TCL_OK )
01092 return TCL_ERROR;
01093 comb->region_id = i;
01094 }
01095 } else if( strcmp(buf, "air")==0 ) {
01096 if( !comb->region_flag ) goto not_region;
01097 if( strcmp( argv[1], "none" ) == 0 )
01098 comb->aircode = 0;
01099 else
01100 {
01101 if( Tcl_GetInt( interp, argv[1], &i ) != TCL_OK)
01102 return TCL_ERROR;
01103 comb->aircode = i;
01104 }
01105 } else if( strcmp(buf, "los")==0 ) {
01106 if( !comb->region_flag ) goto not_region;
01107 if( strcmp( argv[1], "none" ) == 0 )
01108 comb->los = 0;
01109 else
01110 {
01111 if( Tcl_GetInt( interp, argv[1], &i ) != TCL_OK )
01112 return TCL_ERROR;
01113 comb->los = i;
01114 }
01115 } else if( strcmp(buf, "giftmater")==0 ) {
01116 if( !comb->region_flag ) goto not_region;
01117 if( strcmp( argv[1], "none" ) == 0 )
01118 comb->GIFTmater = 0;
01119 else
01120 {
01121 if( Tcl_GetInt( interp, argv[1], &i ) != TCL_OK )
01122 return TCL_ERROR;
01123 comb->GIFTmater = i;
01124 }
01125 } else if( strcmp(buf, "rgb")==0 ) {
01126 if( strcmp(argv[1], "invalid")==0 || strcmp( argv[1], "none" ) == 0 ) {
01127 comb->rgb[0] = comb->rgb[1] =
01128 comb->rgb[2] = 0;
01129 comb->rgb_valid = 0;
01130 } else {
01131 unsigned int r, g, b;
01132 i = sscanf( argv[1], "%u %u %u",
01133 &r, &g, &b );
01134 if( i != 3 ) {
01135 Tcl_AppendResult( interp, "adjust rgb ",
01136 argv[1], ": not valid rgb 3-tuple\n", (char *)NULL );
01137 return TCL_ERROR;
01138 }
01139 comb->rgb[0] = (unsigned char)r;
01140 comb->rgb[1] = (unsigned char)g;
01141 comb->rgb[2] = (unsigned char)b;
01142 comb->rgb_valid = 1;
01143 }
01144 } else if( strcmp(buf, "shader" )==0 ) {
01145 bu_vls_trunc( &comb->shader, 0 );
01146 if( strcmp( argv[1], "none" ) )
01147 {
01148 bu_vls_strcat( &comb->shader, argv[1] );
01149
01150 bu_vls_trimspace( &comb->shader );
01151 }
01152 } else if( strcmp(buf, "material" )==0 ) {
01153 bu_vls_trunc( &comb->material, 0 );
01154 if( strcmp( argv[1], "none" ) )
01155 {
01156 bu_vls_strcat( &comb->material, argv[1] );
01157 bu_vls_trimspace( &comb->material );
01158 }
01159 } else if( strcmp(buf, "inherit" )==0 ) {
01160 if( strcmp( argv[1], "none" ) == 0 )
01161 comb->inherit = 0;
01162 else
01163 {
01164 if( Tcl_GetBoolean( interp, argv[1], &i ) != TCL_OK )
01165 return TCL_ERROR;
01166 comb->inherit = (char)i;
01167 }
01168 } else if( strcmp(buf, "tree" )==0 ) {
01169 union tree *new;
01170
01171 if( *argv[1] == '\0' || strcmp( argv[1], "none" ) == 0 )
01172 {
01173 if( comb->tree ) {
01174 db_free_tree( comb->tree, resp );
01175 }
01176 comb->tree = TREE_NULL;
01177 }
01178 else
01179 {
01180 new = db_tcl_tree_parse( interp, argv[1], resp );
01181 if( new == TREE_NULL ) {
01182 Tcl_AppendResult( interp, "db adjust tree: bad tree '",
01183 argv[1], "'\n", (char *)NULL );
01184 return TCL_ERROR;
01185 }
01186 if( comb->tree )
01187 db_free_tree( comb->tree, resp );
01188 comb->tree = new;
01189 }
01190 } else {
01191 Tcl_AppendResult( interp, "db adjust ", buf,
01192 ": no such attribute",
01193 (char *)NULL );
01194 return TCL_ERROR;
01195 }
01196 argc -= 2;
01197 argv += 2;
01198 }
01199
01200 return TCL_OK;
01201
01202 not_region:
01203 Tcl_AppendResult( interp, "adjusting attribute ",
01204 buf, " is not valid for a non-region combination.",
01205 (char *)NULL );
01206 return TCL_ERROR;
01207 }
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226 int
01227 rt_tcl_import_from_path(Tcl_Interp *interp, struct rt_db_internal *ip, const char *path, struct rt_wdb *wdb)
01228 {
01229 struct db_i *dbip;
01230 int status;
01231
01232
01233 RT_CK_WDB(wdb);
01234 dbip = wdb->dbip;
01235 RT_CK_DBI(dbip);
01236
01237 #if 0
01238 dp = db_lookup( dbip, path, LOOKUP_QUIET );
01239 if( dp == NULL ) {
01240 Tcl_AppendResult( interp, path, ": not found\n",
01241 (char *)NULL );
01242 return TCL_ERROR;
01243 }
01244
01245 status = rt_db_get_internal( ip, dp, dbip, (matp_t)NULL );
01246 if( status < 0 ) {
01247 Tcl_AppendResult( interp, "rt_tcl_import_from_path failure: ",
01248 path, (char *)NULL );
01249 return TCL_ERROR;
01250 }
01251 #else
01252 if( strchr( path, '/' ) )
01253 {
01254
01255 struct db_tree_state ts;
01256 struct db_full_path old_path;
01257 struct db_full_path new_path;
01258 struct directory *dp_curr;
01259 int ret;
01260
01261 db_init_db_tree_state( &ts, dbip, &rt_uniresource );
01262 db_full_path_init(&old_path);
01263 db_full_path_init(&new_path);
01264
01265 if( db_string_to_path( &new_path, dbip, path ) < 0 ) {
01266 Tcl_AppendResult(interp, "rt_tcl_import_from_path: '",
01267 path, "' contains unknown object names\n", (char *)NULL);
01268 return TCL_ERROR;
01269 }
01270
01271 dp_curr = DB_FULL_PATH_CUR_DIR( &new_path );
01272 ret = db_follow_path( &ts, &old_path, &new_path, LOOKUP_NOISY, 0 );
01273 db_free_full_path( &old_path );
01274 db_free_full_path( &new_path );
01275
01276 if( ret < 0 ) {
01277 Tcl_AppendResult(interp, "rt_tcl_import_from_path: '",
01278 path, "' is a bad path\n", (char *)NULL );
01279 return TCL_ERROR;
01280 }
01281
01282 status = wdb_import( wdb, ip, dp_curr->d_namep, ts.ts_mat );
01283 if( status == -4 ) {
01284 Tcl_AppendResult( interp, dp_curr->d_namep,
01285 " not found in path ", path, "\n",
01286 (char *)NULL );
01287 return TCL_ERROR;
01288 }
01289 if( status < 0 ) {
01290 Tcl_AppendResult( interp, "wdb_import failure: ",
01291 dp_curr->d_namep, (char *)NULL );
01292 return TCL_ERROR;
01293 }
01294 }
01295 else
01296 {
01297 status = wdb_import( wdb, ip, path, (matp_t)NULL );
01298 if( status == -4 ) {
01299 Tcl_AppendResult( interp, path, ": not found\n",
01300 (char *)NULL );
01301 return TCL_ERROR;
01302 }
01303 if( status < 0 ) {
01304 Tcl_AppendResult( interp, "wdb_import failure: ",
01305 path, (char *)NULL );
01306 return TCL_ERROR;
01307 }
01308 }
01309 #endif
01310 return TCL_OK;
01311 }
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323 int
01324 rt_parsetab_tclget(Tcl_Interp *interp, const struct rt_db_internal *intern, const char *attr)
01325 {
01326 register const struct bu_structparse *sp = NULL;
01327 register const struct rt_functab *ftp;
01328 int status;
01329 Tcl_DString ds;
01330 struct bu_vls str;
01331
01332 RT_CK_DB_INTERNAL( intern );
01333 ftp = intern->idb_meth;
01334 RT_CK_FUNCTAB(ftp);
01335
01336 sp = ftp->ft_parsetab;
01337 if( !sp ) {
01338 Tcl_AppendResult( interp, ftp->ft_label,
01339 " {a Tcl output routine for this type of object has not yet been implemented}",
01340 (char *)NULL );
01341 return TCL_ERROR;
01342 }
01343
01344 bu_vls_init( &str );
01345 Tcl_DStringInit( &ds );
01346
01347 if( attr == (char *)0 ) {
01348
01349 Tcl_DStringAppendElement( &ds, ftp->ft_label );
01350 while( sp->sp_name != NULL ) {
01351 Tcl_DStringAppendElement( &ds, sp->sp_name );
01352 bu_vls_trunc( &str, 0 );
01353 bu_vls_struct_item( &str, sp,
01354 (char *)intern->idb_ptr, ' ' );
01355 Tcl_DStringAppendElement( &ds, bu_vls_addr(&str) );
01356 ++sp;
01357 }
01358 status = TCL_OK;
01359 } else {
01360 if( bu_vls_struct_item_named( &str, sp, attr,
01361 (char *)intern->idb_ptr, ' ') < 0 ) {
01362 bu_vls_printf(&str,
01363 "Objects of type %s do not have a %s attribute.",
01364 ftp->ft_label, attr);
01365 status = TCL_ERROR;
01366 } else {
01367 status = TCL_OK;
01368 }
01369 Tcl_DStringAppend( &ds, bu_vls_addr(&str), -1 );
01370 }
01371
01372 Tcl_DStringResult( interp, &ds );
01373 Tcl_DStringFree( &ds );
01374 bu_vls_free( &str );
01375
01376 return status;
01377 }
01378
01379
01380
01381
01382 int
01383 rt_comb_tclform(const struct rt_functab *ftp, Tcl_Interp *interp)
01384 {
01385 RT_CK_FUNCTAB(ftp);
01386
01387 Tcl_AppendResult( interp,
01388 "region {%s} id {%d} air {%d} los {%d} GIFTmater {%d} rgb {%d %d %d} \
01389 shader {%s} material {%s} inherit {%s} tree {%s}", (char *)NULL );
01390 return TCL_OK;
01391 }
01392
01393
01394
01395
01396
01397
01398
01399
01400 void
01401 rt_comb_make(const struct rt_functab *ftp, struct rt_db_internal *intern, double diameter)
01402 {
01403 struct rt_comb_internal *comb;
01404
01405 intern->idb_major_type = DB5_MAJORTYPE_BRLCAD;
01406 intern->idb_type = ID_COMBINATION;
01407 intern->idb_meth = &rt_functab[ID_COMBINATION];
01408 intern->idb_ptr = bu_calloc( sizeof(struct rt_comb_internal), 1,
01409 "rt_comb_internal" );
01410
01411 comb = (struct rt_comb_internal *)intern->idb_ptr;
01412 comb->magic = (long)RT_COMB_MAGIC;
01413 comb->temperature = -1;
01414 comb->tree = (union tree *)0;
01415 comb->region_flag = 1;
01416 comb->region_id = 0;
01417 comb->aircode = 0;
01418 comb->GIFTmater = 0;
01419 comb->los = 0;
01420 comb->rgb_valid = 0;
01421 comb->rgb[0] = comb->rgb[1] = comb->rgb[2] = 0;
01422 bu_vls_init( &comb->shader );
01423 bu_vls_init( &comb->material );
01424 comb->inherit = 0;
01425 }
01426
01427
01428
01429
01430
01431
01432
01433
01434 void
01435 rt_generic_make(const struct rt_functab *ftp, struct rt_db_internal *intern, double diameter)
01436 {
01437 intern->idb_type = ftp - rt_functab;
01438 intern->idb_major_type = DB5_MAJORTYPE_BRLCAD;
01439 BU_ASSERT(&rt_functab[intern->idb_type] == ftp);
01440
01441 intern->idb_meth = ftp;
01442 intern->idb_ptr = bu_calloc( ftp->ft_internal_size, 1, "rt_generic_make");
01443 *((long *)(intern->idb_ptr)) = ftp->ft_internal_magic;
01444 }
01445
01446
01447
01448
01449
01450
01451
01452 int
01453 rt_parsetab_tcladjust(Tcl_Interp *interp, struct rt_db_internal *intern, int argc, char **argv)
01454 {
01455 const struct rt_functab *ftp;
01456
01457 RT_CK_DB_INTERNAL(intern);
01458 ftp = intern->idb_meth;
01459 RT_CK_FUNCTAB(ftp);
01460
01461 if( ftp->ft_parsetab == (struct bu_structparse *)NULL ) {
01462 Tcl_AppendResult( interp, ftp->ft_label,
01463 " type objects do not yet have a 'db put' (tcladjust) handler.",
01464 (char *)NULL );
01465 return TCL_ERROR;
01466 }
01467
01468 return bu_structparse_argv(interp, argc, argv, ftp->ft_parsetab,
01469 (char *)intern->idb_ptr );
01470 }
01471
01472
01473
01474
01475
01476
01477
01478
01479 int
01480 rt_parsetab_tclform(const struct rt_functab *ftp, Tcl_Interp *interp)
01481 {
01482 RT_CK_FUNCTAB(ftp);
01483
01484 if( ftp->ft_parsetab ) {
01485 bu_structparse_get_terse_form( interp, ftp->ft_parsetab );
01486 return TCL_OK;
01487 }
01488 Tcl_AppendResult(interp, ftp->ft_label,
01489 " is a valid object type, but a 'form' routine has not yet been implemented.",
01490 (char *)NULL );
01491 return TCL_ERROR;
01492 }
01493
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510 void
01511 rt_tcl_setup(Tcl_Interp *interp)
01512 {
01513 extern int rt_bot_minpieces;
01514 extern int rt_bot_tri_per_piece;
01515
01516
01517 Wdb_Init(interp);
01518
01519
01520 Dgo_Init(interp);
01521
01522
01523 Vo_Init(interp);
01524
01525 Tcl_SetVar(interp, "rt_version", (char *)rt_version+5, TCL_GLOBAL_ONLY);
01526 Tcl_LinkVar(interp, "rt_bot_minpieces", (char *)&rt_bot_minpieces, TCL_LINK_INT);
01527
01528 Tcl_LinkVar(interp, "rt_bot_tri_per_piece",
01529 (char *)&rt_bot_tri_per_piece, TCL_LINK_INT);
01530 }
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541 int
01542 #ifdef BRLCAD_DEBUG
01543 Rt_d_Init(Tcl_Interp *interp)
01544 #else
01545 Rt_Init(Tcl_Interp *interp)
01546 #endif
01547 {
01548 const char *version_number;
01549
01550
01551 if (BU_LIST_UNINITIALIZED(&rt_g.rtg_vlfree)) {
01552 if (bu_avail_cpus() > 1) {
01553 rt_g.rtg_parallel = 1;
01554 bu_semaphore_init(RT_SEM_LAST);
01555 }
01556
01557
01558 BU_LIST_INIT(&rt_g.rtg_vlfree);
01559 BU_LIST_INIT(&rt_g.rtg_headwdb.l);
01560 rt_init_resource(&rt_uniresource, 0, NULL);
01561 }
01562
01563 rt_tcl_setup(interp);
01564 Tcl_Eval(interp, "lindex $rt_version 2");
01565 version_number = Tcl_GetStringResult(interp);
01566 Tcl_PkgProvide(interp, "Rt", version_number);
01567
01568 return TCL_OK;
01569 }
01570
01571
01572
01573
01574
01575
01576
01577
01578
01579
01580
01581
01582
01583 void
01584 db_full_path_appendresult( Tcl_Interp *interp, const struct db_full_path *pp )
01585 {
01586 register int i;
01587
01588 RT_CK_FULL_PATH(pp);
01589
01590 for( i=0; i<pp->fp_len; i++ ) {
01591 Tcl_AppendResult(interp, "/", pp->fp_names[i]->d_namep, (char *)NULL );
01592 }
01593 }
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604 int
01605 tcl_obj_to_int_array(Tcl_Interp *interp, Tcl_Obj *list, int **array, int *array_len)
01606 {
01607 Tcl_Obj **obj_array;
01608 int len, i;
01609
01610 if( Tcl_ListObjGetElements( interp, list, &len, &obj_array ) != TCL_OK )
01611 return( 0 );
01612
01613 if( len < 1 )
01614 return( 0 );
01615
01616 if( *array_len < 1 )
01617 {
01618 *array = (int *)bu_calloc( len, sizeof( int ), "array" );
01619 *array_len = len;
01620 }
01621
01622 for( i=0 ; i<len && i<*array_len ; i++ ) {
01623 (*array)[i] = atoi( Tcl_GetStringFromObj( obj_array[i], NULL ) );
01624 Tcl_DecrRefCount( obj_array[i] );
01625 }
01626
01627 return( len < *array_len ? len : *array_len );
01628 }
01629
01630
01631
01632
01633
01634
01635
01636
01637
01638 int
01639 tcl_list_to_int_array(Tcl_Interp *interp, char *char_list, int **array, int *array_len)
01640 {
01641 Tcl_Obj *obj;
01642 int ret;
01643
01644 obj = Tcl_NewStringObj( char_list, -1 );
01645
01646 ret = tcl_obj_to_int_array( interp, obj, array, array_len );
01647
01648 return( ret );
01649 }
01650
01651
01652
01653
01654
01655
01656
01657
01658
01659
01660
01661 int
01662 tcl_obj_to_fastf_array(Tcl_Interp *interp, Tcl_Obj *list, fastf_t **array, int *array_len)
01663 {
01664 Tcl_Obj **obj_array;
01665 int len, i;
01666 int ret;
01667
01668 if( (ret=Tcl_ListObjGetElements( interp, list, &len, &obj_array )) != TCL_OK )
01669 return( ret );
01670
01671 if( len < 1 )
01672 return( 0 );
01673
01674 if( *array_len < 1 )
01675 {
01676 *array = (fastf_t *)bu_calloc( len, sizeof( fastf_t ), "array" );
01677 *array_len = len;
01678 }
01679
01680 for( i=0 ; i<len && i<*array_len ; i++ ) {
01681 (*array)[i] = atof( Tcl_GetStringFromObj( obj_array[i], NULL ) );
01682 Tcl_DecrRefCount( obj_array[i] );
01683 }
01684
01685 return( len < *array_len ? len : *array_len );
01686 }
01687
01688
01689
01690
01691
01692
01693
01694
01695
01696 int
01697 tcl_list_to_fastf_array(Tcl_Interp *interp, char *char_list, fastf_t **array, int *array_len)
01698 {
01699 Tcl_Obj *obj;
01700 int ret;
01701
01702 obj = Tcl_NewStringObj( char_list, -1 );
01703
01704 ret = tcl_obj_to_fastf_array( interp, obj, array, array_len );
01705
01706 return( ret );
01707 }
01708
01709
01710
01711
01712
01713
01714
01715
01716
01717