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 RCSbundle[] = "@(#)$Header: /cvsroot/brlcad/brlcad/src/librt/bundle.c,v 14.11 2006/09/16 02:04:24 lbutler Exp $ (BRL)";
00041 #endif
00042
00043 #include "common.h"
00044
00045
00046
00047 #include <stdio.h>
00048 #include <math.h>
00049 #include "machine.h"
00050 #include "vmath.h"
00051 #include "bu.h"
00052 #include "bn.h"
00053 #include "raytrace.h"
00054 #include "./debug.h"
00055
00056 extern void rt_plot_cell(const union cutter *cutp, struct rt_shootray_status *ssp, struct bu_list *waiting_segs_hd, struct rt_i *rtip);
00057
00058
00059
00060
00061
00062
00063
00064 extern int rt_find_nugrid(struct nugridnode *nugnp, int axis, fastf_t val);
00065
00066
00067
00068
00069
00070 extern const union cutter *rt_advance_to_next_cell(register struct rt_shootray_status *ssp);
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102 int
00103 rt_shootray_bundle(register struct application *ap, struct xray *rays, int nrays)
00104 {
00105 struct rt_shootray_status ss;
00106 struct seg new_segs;
00107 struct seg waiting_segs;
00108 struct seg finished_segs;
00109 fastf_t last_bool_start;
00110 struct bu_bitv *solidbits;
00111 struct bu_ptbl *regionbits;
00112 char *status;
00113 auto struct partition InitialPart;
00114 auto struct partition FinalPart;
00115 struct soltab **stpp;
00116 register const union cutter *cutp;
00117 struct resource *resp;
00118 struct rt_i *rtip;
00119 const int debug_shoot = RT_G_DEBUG & DEBUG_SHOOT;
00120
00121 RT_AP_CHECK(ap);
00122 if( ap->a_magic ) {
00123 RT_CK_AP(ap);
00124 } else {
00125 ap->a_magic = RT_AP_MAGIC;
00126 }
00127 if( ap->a_ray.magic ) {
00128 RT_CK_RAY(&(ap->a_ray));
00129 } else {
00130 ap->a_ray.magic = RT_RAY_MAGIC;
00131 }
00132 if( ap->a_resource == RESOURCE_NULL ) {
00133 ap->a_resource = &rt_uniresource;
00134 rt_uniresource.re_magic = RESOURCE_MAGIC;
00135 if(RT_G_DEBUG)bu_log("rt_shootray_bundle: defaulting a_resource to &rt_uniresource\n");
00136 }
00137 ss.ap = ap;
00138 rtip = ap->a_rt_i;
00139 RT_CK_RTI( rtip );
00140 resp = ap->a_resource;
00141 RT_CK_RESOURCE(resp);
00142 ss.resp = resp;
00143
00144 if(RT_G_DEBUG&(DEBUG_ALLRAYS|DEBUG_SHOOT|DEBUG_PARTITION|DEBUG_ALLHITS)) {
00145 bu_log_indent_delta(2);
00146 bu_log("\n**********shootray_bundle cpu=%d %d,%d lvl=%d (%s)\n",
00147 resp->re_cpu,
00148 ap->a_x, ap->a_y,
00149 ap->a_level,
00150 ap->a_purpose != (char *)0 ? ap->a_purpose : "?" );
00151 bu_log("Pnt (%g, %g, %g) a_onehit=%d\n",
00152 V3ARGS(ap->a_ray.r_pt),
00153 ap->a_onehit );
00154 VPRINT("Dir", ap->a_ray.r_dir);
00155 }
00156 if(RT_BADVEC(ap->a_ray.r_pt)||RT_BADVEC(ap->a_ray.r_dir)) {
00157 bu_log("\n**********shootray cpu=%d %d,%d lvl=%d (%s)\n",
00158 resp->re_cpu,
00159 ap->a_x, ap->a_y,
00160 ap->a_level,
00161 ap->a_purpose != (char *)0 ? ap->a_purpose : "?" );
00162 VPRINT(" r_pt", ap->a_ray.r_pt);
00163 VPRINT("r_dir", ap->a_ray.r_dir);
00164 rt_bomb("rt_shootray_bundle() bad ray\n");
00165 }
00166
00167 if( rtip->needprep )
00168 rt_prep(rtip);
00169
00170 InitialPart.pt_forw = InitialPart.pt_back = &InitialPart;
00171 InitialPart.pt_magic = PT_HD_MAGIC;
00172 FinalPart.pt_forw = FinalPart.pt_back = &FinalPart;
00173 FinalPart.pt_magic = PT_HD_MAGIC;
00174 ap->a_Final_Part_hdp = &FinalPart;
00175
00176 BU_LIST_INIT( &new_segs.l );
00177 BU_LIST_INIT( &waiting_segs.l );
00178 BU_LIST_INIT( &finished_segs.l );
00179 ap->a_finished_segs_hdp = &finished_segs;
00180
00181 if( BU_LIST_UNINITIALIZED( &resp->re_parthead ) ) {
00182
00183 bu_log("rt_shootray_bundle() resp=x%x uninitialized, fixing it\n", resp);
00184
00185
00186
00187
00188
00189
00190
00191 rt_init_resource( resp, resp->re_cpu, rtip );
00192
00193
00194 BU_ASSERT_PTR( BU_PTBL_GET(&rtip->rti_resources, resp->re_cpu), !=, NULL );
00195 }
00196
00197 solidbits = get_solidbitv( rtip->nsolids, resp );
00198 bu_bitv_clear(solidbits);
00199
00200 if( BU_LIST_IS_EMPTY( &resp->re_region_ptbl ) ) {
00201 BU_GETSTRUCT( regionbits, bu_ptbl );
00202 bu_ptbl_init( regionbits, 7, "rt_shootray_bundle() regionbits ptbl" );
00203 } else {
00204 regionbits = BU_LIST_FIRST( bu_ptbl, &resp->re_region_ptbl );
00205 BU_LIST_DEQUEUE( ®ionbits->l );
00206 BU_CK_PTBL(regionbits);
00207 }
00208
00209
00210 if(RT_G_DEBUG) {
00211 FAST fastf_t f, diff;
00212 f = MAGSQ(ap->a_ray.r_dir);
00213 if( NEAR_ZERO(f, 0.0001) ) {
00214 rt_bomb("rt_shootray_bundle: zero length dir vector\n");
00215 return(0);
00216 }
00217 diff = f - 1;
00218 if( !NEAR_ZERO( diff, 0.0001 ) ) {
00219 bu_log("rt_shootray_bundle: non-unit dir vect (x%d y%d lvl%d)\n",
00220 ap->a_x, ap->a_y, ap->a_level );
00221 f = 1/f;
00222 VSCALE( ap->a_ray.r_dir, ap->a_ray.r_dir, f );
00223 }
00224 }
00225
00226
00227 if( ap->a_ray.r_dir[X] < -SQRT_SMALL_FASTF ) {
00228 ss.abs_inv_dir[X] = -(ss.inv_dir[X]=1.0/ap->a_ray.r_dir[X]);
00229 ss.rstep[X] = -1;
00230 } else if( ap->a_ray.r_dir[X] > SQRT_SMALL_FASTF ) {
00231 ss.abs_inv_dir[X] = (ss.inv_dir[X]=1.0/ap->a_ray.r_dir[X]);
00232 ss.rstep[X] = 1;
00233 } else {
00234 ap->a_ray.r_dir[X] = 0.0;
00235 ss.abs_inv_dir[X] = ss.inv_dir[X] = INFINITY;
00236 ss.rstep[X] = 0;
00237 }
00238 if( ap->a_ray.r_dir[Y] < -SQRT_SMALL_FASTF ) {
00239 ss.abs_inv_dir[Y] = -(ss.inv_dir[Y]=1.0/ap->a_ray.r_dir[Y]);
00240 ss.rstep[Y] = -1;
00241 } else if( ap->a_ray.r_dir[Y] > SQRT_SMALL_FASTF ) {
00242 ss.abs_inv_dir[Y] = (ss.inv_dir[Y]=1.0/ap->a_ray.r_dir[Y]);
00243 ss.rstep[Y] = 1;
00244 } else {
00245 ap->a_ray.r_dir[Y] = 0.0;
00246 ss.abs_inv_dir[Y] = ss.inv_dir[Y] = INFINITY;
00247 ss.rstep[Y] = 0;
00248 }
00249 if( ap->a_ray.r_dir[Z] < -SQRT_SMALL_FASTF ) {
00250 ss.abs_inv_dir[Z] = -(ss.inv_dir[Z]=1.0/ap->a_ray.r_dir[Z]);
00251 ss.rstep[Z] = -1;
00252 } else if( ap->a_ray.r_dir[Z] > SQRT_SMALL_FASTF ) {
00253 ss.abs_inv_dir[Z] = (ss.inv_dir[Z]=1.0/ap->a_ray.r_dir[Z]);
00254 ss.rstep[Z] = 1;
00255 } else {
00256 ap->a_ray.r_dir[Z] = 0.0;
00257 ss.abs_inv_dir[Z] = ss.inv_dir[Z] = INFINITY;
00258 ss.rstep[Z] = 0;
00259 }
00260
00261
00262
00263
00264
00265 if( !rt_in_rpp( &ap->a_ray, ss.inv_dir, rtip->mdl_min, rtip->mdl_max ) ||
00266 ap->a_ray.r_max < 0.0 ) {
00267 resp->re_nmiss_model++;
00268 ap->a_return = ap->a_miss( ap );
00269 status = "MISS model";
00270 goto out;
00271 }
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295 ss.box_start = ss.model_start = ap->a_ray.r_min;
00296 ss.box_end = ss.model_end = ap->a_ray.r_max;
00297
00298 if( ss.box_start < BACKING_DIST )
00299 ss.box_start = BACKING_DIST;
00300
00301 ss.lastcut = CUTTER_NULL;
00302 ss.old_status = (struct rt_shootray_status *)NULL;
00303 ss.curcut = &ap->a_rt_i->rti_CutHead;
00304 if( ss.curcut->cut_type == CUT_NUGRIDNODE ) {
00305 ss.lastcell = CUTTER_NULL;
00306 VSET( ss.curmin, ss.curcut->nugn.nu_axis[X][0].nu_spos,
00307 ss.curcut->nugn.nu_axis[Y][0].nu_spos,
00308 ss.curcut->nugn.nu_axis[Z][0].nu_spos );
00309 VSET( ss.curmax, ss.curcut->nugn.nu_axis[X][ss.curcut->nugn.nu_cells_per_axis[X]-1].nu_epos,
00310 ss.curcut->nugn.nu_axis[Y][ss.curcut->nugn.nu_cells_per_axis[Y]-1].nu_epos,
00311 ss.curcut->nugn.nu_axis[Z][ss.curcut->nugn.nu_cells_per_axis[Z]-1].nu_epos );
00312 } else if( ss.curcut->cut_type == CUT_CUTNODE ||
00313 ss.curcut->cut_type == CUT_BOXNODE ) {
00314 ss.lastcell = ss.curcut;
00315 VMOVE( ss.curmin, rtip->mdl_min );
00316 VMOVE( ss.curmax, rtip->mdl_max );
00317 }
00318
00319 last_bool_start = BACKING_DIST;
00320 ss.newray = ap->a_ray;
00321 ss.odist_corr = ss.obox_start = ss.obox_end = -99;
00322 ss.dist_corr = 0.0;
00323
00324
00325
00326
00327
00328
00329
00330
00331 while( (cutp = rt_advance_to_next_cell( &ss )) != CUTTER_NULL ) {
00332 if(debug_shoot) {
00333 rt_pr_cut( cutp, 0 );
00334 }
00335
00336 if( cutp->bn.bn_len <= 0 ) {
00337
00338 ss.box_start = ss.box_end;
00339 resp->re_nempty_cells++;
00340 continue;
00341 }
00342
00343
00344 stpp = &(cutp->bn.bn_list[cutp->bn.bn_len-1]);
00345 for( ; stpp >= cutp->bn.bn_list; stpp-- ) {
00346 register struct soltab *stp = *stpp;
00347 int ray;
00348
00349 if( BU_BITTEST( solidbits, stp->st_bit ) ) {
00350 resp->re_ndup++;
00351 continue;
00352 }
00353
00354
00355
00356 BU_BITSET( solidbits, stp->st_bit );
00357
00358 for( ray=0; ray < nrays; ray++ ) {
00359 struct xray ss2_newray;
00360
00361
00362 VMOVE( ss2_newray.r_dir, rays[ray].r_dir );
00363 VJOIN1( ss2_newray.r_pt, rays[ray].r_pt, ss.dist_corr, ss2_newray.r_dir );
00364
00365
00366 if( rt_functab[stp->st_id].ft_use_rpp ) {
00367 if( !rt_in_rpp( &ss2_newray, ss.inv_dir,
00368 stp->st_min, stp->st_max ) ) {
00369 if(debug_shoot)bu_log("rpp miss %s by ray %d\n", stp->st_name, ray);
00370 resp->re_prune_solrpp++;
00371 continue;
00372 }
00373 if( ss.dist_corr + ss2_newray.r_max < BACKING_DIST ) {
00374 if(debug_shoot)bu_log("rpp skip %s, dist_corr=%g, r_max=%g, by ray %d\n", stp->st_name, ss.dist_corr, ss2_newray.r_max, ray);
00375 resp->re_prune_solrpp++;
00376 continue;
00377 }
00378 }
00379
00380 if(debug_shoot)bu_log("shooting %s with ray %d\n", stp->st_name, ray);
00381 resp->re_shots++;
00382 BU_LIST_INIT( &(new_segs.l) );
00383 if( rt_functab[stp->st_id].ft_shot(
00384 stp, &ss2_newray, ap, &new_segs ) <= 0 ) {
00385 resp->re_shot_miss++;
00386 continue;
00387 }
00388
00389
00390 {
00391 register struct seg *s2;
00392 while(BU_LIST_WHILE(s2,seg,&(new_segs.l))) {
00393 BU_LIST_DEQUEUE( &(s2->l) );
00394
00395 s2->seg_in.hit_dist += ss.dist_corr;
00396 s2->seg_out.hit_dist += ss.dist_corr;
00397 s2->seg_in.hit_rayp = s2->seg_out.hit_rayp = &rays[ray];
00398 BU_LIST_INSERT( &(waiting_segs.l), &(s2->l) );
00399 }
00400 }
00401 resp->re_shot_hit++;
00402 break;
00403 }
00404 }
00405 if( RT_G_DEBUG & DEBUG_ADVANCE )
00406 rt_plot_cell( cutp, &ss, &(waiting_segs.l), rtip);
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425 if( ap->a_onehit != 0 && BU_LIST_NON_EMPTY( &(waiting_segs.l) ) ) {
00426 int done;
00427
00428
00429 rt_boolweave( &finished_segs, &waiting_segs, &InitialPart, ap );
00430
00431
00432 done = rt_boolfinal( &InitialPart, &FinalPart,
00433 last_bool_start, ss.box_end, regionbits, ap, solidbits );
00434 last_bool_start = ss.box_end;
00435
00436
00437 if( done > 0 ) goto hitit;
00438 }
00439
00440 if( ap->a_ray_length > 0.0 && ss.box_end >= ap->a_ray_length )
00441 goto weave;
00442
00443
00444 ss.box_start = ss.box_end;
00445 }
00446
00447
00448
00449
00450
00451 weave:
00452 if( RT_G_DEBUG&DEBUG_ADVANCE )
00453 bu_log( "rt_shootray_bundle: ray has left known space\n" );
00454
00455 if( BU_LIST_NON_EMPTY( &(waiting_segs.l) ) ) {
00456 rt_boolweave( &finished_segs, &waiting_segs, &InitialPart, ap );
00457 }
00458
00459
00460 if( BU_LIST_IS_EMPTY( &(finished_segs.l) ) ) {
00461 ap->a_return = ap->a_miss( ap );
00462 status = "MISS prims";
00463 goto out;
00464 }
00465
00466
00467
00468
00469
00470 (void)rt_boolfinal( &InitialPart, &FinalPart, BACKING_DIST,
00471 INFINITY,
00472 regionbits, ap, solidbits);
00473
00474 if( FinalPart.pt_forw == &FinalPart ) {
00475 ap->a_return = ap->a_miss( ap );
00476 status = "MISS bool";
00477 RT_FREE_PT_LIST( &InitialPart, resp );
00478 RT_FREE_SEG_LIST( &finished_segs, resp );
00479 goto out;
00480 }
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494 hitit:
00495 if(debug_shoot) rt_pr_partitions(rtip,&FinalPart,"a_hit()");
00496
00497
00498
00499
00500
00501
00502 RT_FREE_PT_LIST( &InitialPart, resp );
00503
00504
00505
00506
00507
00508 if(RT_G_DEBUG&DEBUG_ALLHITS) rt_pr_partitions(rtip,&FinalPart,"Parition list passed to a_hit() routine");
00509 ap->a_return = ap->a_hit( ap, &FinalPart, &finished_segs );
00510 status = "HIT";
00511
00512 RT_FREE_SEG_LIST( &finished_segs, resp );
00513 RT_FREE_PT_LIST( &FinalPart, resp );
00514
00515
00516
00517
00518 out:
00519
00520 BU_CK_BITV(solidbits);
00521 BU_LIST_APPEND( &resp->re_solid_bitv, &solidbits->l );
00522 BU_CK_PTBL(regionbits);
00523 BU_LIST_APPEND( &resp->re_region_ptbl, ®ionbits->l );
00524
00525
00526
00527
00528 resp->re_nshootray++;
00529
00530
00531 if(RT_G_DEBUG&(DEBUG_ALLRAYS|DEBUG_SHOOT|DEBUG_PARTITION|DEBUG_ALLHITS)) {
00532 bu_log_indent_delta(-2);
00533 bu_log("----------shootray_bundle cpu=%d %d,%d lvl=%d (%s) %s ret=%d\n",
00534 resp->re_cpu,
00535 ap->a_x, ap->a_y,
00536 ap->a_level,
00537 ap->a_purpose != (char *)0 ? ap->a_purpose : "?",
00538 status, ap->a_return);
00539 }
00540 return( ap->a_return );
00541 }
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551