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 #ifndef lint
00046 static const char RCSid[] = "@(#)$Header: /cvsroot/brlcad/brlcad/src/librt/bool.c,v 14.14 2006/09/16 02:04:24 lbutler Exp $ (ARL)";
00047 #endif
00048
00049 #include "common.h"
00050
00051 #include <stdio.h>
00052 #ifdef HAVE_STRING_H
00053 # include <string.h>
00054 #else
00055 # include <strings.h>
00056 #endif
00057 #include "machine.h"
00058 #include "vmath.h"
00059 #include "raytrace.h"
00060 #include "bu.h"
00061 #include "./debug.h"
00062
00063
00064 #define FALSE 0
00065 #define TRUE 1
00066
00067
00068 BU_EXTERN(void rt_grow_boolstack, (struct resource *resp) );
00069 int rt_tree_max_raynum(register const union tree *,
00070 register const struct partition *);
00071 int rt_bool_partition_eligible(register const struct bu_ptbl *,
00072 register const struct bu_bitv *,
00073 register const struct partition *);
00074 int rt_booleval(register union tree*,
00075 struct partition *,
00076 struct region **,
00077 struct resource *);
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089 void
00090 rt_weave0seg(struct seg *segp, struct partition *PartHdp, struct application *ap)
00091 {
00092 register struct partition *pp;
00093 struct resource *res = ap->a_resource;
00094 struct rt_i *rtip = ap->a_rt_i;
00095 FAST fastf_t tol_dist;
00096
00097 tol_dist = rtip->rti_tol.dist;
00098
00099 RT_CK_PT_HD(PartHdp);
00100 RT_CK_RTI(ap->a_rt_i);
00101 RT_CK_RESOURCE(res);
00102 RT_CK_RTI(rtip);
00103
00104 if(RT_G_DEBUG&DEBUG_PARTITION) {
00105 bu_log(
00106 "rt_boolweave: Zero thickness seg: %s (%.18e,%.18e) %d,%d\n",
00107 segp->seg_stp->st_name,
00108 segp->seg_in.hit_dist,
00109 segp->seg_out.hit_dist,
00110 segp->seg_in.hit_surfno,
00111 segp->seg_out.hit_surfno );
00112 }
00113
00114 if( PartHdp->pt_forw == PartHdp ) rt_bomb("rt_weave0seg() with empty partition list\n");
00115
00116
00117 if( segp->seg_out.hit_dist < PartHdp->pt_forw->pt_inhit->hit_dist ) {
00118 GET_PT_INIT( rtip, pp, res );
00119 bu_ptbl_ins_unique( &pp->pt_seglist, (long *)segp );
00120 pp->pt_inseg = segp;
00121 pp->pt_inhit = &segp->seg_in;
00122 pp->pt_outseg = segp;
00123 pp->pt_outhit = &segp->seg_out;
00124 APPEND_PT( pp, PartHdp );
00125 if(RT_G_DEBUG&DEBUG_PARTITION) bu_log("0-len segment ends before start of first partition.\n");
00126 return;
00127 }
00128
00129
00130
00131
00132
00133
00134
00135 for( pp=PartHdp->pt_forw; pp != PartHdp; pp=pp->pt_forw ) {
00136 if( NEAR_ZERO( segp->seg_in.hit_dist - pp->pt_inhit->hit_dist, tol_dist ) ||
00137 NEAR_ZERO( segp->seg_out.hit_dist - pp->pt_inhit->hit_dist, tol_dist )
00138 ) {
00139 if(RT_G_DEBUG&DEBUG_PARTITION) bu_log("0-len segment ends right at start of existing partition.\n");
00140 return;
00141 }
00142 if( NEAR_ZERO( segp->seg_in.hit_dist - pp->pt_outhit->hit_dist, tol_dist ) ||
00143 NEAR_ZERO( segp->seg_out.hit_dist - pp->pt_outhit->hit_dist, tol_dist )
00144 ) {
00145 if(RT_G_DEBUG&DEBUG_PARTITION) bu_log("0-len segment ends right at end of existing partition.\n");
00146 return;
00147 }
00148 if( segp->seg_out.hit_dist <= pp->pt_outhit->hit_dist &&
00149 segp->seg_in.hit_dist >= pp->pt_inhit->hit_dist ) {
00150 if(RT_G_DEBUG&DEBUG_PARTITION) bu_log("0-len segment in the middle of existing partition.\n");
00151 return;
00152 }
00153 if( pp->pt_forw == PartHdp ||
00154 segp->seg_out.hit_dist < pp->pt_forw->pt_inhit->hit_dist ) {
00155 struct partition *npp;
00156 if(RT_G_DEBUG&DEBUG_PARTITION) bu_log("0-len segment after existing partition, but before next partition.\n");
00157 GET_PT_INIT( rtip, npp, res );
00158 bu_ptbl_ins_unique( &npp->pt_seglist, (long *)segp );
00159 npp->pt_inseg = segp;
00160 npp->pt_inhit = &segp->seg_in;
00161 npp->pt_outseg = segp;
00162 npp->pt_outhit = &segp->seg_out;
00163 APPEND_PT( npp, pp );
00164 return;
00165 }
00166 }
00167 rt_bomb("rt_weave0seg() fell out of partition loop?\n");
00168 }
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195 void
00196 rt_boolweave(struct seg *out_hd, struct seg *in_hd, struct partition *PartHdp, struct application *ap)
00197 {
00198 register struct seg *segp;
00199 register struct partition *pp;
00200 struct resource *res = ap->a_resource;
00201 struct rt_i *rtip = ap->a_rt_i;
00202
00203 FAST fastf_t diff, diff_se;
00204 FAST fastf_t tol_dist;
00205
00206 RT_CK_PT_HD(PartHdp);
00207
00208 tol_dist = rtip->rti_tol.dist;
00209
00210 RT_CK_RTI(ap->a_rt_i);
00211 RT_CK_RESOURCE(res);
00212 RT_CK_RTI(rtip);
00213
00214 if(RT_G_DEBUG&DEBUG_PARTITION) {
00215 bu_log( "In rt_boolweave, tol_dist = %g\n", tol_dist );
00216 rt_pr_partitions( rtip, PartHdp, "-----------------BOOL_WEAVE" );
00217 }
00218
00219 while( BU_LIST_NON_EMPTY( &(in_hd->l) ) ) {
00220 register struct partition *newpp = PT_NULL;
00221 register struct seg *lastseg = RT_SEG_NULL;
00222 register struct hit *lasthit = HIT_NULL;
00223 LOCAL int lastflip = 0;
00224
00225 segp = BU_LIST_FIRST( seg, &(in_hd->l) );
00226 RT_CHECK_SEG(segp);
00227 RT_CK_HIT(&(segp->seg_in));
00228 RT_CK_RAY(segp->seg_in.hit_rayp);
00229 RT_CK_HIT(&(segp->seg_out));
00230 RT_CK_RAY(segp->seg_out.hit_rayp);
00231 if(RT_G_DEBUG&DEBUG_PARTITION) {
00232 point_t pt;
00233
00234 bu_log( "************ Input segment:\n" );
00235 rt_pr_seg(segp);
00236 rt_pr_hit(" In", &segp->seg_in );
00237 VJOIN1( pt, ap->a_ray.r_pt, segp->seg_in.hit_dist, ap->a_ray.r_dir );
00238
00239 VPRINT(" IPoint", pt );
00240
00241 rt_pr_hit("Out", &segp->seg_out );
00242 VJOIN1( pt, ap->a_ray.r_pt, segp->seg_out.hit_dist, ap->a_ray.r_dir );
00243
00244 VPRINT(" OPoint", pt );
00245 bu_log( "***********\n" );
00246 }
00247 if( segp->seg_stp->st_bit >= rtip->nsolids) rt_bomb("rt_boolweave: st_bit");
00248
00249 BU_LIST_DEQUEUE( &(segp->l) );
00250 BU_LIST_INSERT( &(out_hd->l), &(segp->l) );
00251
00252
00253 if( NEAR_ZERO( segp->seg_in.hit_dist, tol_dist ) )
00254 segp->seg_in.hit_dist = 0;
00255 if( NEAR_ZERO( segp->seg_out.hit_dist, tol_dist ) )
00256 segp->seg_out.hit_dist = 0;
00257
00258
00259 if( segp->seg_out.hit_dist < -10.0 )
00260 continue;
00261
00262 if( segp->seg_stp->st_aradius < INFINITY &&
00263 !(segp->seg_in.hit_dist >= -INFINITY &&
00264 segp->seg_out.hit_dist <= INFINITY) ) {
00265 bu_log("rt_boolweave: Defective %s segment %s (%.18e,%.18e) %d,%d\n",
00266 rt_functab[segp->seg_stp->st_id].ft_name,
00267 segp->seg_stp->st_name,
00268 segp->seg_in.hit_dist,
00269 segp->seg_out.hit_dist,
00270 segp->seg_in.hit_surfno,
00271 segp->seg_out.hit_surfno );
00272 continue;
00273 }
00274 if( segp->seg_in.hit_dist > segp->seg_out.hit_dist ) {
00275 bu_log("rt_boolweave: Inside-out %s segment %s (%.18e,%.18e) %d,%d\n",
00276 rt_functab[segp->seg_stp->st_id].ft_name,
00277 segp->seg_stp->st_name,
00278 segp->seg_in.hit_dist,
00279 segp->seg_out.hit_dist,
00280 segp->seg_in.hit_surfno,
00281 segp->seg_out.hit_surfno );
00282 continue;
00283 }
00284
00285
00286
00287
00288
00289 if( PartHdp->pt_forw == PartHdp ) {
00290
00291 GET_PT_INIT( rtip, pp, res );
00292 bu_ptbl_ins_unique( &pp->pt_seglist, (long *)segp );
00293 pp->pt_inseg = segp;
00294 pp->pt_inhit = &segp->seg_in;
00295 pp->pt_outseg = segp;
00296 pp->pt_outhit = &segp->seg_out;
00297 APPEND_PT( pp, PartHdp );
00298 if(RT_G_DEBUG&DEBUG_PARTITION) bu_log("No partitions yet, segment forms first partition\n");
00299 goto done_weave;
00300 }
00301
00302 if( ap->a_no_booleans ) {
00303 lastseg = segp;
00304 lasthit = &segp->seg_in;
00305 lastflip = 0;
00306
00307 for( pp=PartHdp->pt_forw; pp != PartHdp; pp=pp->pt_forw ) {
00308 if( lasthit->hit_dist < pp->pt_inhit->hit_dist ) {
00309 if(RT_G_DEBUG&DEBUG_PARTITION) {
00310 bu_log("Insert nobool seg before next pt\n");
00311 }
00312 GET_PT_INIT( rtip, newpp, res );
00313 bu_ptbl_ins_unique( &newpp->pt_seglist, (long *)segp );
00314 newpp->pt_inseg = segp;
00315 newpp->pt_inhit = &segp->seg_in;
00316 newpp->pt_outseg = segp;
00317 newpp->pt_outhit = &segp->seg_out;
00318 INSERT_PT( newpp, pp );
00319 goto done_weave;
00320 }
00321 }
00322 if(RT_G_DEBUG&DEBUG_PARTITION) {
00323 bu_log("Append nobool seg at end of list\n");
00324 }
00325 GET_PT_INIT( rtip, newpp, res );
00326 bu_ptbl_ins_unique( &newpp->pt_seglist, (long *)segp );
00327 newpp->pt_inseg = segp;
00328 newpp->pt_inhit = &segp->seg_in;
00329 newpp->pt_outseg = segp;
00330 newpp->pt_outhit = &segp->seg_out;
00331 INSERT_PT( newpp, PartHdp );
00332 goto done_weave;
00333 }
00334
00335
00336 diff = segp->seg_in.hit_dist - segp->seg_out.hit_dist;
00337 if( NEAR_ZERO( diff, tol_dist ) ) {
00338 rt_weave0seg( segp, PartHdp, ap );
00339 goto done_weave;
00340 }
00341
00342 if( segp->seg_in.hit_dist >= PartHdp->pt_back->pt_outhit->hit_dist ) {
00343
00344
00345
00346
00347 if(RT_G_DEBUG&DEBUG_PARTITION) {
00348 bu_log("seg starts beyond last partition end. (%g,%g) Appending new partition\n",
00349 PartHdp->pt_back->pt_inhit->hit_dist,
00350 PartHdp->pt_back->pt_outhit->hit_dist);
00351 }
00352 GET_PT_INIT( rtip, pp, res );
00353 bu_ptbl_ins_unique( &pp->pt_seglist, (long *)segp );
00354 pp->pt_inseg = segp;
00355 pp->pt_inhit = &segp->seg_in;
00356 pp->pt_outseg = segp;
00357 pp->pt_outhit = &segp->seg_out;
00358 APPEND_PT( pp, PartHdp->pt_back );
00359 goto done_weave;
00360 }
00361
00362
00363
00364
00365
00366
00367 lastseg = segp;
00368 lasthit = &segp->seg_in;
00369 lastflip = 0;
00370 for( pp=PartHdp->pt_forw; pp != PartHdp; pp=pp->pt_forw ) {
00371
00372 if(RT_G_DEBUG&DEBUG_PARTITION) {
00373 bu_log( "At start of loop:\n" );
00374 bu_log( " remaining input segment: (%.12e - %.12e)\n",
00375 lasthit->hit_dist, segp->seg_out.hit_dist );
00376 bu_log( " current partition: (%.12e - %.12e)\n",
00377 pp->pt_inhit->hit_dist, pp->pt_outhit->hit_dist );
00378 rt_pr_partitions( rtip, PartHdp, "At start of loop" );
00379 }
00380
00381 diff_se = lasthit->hit_dist - pp->pt_outhit->hit_dist;
00382 if( diff_se > tol_dist ) {
00383
00384
00385
00386
00387
00388
00389 if(RT_G_DEBUG&DEBUG_PARTITION) {
00390 bu_log("seg start beyond partition end, skipping. (%g,%g)\n",
00391 pp->pt_inhit->hit_dist,
00392 pp->pt_outhit->hit_dist);
00393 }
00394 continue;
00395 }
00396 if(RT_G_DEBUG&DEBUG_PARTITION) rt_pr_pt(rtip, pp);
00397 diff = lasthit->hit_dist - pp->pt_inhit->hit_dist;
00398 if( diff_se > -(tol_dist) && diff > tol_dist ) {
00399
00400
00401
00402
00403
00404
00405
00406
00407 lasthit->hit_dist = pp->pt_outhit->hit_dist;
00408 if(RT_G_DEBUG&DEBUG_PARTITION) {
00409 bu_log("seg start fused to partition end, diff=%g\n", diff);
00410 }
00411 continue;
00412 }
00413
00414
00415
00416
00417
00418
00419
00420 if( diff > tol_dist ) {
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432 RT_DUP_PT( rtip, newpp, pp, res );
00433
00434 pp->pt_inseg = segp;
00435 pp->pt_inhit = &segp->seg_in;
00436 pp->pt_inflip = 0;
00437 newpp->pt_outseg = segp;
00438 newpp->pt_outhit = &segp->seg_in;
00439 newpp->pt_outflip = 1;
00440 INSERT_PT( newpp, pp );
00441 if(RT_G_DEBUG&DEBUG_PARTITION) {
00442 bu_log("seg starts within p. Split p at seg start, advance. (diff = %g)\n", diff);
00443 bu_log( "newpp starts at %.12e, pp starts at %.12e\n",
00444 newpp->pt_inhit->hit_dist,
00445 pp->pt_inhit->hit_dist );
00446 bu_log( "newpp = x%x, pp = x%x\n", newpp, pp );
00447 }
00448 goto equal_start;
00449 }
00450 if( diff > -(tol_dist) ) {
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465 diff = segp->seg_in.hit_dist - pp->pt_inhit->hit_dist;
00466 if( !pp->pt_back ||
00467 pp->pt_back == PartHdp ||
00468 pp->pt_back->pt_outhit->hit_dist <=
00469 segp->seg_in.hit_dist ) {
00470 if( NEAR_ZERO(diff, tol_dist) &&
00471 diff < 0 ) {
00472 if(RT_G_DEBUG&DEBUG_PARTITION) bu_log("changing partition start point to segment start point\n");
00473 pp->pt_inseg = segp;
00474 pp->pt_inhit = &segp->seg_in;
00475 pp->pt_inflip = 0;
00476 }
00477 }
00478 equal_start:
00479 if(RT_G_DEBUG&DEBUG_PARTITION) bu_log("equal_start\n");
00480
00481
00482
00483
00484
00485
00486
00487
00488 diff = segp->seg_out.hit_dist - pp->pt_outhit->hit_dist;
00489 if( diff > tol_dist ) {
00490
00491
00492
00493
00494
00495
00496
00497
00498 bu_ptbl_ins_unique( &pp->pt_seglist, (long *)segp );
00499 lasthit = pp->pt_outhit;
00500 lastseg = pp->pt_outseg;
00501 lastflip = 1;
00502 if(RT_G_DEBUG&DEBUG_PARTITION) bu_log("seg spans partition and extends beyond it\n");
00503 continue;
00504 }
00505 if( diff > -(tol_dist) ) {
00506
00507
00508
00509
00510
00511
00512
00513 bu_ptbl_ins_unique( &pp->pt_seglist, (long *)segp );
00514 if(RT_G_DEBUG&DEBUG_PARTITION) bu_log("same start&end\n");
00515 goto done_weave;
00516 } else {
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526 RT_DUP_PT( rtip, newpp, pp, res );
00527
00528 bu_ptbl_ins_unique( &newpp->pt_seglist, (long *)segp );
00529 newpp->pt_outseg = segp;
00530 newpp->pt_outhit = &segp->seg_out;
00531 newpp->pt_outflip = 0;
00532 pp->pt_inseg = segp;
00533 pp->pt_inhit = &segp->seg_out;
00534 pp->pt_inflip = 1;
00535 INSERT_PT( newpp, pp );
00536 if(RT_G_DEBUG&DEBUG_PARTITION) {
00537 bu_log("start together, seg shorter than partition\n");
00538 bu_log( "newpp starts at %.12e, pp starts at %.12e\n",
00539 newpp->pt_inhit->hit_dist,
00540 pp->pt_inhit->hit_dist );
00541 bu_log( "newpp = x%x, pp = x%x\n", newpp, pp );
00542 }
00543 goto done_weave;
00544 }
00545
00546 } else {
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556 GET_PT_INIT( rtip, newpp, res );
00557 bu_ptbl_ins_unique( &newpp->pt_seglist, (long *)segp );
00558 newpp->pt_inseg = lastseg;
00559 newpp->pt_inhit = lasthit;
00560 newpp->pt_inflip = lastflip;
00561 diff = segp->seg_out.hit_dist - pp->pt_inhit->hit_dist;
00562 if( diff < -(tol_dist) ) {
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572 newpp->pt_outseg = segp;
00573 newpp->pt_outhit = &segp->seg_out;
00574 newpp->pt_outflip = 0;
00575 INSERT_PT( newpp, pp );
00576 if(RT_G_DEBUG&DEBUG_PARTITION) bu_log("seg between 2 partitions\n");
00577 goto done_weave;
00578 }
00579 if( diff < tol_dist ) {
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593 newpp->pt_outseg = segp;
00594 newpp->pt_outhit = &segp->seg_out;
00595 newpp->pt_outhit->hit_dist = pp->pt_inhit->hit_dist;
00596 newpp->pt_outflip = 0;
00597 INSERT_PT( newpp, pp );
00598 if(RT_G_DEBUG&DEBUG_PARTITION) bu_log("seg ends at partition start, fuse\n");
00599 goto done_weave;
00600 }
00601
00602
00603
00604
00605
00606
00607
00608
00609 newpp->pt_outseg = pp->pt_inseg;
00610 newpp->pt_outhit = pp->pt_inhit;
00611 newpp->pt_outflip = 1;
00612 lastseg = pp->pt_inseg;
00613 lasthit = pp->pt_inhit;
00614 lastflip = newpp->pt_outflip;
00615 INSERT_PT( newpp, pp );
00616 if(RT_G_DEBUG&DEBUG_PARTITION) bu_log("insert seg before p start, ends after p ends. Making new partition for initial portion.\n");
00617 goto equal_start;
00618 }
00619
00620 }
00621
00622
00623
00624
00625
00626
00627
00628 if(RT_G_DEBUG&DEBUG_PARTITION) bu_log("seg extends beyond partition end\n");
00629 GET_PT_INIT( rtip, newpp, res );
00630 bu_ptbl_ins_unique( &newpp->pt_seglist, (long *)segp );
00631 newpp->pt_inseg = lastseg;
00632 newpp->pt_inhit = lasthit;
00633 newpp->pt_inflip = lastflip;
00634 newpp->pt_outseg = segp;
00635 newpp->pt_outhit = &segp->seg_out;
00636 APPEND_PT( newpp, PartHdp->pt_back );
00637
00638 done_weave: ;
00639 if(RT_G_DEBUG&DEBUG_PARTITION)
00640 rt_pr_partitions( rtip, PartHdp, "After weave" );
00641 }
00642 if(RT_G_DEBUG&DEBUG_PARTITION)
00643 bu_log( "--------------------Leaving Booleweave\n" );
00644 }
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656 HIDDEN int
00657 _rt_defoverlap(register struct application *ap, register struct partition *pp, struct region *reg1, struct region *reg2, struct partition *pheadp, register int verbose)
00658 {
00659 RT_CK_AP(ap);
00660 RT_CK_PT(pp);
00661 RT_CK_REGION(reg1);
00662 RT_CK_REGION(reg2);
00663
00664
00665
00666
00667 if( reg1->reg_aircode != 0 ) {
00668
00669 return 2;
00670 }
00671 if( pp->pt_back != pheadp ) {
00672
00673 if( pp->pt_back->pt_regionp == reg1 )
00674 return 1;
00675 if( pp->pt_back->pt_regionp == reg2 )
00676 return 2;
00677 }
00678
00679
00680 if( reg1->reg_bit < reg2->reg_bit )
00681 return 1;
00682 return 2;
00683 }
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696 int
00697 rt_defoverlap (register struct application *ap, register struct partition *pp, struct region *reg1, struct region *reg2, struct partition *pheadp)
00698 {
00699 return (_rt_defoverlap(ap, pp, reg1, reg2, pheadp, 1));
00700 }
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712 int
00713 rt_overlap_quietly (register struct application *ap, register struct partition *pp, struct region *reg1, struct region *reg2, struct partition *pheadp)
00714 {
00715 return (_rt_defoverlap(ap, pp, reg1, reg2, pheadp, 0));
00716 }
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730 void
00731 rt_get_region_seglist_for_partition(struct bu_ptbl *sl, const struct partition *pp, const struct region *regp)
00732 {
00733 const struct seg **segpp;
00734
00735 bu_ptbl_init( sl, 8, "region seglist for partition" );
00736
00737
00738 for( BU_PTBL_FOR( segpp, (const struct seg **), &pp->pt_seglist ) ) {
00739 const struct region **srpp;
00740
00741 RT_CK_SEG(*segpp);
00742
00743 for( BU_PTBL_FOR( srpp, (const struct region **), &(*segpp)->seg_stp->st_regions ) ) {
00744 RT_CK_REGION(*srpp);
00745
00746 if( *srpp != regp ) continue;
00747
00748 bu_ptbl_ins_unique( sl, (long *)(*segpp) );
00749 }
00750 }
00751
00752 if( BU_PTBL_LEN(sl) <= 0 ) bu_bomb("rt_get_region_seglist_for_partition() didn't find any segments\n");
00753 }
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765 void
00766 rt_fastgen_vol_vol_overlap(struct region **fr1, struct region **fr2, const struct partition *pp)
00767 {
00768 struct bu_ptbl sl1, sl2;
00769 const struct seg *s1 = (const struct seg *)NULL;
00770 const struct seg *s2 = (const struct seg *)NULL;
00771 fastf_t s1_in_dist;
00772 fastf_t s2_in_dist;
00773 fastf_t depth;
00774 struct seg **segpp;
00775
00776 RT_CK_REGION(*fr1);
00777 RT_CK_REGION(*fr2);
00778
00779 if(RT_G_DEBUG&DEBUG_PARTITION) bu_log("Resolving FASTGEN volume/volume overlap: %s %s\n", (*fr1)->reg_name, (*fr2)->reg_name);
00780
00781 rt_get_region_seglist_for_partition( &sl1, pp, *fr1 );
00782 rt_get_region_seglist_for_partition( &sl2, pp, *fr2 );
00783
00784 s1_in_dist = MAX_FASTF;
00785 s2_in_dist = MAX_FASTF;
00786 for( BU_PTBL_FOR( segpp, (struct seg **), &sl1 ) )
00787 {
00788 if( (*segpp)->seg_in.hit_dist < s1_in_dist )
00789 {
00790 s1 = (*segpp);
00791 s1_in_dist = s1->seg_in.hit_dist;
00792 }
00793 }
00794 for( BU_PTBL_FOR( segpp, (struct seg **), &sl2 ) )
00795 {
00796 if( (*segpp)->seg_in.hit_dist < s2_in_dist )
00797 {
00798 s2 = (*segpp);
00799 s2_in_dist = s2->seg_in.hit_dist;
00800 }
00801 }
00802 RT_CK_SEG(s1);
00803 RT_CK_SEG(s2);
00804
00805 depth = pp->pt_outhit->hit_dist - pp->pt_inhit->hit_dist;
00806
00807
00808 if( depth < 6.35 ) {
00809
00810 if( s1->seg_in.hit_dist < s2->seg_in.hit_dist ) {
00811
00812 *fr2 = REGION_NULL;
00813 } else {
00814
00815 *fr1 = REGION_NULL;
00816 }
00817 } else {
00818
00819
00820
00821 if( s1->seg_in.hit_dist >= s2->seg_in.hit_dist ) {
00822
00823 *fr2 = REGION_NULL;
00824 } else {
00825 *fr1 = REGION_NULL;
00826 }
00827 }
00828
00829 bu_ptbl_free( &sl1 );
00830 bu_ptbl_free( &sl2 );
00831 }
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847 void
00848 rt_fastgen_plate_vol_overlap(struct region **fr1, struct region **fr2, struct partition *pp, struct application *ap)
00849 {
00850 struct partition *prev;
00851 fastf_t depth;
00852
00853 RT_CK_REGION(*fr1);
00854 RT_CK_REGION(*fr2);
00855 RT_CK_PT(pp);
00856 RT_CK_AP(ap);
00857
00858 if(RT_G_DEBUG&DEBUG_PARTITION) bu_log("Resolving FASTGEN plate/volume overlap: %s %s\n", (*fr1)->reg_name, (*fr2)->reg_name);
00859
00860 prev = pp->pt_back;
00861 if( prev->pt_magic == PT_HD_MAGIC ) {
00862
00863 *fr2 = REGION_NULL;
00864 return;
00865 }
00866
00867 if( rt_fdiff(prev->pt_outhit->hit_dist, pp->pt_inhit->hit_dist) != 0 ) {
00868
00869
00870 *fr2 = REGION_NULL;
00871 return;
00872 }
00873
00874 if( prev->pt_regionp == *fr2 ) {
00875
00876 depth = prev->pt_outhit->hit_dist - prev->pt_inhit->hit_dist;
00877
00878 if( depth < 6.35 ) {
00879
00880 DEQUEUE_PT(prev);
00881 FREE_PT(prev, ap->a_resource);
00882
00883
00884 *fr2 = REGION_NULL;
00885 } else {
00886
00887
00888 *fr2 = REGION_NULL;
00889 }
00890 } else if( prev->pt_regionp == *fr1 ) {
00891
00892
00893
00894 *fr2 = REGION_NULL;
00895 } else {
00896
00897
00898 *fr2 = REGION_NULL;
00899 }
00900 }
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927 void
00928 rt_default_multioverlap(struct application *ap, struct partition *pp, struct bu_ptbl *regiontable, struct partition *InputHdp)
00929 {
00930 LOCAL struct region *lastregion = (struct region *)NULL;
00931 int n_regions;
00932 int n_fastgen = 0;
00933 int code;
00934 int i;
00935
00936 RT_CK_AP(ap);
00937 RT_CK_PARTITION(pp);
00938 BU_CK_PTBL(regiontable);
00939 RT_CK_PT_HD(InputHdp);
00940
00941 if( ap->a_overlap == RT_AFN_NULL )
00942 ap->a_overlap = rt_defoverlap;
00943
00944
00945 n_regions = BU_PTBL_LEN(regiontable);
00946 for( i = n_regions-1; i >= 0; i-- ) {
00947 struct region *regp = (struct region *)BU_PTBL_GET(regiontable, i);
00948 RT_CK_REGION(regp);
00949 if( regp->reg_is_fastgen != REGION_NON_FASTGEN ) n_fastgen++;
00950 }
00951
00952
00953
00954
00955
00956 if( n_fastgen >= 2 ) {
00957 struct region **fr1;
00958 struct region **fr2;
00959
00960 if(RT_G_DEBUG&DEBUG_PARTITION) {
00961 bu_log("I see %d FASTGEN overlaps in this partition\n", n_fastgen);
00962 for( BU_PTBL_FOR( fr1, (struct region **), regiontable ) ) {
00963 if( *fr1 == REGION_NULL ) continue;
00964 rt_pr_region(*fr1);
00965 }
00966 }
00967
00968
00969
00970
00971
00972
00973 for( BU_PTBL_FOR( fr1, (struct region **), regiontable ) ) {
00974 if( *fr1 == REGION_NULL ) continue;
00975 RT_CK_REGION(*fr1);
00976 if( (*fr1)->reg_is_fastgen != REGION_FASTGEN_VOLUME )
00977 continue;
00978 for( fr2 = fr1-1; fr2 >= (struct region **)BU_PTBL_BASEADDR(regiontable); fr2-- ) {
00979 if( *fr2 == REGION_NULL ) continue;
00980 RT_CK_REGION(*fr2);
00981 if( (*fr2)->reg_is_fastgen != REGION_FASTGEN_VOLUME )
00982 continue;
00983 rt_fastgen_vol_vol_overlap( fr1, fr2, pp );
00984 if( *fr1 == REGION_NULL ) break;
00985 }
00986 }
00987
00988
00989 for( BU_PTBL_FOR( fr1, (struct region **), regiontable ) ) {
00990 if( *fr1 == REGION_NULL ) continue;
00991 RT_CK_REGION(*fr1);
00992 if( (*fr1)->reg_is_fastgen != REGION_FASTGEN_PLATE )
00993 continue;
00994 for( BU_PTBL_FOR( fr2, (struct region **), regiontable ) ) {
00995 if( *fr2 == REGION_NULL ) continue;
00996 RT_CK_REGION(*fr2);
00997 if( (*fr2)->reg_is_fastgen != REGION_FASTGEN_VOLUME )
00998 continue;
00999 rt_fastgen_plate_vol_overlap( fr1, fr2, pp, ap );
01000 if( *fr1 == REGION_NULL ) break;
01001 }
01002 }
01003
01004
01005
01006 n_fastgen = 0;
01007 for( i = n_regions-1; i >= 0; i-- ) {
01008 struct region *regp = (struct region *)BU_PTBL_GET(regiontable, i);
01009 if( regp == REGION_NULL ) continue;
01010 RT_CK_REGION(regp);
01011 if( regp->reg_is_fastgen != REGION_NON_FASTGEN ) n_fastgen++;
01012 }
01013
01014
01015 bu_ptbl_rm( regiontable, (long *)NULL );
01016 }
01017
01018 lastregion = (struct region *)BU_PTBL_GET(regiontable, 0);
01019 RT_CK_REGION(lastregion);
01020
01021 if( BU_PTBL_LEN(regiontable) > 1 && ap->a_rt_i->rti_save_overlaps != 0 ) {
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032 pp->pt_overlap_reg = (struct region **)bu_calloc(
01033 BU_PTBL_LEN(regiontable)+1, sizeof(struct region *),
01034 "pt_overlap_reg" );
01035 bcopy( (char *)BU_PTBL_BASEADDR(regiontable),
01036 (char *)pp->pt_overlap_reg,
01037 BU_PTBL_LEN(regiontable) * sizeof(struct region *) );
01038 }
01039
01040
01041 for( i=1; i < BU_PTBL_LEN(regiontable); i++ ) {
01042 struct region *regp = (struct region *)BU_PTBL_GET(regiontable, i);
01043 if( regp == REGION_NULL ) continue;
01044 RT_CK_REGION(regp);
01045
01046 code = -1;
01047
01048
01049
01050
01051 if( lastregion->reg_aircode != 0 && regp->reg_aircode == 0 ) {
01052
01053 goto code2;
01054 } else if( lastregion->reg_aircode == 0 && regp->reg_aircode != 0 ) {
01055
01056 goto code1;
01057 } else if( lastregion->reg_aircode != 0 &&
01058 regp->reg_aircode != 0 &&
01059 regp->reg_aircode == lastregion->reg_aircode ) {
01060
01061 goto code1;
01062 }
01063
01064
01065
01066
01067
01068
01069
01070 if( lastregion->reg_is_fastgen != regp->reg_is_fastgen ) {
01071 if( lastregion->reg_is_fastgen )
01072 goto code2;
01073 if( regp->reg_is_fastgen )
01074 goto code1;
01075 }
01076
01077
01078
01079
01080
01081
01082 {
01083 int r1 = rt_tree_max_raynum( lastregion->reg_treetop, pp );
01084 int r2 = rt_tree_max_raynum( regp->reg_treetop, pp );
01085
01086 if( r1 > 0 || r2 > 0 ) {
01087
01088 bu_log("Potential overlay along ray bundle: r1=%d, r2=%d, resolved to %s\n", r1, r2,
01089 (r1<r2)?lastregion->reg_name:regp->reg_name);
01090 if( r1 < r2 )
01091 goto code1;
01092 goto code2;
01093 }
01094 }
01095
01096
01097
01098
01099
01100
01101
01102
01103 code = ap->a_overlap(ap, pp, lastregion, regp, InputHdp);
01104
01105
01106 if( code == 0 ) {
01107
01108
01109
01110 if(RT_G_DEBUG&DEBUG_PARTITION) bu_log("rt_default_multioverlap: overlap code=0, partition=x%x deleted\n", pp);
01111 bu_ptbl_reset(regiontable);
01112 return;
01113 } else if( code == 1 ) {
01114 code1:
01115
01116 if(RT_G_DEBUG&DEBUG_PARTITION) bu_log("rt_default_multioverlap: overlap policy=1, code=%d, p retained in region=%s\n",
01117 code, lastregion->reg_name );
01118 BU_PTBL_CLEAR_I(regiontable, i);
01119 } else {
01120 code2:
01121
01122 bu_ptbl_zero(regiontable, (long *)lastregion);
01123 lastregion = regp;
01124 if(RT_G_DEBUG&DEBUG_PARTITION) bu_log("rt_default_multioverlap: overlap policy!=(0,1) code=%d, p retained in region=%s\n",
01125 code, lastregion->reg_name );
01126 }
01127 }
01128 }
01129
01130
01131
01132
01133
01134
01135
01136 void
01137 rt_silent_logoverlap(struct application *ap, const struct partition *pp, const struct bu_ptbl *regiontable, const struct partition *InputHdp)
01138 {
01139 RT_CK_AP(ap);
01140 RT_CK_PT(pp);
01141 BU_CK_PTBL(regiontable);
01142 return;
01143 }
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154 void
01155 rt_default_logoverlap(struct application *ap, const struct partition *pp, const struct bu_ptbl *regiontable, const struct partition *InputHdp)
01156 {
01157 point_t pt;
01158 static long count = 0;
01159 register fastf_t depth;
01160 int i;
01161 struct bu_vls str;
01162
01163 RT_CK_AP(ap);
01164 RT_CK_PT(pp);
01165 BU_CK_PTBL(regiontable);
01166
01167
01168 if( ++count > 100 ) {
01169 if( (count%100) != 3 ) return;
01170 bu_log("(overlaps omitted)\n");
01171 }
01172
01173
01174
01175
01176
01177 bu_vls_init(&str);
01178 bu_vls_extend(&str, 80*8 );
01179 bu_vls_putc(&str, '\n' );
01180
01181
01182 for( i=0; i < BU_PTBL_LEN(regiontable); i++ ) {
01183 struct region *regp = (struct region *)BU_PTBL_GET(regiontable, i);
01184
01185 if( regp == REGION_NULL ) continue;
01186 RT_CK_REGION(regp);
01187
01188 bu_vls_printf(&str, "OVERLAP%d: %s\n", i+1, regp->reg_name);
01189 }
01190
01191
01192 bu_vls_printf(&str, "OVERLAPa: dist=(%g,%g) isol=%s osol=%s\n",
01193 pp->pt_inhit->hit_dist, pp->pt_outhit->hit_dist,
01194 pp->pt_inseg->seg_stp->st_name,
01195 pp->pt_outseg->seg_stp->st_name);
01196
01197 depth = pp->pt_outhit->hit_dist - pp->pt_inhit->hit_dist;
01198 VJOIN1( pt, ap->a_ray.r_pt, pp->pt_inhit->hit_dist,
01199 ap->a_ray.r_dir );
01200
01201 bu_vls_printf(&str, "OVERLAPb: depth %.5fmm at (%g, %g, %g) x%d y%d lvl%d\n",
01202 depth, pt[X], pt[Y], pt[Z],
01203 ap->a_x, ap->a_y, ap->a_level );
01204
01205 bu_log("%s", bu_vls_addr(&str));
01206 bu_vls_free(&str);
01207
01208 #if 0
01209 rt_pr_partitions( ap->a_rt_i, pheadp, "Entire ray containing overlap");
01210 #endif
01211
01212 }
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224 int
01225 rt_overlap_tables_equal( struct region *const*a, struct region *const*b )
01226 {
01227 int alen=0, blen=0;
01228 register struct region *const*app;
01229 register struct region *const*bpp;
01230
01231 if( a == NULL && b == NULL )
01232 return 1;
01233
01234 if( a == NULL || b == NULL )
01235 return 0;
01236
01237
01238 for( app = a; *app != NULL; app++ ) alen++;
01239 for( bpp = b; *bpp != NULL; bpp++ ) blen++;
01240 if( alen != blen ) return 0;
01241
01242
01243 for( app = a; *app != NULL; app++ ) {
01244 register const struct region *t = *app;
01245 for( bpp = b; *bpp != NULL; bpp++ ) {
01246 if( *bpp == t ) goto b_ok;
01247 }
01248
01249 return 0;
01250 b_ok: ;
01251 }
01252
01253 return 1;
01254 }
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323 int
01324 rt_boolfinal(struct partition *InputHdp, struct partition *FinalHdp, fastf_t startdist, fastf_t enddist, struct bu_ptbl *regiontable, struct application *ap, const struct bu_bitv *solidbits)
01325 {
01326 LOCAL struct region *lastregion = (struct region *)NULL;
01327 LOCAL struct region *TrueRg[2];
01328 register struct partition *pp;
01329 register int claiming_regions;
01330 int hits_avail = 0;
01331 int hits_needed;
01332 int ret = 0;
01333 int indefinite_outpt = 0;
01334 char *reason = (char *)NULL;
01335 fastf_t diff;
01336
01337 #define HITS_TODO (hits_needed - hits_avail)
01338
01339 RT_CK_PT_HD(InputHdp);
01340 RT_CK_PT_HD(FinalHdp);
01341 BU_CK_PTBL(regiontable);
01342 RT_CK_RTI(ap->a_rt_i);
01343 BU_CK_BITV(solidbits);
01344
01345 if(RT_G_DEBUG&DEBUG_PARTITION) {
01346 bu_log("\nrt_boolfinal(%g,%g) x%d y%d lvl%d START\n",
01347 startdist, enddist,
01348 ap->a_x, ap->a_y, ap->a_level );
01349 }
01350
01351 if( !ap->a_multioverlap )
01352 ap->a_multioverlap = rt_default_multioverlap;
01353
01354 if( !ap->a_logoverlap )
01355 ap->a_logoverlap = rt_default_logoverlap;
01356
01357 if( enddist <= 0 ) {
01358 reason = "not done, behind start point";
01359 ret = 0;
01360 goto out;
01361 }
01362
01363 if( ap->a_onehit < 0 )
01364 hits_needed = -ap->a_onehit;
01365 else
01366 hits_needed = ap->a_onehit;
01367
01368 if( ap->a_onehit != 0 ) {
01369 register struct partition *npp = FinalHdp->pt_forw;
01370
01371 for(; npp != FinalHdp; npp = npp->pt_forw ) {
01372 if( npp->pt_inhit->hit_dist < 0.0 )
01373 continue;
01374 if( ap->a_onehit < 0 && npp->pt_regionp->reg_aircode != 0 )
01375 continue;
01376 hits_avail += 2;
01377 }
01378 if( hits_avail >= hits_needed ) {
01379 reason = "a_onehit request satisfied at outset";
01380 ret = 1;
01381 goto out;
01382 }
01383 }
01384
01385 if( ap->a_no_booleans ) {
01386 while( (pp = InputHdp->pt_forw) != InputHdp ) {
01387 RT_CK_PT(pp);
01388 DEQUEUE_PT(pp);
01389 pp->pt_regionp = (struct region *)
01390 BU_PTBL_GET(&pp->pt_inseg->seg_stp->st_regions, 0);
01391 RT_CK_REGION(pp->pt_regionp);
01392 if(RT_G_DEBUG&DEBUG_PARTITION) {
01393 rt_pr_pt( ap->a_rt_i, pp );
01394 }
01395 INSERT_PT( pp, FinalHdp );
01396 }
01397 ret = 0;
01398 reason = "No a_onehit processing in a_no_booleans mode";
01399 goto out;
01400 }
01401
01402 pp = InputHdp->pt_forw;
01403 while( pp != InputHdp ) {
01404 RT_CK_PT(pp);
01405 claiming_regions = 0;
01406 if(RT_G_DEBUG&DEBUG_PARTITION) {
01407 bu_log("\nrt_boolfinal(%g,%g) x%d y%d lvl%d, next input pp\n",
01408 startdist, enddist,
01409 ap->a_x, ap->a_y, ap->a_level );
01410 rt_pr_pt( ap->a_rt_i, pp );
01411 }
01412 RT_CHECK_SEG(pp->pt_inseg);
01413 RT_CHECK_SEG(pp->pt_outseg);
01414
01415
01416 diff = pp->pt_inhit->hit_dist - pp->pt_outhit->hit_dist;
01417 if( NEAR_ZERO( diff, ap->a_rt_i->rti_tol.dist ) ) {
01418 if(RT_G_DEBUG&DEBUG_PARTITION) bu_log(
01419 "rt_boolfinal: Zero thickness partition, prims %s %s (%.18e,%.18e) x%d y%d lvl%d\n",
01420 pp->pt_inseg->seg_stp->st_name,
01421 pp->pt_outseg->seg_stp->st_name,
01422 pp->pt_inhit->hit_dist,
01423 pp->pt_outhit->hit_dist,
01424 ap->a_x, ap->a_y, ap->a_level );
01425 pp->pt_outhit->hit_dist = pp->pt_inhit->hit_dist;
01426 }
01427
01428
01429
01430 if( pp->pt_inhit->hit_dist > pp->pt_outhit->hit_dist ) {
01431 bu_log("rt_boolfinal: inverted partition %.8x x%d y%d lvl%d\n",
01432 pp,
01433 ap->a_x, ap->a_y, ap->a_level );
01434 rt_pr_partitions( ap->a_rt_i, InputHdp, "With problem" );
01435 }
01436 if( pp->pt_forw != InputHdp &&
01437 pp->pt_outhit->hit_dist != pp->pt_forw->pt_inhit->hit_dist ) {
01438 diff = pp->pt_outhit->hit_dist - pp->pt_forw->pt_inhit->hit_dist;
01439 if( NEAR_ZERO( diff, ap->a_rt_i->rti_tol.dist ) ) {
01440 if(RT_G_DEBUG&DEBUG_PARTITION) bu_log("rt_boolfinal: fusing 2 partitions x%x x%x\n",
01441 pp, pp->pt_forw );
01442 pp->pt_forw->pt_inhit->hit_dist = pp->pt_outhit->hit_dist;
01443 } else if( diff > 0 ) {
01444 bu_log("rt_boolfinal: sorting defect %e > %e! x%d y%d lvl%d, diff = %g\n",
01445 pp->pt_outhit->hit_dist,
01446 pp->pt_forw->pt_inhit->hit_dist,
01447 ap->a_x, ap->a_y, ap->a_level, diff );
01448 bu_log( "sort defect is between parts x%x and x%x\n",
01449 pp, pp->pt_forw );
01450 if( !(RT_G_DEBUG & DEBUG_PARTITION) )
01451 rt_pr_partitions( ap->a_rt_i, InputHdp, "With DEFECT" );
01452 ret = 0;
01453 reason = "ERROR, sorting defect, give up";
01454 goto out;
01455 }
01456 }
01457
01458
01459
01460
01461
01462
01463
01464 if( pp->pt_outhit->hit_dist <= 0.001 ) {
01465 register struct partition *zap_pp;
01466 if(RT_G_DEBUG&DEBUG_PARTITION)bu_log(
01467 "discarding partition x%x behind ray start, out dist=%g\n",
01468 pp, pp->pt_outhit->hit_dist);
01469 zap_pp = pp;
01470 pp = pp->pt_forw;
01471 DEQUEUE_PT(zap_pp);
01472 FREE_PT(zap_pp, ap->a_resource);
01473 continue;
01474 }
01475
01476
01477
01478
01479
01480
01481
01482 diff = pp->pt_inhit->hit_dist - enddist;
01483 if( diff > ap->a_rt_i->rti_tol.dist ) {
01484 if(RT_G_DEBUG&DEBUG_PARTITION)bu_log(
01485 "partition begins %g beyond current box end, returning\n", diff);
01486 reason = "partition begins beyond current box end";
01487 ret = 0;
01488 goto out;
01489 }
01490
01491
01492
01493
01494
01495
01496
01497
01498 diff = pp->pt_outhit->hit_dist - enddist;
01499 if( diff > ap->a_rt_i->rti_tol.dist ) {
01500 if(RT_G_DEBUG&DEBUG_PARTITION)bu_log(
01501 "partition ends beyond current box end\n");
01502 if( ap->a_onehit != 1 ) {
01503 ret = 0;
01504 reason = "a_onehit != 1, trace remaining boxes";
01505 goto out;
01506 }
01507
01508 indefinite_outpt = 1;
01509 } else {
01510 indefinite_outpt = 0;
01511 }
01512
01513
01514
01515
01516 bu_ptbl_reset(regiontable);
01517
01518
01519
01520
01521
01522
01523 {
01524 struct seg **segpp;
01525
01526 if(RT_G_DEBUG&DEBUG_PARTITION)
01527 bu_log( "Building region table:\n" );
01528 for( BU_PTBL_FOR(segpp, (struct seg **), &pp->pt_seglist) ) {
01529 struct soltab *stp = (*segpp)->seg_stp;
01530 RT_CK_SOLTAB(stp);
01531 bu_ptbl_cat_uniq( regiontable, &stp->st_regions );
01532 }
01533 }
01534
01535 if(RT_G_DEBUG&DEBUG_PARTITION) {
01536 struct region **regpp;
01537 bu_log("Region table for this partition:\n");
01538 for( BU_PTBL_FOR( regpp, (struct region **), regiontable ) ) {
01539 register struct region *regp;
01540
01541 regp = *regpp;
01542 RT_CK_REGION(regp);
01543 bu_log("%9lx %s\n", (long)regp, regp->reg_name);
01544 }
01545 }
01546
01547 if( indefinite_outpt ) {
01548 if(RT_G_DEBUG&DEBUG_PARTITION)bu_log(
01549 "indefinite out point, checking partition eligibility for early evaluation.\n");
01550
01551
01552
01553
01554
01555
01556 if( !rt_bool_partition_eligible(regiontable, solidbits, pp) ) {
01557 ret = 0;
01558 reason = "Partition not yet eligible for evaluation";
01559 goto out;
01560 }
01561 if(RT_G_DEBUG&DEBUG_PARTITION)bu_log(
01562 "Partition is eligibile for evaluation.\n");
01563 }
01564
01565
01566 {
01567 struct region **regpp;
01568 for( BU_PTBL_FOR( regpp, (struct region **), regiontable ) ) {
01569 register struct region *regp;
01570
01571 regp = *regpp;
01572 RT_CK_REGION(regp);
01573 if(RT_G_DEBUG&DEBUG_PARTITION) {
01574 rt_pr_tree_val( regp->reg_treetop, pp, 2, 0 );
01575 rt_pr_tree_val( regp->reg_treetop, pp, 1, 0 );
01576 rt_pr_tree_val( regp->reg_treetop, pp, 0, 0 );
01577 bu_log("%.8x=bit%d, %s: ",
01578 regp, regp->reg_bit,
01579 regp->reg_name );
01580 }
01581 if( regp->reg_all_unions ) {
01582 if(RT_G_DEBUG&DEBUG_PARTITION) bu_log("TRUE (all union)\n");
01583 claiming_regions++;
01584 lastregion = regp;
01585 continue;
01586 }
01587 if( rt_booleval( regp->reg_treetop, pp, TrueRg,
01588 ap->a_resource ) == FALSE ) {
01589 if(RT_G_DEBUG&DEBUG_PARTITION) bu_log("FALSE\n");
01590
01591 *regpp = REGION_NULL;
01592 continue;
01593 }
01594
01595 if(RT_G_DEBUG&DEBUG_PARTITION) bu_log("TRUE (eval)\n");
01596 claiming_regions++;
01597 lastregion = regp;
01598 }
01599 }
01600 if(RT_G_DEBUG&DEBUG_PARTITION) bu_log("rt_boolfinal: claiming_regions=%d (%g <-> %g)\n",
01601 claiming_regions, pp->pt_inhit->hit_dist, pp->pt_outhit->hit_dist);
01602 if( claiming_regions == 0 ) {
01603 if(RT_G_DEBUG&DEBUG_PARTITION)bu_log("rt_boolfinal moving past partition x%x\n", pp);
01604 pp = pp->pt_forw;
01605 continue;
01606 }
01607
01608 if( claiming_regions > 1 ) {
01609
01610
01611
01612
01613 if(RT_G_DEBUG&DEBUG_PARTITION)
01614 bu_log("rt_boolfinal: invoking a_multioverlap() pp=x%x\n", pp);
01615 bu_ptbl_rm( regiontable, (long *)NULL );
01616 ap->a_logoverlap( ap, pp, regiontable, InputHdp );
01617 ap->a_multioverlap( ap, pp, regiontable, InputHdp );
01618
01619
01620 claiming_regions = 0;
01621 {
01622 register struct region **regpp;
01623 for( BU_PTBL_FOR( regpp, (struct region **), regiontable ) ) {
01624 if( *regpp != REGION_NULL ) {
01625 claiming_regions++;
01626 lastregion = *regpp;
01627 }
01628 }
01629 }
01630
01631
01632
01633
01634
01635
01636 if( claiming_regions > 1) {
01637 bu_log("rt_boolfinal() a_multioverlap() failed to resolve overlap, discarding bad partition:\n");
01638 rt_pr_pt( ap->a_rt_i, pp );
01639 }
01640
01641 if( claiming_regions != 1 ) {
01642 register struct partition *zap_pp;
01643
01644 if(RT_G_DEBUG&DEBUG_PARTITION)bu_log("rt_boolfinal discarding overlap partition x%x\n", pp);
01645 zap_pp = pp;
01646 pp = pp->pt_forw;
01647 DEQUEUE_PT( zap_pp );
01648 FREE_PT( zap_pp, ap->a_resource );
01649 continue;
01650 }
01651 }
01652
01653
01654
01655
01656
01657
01658
01659 {
01660 register struct partition *newpp;
01661 register struct partition *lastpp;
01662 if(RT_G_DEBUG&DEBUG_PARTITION )
01663 bu_log( "Appending partition to result queue: %g, %g\n",
01664 pp->pt_inhit->hit_dist, pp->pt_outhit->hit_dist );
01665 newpp = pp;
01666 pp=pp->pt_forw;
01667 DEQUEUE_PT( newpp );
01668 RT_CHECK_SEG(newpp->pt_inseg);
01669 RT_CHECK_SEG(newpp->pt_outseg);
01670
01671 newpp->pt_regionp = lastregion;
01672
01673
01674
01675
01676 lastpp = FinalHdp->pt_back;
01677 if( lastpp != FinalHdp &&
01678 lastregion == lastpp->pt_regionp &&
01679 NEAR_ZERO( newpp->pt_inhit->hit_dist -
01680 lastpp->pt_outhit->hit_dist,
01681 ap->a_rt_i->rti_tol.dist ) &&
01682 ( ap->a_rt_i->rti_save_overlaps == 0 ||
01683 rt_overlap_tables_equal(
01684 lastpp->pt_overlap_reg,
01685 newpp->pt_overlap_reg ) )
01686 ) {
01687
01688 if(RT_G_DEBUG&DEBUG_PARTITION)bu_log("rt_boolfinal 'exact match', extending last partition, discarding x%x\n", newpp);
01689 RT_CK_PT(lastpp);
01690 RT_CHECK_SEG(lastpp->pt_inseg);
01691 RT_CHECK_SEG(lastpp->pt_outseg);
01692 if(RT_G_DEBUG&DEBUG_PARTITION)bu_log("rt_boolfinal collapsing %x %x\n", lastpp, newpp);
01693 lastpp->pt_outhit = newpp->pt_outhit;
01694 lastpp->pt_outflip = newpp->pt_outflip;
01695 lastpp->pt_outseg = newpp->pt_outseg;
01696
01697
01698
01699
01700 bu_ptbl_ins_unique( &lastpp->pt_seglist, (long *)newpp->pt_inseg );
01701 bu_ptbl_ins_unique( &lastpp->pt_seglist, (long *)newpp->pt_outseg );
01702
01703 FREE_PT( newpp, ap->a_resource );
01704 newpp = lastpp;
01705 } else {
01706 APPEND_PT( newpp, lastpp );
01707 if( !(ap->a_onehit < 0 && newpp->pt_regionp->reg_aircode != 0) )
01708 hits_avail += 2;
01709 }
01710
01711 RT_CHECK_SEG(newpp->pt_inseg);
01712 RT_CHECK_SEG(newpp->pt_outseg);
01713 }
01714
01715
01716 if( ap->a_onehit != 0 && HITS_TODO <= 0 ) {
01717 ret = 1;
01718 if( pp == InputHdp )
01719 reason = "a_onehit satisfied at bottom";
01720 else
01721 reason = "a_onehit satisfied early";
01722 goto out;
01723 }
01724 }
01725 if( ap->a_onehit != 0 && HITS_TODO <= 0 ) {
01726 ret = 1;
01727 reason = "a_onehit satisfied at end";
01728 } else {
01729 ret = 0;
01730 reason = "more partitions needed";
01731 }
01732 out:
01733 if( RT_G_DEBUG&DEBUG_PARTITION ) {
01734 bu_log("rt_boolfinal() ret=%d, %s\n", ret, reason);
01735 rt_pr_partitions( ap->a_rt_i, FinalHdp, "rt_boolfinal: Final partition list at return:" );
01736 rt_pr_partitions( ap->a_rt_i, InputHdp, "rt_boolfinal: Input/pending partition list at return:" );
01737 bu_log("rt_boolfinal() ret=%d, %s\n", ret, reason);
01738 }
01739 #if 0
01740
01741
01742 if( RT_G_DEBUG && ap->a_onehit == 0 &&
01743 InputHdp->pt_forw != InputHdp && enddist >= INFINITY ) {
01744 bu_log("rt_boolfinal() ret=%d, %s\n", ret, reason);
01745 rt_pr_partitions( ap->a_rt_i, FinalHdp, "rt_boolfinal: Final partition list at return:" );
01746 rt_pr_partitions( ap->a_rt_i, InputHdp, "rt_boolfinal: Input/pending partition list at return:" );
01747 rt_bomb("rt_boolfinal() failed to process InputHdp list\n");
01748 }
01749 #endif
01750 return ret;
01751 }
01752
01753
01754
01755
01756
01757
01758
01759
01760
01761
01762
01763
01764
01765
01766
01767 int
01768 rt_booleval(register union tree *treep, struct partition *partp, struct region **trueregp, struct resource *resp)
01769
01770
01771
01772
01773 {
01774 static union tree tree_not[MAX_PSW];
01775 static union tree tree_guard[MAX_PSW];
01776 static union tree tree_xnop[MAX_PSW];
01777 register union tree **sp;
01778 register int ret;
01779 register union tree **stackend;
01780
01781 RT_CK_TREE(treep);
01782 RT_CK_PT(partp);
01783 RT_CK_RESOURCE(resp);
01784 if( treep->tr_op != OP_XOR )
01785 trueregp[0] = treep->tr_regionp;
01786 else
01787 trueregp[0] = trueregp[1] = REGION_NULL;
01788 while( (sp = resp->re_boolstack) == (union tree **)0 )
01789 rt_grow_boolstack( resp );
01790 stackend = &(resp->re_boolstack[resp->re_boolslen]);
01791 *sp++ = TREE_NULL;
01792 stack:
01793 switch( treep->tr_op ) {
01794 case OP_NOP:
01795 ret = 0;
01796 goto pop;
01797 case OP_SOLID:
01798 {
01799 register struct soltab *seek_stp = treep->tr_a.tu_stp;
01800 register struct seg **segpp;
01801 for( BU_PTBL_FOR( segpp, (struct seg **), &partp->pt_seglist ) ) {
01802 if( (*segpp)->seg_stp == seek_stp ) {
01803 ret = 1;
01804 goto pop;
01805 }
01806 }
01807 ret = 0;
01808 }
01809 goto pop;
01810 case OP_UNION:
01811 case OP_INTERSECT:
01812 case OP_SUBTRACT:
01813 case OP_XOR:
01814 *sp++ = treep;
01815 if( sp >= stackend ) {
01816 register int off = sp - resp->re_boolstack;
01817 rt_grow_boolstack( resp );
01818 sp = &(resp->re_boolstack[off]);
01819 stackend = &(resp->re_boolstack[resp->re_boolslen]);
01820 }
01821 treep = treep->tr_b.tb_left;
01822 goto stack;
01823 default:
01824 bu_log("rt_booleval: bad stack op x%x\n",treep->tr_op);
01825 return(TRUE);
01826 }
01827 pop:
01828 if( (treep = *--sp) == TREE_NULL )
01829 return(ret);
01830
01831
01832
01833
01834
01835
01836 switch( treep->tr_op ) {
01837 case OP_SOLID:
01838 bu_log("rt_booleval: pop SOLID?\n");
01839 return(TRUE);
01840 case OP_UNION:
01841 if( ret ) goto pop;
01842
01843 treep = treep->tr_b.tb_right;
01844 goto stack;
01845 case OP_INTERSECT:
01846 if( !ret ) {
01847 ret = FALSE;
01848 goto pop;
01849 }
01850
01851 treep = treep->tr_b.tb_right;
01852 goto stack;
01853 case OP_SUBTRACT:
01854 if( !ret ) goto pop;
01855
01856
01857 tree_not[resp->re_cpu].tr_op = OP_NOT;
01858 *sp++ = &tree_not[resp->re_cpu];
01859 treep = treep->tr_b.tb_right;
01860 goto stack;
01861 case OP_NOT:
01862
01863 ret = !ret;
01864 goto pop;
01865 case OP_XOR:
01866 if( ret ) {
01867
01868
01869
01870
01871 if( treep->tr_b.tb_left->tr_regionp )
01872 trueregp[0] = treep->tr_b.tb_left->tr_regionp;
01873 tree_guard[resp->re_cpu].tr_op = OP_GUARD;
01874 treep = treep->tr_b.tb_right;
01875 *sp++ = treep;
01876 *sp++ = &tree_guard[resp->re_cpu];
01877 } else {
01878
01879
01880
01881 tree_xnop[resp->re_cpu].tr_op = OP_XNOP;
01882 treep = treep->tr_b.tb_right;
01883 *sp++ = treep;
01884 *sp++ = &tree_xnop[resp->re_cpu];
01885 }
01886 goto stack;
01887 case OP_GUARD:
01888
01889
01890
01891
01892
01893
01894
01895 if( ret ) {
01896
01897 if( sp[-1]->tr_regionp )
01898 trueregp[1] = sp[-1]->tr_regionp;
01899 return(-1);
01900 }
01901 ret = TRUE;
01902 sp--;
01903 goto pop;
01904 case OP_XNOP:
01905
01906
01907
01908
01909 sp--;
01910 if( ret ) {
01911 if( (*sp)->tr_regionp )
01912 trueregp[0] = (*sp)->tr_regionp;
01913 }
01914 goto pop;
01915 default:
01916 bu_log("rt_booleval: bad pop op x%x\n",treep->tr_op);
01917 return(TRUE);
01918 }
01919
01920 }
01921
01922
01923
01924
01925
01926
01927
01928
01929
01930
01931
01932
01933
01934
01935
01936
01937
01938
01939 int
01940 rt_fdiff(double a, double b)
01941 {
01942 FAST double diff;
01943 FAST double d;
01944 register int ret;
01945
01946
01947 d = (a >= 0.0) ? a : -a;
01948 if( b >= 0.0 ) {
01949 if( b > d ) d = b;
01950 } else {
01951 if( (-b) > d ) d = (-b);
01952 }
01953 if( d <= 1.0e-6 ) {
01954 ret = 0;
01955 goto out;
01956 }
01957 if( d >= INFINITY ) {
01958 if( a == b ) {
01959 ret = 0;
01960 goto out;
01961 }
01962 if( a < b ) {
01963 ret = -1;
01964 goto out;
01965 }
01966 ret = 1;
01967 goto out;
01968 }
01969 if( (diff = a - b) < 0.0 ) diff = -diff;
01970 if( diff < 0.001 ) {
01971 ret = 0;
01972 goto out;
01973 }
01974 if( diff < 0.000001 * d ) {
01975 ret = 0;
01976 goto out;
01977 }
01978 if( a < b ) {
01979 ret = -1;
01980 goto out;
01981 }
01982 ret = 1;
01983 out:
01984 if(RT_G_DEBUG&DEBUG_FDIFF) bu_log("rt_fdiff(%.18e,%.18e)=%d\n", a, b, ret);
01985 return(ret);
01986 }
01987
01988
01989
01990
01991
01992
01993
01994
01995
01996
01997 double
01998 rt_reldiff(double a, double b)
01999 {
02000 FAST fastf_t d;
02001 FAST fastf_t diff;
02002
02003
02004 d = (a >= 0.0) ? a : -a;
02005 if( b >= 0.0 ) {
02006 if( b > d ) d = b;
02007 } else {
02008 if( (-b) > d ) d = (-b);
02009 }
02010 if( d==0.0 )
02011 return( 0.0 );
02012 if( (diff = a - b) < 0.0 ) diff = -diff;
02013 return( diff / d );
02014 }
02015
02016
02017
02018
02019
02020
02021
02022
02023
02024 void
02025 rt_grow_boolstack(register struct resource *resp)
02026 {
02027 if( resp->re_boolstack == (union tree **)0 || resp->re_boolslen <= 0 ) {
02028 resp->re_boolslen = 128;
02029 resp->re_boolstack = (union tree **)bu_malloc(
02030 sizeof(union tree *) * resp->re_boolslen,
02031 "initial boolstack");
02032 } else {
02033 resp->re_boolslen <<= 1;
02034 resp->re_boolstack = (union tree **)rt_realloc(
02035 (char *)resp->re_boolstack,
02036 sizeof(union tree *) * resp->re_boolslen,
02037 "extend boolstack" );
02038 }
02039 }
02040
02041
02042
02043
02044
02045
02046 int
02047 rt_partition_len( const struct partition *partheadp )
02048 {
02049 register struct partition *pp;
02050 register long count = 0;
02051
02052 pp = partheadp->pt_forw;
02053 if( pp == PT_NULL )
02054 return(0);
02055 for( ; pp != partheadp; pp = pp->pt_forw ) {
02056 if( pp->pt_magic != 0 ) {
02057
02058 RT_CK_PT(pp);
02059 }
02060 if( ++count > 1000000 ) rt_bomb("partition length > 10000000 elements\n");
02061 }
02062 return( (int)count );
02063 }
02064
02065
02066
02067
02068
02069
02070
02071
02072
02073
02074
02075
02076 int
02077 rt_tree_test_ready(register const union tree *tp, register const struct bu_bitv *solidbits, register const struct region *regionp, register const struct partition *pp)
02078 {
02079 RT_CK_TREE(tp);
02080 BU_CK_BITV(solidbits);
02081 RT_CK_REGION(regionp);
02082 RT_CK_PT(pp);
02083
02084 switch( tp->tr_op ) {
02085 case OP_NOP:
02086 return 1;
02087
02088 case OP_SOLID:
02089 if( BU_BITTEST( solidbits, tp->tr_a.tu_stp->st_bit ) )
02090 return 1;
02091
02092
02093
02094 return 0;
02095
02096 case OP_NOT:
02097 return !rt_tree_test_ready( tp->tr_b.tb_left, solidbits, regionp, pp );
02098
02099 case OP_UNION:
02100 case OP_INTERSECT:
02101 case OP_SUBTRACT:
02102 case OP_XOR:
02103 if( !rt_tree_test_ready( tp->tr_b.tb_left, solidbits, regionp, pp ) )
02104 return 0;
02105 return rt_tree_test_ready( tp->tr_b.tb_right, solidbits, regionp, pp );
02106
02107 default:
02108 rt_bomb("rt_tree_test_ready: bad op\n");
02109 }
02110 return 0;
02111 }
02112
02113
02114
02115
02116
02117
02118
02119
02120
02121
02122
02123
02124 int
02125 rt_bool_partition_eligible(register const struct bu_ptbl *regiontable, register const struct bu_bitv *solidbits, register const struct partition *pp)
02126 {
02127 struct region **regpp;
02128
02129 BU_CK_PTBL(regiontable);
02130 BU_CK_BITV(solidbits);
02131 RT_CK_PT(pp);
02132
02133 for( BU_PTBL_FOR( regpp, (struct region **), regiontable ) ) {
02134 register struct region *regp;
02135
02136 regp = *regpp;
02137 RT_CK_REGION(regp);
02138
02139
02140 if( !rt_tree_test_ready( regp->reg_treetop, solidbits, regp, pp) ) {
02141 return 0;
02142 }
02143 }
02144 return 1;
02145 }
02146
02147
02148
02149
02150
02151
02152
02153
02154
02155
02156
02157
02158 int
02159 rt_tree_max_raynum(register const union tree *tp, register const struct partition *pp)
02160 {
02161 RT_CK_TREE(tp);
02162 RT_CK_PARTITION(pp);
02163
02164 switch( tp->tr_op ) {
02165 case OP_NOP:
02166 return -1;
02167
02168 case OP_SOLID:
02169 {
02170 register struct soltab *seek_stp = tp->tr_a.tu_stp;
02171 register struct seg **segpp;
02172 for( BU_PTBL_FOR( segpp, (struct seg **), &pp->pt_seglist ) ) {
02173 if( (*segpp)->seg_stp != seek_stp ) continue;
02174 return (*segpp)->seg_in.hit_rayp->index;
02175 }
02176 }
02177
02178 return -1;
02179
02180 case OP_NOT:
02181 return rt_tree_max_raynum( tp->tr_b.tb_left, pp );
02182
02183 case OP_UNION:
02184 case OP_INTERSECT:
02185 case OP_SUBTRACT:
02186 case OP_XOR:
02187 {
02188 int a = rt_tree_max_raynum( tp->tr_b.tb_left, pp );
02189 int b = rt_tree_max_raynum( tp->tr_b.tb_right, pp );
02190 if( a > b ) return a;
02191 return b;
02192 }
02193 default:
02194 bu_bomb("rt_tree_max_raynum: bad op\n");
02195 }
02196 return 0;
02197 }
02198
02199
02200
02201
02202
02203 void
02204 rt_rebuild_overlaps(struct partition *PartHdp, struct application *ap, int rebuild_fastgen_plates_only)
02205 {
02206 struct partition *pp, *next, *curr;
02207 struct region *pp_reg;
02208 struct partition *pp_open;
02209 struct bu_ptbl open_parts;
02210 int i, j;
02211
02212
02213
02214 RT_CK_PT_HD(PartHdp);
02215 RT_CK_AP(ap);
02216
02217 bu_ptbl_init( &open_parts, 0, "Open partitions" );
02218
02219 pp = PartHdp->pt_forw;
02220 while( pp != PartHdp )
02221 {
02222 RT_CK_PARTITION(pp);
02223 next = pp->pt_forw;
02224
02225 if( rebuild_fastgen_plates_only && pp->pt_regionp->reg_is_fastgen != REGION_FASTGEN_PLATE )
02226 {
02227 bu_ptbl_trunc( &open_parts, 0 );
02228 pp = next;
02229 continue;
02230 }
02231
02232 for( i=0 ; i<BU_PTBL_END( &open_parts ) ; i++ )
02233 {
02234 int keep_open=0;
02235
02236 if( !pp )
02237 break;
02238
02239 pp_open = (struct partition *)BU_PTBL_GET( &open_parts, i );
02240 if( !pp_open )
02241 continue;
02242 RT_CK_PARTITION(pp_open);
02243
02244 if( pp->pt_overlap_reg )
02245 {
02246 j = -1;
02247 while( (pp_reg = pp->pt_overlap_reg[++j]) )
02248 {
02249 if( pp_reg == (struct region *)(-1) )
02250 continue;
02251 RT_CK_REGION(pp_reg);
02252
02253 if( pp_reg == pp_open->pt_regionp )
02254 {
02255
02256 pp_open->pt_outseg = pp->pt_outseg;
02257 pp_open->pt_outhit = pp->pt_outhit;
02258 pp_open->pt_outflip = pp->pt_outflip;
02259 bu_ptbl_cat_uniq( &pp_open->pt_seglist, &pp->pt_seglist );
02260
02261
02262 pp->pt_overlap_reg[j] = (struct region *)(-1);
02263 if( pp_reg == pp->pt_regionp )
02264 pp->pt_regionp = (struct region *)NULL;
02265
02266
02267 keep_open = 1;
02268 }
02269 }
02270 }
02271 else
02272 {
02273 if( pp->pt_regionp == pp_open->pt_regionp && pp->pt_inhit->hit_dist <= pp_open->pt_outhit->hit_dist )
02274 {
02275
02276 pp_open->pt_outseg = pp->pt_outseg;
02277 pp_open->pt_outhit = pp->pt_outhit;
02278 pp_open->pt_outflip = pp->pt_outflip;
02279 bu_ptbl_cat_uniq( &pp_open->pt_seglist, &pp->pt_seglist );
02280
02281
02282 BU_LIST_DEQUEUE( (struct bu_list *)pp )
02283 pp->pt_overlap_reg = NULL;
02284 #if 0
02285 FREE_PT( pp, ap->a_resource )
02286 #endif
02287 pp = (struct partition *)NULL;
02288
02289
02290 keep_open = 1;
02291 }
02292 }
02293
02294 if( !keep_open )
02295 {
02296 BU_PTBL_CLEAR_I( &open_parts, i );
02297 }
02298 }
02299
02300
02301 if( pp && pp->pt_overlap_reg )
02302 {
02303 int reg_count=0;
02304
02305
02306 j = -1;
02307 while( (pp_reg = pp->pt_overlap_reg[++j]) )
02308 if( pp_reg != (struct region *)(-1) ) {
02309 RT_CK_REGION(pp_reg);
02310 reg_count++;
02311 }
02312
02313 if( !reg_count )
02314 {
02315 BU_LIST_DEQUEUE( (struct bu_list *)pp )
02316 bu_free( (char *)pp->pt_overlap_reg, "overlap list" );
02317 pp->pt_overlap_reg = NULL;
02318 #if 0
02319 FREE_PT( pp, ap->a_resource )
02320 #endif
02321 pp = (struct partition *)NULL;
02322 }
02323 }
02324
02325
02326 if( pp )
02327 {
02328 if( pp->pt_overlap_reg )
02329 {
02330 j = -1;
02331 curr = pp;
02332 while( (pp_reg = pp->pt_overlap_reg[++j]) )
02333 {
02334 struct partition *new_pp;
02335
02336 if( pp_reg == (struct region *)(-1) )
02337 continue;
02338 RT_CK_REGION(pp_reg);
02339
02340 if( rebuild_fastgen_plates_only &&
02341 pp_reg->reg_is_fastgen != REGION_FASTGEN_PLATE )
02342 continue;
02343
02344
02345 if( !pp->pt_regionp || pp->pt_regionp == pp_reg )
02346 {
02347 pp->pt_regionp = pp_reg;
02348 bu_ptbl_ins( &open_parts, (long *)pp );
02349 }
02350 else
02351 {
02352
02353
02354 RT_DUP_PT( ap->a_rt_i, new_pp, pp, ap->a_resource )
02355 new_pp->pt_regionp = pp_reg;
02356 new_pp->pt_overlap_reg = (struct region **)NULL;
02357 BU_LIST_APPEND( (struct bu_list *)curr, (struct bu_list *)new_pp )
02358 bu_ptbl_ins( &open_parts, (long *)new_pp );
02359 curr = new_pp;
02360 }
02361 }
02362 }
02363 else
02364 {
02365 if( rebuild_fastgen_plates_only )
02366 {
02367 if( pp->pt_regionp->reg_is_fastgen == REGION_FASTGEN_PLATE )
02368 {
02369 bu_ptbl_ins( &open_parts, (long *)pp );
02370 }
02371 }
02372 else
02373 {
02374 bu_ptbl_ins( &open_parts, (long *)pp );
02375 }
02376 }
02377 if( pp->pt_overlap_reg )
02378 {
02379 bu_free( (char *)pp->pt_overlap_reg, "overlap list" );
02380 pp->pt_overlap_reg = (struct region **)NULL;
02381 }
02382 }
02383 pp = next;
02384 }
02385
02386 bu_ptbl_free( &open_parts );
02387
02388
02389
02390 }
02391
02392
02393
02394
02395
02396
02397
02398
02399
02400