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
00044
00045
00046
00047
00048
00049
00050
00051 #ifndef lint
00052 static const char RCSid[] = "@(#)$Header: /cvsroot/brlcad/brlcad/src/librt/db5_comb.c,v 14.11 2006/09/16 02:04:24 lbutler Exp $ (ARL)";
00053 #endif
00054
00055 #include "common.h"
00056
00057 #include <stdlib.h>
00058 #include <stdio.h>
00059 #ifdef HAVE_STRING_H
00060 # include <string.h>
00061 #else
00062 # include <strings.h>
00063 #endif
00064
00065 #include "machine.h"
00066 #include "bu.h"
00067 #include "vmath.h"
00068 #include "bn.h"
00069 #include "db5.h"
00070 #include "raytrace.h"
00071
00072 #include "./debug.h"
00073
00074
00075 struct db_tree_counter_state {
00076 long magic;
00077 long n_mat;
00078 long n_leaf;
00079 long n_oper;
00080 long leafbytes;
00081 int non_union_seen;
00082 };
00083 #define DB_TREE_COUNTER_STATE_MAGIC 0x64546373
00084 #define DB_CK_TREE_COUNTER_STATE(_p) BU_CKMAG(_p, DB_TREE_COUNTER_STATE_MAGIC, "db_tree_counter_state");
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101 long
00102 db_tree_counter( const union tree *tp, struct db_tree_counter_state *tcsp )
00103 {
00104 long ldepth, rdepth;
00105
00106 RT_CK_TREE(tp);
00107 DB_CK_TREE_COUNTER_STATE(tcsp);
00108
00109 switch( tp->tr_op ) {
00110 case OP_DB_LEAF:
00111 tcsp->n_leaf++;
00112 if( tp->tr_l.tl_mat && !bn_mat_is_identity(tp->tr_l.tl_mat) ) tcsp->n_mat++;
00113
00114 tcsp->leafbytes += strlen(tp->tr_l.tl_name) + 1 + 8;
00115 return 1;
00116
00117 case OP_NOT:
00118
00119 tcsp->n_oper++;
00120 tcsp->non_union_seen = 1;
00121 return 1 + db_tree_counter( tp->tr_b.tb_left, tcsp );
00122
00123 case OP_UNION:
00124
00125 tcsp->n_oper++;
00126 ldepth = db_tree_counter( tp->tr_b.tb_left, tcsp );
00127 rdepth = db_tree_counter( tp->tr_b.tb_right, tcsp );
00128 if( ldepth > rdepth ) return ldepth;
00129 return rdepth;
00130
00131 case OP_INTERSECT:
00132 case OP_SUBTRACT:
00133 case OP_XOR:
00134
00135 tcsp->n_oper++;
00136 tcsp->non_union_seen = 1;
00137 ldepth = db_tree_counter( tp->tr_b.tb_left, tcsp );
00138 rdepth = db_tree_counter( tp->tr_b.tb_right, tcsp );
00139 if( ldepth > rdepth ) return ldepth;
00140 return rdepth;
00141
00142 default:
00143 bu_log("db_tree_counter: bad op %d\n", tp->tr_op);
00144 bu_bomb("db_tree_counter\n");
00145
00146 }
00147
00148 return 0;
00149 }
00150
00151 #define DB5COMB_TOKEN_LEAF 1
00152 #define DB5COMB_TOKEN_UNION 2
00153 #define DB5COMB_TOKEN_INTERSECT 3
00154 #define DB5COMB_TOKEN_SUBTRACT 4
00155 #define DB5COMB_TOKEN_XOR 5
00156 #define DB5COMB_TOKEN_NOT 6
00157
00158 struct rt_comb_v5_serialize_state {
00159 long magic;
00160 long mat_num;
00161 long nmat;
00162 unsigned char *matp;
00163 unsigned char *leafp;
00164 unsigned char *exprp;
00165 int wid;
00166 };
00167 #define RT_COMB_V5_SERIALIZE_STATE_MAGIC 0x43357373
00168 #define RT_CK_COMB_V5_SERIALIZE_STATE(_p) BU_CKMAG(_p, RT_COMB_V5_SERIALIZE_STATE_MAGIC, "rt_comb_v5_serialize_state")
00169
00170
00171
00172
00173
00174
00175
00176 void
00177 rt_comb_v5_serialize(
00178 const union tree *tp,
00179 struct rt_comb_v5_serialize_state *ssp)
00180 {
00181 int n;
00182 int mi;
00183
00184 RT_CK_TREE(tp);
00185 RT_CK_COMB_V5_SERIALIZE_STATE(ssp);
00186
00187 switch( tp->tr_op ) {
00188 case OP_DB_LEAF:
00189
00190
00191
00192
00193
00194 n = strlen(tp->tr_l.tl_name) + 1;
00195 bcopy( tp->tr_l.tl_name, ssp->leafp, n );
00196 ssp->leafp += n;
00197
00198 if( tp->tr_l.tl_mat && !bn_mat_is_identity(tp->tr_l.tl_mat) )
00199 mi = ssp->mat_num++;
00200 else
00201 mi = -1;
00202 BU_ASSERT_LONG( mi, <, ssp->nmat );
00203 ssp->leafp = db5_encode_length( ssp->leafp, mi, ssp->wid );
00204
00205
00206 if( mi > -1 ) {
00207 htond( ssp->matp,
00208 (const unsigned char *)tp->tr_l.tl_mat,
00209 ELEMENTS_PER_MAT );
00210 ssp->matp += ELEMENTS_PER_MAT * SIZEOF_NETWORK_DOUBLE;
00211 }
00212
00213
00214 if( ssp->exprp )
00215 *ssp->exprp++ = DB5COMB_TOKEN_LEAF;
00216 return;
00217
00218 case OP_NOT:
00219
00220 rt_comb_v5_serialize( tp->tr_b.tb_left, ssp );
00221 if( ssp->exprp )
00222 *ssp->exprp++ = DB5COMB_TOKEN_NOT;
00223 return;
00224
00225 case OP_UNION:
00226
00227 rt_comb_v5_serialize( tp->tr_b.tb_left, ssp );
00228 rt_comb_v5_serialize( tp->tr_b.tb_right, ssp );
00229 if( ssp->exprp )
00230 *ssp->exprp++ = DB5COMB_TOKEN_UNION;
00231 return;
00232 case OP_INTERSECT:
00233
00234 rt_comb_v5_serialize( tp->tr_b.tb_left, ssp );
00235 rt_comb_v5_serialize( tp->tr_b.tb_right, ssp );
00236 if( ssp->exprp )
00237 *ssp->exprp++ = DB5COMB_TOKEN_INTERSECT;
00238 return;
00239 case OP_SUBTRACT:
00240
00241 rt_comb_v5_serialize( tp->tr_b.tb_left, ssp );
00242 rt_comb_v5_serialize( tp->tr_b.tb_right, ssp );
00243 if( ssp->exprp )
00244 *ssp->exprp++ = DB5COMB_TOKEN_SUBTRACT;
00245 return;
00246 case OP_XOR:
00247
00248 rt_comb_v5_serialize( tp->tr_b.tb_left, ssp );
00249 rt_comb_v5_serialize( tp->tr_b.tb_right, ssp );
00250 if( ssp->exprp )
00251 *ssp->exprp++ = DB5COMB_TOKEN_XOR;
00252 return;
00253
00254 default:
00255 bu_log("rt_comb_v5_serialize: bad op %d\n", tp->tr_op);
00256 bu_bomb("rt_comb_v5_serialize\n");
00257 }
00258 }
00259
00260
00261
00262
00263 int
00264 rt_comb_export5(
00265 struct bu_external *ep,
00266 const struct rt_db_internal *ip,
00267 double local2mm,
00268 const struct db_i *dbip,
00269 struct resource *resp)
00270 {
00271 struct rt_comb_internal *comb;
00272 struct db_tree_counter_state tcs;
00273 struct rt_comb_v5_serialize_state ss;
00274 long max_stack_depth;
00275 long need;
00276 int rpn_len = 0;
00277 int wid;
00278 unsigned char *cp;
00279 unsigned char *leafp_end;
00280 struct bu_attribute_value_set *avsp;
00281 struct bu_vls value;
00282
00283 RT_CK_DB_INTERNAL( ip );
00284 RT_CK_RESOURCE(resp);
00285
00286 if( ip->idb_type != ID_COMBINATION ) bu_bomb("rt_comb_export5() type not ID_COMBINATION");
00287 comb = (struct rt_comb_internal *)ip->idb_ptr;
00288 RT_CK_COMB(comb);
00289
00290
00291
00292
00293 bzero( (char *)&tcs, sizeof(tcs) );
00294 tcs.magic = DB_TREE_COUNTER_STATE_MAGIC;
00295 if( comb->tree )
00296 max_stack_depth = db_tree_counter( comb->tree, &tcs );
00297 else
00298 max_stack_depth = 0;
00299
00300 if( tcs.non_union_seen ) {
00301
00302 rpn_len = tcs.n_leaf + tcs.n_oper;
00303 } else {
00304 rpn_len = 0;
00305 }
00306
00307 wid = db5_select_length_encoding(
00308 tcs.n_mat | tcs.n_leaf | tcs.leafbytes |
00309 rpn_len | max_stack_depth );
00310
00311
00312
00313
00314 tcs.leafbytes -= tcs.n_leaf * (8 - db5_enc_len[wid]);
00315
00316
00317 need = 1 +
00318 db5_enc_len[wid] +
00319 db5_enc_len[wid] +
00320 db5_enc_len[wid] +
00321 db5_enc_len[wid] +
00322 db5_enc_len[wid] +
00323 tcs.n_mat * (ELEMENTS_PER_MAT * SIZEOF_NETWORK_DOUBLE) +
00324 tcs.leafbytes +
00325 rpn_len;
00326
00327 BU_INIT_EXTERNAL(ep);
00328 ep->ext_nbytes = need;
00329 #if 0
00330 ep->ext_buf = bu_malloc( need, "rt_comb_export5 ext_buf" );
00331 #else
00332 ep->ext_buf = bu_calloc( 1, need, "rt_comb_export5 ext_buf" );
00333 #endif
00334
00335
00336 cp = (unsigned char *)ep->ext_buf;
00337 *cp++ = wid;
00338 cp = db5_encode_length( cp, tcs.n_mat, wid );
00339 cp = db5_encode_length( cp, tcs.n_leaf, wid );
00340 cp = db5_encode_length( cp, tcs.leafbytes, wid );
00341 cp = db5_encode_length( cp, rpn_len, wid );
00342 cp = db5_encode_length( cp, max_stack_depth, wid );
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354 ss.magic = RT_COMB_V5_SERIALIZE_STATE_MAGIC;
00355 ss.wid = wid;
00356 ss.mat_num = 0;
00357 ss.nmat = tcs.n_mat;
00358 ss.matp = cp;
00359 ss.leafp = cp + tcs.n_mat * (ELEMENTS_PER_MAT * SIZEOF_NETWORK_DOUBLE);
00360 leafp_end = ss.leafp + tcs.leafbytes;
00361 if( rpn_len )
00362 ss.exprp = leafp_end;
00363 else
00364 ss.exprp = NULL;
00365
00366 if( comb->tree )
00367 rt_comb_v5_serialize( comb->tree, &ss );
00368
00369 BU_ASSERT_LONG( ss.mat_num, ==, tcs.n_mat );
00370 BU_ASSERT_PTR( ss.matp, ==, cp + tcs.n_mat * (ELEMENTS_PER_MAT * SIZEOF_NETWORK_DOUBLE) );
00371 BU_ASSERT_PTR( ss.leafp, ==, leafp_end );
00372 if( rpn_len )
00373 BU_ASSERT_PTR( ss.exprp, <=, ((unsigned char *)ep->ext_buf) + ep->ext_nbytes );
00374
00375
00376 bu_vls_init( &value );
00377
00378 avsp = (struct bu_attribute_value_set *)&ip->idb_avs;
00379 if( avsp->magic != BU_AVS_MAGIC )
00380 bu_avs_init( avsp, 32, "rt_comb v5 attributes" );
00381 if( comb->region_flag ) {
00382
00383
00384
00385
00386 bu_vls_trunc( &value, 0 );
00387 switch (comb->is_fastgen) {
00388 case REGION_FASTGEN_PLATE:
00389 bu_vls_printf(&value, "P");
00390 break;
00391 case REGION_FASTGEN_VOLUME:
00392 bu_vls_printf(&value, "V");
00393 break;
00394 case REGION_NON_FASTGEN:
00395 default:
00396 bu_vls_printf(&value, "R");
00397 break;
00398 }
00399 bu_avs_add_vls( avsp, "region", &value );
00400 } else
00401 bu_avs_remove( avsp, "region" );
00402
00403 if( comb->inherit )
00404 bu_avs_add( avsp, "inherit", "1" );
00405 else
00406 bu_avs_remove( avsp, "inherit" );
00407
00408 if( comb->rgb_valid ) {
00409 bu_vls_trunc( &value, 0 );
00410 bu_vls_printf( &value, "%d/%d/%d", V3ARGS(comb->rgb) );
00411 bu_avs_add_vls( avsp, "rgb", &value );
00412 } else
00413 bu_avs_remove( avsp, "rgb" );
00414
00415
00416 if( bu_vls_strlen( &comb->shader ) > 0 )
00417 bu_avs_add_vls( avsp, "oshader", &comb->shader );
00418 else
00419 bu_avs_remove( avsp, "oshader" );
00420
00421 #if 0
00422 if( bu_vls_strlen( &comb->material ) > 0 )
00423 bu_avs_add_vls( avsp, "material", &comb->material );
00424 else
00425 bu_avs_remove( avsp, "material" );
00426 #endif
00427 #if 0
00428 if( comb->temperature > 0 ) {
00429 bu_vls_trunc( &value, 0 );
00430 bu_vls_printf( &value, "%f", comb->temperature );
00431 bu_avs_add_vls( avsp, "temp", &value );
00432 } else
00433 bu_avs_remove( avsp, "temp" );
00434 #endif
00435
00436 if( comb->region_id != 0 ) {
00437 bu_vls_trunc( &value, 0 );
00438 bu_vls_printf( &value, "%d", comb->region_id );
00439 bu_avs_add_vls( avsp, "region_id", &value );
00440 } else
00441 bu_avs_remove( avsp, "region_id" );
00442
00443 if( comb->aircode != 0 ) {
00444 bu_vls_trunc( &value, 0 );
00445 bu_vls_printf( &value, "%d", comb->aircode );
00446 bu_avs_add_vls( avsp, "aircode", &value );
00447 } else
00448 bu_avs_remove( avsp, "aircode" );
00449
00450 if( comb->GIFTmater != 0 ) {
00451 bu_vls_trunc( &value, 0 );
00452 bu_vls_printf( &value, "%d", comb->GIFTmater );
00453 bu_avs_add_vls( avsp, "material_id", &value );
00454 } else
00455 bu_avs_remove( avsp, "material_id" );
00456
00457 if( comb->los != 0 ) {
00458 bu_vls_trunc( &value, 0 );
00459 bu_vls_printf( &value, "%d", comb->los );
00460 bu_avs_add_vls( avsp, "los", &value );
00461 } else
00462 bu_avs_remove( avsp, "los" );
00463
00464 bu_vls_free( &value );
00465 return 0;
00466 }
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483 int
00484 rt_comb_import5(
00485 struct rt_db_internal *ip,
00486 const struct bu_external *ep,
00487 const mat_t mat,
00488 const struct db_i *dbip,
00489 struct resource *resp,
00490 const int minor_type)
00491 {
00492 struct rt_comb_internal *comb;
00493 unsigned char *cp;
00494 int wid;
00495 long nmat, nleaf, rpn_len, max_stack_depth;
00496 long leafbytes;
00497 unsigned char *matp;
00498 unsigned char *leafp;
00499 unsigned char *leafp_end;
00500 unsigned char *exprp;
00501 #define MAX_V5_STACK 8000
00502 union tree *stack[MAX_V5_STACK];
00503 union tree **sp;
00504 const char *ap;
00505 int i;
00506
00507 RT_CK_DB_INTERNAL( ip );
00508 BU_CK_EXTERNAL(ep);
00509 RT_CK_DBI(dbip);
00510 RT_CK_RESOURCE(resp);
00511
00512 ip->idb_major_type = DB5_MAJORTYPE_BRLCAD;
00513 ip->idb_type = ID_COMBINATION;
00514 ip->idb_meth = &rt_functab[ID_COMBINATION];
00515 BU_GETSTRUCT( comb, rt_comb_internal );
00516 ip->idb_ptr = (genptr_t)comb;
00517 comb->magic = RT_COMB_MAGIC;
00518 bu_vls_init( &comb->shader );
00519 bu_vls_init( &comb->material );
00520 comb->temperature = -1;
00521
00522 cp = ep->ext_buf;
00523 wid = *cp++;
00524 cp += db5_decode_length( &nmat, cp, wid );
00525 cp += db5_decode_length( &nleaf, cp, wid );
00526 cp += db5_decode_length( &leafbytes, cp, wid );
00527 cp += db5_decode_length( &rpn_len, cp, wid );
00528 cp += db5_decode_length( &max_stack_depth, cp, wid );
00529 matp = cp;
00530 leafp = cp + nmat * (ELEMENTS_PER_MAT * SIZEOF_NETWORK_DOUBLE);
00531 exprp = leafp + leafbytes;
00532 leafp_end = exprp;
00533
00534 if( rpn_len == 0 ) {
00535
00536
00537 int i;
00538 struct bu_ptbl *tbl1, *tbl2;
00539
00540 tbl1 = (struct bu_ptbl *)bu_malloc( sizeof( struct bu_ptbl ), "rt_comb_import5: tbl1" );
00541 tbl2 = (struct bu_ptbl *)bu_malloc( sizeof( struct bu_ptbl ), "rt_comb_import5: tbl2" );
00542
00543
00544 bu_ptbl_init( tbl1, nleaf, "rt_comb_import5: tbl" );
00545 for( i = nleaf-1; i >= 0; i-- ) {
00546 union tree *tp;
00547 long mi;
00548
00549 RT_GET_TREE( tp, resp );
00550 tp->tr_l.magic = RT_TREE_MAGIC;
00551 tp->tr_l.tl_op = OP_DB_LEAF;
00552 tp->tr_l.tl_name = bu_strdup( (const char *)leafp );
00553 leafp += strlen( (const char *)leafp) + 1;
00554
00555
00556 mi = 4095;
00557 leafp += db5_decode_signed( &mi, leafp, wid );
00558
00559 if( mi < 0 ) {
00560
00561 if( !mat || bn_mat_is_identity( mat ) ) {
00562 tp->tr_l.tl_mat = (matp_t)NULL;
00563 } else
00564 tp->tr_l.tl_mat = bn_mat_dup( mat );
00565 } else {
00566 mat_t diskmat;
00567
00568
00569 BU_ASSERT_LONG( mi, <, nmat );
00570 ntohd( (unsigned char *)diskmat,
00571 &matp[mi*ELEMENTS_PER_MAT*SIZEOF_NETWORK_DOUBLE],
00572 ELEMENTS_PER_MAT);
00573 if( !mat || bn_mat_is_identity( mat ) ) {
00574 tp->tr_l.tl_mat = bn_mat_dup( diskmat );
00575 } else {
00576 tp->tr_l.tl_mat = (matp_t)bu_malloc(
00577 sizeof(mat_t), "v5comb mat");
00578 bn_mat_mul( tp->tr_l.tl_mat, mat, diskmat );
00579 if( bn_mat_is_identity( tp->tr_l.tl_mat ) ) {
00580 bu_free( (char *)tp->tr_l.tl_mat,"tl_mat");
00581 tp->tr_l.tl_mat = (matp_t)NULL;
00582 }
00583 }
00584 }
00585 bu_ptbl_ins( tbl1, (long *)tp );
00586 }
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597 bu_ptbl_init( tbl2, (BU_PTBL_LEN( tbl1) + 1)/2, "rt_comb_import5: tbl1" );
00598 while( 1 ) {
00599 struct bu_ptbl *tmp;
00600
00601 for( i=0 ; i<BU_PTBL_LEN( tbl1 ) ; i += 2 ) {
00602 union tree *tp1, *tp2, *unionp;
00603 int j;
00604
00605 j = i + 1;
00606 tp1 = (union tree *)BU_PTBL_GET( tbl1, i );
00607 if( j < BU_PTBL_LEN( tbl1 ) ) {
00608 tp2 = (union tree *)BU_PTBL_GET( tbl1, j );
00609 } else {
00610 tp2 = (union tree *)NULL;
00611 }
00612
00613 if( tp2 ) {
00614 RT_GET_TREE( unionp, resp );
00615 unionp->tr_b.magic = RT_TREE_MAGIC;
00616 unionp->tr_b.tb_op = OP_UNION;
00617 unionp->tr_b.tb_left = tp1;
00618 unionp->tr_b.tb_right = tp2;
00619 bu_ptbl_ins( tbl2, (long *)unionp );
00620 } else {
00621 bu_ptbl_ins( tbl2, (long *)tp1 );
00622 }
00623
00624 }
00625
00626 if( BU_PTBL_LEN( tbl2 ) == 0 ) {
00627 comb->tree = (union tree *)NULL;
00628 bu_ptbl_free( tbl1 );
00629 bu_ptbl_free( tbl2 );
00630 bu_free( (char *)tbl1, "rt_comb_import5: tbl1" );
00631 bu_free( (char *)tbl2, "rt_comb_import5: tbl2" );
00632 break;
00633 } else if( BU_PTBL_LEN( tbl2 ) == 1 ) {
00634 comb->tree = (union tree *)BU_PTBL_GET( tbl2, 0 );
00635 bu_ptbl_free( tbl1 );
00636 bu_ptbl_free( tbl2 );
00637 bu_free( (char *)tbl1, "rt_comb_import5: tbl1" );
00638 bu_free( (char *)tbl2, "rt_comb_import5: tbl2" );
00639 break;
00640 }
00641
00642 tmp = tbl2;
00643 tbl2 = tbl1;
00644 tbl1 = tmp;
00645 bu_ptbl_trunc( tbl2, 0 );
00646 }
00647 BU_ASSERT_PTR( leafp, ==, leafp_end );
00648 goto finish;
00649 }
00650
00651
00652
00653
00654
00655 if( max_stack_depth > MAX_V5_STACK ) {
00656 bu_log("Combination needs stack depth %d, only have %d, aborted\n",
00657 max_stack_depth, MAX_V5_STACK);
00658 return -1;
00659 }
00660 sp = &stack[0];
00661
00662 for( i=0; i < rpn_len; i++,exprp++ ) {
00663 union tree *tp;
00664 long mi;
00665
00666 RT_GET_TREE( tp, resp );
00667 tp->tr_b.magic = RT_TREE_MAGIC;
00668
00669 switch( *exprp ) {
00670 case DB5COMB_TOKEN_LEAF:
00671 tp->tr_l.tl_op = OP_DB_LEAF;
00672 tp->tr_l.tl_name = bu_strdup( (const char *)leafp );
00673 leafp += strlen( (const char *)leafp) + 1;
00674
00675
00676 mi = 4095;
00677 leafp += db5_decode_signed( &mi, leafp, wid );
00678
00679 if( mi < 0 ) {
00680
00681 if( !mat || bn_mat_is_identity( mat ) ) {
00682 tp->tr_l.tl_mat = (matp_t)NULL;
00683 } else
00684 tp->tr_l.tl_mat = bn_mat_dup( mat );
00685 } else {
00686 mat_t diskmat;
00687
00688
00689 BU_ASSERT_LONG( mi, <, nmat );
00690 ntohd( (unsigned char *)diskmat,
00691 &matp[mi*ELEMENTS_PER_MAT*SIZEOF_NETWORK_DOUBLE],
00692 ELEMENTS_PER_MAT);
00693 if( !mat || bn_mat_is_identity( mat ) ) {
00694 tp->tr_l.tl_mat = bn_mat_dup( diskmat );
00695 } else {
00696 tp->tr_l.tl_mat = (matp_t)bu_malloc(
00697 sizeof(mat_t), "v5comb mat");
00698 bn_mat_mul( tp->tr_l.tl_mat, mat, diskmat );
00699 if( bn_mat_is_identity( tp->tr_l.tl_mat ) ) {
00700 bu_free( (char *)tp->tr_l.tl_mat,"tl_mat");
00701 tp->tr_l.tl_mat = (matp_t)NULL;
00702 }
00703 }
00704 }
00705 break;
00706
00707 case DB5COMB_TOKEN_UNION:
00708 case DB5COMB_TOKEN_INTERSECT:
00709 case DB5COMB_TOKEN_SUBTRACT:
00710 case DB5COMB_TOKEN_XOR:
00711
00712 tp->tr_b.tb_regionp = REGION_NULL;
00713 tp->tr_b.tb_right = *--sp;
00714 RT_CK_TREE(tp->tr_b.tb_right);
00715 tp->tr_b.tb_left = *--sp;
00716 RT_CK_TREE(tp->tr_b.tb_left);
00717 switch( *exprp ) {
00718 case DB5COMB_TOKEN_UNION:
00719 tp->tr_b.tb_op = OP_UNION;
00720 break;
00721 case DB5COMB_TOKEN_INTERSECT:
00722 tp->tr_b.tb_op = OP_INTERSECT;
00723 break;
00724 case DB5COMB_TOKEN_SUBTRACT:
00725 tp->tr_b.tb_op = OP_SUBTRACT;
00726 break;
00727 case DB5COMB_TOKEN_XOR:
00728 tp->tr_b.tb_op = OP_XOR;
00729 break;
00730 }
00731 break;
00732
00733 case DB5COMB_TOKEN_NOT:
00734
00735 tp->tr_b.tb_regionp = REGION_NULL;
00736 tp->tr_b.tb_left = *--sp;
00737 RT_CK_TREE(tp->tr_b.tb_left);
00738 tp->tr_b.tb_right = TREE_NULL;
00739 tp->tr_b.tb_op = OP_NOT;
00740 break;
00741 default:
00742 bu_log("rt_comb_import5() unknown RPN expression token=%d, import aborted\n", *exprp);
00743 return -1;
00744 }
00745
00746
00747 *sp++ = tp;
00748 }
00749 BU_ASSERT_PTR( leafp, ==, leafp_end );
00750
00751
00752 BU_ASSERT_PTR( sp, ==, &stack[1] );
00753
00754 comb->tree = stack[0];
00755 RT_CK_TREE(comb->tree);
00756
00757 finish:
00758 if( ip->idb_avs.magic != BU_AVS_MAGIC ) return 0;
00759
00760
00761 comb->rgb_valid = 0;
00762 if( (ap = bu_avs_get( &ip->idb_avs, "rgb" )) != NULL ) {
00763 int ibuf[3];
00764 if( sscanf( ap, "%d/%d/%d", ibuf, ibuf+1, ibuf+2 ) == 3 ) {
00765 VMOVE( comb->rgb, ibuf );
00766 comb->rgb_valid = 1;
00767 } else {
00768 bu_log("unable to parse 'rgb' attribute '%s'\n", ap);
00769 }
00770 }
00771 if( (ap = bu_avs_get( &ip->idb_avs, "inherit" )) != NULL ) {
00772 comb->inherit = atoi( ap );
00773 }
00774 if( (ap = bu_avs_get( &ip->idb_avs, "region" )) != NULL ) {
00775
00776 comb->region_flag = 1;
00777
00778
00779 switch (*ap) {
00780 case 'V' :
00781 case '2' :
00782 comb->is_fastgen = REGION_FASTGEN_VOLUME;
00783 break;
00784 case 'P' :
00785 case '1' :
00786 comb->is_fastgen = REGION_FASTGEN_PLATE;
00787 break;
00788 case 'R' :
00789 case '0' :
00790 comb->is_fastgen = REGION_NON_FASTGEN;
00791 break;
00792 default:
00793 bu_log("unable to parse 'region' attribute '%s'\n", ap);
00794 break;
00795 }
00796
00797
00798 if( (ap = bu_avs_get( &ip->idb_avs, "region_id" )) != NULL ) {
00799 comb->region_id = atoi( ap );
00800 }
00801 if( (ap = bu_avs_get( &ip->idb_avs, "aircode" )) != NULL ) {
00802 comb->aircode = atoi( ap );
00803 }
00804 if( (ap = bu_avs_get( &ip->idb_avs, "material_id" )) != NULL ) {
00805 comb->GIFTmater = atoi( ap );
00806 #if 0
00807 bu_vls_printf( &comb->material, "gift%d", comb->GIFTmater );
00808 #endif
00809 }
00810 if( (ap = bu_avs_get( &ip->idb_avs, "los" )) != NULL ) {
00811 comb->los = atoi( ap );
00812 }
00813 }
00814 if( (ap = bu_avs_get( &ip->idb_avs, "oshader" )) != NULL ) {
00815 bu_vls_strcat( &comb->shader, ap );
00816 }
00817
00818 return 0;
00819 }
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829