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 #ifndef lint
00040 static const char RCSprep[] = "@(#)$Header: /cvsroot/brlcad/brlcad/src/librt/prep.c,v 14.16 2006/09/16 02:04:25 lbutler Exp $ (BRL)";
00041 #endif
00042
00043 #include "common.h"
00044
00045 #include <stddef.h>
00046 #include <stdio.h>
00047 #include <math.h>
00048 #ifdef HAVE_STRING_H
00049 # include <string.h>
00050 #else
00051 # include <strings.h>
00052 #endif
00053 #ifdef HAVE_UNISTD_H
00054 # include <unistd.h>
00055 #endif
00056
00057 #include "machine.h"
00058 #include "bu.h"
00059 #include "vmath.h"
00060 #include "bn.h"
00061 #include "raytrace.h"
00062 #include "plot3.h"
00063
00064 #include "./debug.h"
00065
00066
00067 BU_EXTERN(void rt_ck, (struct rt_i *rtip));
00068
00069 HIDDEN void rt_solid_bitfinder(register union tree *treep, struct region *regp, struct resource *resp);
00070
00071 extern struct resource rt_uniresource;
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082 struct rt_i *
00083 rt_new_rti(struct db_i *dbip)
00084 {
00085 register struct rt_i *rtip;
00086 register int i;
00087
00088 RT_CK_DBI( dbip );
00089
00090
00091 if( BU_LIST_FIRST( bu_list, &rt_g.rtg_vlfree ) == 0 ) {
00092 BU_LIST_INIT( &rt_g.rtg_vlfree );
00093 }
00094
00095 BU_GETSTRUCT( rtip, rt_i );
00096 rtip->rti_magic = RTI_MAGIC;
00097 for( i=0; i < RT_DBNHASH; i++ ) {
00098 BU_LIST_INIT( &(rtip->rti_solidheads[i]) );
00099 }
00100 rtip->rti_dbip = db_clone_dbi( dbip, (long *)rtip );
00101 rtip->needprep = 1;
00102
00103 BU_LIST_INIT( &rtip->HeadRegion );
00104
00105
00106 bu_ptbl_init( &rtip->rti_resources, MAX_PSW+1, "rti_resources ptbl" );
00107 BU_PTBL_END(&rtip->rti_resources) = MAX_PSW+1;
00108
00109 rt_uniresource.re_magic = RESOURCE_MAGIC;
00110
00111
00112 bu_ptbl_init( &rtip->delete_regs, 8, "rt_i delete regions list" );
00113
00114 VSETALL( rtip->mdl_min, INFINITY );
00115 VSETALL( rtip->mdl_max, -INFINITY );
00116 VSETALL( rtip->rti_inf_box.bn.bn_min, -0.1 );
00117 VSETALL( rtip->rti_inf_box.bn.bn_max, 0.1 );
00118 rtip->rti_inf_box.bn.bn_type = CUT_BOXNODE;
00119
00120
00121 rtip->rti_tol.magic = BN_TOL_MAGIC;
00122 rtip->rti_tol.dist = 0.0005;
00123 rtip->rti_tol.dist_sq = rtip->rti_tol.dist * rtip->rti_tol.dist;
00124 rtip->rti_tol.perp = 1e-6;
00125 rtip->rti_tol.para = 1 - rtip->rti_tol.perp;
00126
00127 rtip->rti_ttol.magic = RT_TESS_TOL_MAGIC;
00128 rtip->rti_ttol.abs = 0.0;
00129 rtip->rti_ttol.rel = 0.01;
00130 rtip->rti_ttol.norm = 0;
00131
00132 rtip->rti_max_beam_radius = 175.0/2;
00133
00134
00135
00136
00137
00138
00139
00140 rtip->rti_space_partition = RT_PART_NUBSPT;
00141
00142 rtip->rti_nugrid_dimlimit = 0;
00143 rtip->rti_nu_gfactor = RT_NU_GFACTOR_DEFAULT;
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155 for( i=0; i < RT_DBNHASH; i++ ) {
00156 register struct directory *dp;
00157
00158 dp = rtip->rti_dbip->dbi_Head[i];
00159 for( ; dp != DIR_NULL; dp = dp->d_forw )
00160 dp->d_uses = 0;
00161 }
00162
00163 return rtip;
00164 }
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175 void
00176 rt_free_rti(struct rt_i *rtip)
00177 {
00178 RT_CK_RTI(rtip);
00179
00180 rt_clean( rtip );
00181
00182 #if 0
00183
00184
00185
00186
00187
00188
00189 resp->re_directory_hd = NULL;
00190 if( BU_LIST_IS_INITIALIZED( &resp->re_directory_blocks.l ) ) {
00191 struct directory **dpp;
00192 BU_CK_PTBL( &resp->re_directory_blocks );
00193 for( BU_PTBL_FOR( dpp, (struct directory **), &resp->re_directory_blocks ) ) {
00194 RT_CK_DIR(*dpp);
00195 bu_free( (genptr_t)(*dpp), "struct directory block" );
00196 }
00197 bu_ptbl_free( &resp->re_directory_blocks );
00198 }
00199 #endif
00200
00201 db_close_client( rtip->rti_dbip, (long *)rtip );
00202 rtip->rti_dbip = (struct db_i *)NULL;
00203
00204
00205 bu_ptbl_free( &rtip->rti_resources );
00206
00207 bu_free( (char *)rtip, "struct rt_i" );
00208 }
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220 void
00221 rt_prep_parallel(register struct rt_i *rtip, int ncpu)
00222 {
00223 register struct region *regp;
00224 register struct soltab *stp;
00225 register int i;
00226 struct resource *resp;
00227 vect_t diag;
00228
00229 RT_CK_RTI(rtip);
00230
00231 if(RT_G_DEBUG&DEBUG_REGIONS) bu_log("rt_prep_parallel(%s,%d,ncpu=%d) START\n",
00232 rtip->rti_dbip->dbi_filename,
00233 rtip->rti_dbip->dbi_uses, ncpu);
00234
00235 bu_semaphore_acquire(RT_SEM_RESULTS);
00236 if(!rtip->needprep) {
00237 bu_log("WARNING: rt_prep_parallel(%s,%d) invoked a second time, ignored",
00238 rtip->rti_dbip->dbi_filename,
00239 rtip->rti_dbip->dbi_uses);
00240 bu_semaphore_release(RT_SEM_RESULTS);
00241 return;
00242 }
00243
00244 if( rtip->nsolids <= 0 ) {
00245 if( rtip->rti_air_discards > 0 )
00246 bu_log("rt_prep_parallel(%s,%d): %d primitives discarded due to air regions\n",
00247 rtip->rti_dbip->dbi_filename,
00248 rtip->rti_dbip->dbi_uses,
00249 rtip->rti_air_discards );
00250 rt_bomb("rt_prep_parallel: no primitives left to prep\n");
00251 }
00252
00253 if ( rtip->nregions <= 0 ) {
00254 rt_bomb("rt_prep_parallel: no regions left to prep\n");
00255 }
00256
00257
00258 if( rtip->mdl_min[X] >= INFINITY ) {
00259 bu_log("All primitives are halfspaces, setting minimum\n");
00260 VSETALL( rtip->mdl_min, -1 );
00261 }
00262 if( rtip->mdl_max[X] <= -INFINITY ) {
00263 bu_log("All primitives are halfspaces, setting maximum\n");
00264 VSETALL( rtip->mdl_max, 1 );
00265 }
00266
00267
00268
00269
00270
00271 rtip->mdl_min[X] = floor( rtip->mdl_min[X] );
00272 rtip->mdl_min[Y] = floor( rtip->mdl_min[Y] );
00273 rtip->mdl_min[Z] = floor( rtip->mdl_min[Z] );
00274 rtip->mdl_max[X] = ceil( rtip->mdl_max[X] );
00275 rtip->mdl_max[Y] = ceil( rtip->mdl_max[Y] );
00276 rtip->mdl_max[Z] = ceil( rtip->mdl_max[Z] );
00277
00278
00279 VSUB2( diag, rtip->mdl_max, rtip->mdl_min );
00280 rtip->rti_radius = 0.5 * MAGNITUDE(diag);
00281
00282
00283 resp = (struct resource *)BU_PTBL_GET(&rtip->rti_resources, 0);
00284 if( !resp ) resp = &rt_uniresource;
00285 RT_CK_RESOURCE(resp);
00286
00287
00288
00289
00290
00291
00292 rtip->Regions = (struct region **)bu_calloc(rtip->nregions, sizeof(struct region *), "rtip->Regions[]" );
00293 if(RT_G_DEBUG&DEBUG_REGIONS) bu_log("rt_prep_parallel(%s,%d) about to optimize regions\n",
00294 rtip->rti_dbip->dbi_filename,
00295 rtip->rti_dbip->dbi_uses);
00296 for( BU_LIST_FOR( regp, region, &(rtip->HeadRegion) ) ) {
00297
00298 BU_ASSERT_PTR(rtip->Regions[regp->reg_bit], ==, REGION_NULL);
00299 rtip->Regions[regp->reg_bit] = regp;
00300 rt_optim_tree( regp->reg_treetop, resp );
00301 rt_solid_bitfinder( regp->reg_treetop, regp, resp );
00302 if(RT_G_DEBUG&DEBUG_REGIONS) {
00303 db_ck_tree( regp->reg_treetop);
00304 rt_pr_region( regp );
00305 }
00306 }
00307 if(RT_G_DEBUG&DEBUG_REGIONS) {
00308 bu_log("rt_prep_parallel() printing primitives' region pointers\n");
00309 RT_VISIT_ALL_SOLTABS_START( stp, rtip ) {
00310 bu_log("solid %s ", stp->st_name);
00311 bu_pr_ptbl( "st_regions", &stp->st_regions, 1 );
00312 } RT_VISIT_ALL_SOLTABS_END
00313 }
00314
00315
00316
00317
00318
00319 rtip->rti_Solids = (struct soltab **)bu_calloc(
00320 rtip->nsolids + (1<<BITV_SHIFT), sizeof(struct soltab *),
00321 "rtip->rti_Solids[]" );
00322
00323
00324
00325
00326
00327 RT_VISIT_ALL_SOLTABS_START( stp, rtip ) {
00328
00329 register struct soltab **ssp = &rtip->rti_Solids[stp->st_bit];
00330 if( *ssp != SOLTAB_NULL ) {
00331 bu_log("rti_Solids[%d] is non-empty! rtip=x%x\n", stp->st_bit, rtip);
00332 bu_log("Existing entry is (st_rtip=x%x):\n", (*ssp)->st_rtip);
00333 rt_pr_soltab(*ssp);
00334 bu_log("2nd soltab also claiming that bit is (st_rtip=x%x):\n", stp->st_rtip);
00335 rt_pr_soltab(stp);
00336 }
00337 BU_ASSERT_PTR(*ssp, ==, SOLTAB_NULL);
00338 *ssp = stp;
00339 rtip->rti_nsol_by_type[stp->st_id]++;
00340 } RT_VISIT_ALL_SOLTABS_END
00341
00342
00343 rtip->rti_maxsol_by_type = 0;
00344 for( i=0; i <= ID_MAX_SOLID; i++ ) {
00345 if( rtip->rti_nsol_by_type[i] > rtip->rti_maxsol_by_type )
00346 rtip->rti_maxsol_by_type = rtip->rti_nsol_by_type[i];
00347 }
00348
00349 for( i=0; i <= ID_MAX_SOLID; i++ ) {
00350 if( rtip->rti_nsol_by_type[i] <= 0 ) continue;
00351 rtip->rti_sol_by_type[i] = (struct soltab **)bu_calloc(
00352 rtip->rti_nsol_by_type[i],
00353 sizeof(struct soltab *),
00354 "rti_sol_by_type[]" );
00355 rtip->rti_nsol_by_type[i] = 0;
00356 }
00357
00358 RT_VISIT_ALL_SOLTABS_START( stp, rtip ) {
00359 register int id;
00360 id = stp->st_id;
00361 rtip->rti_sol_by_type[id][rtip->rti_nsol_by_type[id]++] = stp;
00362 } RT_VISIT_ALL_SOLTABS_END
00363 if( RT_G_DEBUG & (DEBUG_DB|DEBUG_SOLIDS) ) {
00364 bu_log("rt_prep_parallel(%s,%d) printing number of prims by type\n",
00365 rtip->rti_dbip->dbi_filename,
00366 rtip->rti_dbip->dbi_uses);
00367 for( i=1; i <= ID_MAX_SOLID; i++ ) {
00368 bu_log("%5d %s (%d)\n",
00369 rtip->rti_nsol_by_type[i],
00370 rt_functab[i].ft_name,
00371 i );
00372 }
00373 }
00374
00375
00376 rt_regionfix(rtip);
00377
00378
00379
00380
00381
00382 {
00383 register fastf_t f, diff;
00384
00385 diff = (rtip->mdl_max[X] - rtip->mdl_min[X]);
00386 f = (rtip->mdl_max[Y] - rtip->mdl_min[Y]);
00387 if( f > diff ) diff = f;
00388 f = (rtip->mdl_max[Z] - rtip->mdl_min[Z]);
00389 if( f > diff ) diff = f;
00390 diff *= 0.1;
00391 rtip->rti_pmin[0] = rtip->mdl_min[0] - diff;
00392 rtip->rti_pmin[1] = rtip->mdl_min[1] - diff;
00393 rtip->rti_pmin[2] = rtip->mdl_min[2] - diff;
00394 rtip->rti_pmax[0] = rtip->mdl_max[0] + diff;
00395 rtip->rti_pmax[1] = rtip->mdl_max[1] + diff;
00396 rtip->rti_pmax[2] = rtip->mdl_max[2] + diff;
00397 }
00398
00399
00400
00401
00402
00403
00404 for( i=1; i<=CUT_MAXIMUM; i++ ) rtip->rti_ncut_by_type[i] = 0;
00405 rt_cut_it(rtip, ncpu);
00406
00407
00408 RT_VISIT_ALL_SOLTABS_START( stp, rtip ) {
00409 if( stp->st_piece_rpps ) {
00410 bu_free( (char *)stp->st_piece_rpps, "st_piece_rpps[]" );
00411 stp->st_piece_rpps = NULL;
00412 }
00413 } RT_VISIT_ALL_SOLTABS_END
00414
00415
00416 if( (RT_G_DEBUG&DEBUG_PLOTBOX) ) {
00417 FILE *plotfp;
00418
00419 if( (plotfp=fopen("rtrpp.plot", "w"))!=NULL) {
00420
00421 pl_color( plotfp, 255, 255, 255 );
00422 rt_plot_all_bboxes( plotfp, rtip );
00423 (void)fclose(plotfp);
00424 }
00425 }
00426
00427
00428 if( (RT_G_DEBUG&DEBUG_PLOTSOLIDS) ) {
00429 FILE *plotfp;
00430
00431 if( (plotfp=fopen("rtsolids.pl", "w")) != NULL) {
00432 rt_plot_all_solids( plotfp, rtip, resp );
00433 (void)fclose(plotfp);
00434 }
00435 }
00436 rtip->needprep = 0;
00437 bu_semaphore_release(RT_SEM_RESULTS);
00438
00439 if(RT_G_DEBUG&DEBUG_REGIONS) bu_log("rt_prep_parallel(%s,%d,ncpu=%d) FINISH\n",
00440 rtip->rti_dbip->dbi_filename,
00441 rtip->rti_dbip->dbi_uses, ncpu);
00442 }
00443
00444
00445
00446
00447
00448
00449 void
00450 rt_prep(register struct rt_i *rtip)
00451 {
00452 RT_CK_RTI(rtip);
00453 rt_prep_parallel(rtip, 1);
00454 }
00455
00456
00457
00458
00459
00460
00461
00462 void
00463 rt_plot_all_bboxes(FILE *fp, struct rt_i *rtip)
00464 {
00465 register struct soltab *stp;
00466
00467 RT_CK_RTI(rtip);
00468 pdv_3space( fp, rtip->rti_pmin, rtip->rti_pmax );
00469 RT_VISIT_ALL_SOLTABS_START( stp, rtip ) {
00470
00471 if( stp->st_aradius <= 0 ) continue;
00472
00473 if( stp->st_aradius >= INFINITY )
00474 continue;
00475 pdv_3box( fp, stp->st_min, stp->st_max );
00476 } RT_VISIT_ALL_SOLTABS_END
00477 }
00478
00479
00480
00481
00482 void
00483 rt_plot_all_solids(
00484 FILE *fp,
00485 struct rt_i *rtip,
00486 struct resource *resp)
00487 {
00488 register struct soltab *stp;
00489
00490 RT_CK_RTI(rtip);
00491
00492 pdv_3space( fp, rtip->rti_pmin, rtip->rti_pmax );
00493
00494 RT_VISIT_ALL_SOLTABS_START( stp, rtip ) {
00495
00496 if( stp->st_aradius <= 0 ) continue;
00497
00498
00499 if( stp->st_aradius >= INFINITY )
00500 continue;
00501
00502 (void)rt_plot_solid( fp, rtip, stp, resp );
00503 } RT_VISIT_ALL_SOLTABS_END
00504 }
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516 int
00517 rt_vlist_solid(
00518 struct bu_list *vhead,
00519 struct rt_i *rtip,
00520 const struct soltab *stp,
00521 struct resource *resp)
00522 {
00523 struct rt_db_internal intern;
00524
00525 if( rt_db_get_internal( &intern, stp->st_dp, rtip->rti_dbip, stp->st_matp, resp ) < 0 ) {
00526 bu_log("rt_vlist_solid(%s): rt_db_get_internal() failed\n",
00527 stp->st_name);
00528 return(-1);
00529 }
00530 RT_CK_DB_INTERNAL( &intern );
00531
00532 if( rt_functab[intern.idb_type].ft_plot(
00533 vhead,
00534 &intern,
00535 &rtip->rti_ttol,
00536 &rtip->rti_tol
00537 ) < 0 ) {
00538 bu_log("rt_vlist_solid(%s): ft_plot() failure\n",
00539 stp->st_name);
00540 rt_db_free_internal( &intern, resp );
00541 return(-2);
00542 }
00543 rt_db_free_internal( &intern, resp );
00544 return 0;
00545 }
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558 int
00559 rt_plot_solid(
00560 register FILE *fp,
00561 struct rt_i *rtip,
00562 const struct soltab *stp,
00563 struct resource *resp)
00564 {
00565 struct bu_list vhead;
00566 struct region *regp;
00567
00568 RT_CK_RTI(rtip);
00569 RT_CK_SOLTAB(stp);
00570
00571 BU_LIST_INIT( &vhead );
00572
00573 if( rt_vlist_solid( &vhead, rtip, stp, resp ) < 0 ) {
00574 bu_log("rt_plot_solid(%s): rt_vlist_solid() failed\n",
00575 stp->st_name);
00576 return(-1);
00577 }
00578
00579 if( BU_LIST_IS_EMPTY( &vhead ) ) {
00580 bu_log("rt_plot_solid(%s): no vectors to plot?\n",
00581 stp->st_name);
00582 return(-3);
00583 }
00584
00585
00586 if( (regp = (struct region *)BU_PTBL_GET(&stp->st_regions,0)) != REGION_NULL ) {
00587 pl_color( fp,
00588 (int)(255*regp->reg_mater.ma_color[0]),
00589 (int)(255*regp->reg_mater.ma_color[1]),
00590 (int)(255*regp->reg_mater.ma_color[2]) );
00591 }
00592
00593 rt_vlist_to_uplot( fp, &vhead );
00594
00595 RT_FREE_VLIST( &vhead );
00596 return(0);
00597 }
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613 void
00614 rt_init_resource(struct resource *resp,
00615 int cpu_num,
00616 struct rt_i *rtip)
00617 {
00618
00619 if( resp == &rt_uniresource ) {
00620 cpu_num = MAX_PSW;
00621 if(rtip) RT_CK_RTI(rtip);
00622 } else {
00623 BU_ASSERT_PTR( resp, !=, NULL );
00624 BU_ASSERT_LONG( cpu_num, >=, 0 );
00625 if( rtip->rti_treetop ) {
00626
00627 BU_ASSERT_LONG( cpu_num, <, rtip->rti_resources.blen );
00628 } else {
00629 BU_ASSERT_LONG( cpu_num, <, MAX_PSW );
00630 }
00631 RT_CK_RTI(rtip);
00632 }
00633
00634 resp->re_magic = RESOURCE_MAGIC;
00635 resp->re_cpu = cpu_num;
00636
00637
00638
00639 if( BU_LIST_UNINITIALIZED( &resp->re_seg ) )
00640 BU_LIST_INIT( &resp->re_seg )
00641
00642 if( BU_LIST_UNINITIALIZED( &resp->re_seg_blocks.l ) )
00643 bu_ptbl_init( &resp->re_seg_blocks, 64, "re_seg_blocks ptbl" );
00644
00645 if( BU_LIST_UNINITIALIZED( &resp->re_directory_blocks.l ) )
00646 bu_ptbl_init( &resp->re_directory_blocks, 64, "re_directory_blocks ptbl" );
00647
00648 if( BU_LIST_UNINITIALIZED( &resp->re_parthead ) )
00649 BU_LIST_INIT( &resp->re_parthead )
00650
00651 if( BU_LIST_UNINITIALIZED( &resp->re_solid_bitv ) )
00652 BU_LIST_INIT( &resp->re_solid_bitv )
00653
00654 if( BU_LIST_UNINITIALIZED( &resp->re_region_ptbl ) )
00655 BU_LIST_INIT( &resp->re_region_ptbl )
00656
00657 if( BU_LIST_UNINITIALIZED( &resp->re_nmgfree ) )
00658 BU_LIST_INIT( &resp->re_nmgfree )
00659
00660 resp->re_boolstack = NULL;
00661 resp->re_boolslen = 0;
00662
00663 if( rtip == NULL ) return;
00664
00665
00666
00667 {
00668 struct resource *ores = (struct resource *)
00669 BU_PTBL_GET(&rtip->rti_resources, cpu_num);
00670 if( ores != NULL && ores != resp ) {
00671 bu_log("rt_init_resource(cpu=%d) re-registering resource, had x%x, new=x%x\n",
00672 cpu_num,
00673 ores,
00674 resp );
00675 bu_bomb("rt_init_resource() re-registration\n");
00676 }
00677 BU_PTBL_SET(&rtip->rti_resources, cpu_num, resp);
00678 }
00679 }
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703 void
00704 rt_clean_resource(struct rt_i *rtip, struct resource *resp)
00705 {
00706 RT_CK_RTI(rtip);
00707 RT_CK_RESOURCE(resp);
00708
00709
00710
00711
00712 BU_LIST_INIT( &resp->re_seg );
00713 if( BU_LIST_IS_INITIALIZED( &resp->re_seg_blocks.l ) ) {
00714 struct seg **spp;
00715 BU_CK_PTBL( &resp->re_seg_blocks );
00716 for( BU_PTBL_FOR( spp, (struct seg **), &resp->re_seg_blocks ) ) {
00717 RT_CK_SEG(*spp);
00718 bu_free( (genptr_t)(*spp), "struct seg block" );
00719 }
00720 bu_ptbl_free( &resp->re_seg_blocks );
00721 }
00722
00723
00724
00725
00726
00727
00728
00729 if( BU_LIST_IS_INITIALIZED( &resp->re_nmgfree ) ) {
00730 struct hitmiss *hitp;
00731 while( BU_LIST_WHILE( hitp, hitmiss, &resp->re_nmgfree ) ) {
00732 NMG_CK_HITMISS(hitp);
00733 BU_LIST_DEQUEUE( (struct bu_list *)hitp );
00734 bu_free( (genptr_t)hitp, "struct hitmiss" );
00735 }
00736 }
00737
00738
00739 if( BU_LIST_IS_INITIALIZED( &resp->re_parthead ) ) {
00740 struct partition *pp;
00741 while( BU_LIST_WHILE( pp, partition, &resp->re_parthead ) ) {
00742 RT_CK_PT(pp);
00743 BU_LIST_DEQUEUE( (struct bu_list *)pp );
00744 bu_ptbl_free( &pp->pt_seglist );
00745 bu_free( (genptr_t)pp, "struct partition" );
00746 }
00747 }
00748
00749
00750 if( BU_LIST_IS_INITIALIZED( &resp->re_solid_bitv ) ) {
00751 struct bu_bitv *bvp;
00752 while( BU_LIST_WHILE( bvp, bu_bitv, &resp->re_solid_bitv ) ) {
00753 BU_CK_BITV( bvp );
00754 BU_LIST_DEQUEUE( &bvp->l );
00755 bvp->nbits = 0;
00756 bu_free( (genptr_t)bvp, "struct bu_bitv" );
00757 }
00758 }
00759
00760
00761 if( BU_LIST_IS_INITIALIZED( &resp->re_region_ptbl ) ) {
00762 struct bu_ptbl *tabp;
00763 while( BU_LIST_WHILE( tabp, bu_ptbl, &resp->re_region_ptbl ) ) {
00764 BU_CK_PTBL(tabp);
00765 BU_LIST_DEQUEUE( &tabp->l );
00766 bu_ptbl_free( tabp );
00767 bu_free( (genptr_t)tabp, "struct bu_ptbl" );
00768 }
00769 }
00770
00771
00772 if( resp->re_tree_hd != TREE_NULL ) {
00773 union tree *tp;
00774
00775 tp = resp->re_tree_hd;
00776 while( tp != TREE_NULL ) {
00777 resp->re_tree_hd = tp->tr_b.tb_left;
00778 bu_free( (char *)tp, "union tree in resource struct" );
00779 tp = resp->re_tree_hd;
00780 }
00781 }
00782
00783
00784 if( resp->re_boolstack ) {
00785 bu_free( (genptr_t)resp->re_boolstack, "boolstack" );
00786 resp->re_boolstack = NULL;
00787 resp->re_boolslen = 0;
00788 }
00789
00790
00791 rt_res_pieces_clean( resp, rtip );
00792
00793
00794 rt_init_resource( resp, resp->re_cpu, rtip );
00795 }
00796
00797 struct bu_bitv *
00798 get_solidbitv( long nbits, struct resource *resp )
00799 {
00800 struct bu_bitv *solidbits;
00801 int counter=0;
00802
00803 if( resp->re_solid_bitv.magic != BU_LIST_HEAD_MAGIC ) {
00804 bu_bomb( "Bad magic number in re_solid_btiv list\n" );
00805 }
00806
00807 if( BU_LIST_IS_EMPTY( &resp->re_solid_bitv ) ) {
00808 solidbits = bu_bitv_new( nbits );
00809 } else {
00810 for( BU_LIST_FOR( solidbits, bu_bitv, &resp->re_solid_bitv ) ) {
00811 if( solidbits->nbits >= nbits ) {
00812 BU_LIST_DEQUEUE( &solidbits->l );
00813 BU_CK_BITV(solidbits);
00814 break;
00815 }
00816 counter++;
00817 }
00818 if( solidbits == (struct bu_bitv *)&resp->re_solid_bitv ) {
00819 solidbits = bu_bitv_new( nbits );
00820 }
00821 }
00822
00823 return( solidbits );
00824 }
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836 void
00837 rt_clean(register struct rt_i *rtip)
00838 {
00839 register struct region *regp;
00840 register struct bu_list *head;
00841 register struct soltab *stp;
00842 int i;
00843
00844 RT_CK_RTI(rtip);
00845
00846
00847 for( BU_LIST_FOR( regp, region, &(rtip->HeadRegion) ) ) {
00848 RT_CK_REGION(regp);
00849 db_ck_tree( regp->reg_treetop );
00850 }
00851
00852
00853
00854
00855 while( BU_LIST_WHILE( regp, region, &rtip->HeadRegion ) ) {
00856 RT_CK_REGION(regp);
00857 BU_LIST_DEQUEUE(&(regp->l));
00858 db_free_tree( regp->reg_treetop, &rt_uniresource );
00859 bu_free( (genptr_t)regp->reg_name, "region name str");
00860 regp->reg_name = (char *)0;
00861 if( regp->reg_mater.ma_shader )
00862 {
00863 bu_free( (genptr_t)regp->reg_mater.ma_shader, "ma_shader" );
00864 regp->reg_mater.ma_shader = (char *)NULL;
00865 }
00866 if( regp->attr_values ) {
00867 i = 0;
00868 while( regp->attr_values[i] ) {
00869 bu_mro_free( regp->attr_values[i] );
00870 i++;
00871 }
00872 bu_free( (char *)regp->attr_values, "regp->attr_values" );
00873 }
00874 bu_free( (genptr_t)regp, "struct region");
00875 }
00876 rtip->nregions = 0;
00877
00878
00879
00880
00881
00882 head = &(rtip->rti_solidheads[0]);
00883 for( ; head < &(rtip->rti_solidheads[RT_DBNHASH]); head++ ) {
00884 while( BU_LIST_WHILE( stp, soltab, head ) ) {
00885 RT_CHECK_SOLTAB(stp);
00886 rt_free_soltab(stp);
00887 }
00888 }
00889 rtip->nsolids = 0;
00890
00891
00892 if( rtip->Regions ) {
00893 bu_free( (char *)rtip->Regions, "rtip->Regions[]" );
00894 rtip->Regions = (struct region **)0;
00895
00896
00897 rt_fr_cut( rtip, &(rtip->rti_CutHead) );
00898 bzero( (char *)&(rtip->rti_CutHead), sizeof(union cutter) );
00899 rt_fr_cut( rtip, &(rtip->rti_inf_box) );
00900 bzero( (char *)&(rtip->rti_inf_box), sizeof(union cutter) );
00901 }
00902 rt_cut_clean(rtip);
00903
00904
00905
00906 db_free_anim(rtip->rti_dbip);
00907
00908
00909 for( i=0; i <= ID_MAX_SOLID; i++ ) {
00910 if( rtip->rti_nsol_by_type[i] <= 0 ) continue;
00911 if (rtip->rti_sol_by_type[i]) {
00912 bu_free( (char *)rtip->rti_sol_by_type[i], "sol_by_type" );
00913 }
00914 rtip->rti_sol_by_type[i] = (struct soltab **)0;
00915 rtip->rti_nsol_by_type[i] = 0;
00916 }
00917 if( rtip->rti_Solids ) {
00918 bu_free( (char *)rtip->rti_Solids, "rtip->rti_Solids[]" );
00919 rtip->rti_Solids = (struct soltab **)0;
00920 }
00921
00922
00923
00924
00925
00926
00927
00928
00929 if( BU_LIST_MAGIC_OK(&rtip->rti_resources.l, BU_PTBL_MAGIC ) ) {
00930 struct resource **rpp;
00931 BU_CK_PTBL( &rtip->rti_resources );
00932 for( BU_PTBL_FOR( rpp, (struct resource **), &rtip->rti_resources ) ) {
00933
00934
00935
00936 if( *rpp == NULL ) continue;
00937 RT_CK_RESOURCE(*rpp);
00938
00939 rt_clean_resource(rtip, *rpp);
00940 #if 0
00941
00942
00943
00944
00945 *rpp = NULL;
00946 #endif
00947 }
00948 }
00949
00950 if( rtip->Orca_hash_tbl ) {
00951 bu_free( (char *)rtip->Orca_hash_tbl, "rtip->Orca_hash_tbl" );
00952 rtip->Orca_hash_tbl = NULL;
00953 }
00954 if( rt_uniresource.re_magic ) {
00955 rt_clean_resource(rtip, &rt_uniresource );
00956 }
00957
00958
00959
00960
00961
00962
00963 rtip->rti_inf_box.bn.bn_type = CUT_BOXNODE;
00964 VMOVE( rtip->rti_inf_box.bn.bn_min, rtip->mdl_min );
00965 VMOVE( rtip->rti_inf_box.bn.bn_max, rtip->mdl_max );
00966 VSETALL( rtip->mdl_min, INFINITY );
00967 VSETALL( rtip->mdl_max, -INFINITY );
00968
00969 bu_hist_free( &rtip->rti_hist_cellsize );
00970 bu_hist_free( &rtip->rti_hist_cutdepth );
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985 for( i=0; i < RT_DBNHASH; i++ ) {
00986 register struct directory *dp;
00987
00988 dp = rtip->rti_dbip->dbi_Head[i];
00989 for( ; dp != DIR_NULL; dp = dp->d_forw )
00990 dp->d_uses = 0;
00991 }
00992
00993 bu_ptbl_reset( &rtip->delete_regs );
00994
00995 rtip->rti_magic = RTI_MAGIC;
00996 rtip->needprep = 1;
00997 }
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010 int
01011 rt_del_regtree( struct rt_i *rtip, register struct region *delregp, struct resource *resp )
01012 {
01013 RT_CK_RESOURCE(resp);
01014
01015 if( RT_G_DEBUG & DEBUG_REGIONS )
01016 bu_log("rt_del_regtree(%s): region deleted\n", delregp->reg_name);
01017
01018 BU_LIST_DEQUEUE(&(delregp->l));
01019
01020 db_free_tree( delregp->reg_treetop, resp );
01021 delregp->reg_treetop = TREE_NULL;
01022 bu_free( (char *)delregp->reg_name, "region name str");
01023 delregp->reg_name = (char *)0;
01024 if( delregp->attr_values ) {
01025 int i=0;
01026 while( delregp->attr_values[i] ) {
01027 bu_mro_free( delregp->attr_values[i] );
01028 i++;
01029 }
01030 bu_free( (char *)delregp->attr_values, "delregp->attr_values" );
01031 }
01032 bu_free( (char *)delregp, "struct region");
01033 return(0);
01034 }
01035
01036
01037
01038
01039
01040
01041
01042
01043 HIDDEN void
01044 rt_solid_bitfinder(register union tree *treep, struct region *regp, struct resource *resp)
01045 {
01046 register union tree **sp;
01047 register struct soltab *stp;
01048 register union tree **stackend;
01049
01050 RT_CK_REGION(regp);
01051 RT_CK_RESOURCE(resp);
01052
01053 while( (sp = resp->re_boolstack) == (union tree **)0 )
01054 rt_grow_boolstack( resp );
01055 stackend = &(resp->re_boolstack[resp->re_boolslen-1]);
01056
01057 *sp++ = TREE_NULL;
01058 *sp++ = treep;
01059 while( (treep = *--sp) != TREE_NULL ) {
01060 RT_CK_TREE(treep);
01061 switch( treep->tr_op ) {
01062 case OP_NOP:
01063 break;
01064 case OP_SOLID:
01065 stp = treep->tr_a.tu_stp;
01066 RT_CK_SOLTAB(stp);
01067 bu_ptbl_ins( &stp->st_regions, (long *)regp );
01068 break;
01069 case OP_UNION:
01070 case OP_INTERSECT:
01071 case OP_SUBTRACT:
01072
01073
01074 *sp++ = treep->tr_b.tb_right;
01075 *sp++ = treep->tr_b.tb_left;
01076 if( sp >= stackend ) {
01077 register int off = sp - resp->re_boolstack;
01078 rt_grow_boolstack( resp );
01079 sp = &(resp->re_boolstack[off]);
01080 stackend = &(resp->re_boolstack[resp->re_boolslen-1]);
01081 }
01082 break;
01083 default:
01084 bu_log("rt_solid_bitfinder: op=x%x\n", treep->tr_op);
01085 break;
01086 }
01087 }
01088 }
01089
01090
01091
01092
01093
01094
01095
01096
01097 void
01098 rt_ck(register struct rt_i *rtip)
01099 {
01100 struct region *regp;
01101 struct soltab *stp;
01102
01103 RT_CK_RTI(rtip);
01104 RT_CK_DBI(rtip->rti_dbip);
01105
01106 db_ck_directory(rtip->rti_dbip);
01107
01108 RT_VISIT_ALL_SOLTABS_START( stp, rtip ) {
01109 RT_CK_SOLTAB(stp);
01110 } RT_VISIT_ALL_SOLTABS_END
01111
01112 for( BU_LIST_FOR( regp, region, &(rtip->HeadRegion) ) ) {
01113 RT_CK_REGION(regp);
01114 db_ck_tree(regp->reg_treetop);
01115 }
01116
01117
01118 }
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130 int rt_load_attrs( struct rt_i *rtip, char **attrs )
01131 {
01132 struct region *regp;
01133 struct bu_attribute_value_set avs;
01134 struct directory *dp;
01135 const char *reg_name;
01136 const char *attr;
01137 int attr_count=0;
01138 int mro_count;
01139 int did_set;
01140 int region_count=0;
01141 int i;
01142
01143 RT_CHECK_RTI(rtip);
01144 RT_CK_DBI(rtip->rti_dbip);
01145
01146 if( rtip->rti_dbip->dbi_version < 5 )
01147 return 0;
01148
01149 while( attrs[attr_count] )
01150 attr_count++;
01151
01152 for( BU_LIST_FOR( regp, region, &(rtip->HeadRegion) ) ) {
01153 RT_CK_REGION(regp);
01154
01155 did_set = 0;
01156 mro_count = 0;
01157 while( regp->attr_values[mro_count] )
01158 mro_count++;
01159
01160 if( mro_count < attr_count ) {
01161
01162 for( i=0 ; i<mro_count ; i++ ) {
01163 bu_mro_free( regp->attr_values[i] );
01164 bu_free( (char *)regp->attr_values[i], "regp->attr_values[i]" );
01165 }
01166 if( mro_count )
01167 bu_free( (char *)regp->attr_values, "regp->attr_values" );
01168 regp->attr_values = (struct bu_mro **)bu_calloc( attr_count + 1,
01169 sizeof( struct bu_mro *), "regp->attr_values" );
01170 for( i=0 ; i<attr_count ; i++ ) {
01171 regp->attr_values[i] = bu_malloc( sizeof( struct bu_mro ),
01172 "regpp->attr_values[i]" );
01173 bu_mro_init( regp->attr_values[i] );
01174 }
01175 } else if ( mro_count > attr_count ) {
01176
01177 for( i=attr_count ; i<mro_count ; i++ ) {
01178 bu_mro_free( regp->attr_values[i] );
01179 bu_free( (char *)regp->attr_values[i], "regp->attr_values[i]" );
01180 }
01181 regp->attr_values[attr_count] = (struct bu_mro *)NULL;
01182 }
01183
01184 if( (reg_name=strrchr( regp->reg_name, '/' ) ) == NULL )
01185 reg_name = regp->reg_name;
01186 else
01187 reg_name++;
01188
01189 if( (dp=db_lookup( rtip->rti_dbip, reg_name, LOOKUP_NOISY ) ) == DIR_NULL )
01190 continue;
01191
01192 bu_avs_init_empty(&avs);
01193 if( db5_get_attributes( rtip->rti_dbip, &avs, dp ) ) {
01194 bu_log( "rt_load_attrs: Failed to get attributes for region %s\n", reg_name );
01195 continue;
01196 }
01197
01198 for( i=0 ; i<attr_count ; i++ ) {
01199 if( (attr = bu_avs_get( &avs, attrs[i] ) ) == NULL )
01200 continue;
01201
01202 bu_mro_set( regp->attr_values[i], attr );
01203 did_set = 1;
01204 }
01205
01206 if( did_set )
01207 region_count++;
01208
01209 bu_avs_free( &avs );
01210 }
01211
01212 return( region_count );
01213 }
01214
01215
01216
01217
01218
01219
01220 static void
01221 rt_find_path( struct db_i *dbip,
01222 union tree *tp,
01223 struct directory *end,
01224 struct bu_ptbl *paths,
01225 struct db_full_path **curr_path,
01226 struct resource *resp )
01227 {
01228 int curr_path_index=(*curr_path)->fp_len;
01229 struct db_full_path *newpath;
01230 struct directory *dp;
01231 struct rt_db_internal intern;
01232 struct rt_comb_internal *comb;
01233
01234 switch( tp->tr_op ) {
01235 case OP_DB_LEAF:
01236 dp = db_lookup( dbip, tp->tr_l.tl_name, 1 );
01237 if( dp == DIR_NULL ) {
01238 bu_bomb( "rt_find_path() failed!!\n" );
01239 }
01240 db_add_node_to_full_path( *curr_path, dp );
01241 if( dp == end ) {
01242 bu_ptbl_ins( paths, (long *)(*curr_path) );
01243 newpath = (struct db_full_path *)bu_malloc( sizeof( struct db_full_path ),
01244 "newpath" );
01245 db_full_path_init( newpath );
01246 db_dup_full_path( newpath, (*curr_path) );
01247 (*curr_path) = newpath;
01248 } else if( (dp->d_flags & DIR_COMB) && !(dp->d_flags & DIR_REGION ) ) {
01249 if( rt_db_get_internal( &intern, dp, dbip, NULL, resp ) < 0 ) {
01250 bu_bomb( "db_get_internal() failed!!\n" );
01251 }
01252 comb = (struct rt_comb_internal *)intern.idb_ptr;
01253 rt_find_path( dbip, comb->tree, end, paths, curr_path, resp );
01254 rt_db_free_internal( &intern, resp );
01255 }
01256 break;
01257 case OP_UNION:
01258 case OP_SUBTRACT:
01259 case OP_INTERSECT:
01260 case OP_XOR:
01261
01262 rt_find_path( dbip, tp->tr_b.tb_left, end, paths, curr_path, resp );
01263 (*curr_path)->fp_len = curr_path_index;
01264 rt_find_path( dbip, tp->tr_b.tb_right, end, paths, curr_path, resp );
01265 break;
01266 case OP_NOT:
01267 case OP_GUARD:
01268 rt_find_path( dbip, tp->tr_b.tb_left, end, paths, curr_path, resp );
01269 break;
01270 default:
01271 bu_log( "rt_find_path(): Unrecognized OP (%d)\n", tp->tr_op );
01272 bu_bomb( "rt_find_path(): Unrecognized OP\n" );
01273 break;
01274 }
01275 }
01276
01277
01278
01279
01280
01281
01282 int
01283 rt_find_paths( struct db_i *dbip,
01284 struct directory *start,
01285 struct directory *end,
01286 struct bu_ptbl *paths,
01287 struct resource *resp )
01288 {
01289 struct rt_db_internal intern;
01290 struct db_full_path *path;
01291 struct rt_comb_internal *comb;
01292
01293 path = (struct db_full_path *)bu_malloc( sizeof( struct db_full_path ), "path" );
01294 db_full_path_init( path );
01295 db_add_node_to_full_path( path, start );
01296
01297 if( start == end ) {
01298 bu_ptbl_ins( paths, (long *)path );
01299 return( 0 );
01300 }
01301
01302 if( !(start->d_flags & DIR_COMB) || (start->d_flags & DIR_REGION) ) {
01303 bu_log( "Cannot find path from %s to %s\n",
01304 start->d_namep, end->d_namep );
01305 db_free_full_path( path );
01306 bu_free( (char *)path, "path" );
01307 return( 1 );
01308 }
01309
01310 if( rt_db_get_internal( &intern, start, dbip, NULL, resp ) < 0 ) {
01311 db_free_full_path( path );
01312 bu_free( (char *)path, "path" );
01313 return( 1 );
01314 }
01315
01316 comb = (struct rt_comb_internal *)intern.idb_ptr;
01317 rt_find_path( dbip, comb->tree, end, paths, &path, resp );
01318 rt_db_free_internal( &intern, resp );
01319
01320 return( 0 );
01321 }
01322
01323
01324
01325
01326
01327
01328
01329
01330 int
01331 obj_in_path( const char *path, const char *obj )
01332 {
01333 int obj_len=strlen( obj );
01334 char *ptr;
01335
01336 ptr = strstr( path, obj );
01337
01338 while( ptr ) {
01339 if( ptr == path ) {
01340
01341 ptr += obj_len;
01342 if( *ptr == '\0' || *ptr == '/' ) {
01343
01344 return( 1 );
01345 }
01346 } else if( *(ptr-1) == '/' ) {
01347 ptr += obj_len;
01348 if( *ptr == '\0' || *ptr == '/' ) {
01349
01350 return( 1 );
01351 }
01352 } else {
01353 ptr++;
01354 }
01355
01356 ptr = strstr( ptr, obj );
01357 }
01358
01359 return( 0 );
01360 }
01361
01362 static int
01363 unprep_reg_start( struct db_tree_state *tsp,
01364 struct db_full_path *pathp,
01365 const struct rt_comb_internal *comb,
01366 genptr_t client_data )
01367 {
01368 RT_CK_RTI(tsp->ts_rtip);
01369 RT_CK_RESOURCE(tsp->ts_resp);
01370
01371
01372 if( tsp->ts_rtip->useair == 0 && tsp->ts_aircode != 0 ) {
01373 tsp->ts_rtip->rti_air_discards++;
01374 return(-1);
01375 }
01376 return(0);
01377 }
01378
01379 static union tree *
01380 unprep_reg_end( struct db_tree_state *tsp,
01381 struct db_full_path *pathp,
01382 union tree *tree,
01383 genptr_t client_data )
01384 {
01385 return( (union tree *)NULL );
01386 }
01387
01388 static union tree *
01389 unprep_leaf( struct db_tree_state *tsp,
01390 struct db_full_path *pathp,
01391 struct rt_db_internal *ip,
01392 genptr_t client_data )
01393 {
01394 register struct soltab *stp;
01395 struct directory *dp;
01396 register matp_t mat;
01397 struct rt_i *rtip;
01398 struct bu_list *mid;
01399 struct rt_reprep_obj_list *objs=(struct rt_reprep_obj_list *)client_data;
01400
01401 RT_CK_DBTS(tsp);
01402 RT_CK_DBI(tsp->ts_dbip);
01403 RT_CK_FULL_PATH(pathp);
01404 RT_CK_DB_INTERNAL(ip);
01405 rtip = tsp->ts_rtip;
01406 RT_CK_RTI(rtip);
01407 RT_CK_RESOURCE(tsp->ts_resp);
01408 dp = DB_FULL_PATH_CUR_DIR(pathp);
01409
01410
01411
01412 if( !bn_mat_is_equal(tsp->ts_mat, bn_mat_identity, &rtip->rti_tol)) {
01413
01414 mat = (matp_t)tsp->ts_mat;
01415 } else {
01416
01417 mat = (matp_t)0;
01418 }
01419
01420
01421 mid = BU_LIST_FIRST( bu_list, &dp->d_use_hd );
01422 while( mid != &dp->d_use_hd ) {
01423 stp = BU_LIST_MAIN_PTR( soltab, mid, l2 );
01424 RT_CK_SOLTAB(stp);
01425
01426 mid = BU_LIST_PNEXT( bu_list, mid );
01427
01428 if( ((mat == (matp_t)0) && (stp->st_matp == (matp_t)0) ) ||
01429 bn_mat_is_equal( mat, stp->st_matp, &rtip->rti_tol ) ) {
01430 if( stp->st_rtip == rtip ) {
01431 long bit=stp->st_bit;
01432 struct region *rp;
01433 int i,j;
01434
01435
01436
01437
01438
01439
01440
01441 for( i=0 ; i<BU_PTBL_LEN( &stp->st_regions ) ; i++ ) {
01442 rp = (struct region *)BU_PTBL_GET( &stp->st_regions, i );
01443 for( j=0 ; j<objs->nunprepped ; j++ ) {
01444 if( obj_in_path( rp->reg_name, objs->unprepped[j] ) ) {
01445
01446
01447 bu_ptbl_ins_unique( &objs->unprep_regions, (long *)rp );
01448 bu_ptbl_rm( &stp->st_regions, (long *)rp );
01449 break;
01450 }
01451 }
01452 }
01453 if( stp->st_uses <= 1 ) {
01454
01455 remove_from_bsp( stp, &rtip->rti_inf_box, &rtip->rti_tol );
01456 remove_from_bsp( stp, &rtip->rti_CutHead, &rtip->rti_tol );
01457 rtip->rti_Solids[bit] = (struct soltab *)NULL;
01458 }
01459 rt_free_soltab( stp );
01460 return( (union tree *)NULL );
01461 }
01462 }
01463 }
01464
01465 bu_log( "rt_unprep(): Failed to find soltab structure for an instance of %s\n", dp->d_namep );
01466 bu_bomb( "rt_unprep(): Failed to find soltab structure for a solid instance\n");
01467
01468 return( (union tree *)NULL );
01469 }
01470
01471
01472
01473
01474
01475
01476
01477 int
01478 rt_unprep( struct rt_i *rtip, struct rt_reprep_obj_list *objs, struct resource *resp )
01479 {
01480 struct bu_ptbl paths;
01481 struct bu_ptbl unprep_regions;
01482 struct db_full_path *path;
01483 int i,j,k;
01484
01485 rt_res_pieces_clean( resp, rtip );
01486
01487
01488 bu_ptbl_init( &objs->paths, 5, "paths" );
01489 for( i=0 ; i<objs->ntopobjs ; i++ ) {
01490 struct directory *start, *end;
01491
01492 start = db_lookup( rtip->rti_dbip, objs->topobjs[i], 1 );
01493 if( start == DIR_NULL ) {
01494 for( k=0 ; k<BU_PTBL_END(&objs->paths) ; k++ ) {
01495 path = (struct db_full_path *)BU_PTBL_GET( &objs->paths, k );
01496 db_free_full_path( path );
01497 }
01498 bu_ptbl_free( &objs->paths );
01499 return( 1 );
01500 }
01501 for( j=0 ; j<objs->nunprepped ; j++ ) {
01502 end = db_lookup( rtip->rti_dbip, objs->unprepped[j], 1 );
01503 if( end == DIR_NULL ) {
01504 for( k=0 ; k<BU_PTBL_END(&objs->paths) ; k++ ) {
01505 path = (struct db_full_path *)BU_PTBL_GET( &objs->paths, k );
01506 db_free_full_path( path );
01507 }
01508 bu_ptbl_free( &objs->paths );
01509 return( 1 );
01510 }
01511 rt_find_paths( rtip->rti_dbip, start, end, &objs->paths, resp );
01512 }
01513 }
01514
01515 if( BU_PTBL_LEN( &objs->paths ) < 1 ) {
01516 bu_log( "rt_unprep(): Failed to find any paths to objects to reprep!!\n" );
01517 bu_ptbl_free( &objs->paths );
01518 }
01519
01520
01521 objs->tsp = (struct db_tree_state **)bu_calloc(
01522 BU_PTBL_LEN( &objs->paths ),
01523 sizeof( struct db_tree_state *),
01524 "objs->tsp" );
01525
01526 bu_ptbl_init( &objs->unprep_regions, 5, "unprep_regions" );
01527
01528 for( i=0 ; i<BU_PTBL_LEN( &objs->paths ) ; i++ ) {
01529 struct db_full_path another_path;
01530 struct db_tree_state *tree_state;
01531 char *obj_name;
01532
01533 tree_state = (struct db_tree_state *)bu_malloc( sizeof( struct db_tree_state ),
01534 "tree_state" );
01535 *tree_state = rt_initial_tree_state;
01536 tree_state->ts_dbip = rtip->rti_dbip;
01537 tree_state->ts_resp = resp;
01538 tree_state->ts_rtip = rtip;
01539 tree_state->ts_tol = &rtip->rti_tol;
01540 objs->tsp[i] = tree_state;
01541
01542 db_full_path_init( &another_path );
01543 path = (struct db_full_path *)BU_PTBL_GET( &objs->paths, i );
01544 if( db_follow_path( tree_state, &another_path, path, 1, 0 ) ) {
01545 bu_log( "rt_unprep(): db_follow_path failed!!\n" );
01546 for( k=0 ; k<BU_PTBL_END(&paths) ; k++ ) {
01547 if( objs->tsp[k] ) {
01548 db_free_db_tree_state( objs->tsp[k] );
01549 bu_free( (char *)objs->tsp[k], "tree_state" );
01550 }
01551 path = (struct db_full_path *)BU_PTBL_GET( &objs->paths, k );
01552 db_free_full_path( path );
01553 }
01554 bu_ptbl_free( &paths );
01555 bu_ptbl_free( &unprep_regions );
01556 return( 1 );
01557 }
01558 db_free_full_path( &another_path );
01559
01560
01561
01562
01563
01564 obj_name = DB_FULL_PATH_CUR_DIR(path)->d_namep;
01565 if( db_walk_tree( rtip->rti_dbip, 1, (const char **)&obj_name, 1, tree_state,
01566 unprep_reg_start, unprep_reg_end, unprep_leaf,
01567 (genptr_t)objs ) ) {
01568 bu_log( "rt_unprep(): db_walk_tree failed!!!\n" );
01569 for( k=0 ; k<BU_PTBL_END(&paths) ; k++ ) {
01570 if( objs->tsp[k] ) {
01571 db_free_db_tree_state( objs->tsp[k] );
01572 bu_free( (char *)objs->tsp[k], "tree_state" );
01573 }
01574 path = (struct db_full_path *)BU_PTBL_GET( &objs->paths, k );
01575 db_free_full_path( path );
01576 }
01577 bu_ptbl_free( &paths );
01578 bu_ptbl_free( &unprep_regions );
01579 return( 1 );
01580 }
01581
01582 db_free_db_tree_state( tree_state );
01583 bu_free( (char *)tree_state, "tree_state" );
01584 }
01585
01586
01587 objs->nregions_unprepped = BU_PTBL_LEN( &objs->unprep_regions );
01588 for( i=0 ; i<BU_PTBL_LEN( &objs->unprep_regions ) ; i++ ) {
01589 struct region *rp;
01590
01591 rp = (struct region *)BU_PTBL_GET( &objs->unprep_regions, i );
01592 BU_LIST_DEQUEUE( &rp->l );
01593 rtip->Regions[rp->reg_bit] = (struct region *)NULL;
01594
01595
01596
01597 bu_free( (genptr_t)rp->reg_name, "region name str");
01598 rp->reg_name = (char *)0;
01599 if( rp->reg_mater.ma_shader )
01600 {
01601 bu_free( (genptr_t)rp->reg_mater.ma_shader, "ma_shader" );
01602 rp->reg_mater.ma_shader = (char *)NULL;
01603 }
01604 if( rp->attr_values ) {
01605 i = 0;
01606 while( rp->attr_values[i] ) {
01607 bu_mro_free( rp->attr_values[i] );
01608 i++;
01609 }
01610 bu_free( (char *)rp->attr_values, "rp->attr_values" );
01611 }
01612 bu_free( (genptr_t)rp, "struct region");
01613 }
01614
01615
01616 objs->old_nregions = rtip->nregions;
01617 i = 0;
01618 while( i < rtip->nregions ) {
01619 int nulls=0;
01620
01621 while( i < rtip->nregions && !rtip->Regions[i] ) {
01622 i++;
01623 nulls++;
01624 }
01625
01626 if( nulls ) {
01627 rtip->nregions -= nulls;
01628 for( j=i-nulls ; j<rtip->nregions ; j++ ) {
01629 rtip->Regions[j] = rtip->Regions[j+nulls];
01630 if( rtip->Regions[j] ) {
01631 rtip->Regions[j]->reg_bit = j;
01632 }
01633 }
01634 nulls = 0;
01635 } else {
01636 i++;
01637 }
01638 }
01639
01640
01641 objs->old_nsolids = rtip->nsolids;
01642 objs->nsolids_unprepped = 0;
01643 i = 0;
01644 while( i < rtip->nsolids) {
01645 int nulls=0;
01646
01647 while( i < rtip->nsolids && !rtip->rti_Solids[i] ) {
01648 objs->nsolids_unprepped++;
01649 i++;
01650 nulls++;
01651 }
01652 if( nulls ) {
01653 for( j=i-nulls ; j+nulls<rtip->nsolids ; j++ ) {
01654 rtip->rti_Solids[j] = rtip->rti_Solids[j+nulls];
01655 if( rtip->rti_Solids[j] ) {
01656 rtip->rti_Solids[j]->st_bit = j;
01657 }
01658 }
01659 rtip->nsolids -= nulls;
01660 i -= nulls;
01661 } else {
01662 i++;
01663 }
01664 }
01665
01666 return( 0 );
01667 }
01668
01669
01670
01671
01672
01673 int
01674 rt_reprep( struct rt_i *rtip, struct rt_reprep_obj_list *objs, struct resource *resp )
01675 {
01676 int i;
01677 char **argv;
01678 struct region *rp;
01679 struct soltab *stp;
01680 fastf_t old_min[3], old_max[3];
01681 int model_extremes_have_changed=0;
01682 long bitno;
01683
01684 VMOVE( old_min, rtip->mdl_min );
01685 VMOVE( old_max, rtip->mdl_max );
01686
01687 rtip->needprep = 1;
01688
01689 argv = (char **)bu_calloc( BU_PTBL_LEN( &(objs->paths) ), sizeof( char *), "argv" );
01690 for( i=0 ; i<BU_PTBL_LEN( &(objs->paths) ) ; i++ ) {
01691 argv[i] = db_path_to_string( (const struct db_full_path *)BU_PTBL_GET( &(objs->paths), i ));
01692 }
01693
01694 rtip->rti_add_to_new_solids_list = 1;
01695 bu_ptbl_init( &rtip->rti_new_solids, 128, "rti_new_solids" );
01696 if( rt_gettrees( rtip, BU_PTBL_LEN( &(objs->paths) ), (const char **)argv, 1 ) ) {
01697 return( 1 );
01698 }
01699 rtip->rti_add_to_new_solids_list = 0;
01700
01701 for( i=0 ; i<BU_PTBL_LEN( &(objs->paths) ) ; i++ ) {
01702 bu_free( argv[i], "argv[i]" );
01703 }
01704 bu_free( (char *)argv, "argv" );
01705
01706 rtip->needprep = 0;
01707
01708 if( rtip->nregions > objs->old_nregions ) {
01709 rtip->Regions = (struct region **)bu_realloc( rtip->Regions,
01710 rtip->nregions * sizeof( struct region *), "rtip->Regions" );
01711 memset( rtip->Regions, 0, rtip->nregions );
01712 }
01713
01714
01715 bitno = 0;
01716 for( BU_LIST_FOR( rp, region, &(rtip->HeadRegion) ) ) {
01717 rp->reg_bit = bitno;
01718 rtip->Regions[bitno] = rp;
01719 if( bitno >= objs->old_nregions - objs->nregions_unprepped ) {
01720 point_t region_min, region_max;
01721
01722 if( rt_bound_tree( rp->reg_treetop, region_min, region_max ) ) {
01723 bu_log( "rt_reprep(): rt_bound_tree() FAILED for %s\n",
01724 rp->reg_name );
01725 bu_bomb( "rt_reprep(): rt_bound_tree() FAILED\n" );
01726 }
01727 if( region_max[X] < INFINITY ) {
01728
01729 VMINMAX( rtip->mdl_min, rtip->mdl_max, region_min );
01730 VMINMAX( rtip->mdl_min, rtip->mdl_max, region_max );
01731 }
01732 rt_solid_bitfinder( rp->reg_treetop, rp, resp );
01733 }
01734 bitno++;
01735 }
01736
01737 if( rtip->nsolids > objs->old_nsolids ) {
01738 rtip->rti_Solids = (struct soltab **)bu_realloc( rtip->rti_Solids,
01739 rtip->nsolids * sizeof( struct soltab *),
01740 "rtip->rti_Solids" );
01741 memset( rtip->rti_Solids, 0, rtip->nsolids * sizeof(struct soltab *));
01742 }
01743
01744 bitno = 0;
01745 RT_VISIT_ALL_SOLTABS_START( stp, rtip ) {
01746 stp->st_bit = bitno;
01747 rtip->rti_Solids[bitno] = stp;
01748 bitno++;
01749
01750 } RT_VISIT_ALL_SOLTABS_END
01751
01752 for( i=0 ; i<BU_PTBL_LEN( &rtip->rti_new_solids ) ; i++ ) {
01753 stp = (struct soltab * )BU_PTBL_GET( &rtip->rti_new_solids, i );
01754 if( stp->st_aradius >= INFINITY ) {
01755 insert_in_bsp( stp, &rtip->rti_inf_box );
01756 } else {
01757 insert_in_bsp( stp, &rtip->rti_CutHead );
01758 }
01759 }
01760
01761 bu_ptbl_free( &rtip->rti_new_solids );
01762
01763 for( i=0 ; i<3 ; i++ ) {
01764 if( rtip->mdl_min[i] != old_min[i] ) {
01765 model_extremes_have_changed = 1;
01766 break;
01767 }
01768 if( rtip->mdl_max[i] != old_max[i] ) {
01769 model_extremes_have_changed = 1;
01770 break;
01771 }
01772 }
01773
01774 if( model_extremes_have_changed ) {
01775
01776 fastf_t bb[6];
01777
01778 VSETALL( bb, INFINITY );
01779 VSETALL( &bb[3], -INFINITY );
01780 fill_out_bsp( rtip, &rtip->rti_CutHead, resp, bb );
01781 }
01782
01783 if( BU_PTBL_LEN( &rtip->rti_resources ) ) {
01784 for( i=0 ; i<BU_PTBL_LEN( &rtip->rti_resources ) ; i++ ) {
01785 struct resource *re;
01786
01787 re = (struct resource *)BU_PTBL_GET( &rtip->rti_resources, i );
01788 if( re && rtip->rti_nsolids_with_pieces )
01789 rt_res_pieces_init( re, rtip );
01790 }
01791 } else if( rtip->rti_nsolids_with_pieces ) {
01792 rt_res_pieces_init( &rt_uniresource, rtip );
01793 }
01794
01795 return( 0 );
01796 }
01797
01798
01799
01800
01801
01802
01803
01804
01805
01806