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 #ifndef lint
00036 static const char RCSid[] = "@(#)$Header: /cvsroot/brlcad/brlcad/src/librt/wdb_comb_std.c,v 14.12 2006/09/16 02:04:26 lbutler Exp $ (BRL)";
00037 #endif
00038
00039 #include "common.h"
00040
00041 #include <stdio.h>
00042 #ifdef HAVE_STRING_H
00043 # include <string.h>
00044 #else
00045 # include <strings.h>
00046 #endif
00047
00048 #include "tcl.h"
00049 #include "machine.h"
00050 #include "bu.h"
00051 #include "vmath.h"
00052 #include "raytrace.h"
00053 #include "rtgeom.h"
00054
00055
00056 #define PRINT_USAGE Tcl_AppendResult(interp, "c: usage 'c [-cr] comb_name [bool_expr]'\n",\
00057 (char *)NULL)
00058
00059 struct tokens {
00060 struct bu_list l;
00061 short type;
00062 union tree *tp;
00063 };
00064
00065
00066 #define WDB_TOK_NULL 0
00067 #define WDB_TOK_LPAREN 1
00068 #define WDB_TOK_RPAREN 2
00069 #define WDB_TOK_UNION 3
00070 #define WDB_TOK_INTER 4
00071 #define WDB_TOK_SUBTR 5
00072 #define WDB_TOK_TREE 6
00073
00074 HIDDEN void
00075 wdb_free_tokens(struct bu_list *hp)
00076 {
00077 struct tokens *tok;
00078
00079 BU_CK_LIST_HEAD(hp);
00080
00081 while (BU_LIST_WHILE(tok, tokens, hp)) {
00082 BU_LIST_DEQUEUE(&tok->l);
00083 if (tok->type == WDB_TOK_TREE) {
00084 if (tok->tp)
00085 db_free_tree(tok->tp, &rt_uniresource);
00086 }
00087 }
00088 }
00089
00090 HIDDEN void
00091 wdb_append_union(struct bu_list *hp)
00092 {
00093 struct tokens *tok;
00094
00095 BU_CK_LIST_HEAD( hp );
00096
00097 tok = (struct tokens *)bu_malloc(sizeof(struct tokens), "tok");
00098 tok->type = WDB_TOK_UNION;
00099 tok->tp = (union tree *)NULL;
00100 BU_LIST_INSERT(hp, &tok->l);
00101 }
00102
00103 HIDDEN void
00104 wdb_append_inter(struct bu_list *hp)
00105 {
00106 struct tokens *tok;
00107
00108 BU_CK_LIST_HEAD(hp);
00109
00110 tok = (struct tokens *)bu_malloc(sizeof(struct tokens), "tok");
00111 tok->type = WDB_TOK_INTER;
00112 tok->tp = (union tree *)NULL;
00113 BU_LIST_INSERT( hp, &tok->l );
00114 }
00115
00116 HIDDEN void
00117 wdb_append_subtr(struct bu_list *hp)
00118 {
00119 struct tokens *tok;
00120
00121 BU_CK_LIST_HEAD(hp);
00122
00123 tok = (struct tokens *)bu_malloc(sizeof(struct tokens), "tok");
00124 tok->type = WDB_TOK_SUBTR;
00125 tok->tp = (union tree *)NULL;
00126 BU_LIST_INSERT( hp, &tok->l );
00127 }
00128
00129 HIDDEN void
00130 wdb_append_lparen(struct bu_list *hp)
00131 {
00132 struct tokens *tok;
00133
00134 BU_CK_LIST_HEAD(hp);
00135
00136 tok = (struct tokens *)bu_malloc(sizeof(struct tokens), "tok");
00137 tok->type = WDB_TOK_LPAREN;
00138 tok->tp = (union tree *)NULL;
00139 BU_LIST_INSERT( hp, &tok->l );
00140 }
00141
00142 HIDDEN void
00143 wdb_append_rparen(struct bu_list *hp)
00144 {
00145 struct tokens *tok;
00146
00147 BU_CK_LIST_HEAD(hp);
00148
00149 tok = (struct tokens *)bu_malloc(sizeof(struct tokens), "tok");
00150 tok->type = WDB_TOK_RPAREN;
00151 tok->tp = (union tree *)NULL;
00152 BU_LIST_INSERT(hp, &tok->l);
00153 }
00154
00155 HIDDEN int
00156 wdb_add_operator(Tcl_Interp *interp, struct bu_list *hp, char ch, short int *last_tok)
00157 {
00158 char illegal[2];
00159
00160 BU_CK_LIST_HEAD(hp);
00161
00162 switch( ch )
00163 {
00164 case 'u':
00165 wdb_append_union(hp);
00166 *last_tok = WDB_TOK_UNION;
00167 break;
00168 case '+':
00169 wdb_append_inter(hp);
00170 *last_tok = WDB_TOK_INTER;
00171 break;
00172 case '-':
00173 wdb_append_subtr(hp);
00174 *last_tok = WDB_TOK_SUBTR;
00175 break;
00176 default:
00177 illegal[0] = ch;
00178 illegal[1] = '\0';
00179 Tcl_AppendResult(interp, "Illegal operator: ", illegal,
00180 ", aborting\n", (char *)NULL );
00181 wdb_free_tokens(hp);
00182 return TCL_ERROR;
00183 }
00184 return TCL_OK;
00185 }
00186
00187 HIDDEN int
00188 wdb_add_operand(Tcl_Interp *interp, struct bu_list *hp, char *name)
00189 {
00190 char *ptr_lparen;
00191 char *ptr_rparen;
00192 int name_len;
00193 union tree *node;
00194 struct tokens *tok;
00195
00196 BU_CK_LIST_HEAD(hp);
00197
00198 ptr_lparen = strchr(name, '(');
00199 ptr_rparen = strchr(name, ')');
00200
00201 RT_GET_TREE( node, &rt_uniresource );
00202 node->magic = RT_TREE_MAGIC;
00203 node->tr_op = OP_DB_LEAF;
00204 node->tr_l.tl_mat = (matp_t)NULL;
00205 if (ptr_lparen || ptr_rparen) {
00206 int tmp1,tmp2;
00207
00208 if (ptr_rparen)
00209 tmp1 = ptr_rparen - name;
00210 else
00211 tmp1 = (-1);
00212 if (ptr_lparen)
00213 tmp2 = ptr_lparen - name;
00214 else
00215 tmp2 = (-1);
00216
00217 if (tmp2 == (-1) && tmp1 > 0)
00218 name_len = tmp1;
00219 else if (tmp1 == (-1) && tmp2 > 0)
00220 name_len = tmp2;
00221 else if(tmp1 > 0 && tmp2 > 0) {
00222 if (tmp1 < tmp2)
00223 name_len = tmp1;
00224 else
00225 name_len = tmp2;
00226 }
00227 else {
00228 Tcl_AppendResult(interp, "Cannot determine length of operand name: ",
00229 name, ", aborting\n", (char *)NULL);
00230 return (0);
00231 }
00232 } else
00233 name_len = strlen( name );
00234
00235 node->tr_l.tl_name = (char *)bu_malloc(name_len + 1, "node name");
00236 strncpy(node->tr_l.tl_name, name, name_len);
00237 node->tr_l.tl_name[name_len] = '\0';
00238 tok = (struct tokens *)bu_malloc(sizeof(struct tokens), "tok");
00239 tok->type = WDB_TOK_TREE;
00240 tok->tp = node;
00241 BU_LIST_INSERT(hp, &tok->l);
00242 return (name_len);
00243 }
00244
00245 HIDDEN void
00246 wdb_do_inter(struct bu_list *hp)
00247 {
00248 struct tokens *tok;
00249
00250 for (BU_LIST_FOR(tok, tokens, hp )) {
00251 struct tokens *prev, *next;
00252 union tree *tp;
00253
00254 if (tok->type != WDB_TOK_INTER)
00255 continue;
00256
00257 prev = BU_LIST_PREV( tokens, &tok->l );
00258 next = BU_LIST_NEXT( tokens, &tok->l );
00259
00260 if (prev->type !=WDB_TOK_TREE || next->type != WDB_TOK_TREE)
00261 continue;
00262
00263
00264 tp = (union tree *)bu_malloc( sizeof( union tree ), "tp" );
00265 tp->magic = RT_TREE_MAGIC;
00266 tp->tr_b.tb_op = OP_INTERSECT;
00267 tp->tr_b.tb_regionp = (struct region *)NULL;
00268 tp->tr_b.tb_left = prev->tp;
00269 tp->tr_b.tb_right = next->tp;
00270 BU_LIST_DEQUEUE( &tok->l );
00271 bu_free( (char *)tok, "tok" );
00272 BU_LIST_DEQUEUE( &prev->l );
00273 bu_free( (char *)prev, "prev" );
00274 next->tp = tp;
00275 tok = next;
00276 }
00277 }
00278
00279 HIDDEN void
00280 wdb_do_union_subtr(struct bu_list *hp)
00281 {
00282 struct tokens *tok;
00283
00284 for(BU_LIST_FOR(tok, tokens, hp)) {
00285 struct tokens *prev, *next;
00286 union tree *tp;
00287
00288 if (tok->type != WDB_TOK_UNION && tok->type != WDB_TOK_SUBTR)
00289 continue;
00290
00291 prev = BU_LIST_PREV( tokens, &tok->l );
00292 next = BU_LIST_NEXT( tokens, &tok->l );
00293
00294 if (prev->type !=WDB_TOK_TREE || next->type != WDB_TOK_TREE)
00295 continue;
00296
00297
00298 tp = (union tree *)bu_malloc( sizeof( union tree ), "tp" );
00299 tp->magic = RT_TREE_MAGIC;
00300 if (tok->type == WDB_TOK_UNION)
00301 tp->tr_b.tb_op = OP_UNION;
00302 else
00303 tp->tr_b.tb_op = OP_SUBTRACT;
00304 tp->tr_b.tb_regionp = (struct region *)NULL;
00305 tp->tr_b.tb_left = prev->tp;
00306 tp->tr_b.tb_right = next->tp;
00307 BU_LIST_DEQUEUE(&tok->l);
00308 bu_free((char *)tok, "tok");
00309 BU_LIST_DEQUEUE(&prev->l);
00310 bu_free((char *)prev, "prev");
00311 next->tp = tp;
00312 tok = next;
00313 }
00314 }
00315
00316 HIDDEN int
00317 wdb_do_paren(struct bu_list *hp)
00318 {
00319 struct tokens *tok;
00320
00321 for (BU_LIST_FOR(tok, tokens, hp)) {
00322 struct tokens *prev, *next;
00323
00324 if (tok->type != WDB_TOK_TREE)
00325 continue;
00326
00327 prev = BU_LIST_PREV( tokens, &tok->l );
00328 next = BU_LIST_NEXT( tokens, &tok->l );
00329
00330 if (prev->type !=WDB_TOK_LPAREN || next->type != WDB_TOK_RPAREN)
00331 continue;
00332
00333
00334 BU_LIST_DEQUEUE(&next->l);
00335 bu_free((char *)next, "next");
00336 BU_LIST_DEQUEUE(&prev->l);
00337 bu_free((char *)prev, "prev");
00338 }
00339
00340 if (hp->forw == hp->back && hp->forw != hp)
00341 return 1;
00342 else if (BU_LIST_IS_EMPTY(hp))
00343 return -1;
00344 else
00345 return 0;
00346
00347 }
00348
00349 HIDDEN union tree *
00350 wdb_eval_bool(struct bu_list *hp)
00351 {
00352 int done=0;
00353 union tree *final_tree;
00354 struct tokens *tok;
00355
00356 while (done != 1) {
00357 wdb_do_inter(hp);
00358 wdb_do_union_subtr(hp);
00359 done = wdb_do_paren(hp);
00360 }
00361
00362 if (done == 1) {
00363 tok = BU_LIST_NEXT(tokens, hp);
00364 final_tree = tok->tp;
00365 BU_LIST_DEQUEUE(&tok->l);
00366 bu_free((char *)tok, "tok");
00367 return(final_tree);
00368 }
00369
00370 return (union tree *)NULL;
00371 }
00372
00373 HIDDEN int
00374 wdb_check_syntax(Tcl_Interp *interp, struct db_i *dbip, struct bu_list *hp, char *comb_name, struct directory *dp)
00375 {
00376 struct tokens *tok;
00377 int paren_count=0;
00378 int paren_error=0;
00379 int missing_exp=0;
00380 int missing_op=0;
00381 int op_count=0;
00382 int arg_count=0;
00383 int circular_ref=0;
00384 int errors=0;
00385 short last_tok=WDB_TOK_NULL;
00386
00387 if(dbip == DBI_NULL)
00388 return 0;
00389
00390 for( BU_LIST_FOR( tok, tokens, hp ) )
00391 {
00392 switch( tok->type )
00393 {
00394 case WDB_TOK_LPAREN:
00395 paren_count++;
00396 if( last_tok == WDB_TOK_RPAREN )
00397 missing_op++;
00398 break;
00399 case WDB_TOK_RPAREN:
00400 paren_count--;
00401 if( last_tok == WDB_TOK_LPAREN )
00402 missing_exp++;
00403 break;
00404 case WDB_TOK_UNION:
00405 case WDB_TOK_SUBTR:
00406 case WDB_TOK_INTER:
00407 op_count++;
00408 break;
00409 case WDB_TOK_TREE:
00410 arg_count++;
00411 if( !dp && !strcmp( comb_name, tok->tp->tr_l.tl_name ) )
00412 circular_ref++;
00413 else if( db_lookup( dbip, tok->tp->tr_l.tl_name, LOOKUP_QUIET ) == DIR_NULL )
00414 Tcl_AppendResult(interp, "WARNING: '",
00415 tok->tp->tr_l.tl_name,
00416 "' does not actually exist\n", (char *)NULL );
00417 break;
00418 }
00419 if( paren_count < 0 )
00420 paren_error++;
00421 last_tok = tok->type;
00422 }
00423
00424 if( paren_count || paren_error )
00425 {
00426 Tcl_AppendResult(interp, "ERROR: unbalanced parenthesis\n", (char *)NULL );
00427 errors++;
00428 }
00429
00430 if( missing_exp )
00431 {
00432 Tcl_AppendResult(interp, "ERROR: empty parenthesis (missing expression)\n", (char *)NULL );
00433 errors++;
00434 }
00435
00436 if( missing_op )
00437 {
00438 Tcl_AppendResult(interp, "ERROR: must have operator between ')('\n", (char *)NULL );
00439 errors++;
00440 }
00441
00442 if( op_count != arg_count-1 )
00443 {
00444 Tcl_AppendResult(interp, "ERROR: mismatch of operators and operands\n", (char *)NULL );
00445 errors++;
00446 }
00447
00448 if( circular_ref )
00449 {
00450 Tcl_AppendResult(interp, "ERROR: combination cannot reference itself during initial creation\n", (char *)NULL );
00451 errors++;
00452 }
00453
00454 if( errors )
00455 {
00456 Tcl_AppendResult(interp, "\t---------aborting!\n", (char *)NULL );
00457 return( 1 );
00458 }
00459
00460 return( 0 );
00461 }
00462
00463 int
00464 wdb_comb_std_cmd(struct rt_wdb *wdbp,
00465 Tcl_Interp *interp,
00466 int argc,
00467 char **argv)
00468 {
00469 char *comb_name;
00470 int ch;
00471 int region_flag = -1;
00472 register struct directory *dp;
00473 struct rt_db_internal intern;
00474 struct rt_comb_internal *comb = NULL;
00475 struct tokens tok_hd;
00476 struct tokens *tok;
00477 short last_tok;
00478 int i;
00479 union tree *final_tree;
00480
00481 if (wdbp->dbip->dbi_read_only) {
00482 Tcl_AppendResult(interp, "Database is read-only!\n", (char *)NULL);
00483 return TCL_ERROR;
00484 }
00485
00486 if (argc < 3 || RT_MAXARGS < argc) {
00487 struct bu_vls vls;
00488
00489 bu_vls_init(&vls);
00490 bu_vls_printf(&vls, "helplib_alias wdb_comb_std %s", argv[0]);
00491 Tcl_Eval(interp, bu_vls_addr(&vls));
00492 bu_vls_free(&vls);
00493 return TCL_ERROR;
00494 }
00495
00496
00497 bu_optind = 1;
00498 while ((ch = bu_getopt(argc, argv, "cgr?")) != EOF) {
00499 switch (ch) {
00500 case 'c':
00501 case 'g':
00502 region_flag = 0;
00503 break;
00504 case 'r':
00505 region_flag = 1;
00506 break;
00507
00508 case '?':
00509 default:
00510 PRINT_USAGE;
00511 return TCL_OK;
00512 }
00513 }
00514 argc -= (bu_optind + 1);
00515 argv += bu_optind;
00516
00517 comb_name = *argv++;
00518 if (argc == -1) {
00519 PRINT_USAGE;
00520 return TCL_OK;
00521 }
00522
00523 if ((region_flag != -1) && (argc == 0)) {
00524
00525
00526
00527 if ((dp = db_lookup(wdbp->dbip, comb_name, LOOKUP_NOISY)) == DIR_NULL)
00528 return TCL_ERROR;
00529
00530 if (!(dp->d_flags & DIR_COMB)) {
00531 Tcl_AppendResult(interp, comb_name, " is not a combination\n", (char *)0 );
00532 return TCL_ERROR;
00533 }
00534
00535 if (rt_db_get_internal(&intern, dp, wdbp->dbip, (fastf_t *)NULL, &rt_uniresource) < 0) {
00536 Tcl_AppendResult(interp, "Database read error, aborting\n", (char *)NULL);
00537 return TCL_ERROR;
00538 }
00539 comb = (struct rt_comb_internal *)intern.idb_ptr;
00540 RT_CK_COMB(comb);
00541
00542 if (region_flag) {
00543 if( !comb->region_flag ) {
00544
00545 comb->region_id = wdbp->wdb_item_default++;
00546 comb->aircode = wdbp->wdb_air_default;
00547 comb->GIFTmater = wdbp->wdb_mat_default;
00548 comb->los = wdbp->wdb_los_default;
00549 }
00550 comb->region_flag = 1;
00551 }
00552 else
00553 comb->region_flag = 0;
00554
00555 if (rt_db_put_internal(dp, wdbp->dbip, &intern, &rt_uniresource) < 0) {
00556 rt_db_free_internal(&intern, &rt_uniresource);
00557 Tcl_AppendResult(interp, "Database write error, aborting\n", (char *)NULL);
00558 return TCL_ERROR;
00559 }
00560
00561 return TCL_OK;
00562 }
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572 dp = db_lookup( wdbp->dbip, comb_name, LOOKUP_QUIET );
00573 if (dp != DIR_NULL) {
00574 Tcl_AppendResult(interp, "ERROR: ", comb_name, " already exists\n", (char *)0 );
00575 return TCL_ERROR;
00576 }
00577
00578
00579 BU_LIST_INIT(&tok_hd.l);
00580 tok_hd.type = WDB_TOK_NULL;
00581
00582 last_tok = WDB_TOK_LPAREN;
00583 for (i=0 ; i<argc ; i++) {
00584 char *ptr;
00585
00586 ptr = argv[i];
00587 while (*ptr) {
00588 while (*ptr == '(' || *ptr == ')') {
00589 switch (*ptr) {
00590 case '(':
00591 wdb_append_lparen( &tok_hd.l );
00592 last_tok = WDB_TOK_LPAREN;
00593 break;
00594 case ')':
00595 wdb_append_rparen( &tok_hd.l );
00596 last_tok = WDB_TOK_RPAREN;
00597 break;
00598 }
00599 ptr++;
00600 }
00601
00602 if (*ptr == '\0')
00603 continue;
00604
00605 if (last_tok == WDB_TOK_RPAREN) {
00606
00607 if (wdb_add_operator(interp, &tok_hd.l, *ptr, &last_tok) == TCL_ERROR) {
00608 wdb_free_tokens(&tok_hd.l);
00609 if (dp != DIR_NULL)
00610 rt_db_free_internal(&intern, &rt_uniresource);
00611 return TCL_ERROR;
00612 }
00613 ptr++;
00614 } else if (last_tok == WDB_TOK_LPAREN) {
00615
00616 int name_len;
00617
00618 name_len = wdb_add_operand(interp, &tok_hd.l, ptr );
00619 if (name_len < 1) {
00620 wdb_free_tokens(&tok_hd.l);
00621 if (dp != DIR_NULL)
00622 rt_db_free_internal(&intern, &rt_uniresource);
00623 return TCL_ERROR;
00624 }
00625 last_tok = WDB_TOK_TREE;
00626 ptr += name_len;
00627 } else if (last_tok == WDB_TOK_TREE) {
00628
00629 if (wdb_add_operator(interp, &tok_hd.l, *ptr, &last_tok) == TCL_ERROR) {
00630 wdb_free_tokens(&tok_hd.l);
00631 if (dp != DIR_NULL)
00632 rt_db_free_internal(&intern, &rt_uniresource);
00633 return TCL_ERROR;
00634 }
00635 ptr++;
00636 } else if (last_tok == WDB_TOK_UNION ||
00637 last_tok == WDB_TOK_INTER ||
00638 last_tok == WDB_TOK_SUBTR) {
00639
00640 int name_len;
00641
00642 name_len = wdb_add_operand(interp, &tok_hd.l, ptr );
00643 if (name_len < 1) {
00644 wdb_free_tokens(&tok_hd.l);
00645 if (dp != DIR_NULL)
00646 rt_db_free_internal(&intern, &rt_uniresource);
00647 return TCL_ERROR;
00648 }
00649 last_tok = WDB_TOK_TREE;
00650 ptr += name_len;
00651 }
00652 }
00653 }
00654
00655 if (wdb_check_syntax(interp, wdbp->dbip, &tok_hd.l, comb_name, dp)) {
00656 wdb_free_tokens(&tok_hd.l);
00657 return TCL_ERROR;
00658 }
00659
00660
00661 if (dp != DIR_NULL) {
00662 for (BU_LIST_FOR(tok, tokens, &tok_hd.l)) {
00663 struct rt_db_internal intern1;
00664 struct rt_comb_internal *comb1;
00665
00666 switch (tok->type) {
00667 case WDB_TOK_LPAREN:
00668 case WDB_TOK_RPAREN:
00669 case WDB_TOK_UNION:
00670 case WDB_TOK_INTER:
00671 case WDB_TOK_SUBTR:
00672 break;
00673 case WDB_TOK_TREE:
00674 if (!strcmp(tok->tp->tr_l.tl_name, comb_name)) {
00675 db_free_tree( tok->tp, &rt_uniresource );
00676 if (rt_db_get_internal(&intern1, dp, wdbp->dbip, (fastf_t *)NULL, &rt_uniresource) < 0) {
00677 Tcl_AppendResult(interp, "Cannot get records for ", comb_name, "\n" );
00678 Tcl_AppendResult(interp, "Database read error, aborting\n", (char *)NULL);
00679 return TCL_ERROR;
00680 }
00681 comb1 = (struct rt_comb_internal *)intern1.idb_ptr;
00682 RT_CK_COMB(comb1);
00683
00684 tok->tp = comb1->tree;
00685 comb1->tree = (union tree *)NULL;
00686 rt_db_free_internal(&intern1, &rt_uniresource);
00687 }
00688 break;
00689 default:
00690 Tcl_AppendResult(interp, "ERROR: Unrecognized token type\n", (char *)NULL);
00691 wdb_free_tokens(&tok_hd.l);
00692 return TCL_ERROR;
00693 }
00694 }
00695 }
00696
00697 final_tree = wdb_eval_bool(&tok_hd.l);
00698
00699 if (dp == DIR_NULL) {
00700 int flags;
00701
00702 flags = DIR_COMB;
00703 BU_GETSTRUCT(comb, rt_comb_internal);
00704 comb->magic = RT_COMB_MAGIC;
00705 comb->tree = final_tree;
00706 bu_vls_init(&comb->shader);
00707 bu_vls_init(&comb->material);
00708 comb->region_id = -1;
00709 if (region_flag == (-1))
00710 comb->region_flag = 0;
00711 else
00712 comb->region_flag = region_flag;
00713
00714 if (comb->region_flag) {
00715 struct bu_vls tmp_vls;
00716
00717 comb->region_flag = 1;
00718 comb->region_id = wdbp->wdb_item_default++;;
00719 comb->aircode = wdbp->wdb_air_default;
00720 comb->los = wdbp->wdb_los_default;
00721 comb->GIFTmater = wdbp->wdb_mat_default;
00722 bu_vls_init(&tmp_vls);
00723 bu_vls_printf(&tmp_vls,
00724 "Creating region id=%d, air=%d, los=%d, GIFTmaterial=%d\n",
00725 comb->region_id, comb->aircode, comb->los, comb->GIFTmater);
00726 Tcl_AppendResult(interp, bu_vls_addr(&tmp_vls), (char *)NULL);
00727 bu_vls_free(&tmp_vls);
00728
00729 flags |= DIR_REGION;
00730 }
00731
00732 RT_INIT_DB_INTERNAL(&intern);
00733 intern.idb_major_type = DB5_MAJORTYPE_BRLCAD;
00734 intern.idb_type = ID_COMBINATION;
00735 intern.idb_meth = &rt_functab[ID_COMBINATION];
00736 intern.idb_ptr = (genptr_t)comb;
00737
00738 if ((dp=db_diradd(wdbp->dbip, comb_name, -1L, 0, flags, (genptr_t)&intern.idb_type)) == DIR_NULL) {
00739 Tcl_AppendResult(interp, "Failed to add ", comb_name,
00740 " to directory, aborting\n" , (char *)NULL);
00741 return TCL_ERROR;
00742 }
00743
00744 if (rt_db_put_internal(dp, wdbp->dbip, &intern, &rt_uniresource) < 0) {
00745 Tcl_AppendResult(interp, "Failed to write ", dp->d_namep, (char *)NULL );
00746 return TCL_ERROR;
00747 }
00748 } else {
00749 db_delete(wdbp->dbip, dp);
00750
00751 dp->d_len = 0;
00752 dp->d_un.file_offset = -1;
00753 db_free_tree(comb->tree, &rt_uniresource);
00754 comb->tree = final_tree;
00755
00756 if (rt_db_put_internal(dp, wdbp->dbip, &intern, &rt_uniresource) < 0) {
00757 Tcl_AppendResult(interp, "Failed to write ", dp->d_namep, (char *)NULL );
00758 return TCL_ERROR;
00759 }
00760 }
00761
00762 return TCL_OK;
00763 }
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773 int
00774 wdb_comb_std_tcl(ClientData clientData,
00775 Tcl_Interp *interp,
00776 int argc,
00777 char **argv)
00778 {
00779 struct rt_wdb *wdbp = (struct rt_wdb *)clientData;
00780
00781 return wdb_comb_std_cmd(wdbp, interp, argc-1, argv+1);
00782 }
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793