[brlcad-commits] SF.net SVN: brlcad: [31744] brlcad/trunk/src/librt/primitives/pipe/pipe.c
Open Source Solid Modeling CAD
Brought to you by:
brlcad
From: <joh...@us...> - 2008-07-04 23:05:31
|
Revision: 31744 http://brlcad.svn.sourceforge.net/brlcad/?rev=31744&view=rev Author: johnranderson Date: 2008-07-04 16:05:30 -0700 (Fri, 04 Jul 2008) Log Message: ----------- Eliminated use of BU_GETSTRUCT for hits. This should correct the recent bug added to the BUGS list. Modified Paths: -------------- brlcad/trunk/src/librt/primitives/pipe/pipe.c Modified: brlcad/trunk/src/librt/primitives/pipe/pipe.c =================================================================== --- brlcad/trunk/src/librt/primitives/pipe/pipe.c 2008-07-04 15:19:57 UTC (rev 31743) +++ brlcad/trunk/src/librt/primitives/pipe/pipe.c 2008-07-04 23:05:30 UTC (rev 31744) @@ -49,14 +49,12 @@ #include "wdb.h" -struct id_pipe -{ +struct id_pipe { struct bu_list l; int pipe_is_bend; }; -struct lin_pipe -{ +struct lin_pipe { struct bu_list l; int pipe_is_bend; vect_t pipe_V; /* start point for pipe section */ @@ -74,8 +72,7 @@ point_t pipe_max; }; -struct bend_pipe -{ +struct bend_pipe { struct bu_list l; int pipe_is_bend; fastf_t bend_radius; /* distance from bend_v to center of pipe */ @@ -98,13 +95,6 @@ fastf_t bend_bound_radius_sq; /* square of bounding sphere radius */ }; - -struct hit_list -{ - struct bu_list l; - struct hit *hitp; -}; - #define PIPE_MM(_v) VMINMAX( stp->st_min, stp->st_max, _v ); #define ARC_SEGS 16 /* number of segments used to plot a circle */ @@ -119,15 +109,16 @@ #define PIPE_BEND_TOP 8 #define PIPE_RADIUS_CHANGE 9 +#define RT_PIPE_MAXHITS 128 + BU_EXTERN( void rt_pipe_ifree, (struct rt_db_internal *ip) ); HIDDEN int rt_bend_pipe_prep(struct soltab *stp, struct bu_list *head, fastf_t *bend_center, - fastf_t *bend_start, fastf_t *bend_end, fastf_t bend_radius, - fastf_t bend_angle, fastf_t *v1, fastf_t *v2, fastf_t od, fastf_t id, - fastf_t prev_od, fastf_t next_od) -{ + fastf_t *bend_start, fastf_t *bend_end, fastf_t bend_radius, + fastf_t bend_angle, fastf_t *v1, fastf_t *v2, fastf_t od, fastf_t id, + fastf_t prev_od, fastf_t next_od) { register struct bend_pipe *pipe; vect_t to_start, to_end; mat_t R; @@ -136,13 +127,13 @@ fastf_t max_od; fastf_t max_or; fastf_t max_r; - + pipe = (struct bend_pipe *)bu_malloc( sizeof( struct bend_pipe ), "rt_bend_pipe_prep:pipe" ); - + pipe->pipe_is_bend = 1; pipe->bend_or = od * 0.5; pipe->bend_ir = id * 0.5; - + VMOVE( pipe->bend_start, bend_start ); VMOVE( pipe->bend_end, bend_end ); VMOVE( pipe->bend_V, bend_center ); @@ -156,47 +147,46 @@ VCROSS( pipe->bend_startNorm, pipe->bend_ra, pipe->bend_N ); VCROSS( pipe->bend_endNorm, pipe->bend_N, to_end ); VUNITIZE( pipe->bend_endNorm ); - + pipe->bend_angle = bend_angle; - + /* angle goes from 0.0 at start to some angle less than PI */ - if ( pipe->bend_angle >= bn_pi ) - { - bu_log( "Error: rt_pipe_prep: Bend section bends through more than 180 degrees\n" ); - return( 1 ); + if ( pipe->bend_angle >= bn_pi ) { + bu_log( "Error: rt_pipe_prep: Bend section bends through more than 180 degrees\n" ); + return( 1 ); } - + pipe->bend_alpha_i = pipe->bend_ir/pipe->bend_radius; pipe->bend_alpha_o = pipe->bend_or/pipe->bend_radius; - + MAT_IDN( R ); VMOVE( &R[0], pipe->bend_ra ); VMOVE( &R[4], pipe->bend_rb ); VMOVE( &R[8], pipe->bend_N ); - + if (bn_mat_inverse( pipe->bend_invR, R ) == 0) { - bu_free(pipe, "rt_bend_pipe_prep:pipe"); - return 0; /* there is nothing to bend, that's OK */ + bu_free(pipe, "rt_bend_pipe_prep:pipe"); + return 0; /* there is nothing to bend, that's OK */ } - - + + MAT_COPY( pipe->bend_SoR, R ); pipe->bend_SoR[15] *= pipe->bend_radius; - + /* bounding box for entire torus */ /* include od of previous and next segment * to allow for dinscontinuous radii */ max_od = od; if ( prev_od > max_od ) { - max_od = prev_od; + max_od = prev_od; } if ( next_od > max_od ) { - max_od = next_od; + max_od = next_od; } max_or = max_od/2.0; max_r = bend_radius + max_or; - + VBLEND2(pipe->bend_bound_center, 0.5, bend_start, 0.5, bend_end ); pipe->bend_bound_radius_sq = max_r * sin( bend_angle/2.0 ); pipe->bend_bound_radius_sq = pipe->bend_bound_radius_sq * pipe->bend_bound_radius_sq; @@ -212,16 +202,15 @@ work[Y] += f; work[Z] += f; PIPE_MM(work); - + BU_LIST_INSERT( head, &pipe->l ); - + return( 0 ); - + } HIDDEN void -rt_linear_pipe_prep(struct soltab *stp, struct bu_list *head, fastf_t *pt1, fastf_t id1, fastf_t od1, fastf_t *pt2, fastf_t id2, fastf_t od2) -{ +rt_linear_pipe_prep(struct soltab *stp, struct bu_list *head, fastf_t *pt1, fastf_t id1, fastf_t od1, fastf_t *pt2, fastf_t id2, fastf_t od2) { register struct lin_pipe *pipe; mat_t R; mat_t Rinv; @@ -229,13 +218,13 @@ point_t work; vect_t seg_ht; vect_t v1, v2; - + pipe = (struct lin_pipe *)bu_malloc( sizeof( struct lin_pipe ), "rt_bend_pipe_prep:pipe" ); BU_LIST_INSERT( head, &pipe->l ); - - + + VMOVE( pipe->pipe_V, pt1 ); - + VSUB2( seg_ht, pt2, pt1 ); pipe->pipe_ribase = id1/2.0; pipe->pipe_ribase_sq = pipe->pipe_ribase * pipe->pipe_ribase; @@ -250,59 +239,59 @@ pipe->pipe_rodiff = pipe->pipe_rotop - pipe->pipe_robase; pipe->pipe_rodiff_sq = pipe->pipe_rodiff * pipe->pipe_rodiff; pipe->pipe_is_bend = 0; - + pipe->pipe_len = MAGNITUDE( seg_ht ); VSCALE( seg_ht, seg_ht, 1.0/pipe->pipe_len ); VMOVE( pipe->pipe_H, seg_ht ); bn_vec_ortho( v1, seg_ht ); VCROSS( v2, seg_ht, v1 ); - + /* build R matrix */ MAT_IDN( R ); VMOVE( &R[0], v1 ); VMOVE( &R[4], v2 ); VMOVE( &R[8], seg_ht ); - + /* Rinv is transpose */ bn_mat_trn( Rinv, R ); - + /* Build Scale matrix */ MAT_IDN( S ); S[10] = 1.0/pipe->pipe_len; - + /* Compute SoR and invRoS */ bn_mat_mul( pipe->pipe_SoR, S, R ); bn_mat_mul( pipe->pipe_invRoS, Rinv, S ); - + VSETALL( pipe->pipe_min, MAX_FASTF ); VSETALL( pipe->pipe_max, -MAX_FASTF ); - + VJOIN2( work, pt1, od1, v1, od1, v2 ); PIPE_MM( work ) - VMINMAX( pipe->pipe_min, pipe->pipe_max, work ); + VMINMAX( pipe->pipe_min, pipe->pipe_max, work ); VJOIN2( work, pt1, -od1, v1, od1, v2 ); PIPE_MM( work ) - VMINMAX( pipe->pipe_min, pipe->pipe_max, work ); + VMINMAX( pipe->pipe_min, pipe->pipe_max, work ); VJOIN2( work, pt1, od1, v1, -od1, v2 ); PIPE_MM( work ) - VMINMAX( pipe->pipe_min, pipe->pipe_max, work ); + VMINMAX( pipe->pipe_min, pipe->pipe_max, work ); VJOIN2( work, pt1, -od1, v1, -od1, v2 ); PIPE_MM( work ) - VMINMAX( pipe->pipe_min, pipe->pipe_max, work ); - + VMINMAX( pipe->pipe_min, pipe->pipe_max, work ); + VJOIN2( work, pt2, od2, v1, od2, v2 ); PIPE_MM( work ) - VMINMAX( pipe->pipe_min, pipe->pipe_max, work ); + VMINMAX( pipe->pipe_min, pipe->pipe_max, work ); VJOIN2( work, pt2, -od2, v1, od2, v2 ); PIPE_MM( work ) - VMINMAX( pipe->pipe_min, pipe->pipe_max, work ); + VMINMAX( pipe->pipe_min, pipe->pipe_max, work ); VJOIN2( work, pt2, od2, v1, -od2, v2 ); PIPE_MM( work ) - VMINMAX( pipe->pipe_min, pipe->pipe_max, work ); + VMINMAX( pipe->pipe_min, pipe->pipe_max, work ); VJOIN2( work, pt2, -od2, v1, -od2, v2 ); PIPE_MM( work ) - VMINMAX( pipe->pipe_min, pipe->pipe_max, work ); - + VMINMAX( pipe->pipe_min, pipe->pipe_max, work ); + } /** @@ -321,115 +310,110 @@ * stp->st_specific for use by pipe_shot(). */ int -rt_pipe_prep(struct soltab *stp, struct rt_db_internal *ip, struct rt_i *rtip) -{ +rt_pipe_prep(struct soltab *stp, struct rt_db_internal *ip, struct rt_i *rtip) { register struct bu_list *head; struct rt_pipe_internal *pip; struct wdb_pipept *pp1, *pp2, *pp3; point_t curr_pt; fastf_t curr_id, curr_od; fastf_t dx, dy, dz, f; - + RT_CK_DB_INTERNAL( ip ); pip = (struct rt_pipe_internal *)ip->idb_ptr; RT_PIPE_CK_MAGIC(pip); - + head = (struct bu_list *)bu_malloc( sizeof( struct bu_list ), "rt_pipe_prep:head" ); stp->st_specific = (genptr_t)head; BU_LIST_INIT( head ); - + if ( BU_LIST_IS_EMPTY( &(pip->pipe_segs_head) ) ) - return( 0 ); - + return( 0 ); + pp1 = BU_LIST_FIRST( wdb_pipept, &(pip->pipe_segs_head) ); pp2 = BU_LIST_NEXT( wdb_pipept, &pp1->l ); if ( BU_LIST_IS_HEAD( &pp2->l, &(pip->pipe_segs_head) ) ) - return( 0 ); + return( 0 ); pp3 = BU_LIST_NEXT( wdb_pipept, &pp2->l ); if ( BU_LIST_IS_HEAD( &pp3->l, &(pip->pipe_segs_head) ) ) - pp3 = (struct wdb_pipept *)NULL; - + pp3 = (struct wdb_pipept *)NULL; + VMOVE( curr_pt, pp1->pp_coord ); curr_od = pp1->pp_od; curr_id = pp1->pp_id; - while ( 1 ) - { - vect_t n1, n2; - vect_t norm; - vect_t v1, v2; - vect_t diff; - fastf_t angle; - fastf_t dist_to_bend; - point_t bend_start, bend_end, bend_center; - - VSUB2( n1, curr_pt, pp2->pp_coord ); - if ( VNEAR_ZERO( n1, RT_LEN_TOL ) ) - { - /* duplicate point, skip to next point */ - goto next_pt; - } - - if ( !pp3 ) - { - /* last segment */ - rt_linear_pipe_prep( stp, head, curr_pt, curr_id, curr_od, pp2->pp_coord, pp2->pp_id, pp2->pp_od ); - break; - } - - VSUB2( n2, pp3->pp_coord, pp2->pp_coord ); - VCROSS( norm, n1, n2 ); - VUNITIZE( n1 ); - VUNITIZE( n2 ); - angle = bn_pi - acos( VDOT( n1, n2 ) ); - dist_to_bend = pp2->pp_bendradius * tan( angle/2.0 ); - if ( isnan( dist_to_bend ) || VNEAR_ZERO( norm, SQRT_SMALL_FASTF) || NEAR_ZERO( dist_to_bend, SQRT_SMALL_FASTF) ) - { - /* points are colinear, treat as a linear segment */ - rt_linear_pipe_prep( stp, head, curr_pt, curr_id, curr_od, - pp2->pp_coord, pp2->pp_id, pp2->pp_od ); - VMOVE( curr_pt, pp2->pp_coord ); - goto next_pt; - } - - VJOIN1( bend_start, pp2->pp_coord, dist_to_bend, n1 ); - VJOIN1( bend_end, pp2->pp_coord, dist_to_bend, n2 ); - - VUNITIZE( norm ); - - /* linear section */ - VSUB2( diff, curr_pt, bend_start ); - if ( MAGNITUDE( diff ) <= RT_LEN_TOL ) { - /* do not make linear sections that are too small to raytrace */ - VMOVE( bend_start, curr_pt ); - } else { - rt_linear_pipe_prep( stp, head, curr_pt, curr_id, curr_od, - bend_start, pp2->pp_id, pp2->pp_od ); - } - - /* and bend section */ - VCROSS( v1, n1, norm ); - VCROSS( v2, v1, norm ); - VJOIN1( bend_center, bend_start, -pp2->pp_bendradius, v1 ); - rt_bend_pipe_prep( stp, head, bend_center, bend_start, bend_end, pp2->pp_bendradius, angle, - v1, v2, pp2->pp_od, pp2->pp_id, pp1->pp_od, pp3->pp_od ); - - VMOVE( curr_pt, bend_end ); - next_pt: - if (!pp3) break; - curr_id = pp2->pp_id; - curr_od = pp2->pp_od; - pp1 = pp2; - pp2 = pp3; - pp3 = BU_LIST_NEXT( wdb_pipept, &pp3->l ); - if ( BU_LIST_IS_HEAD( &pp3->l, &(pip->pipe_segs_head) ) ) - pp3 = (struct wdb_pipept *)NULL; + while ( 1 ) { + vect_t n1, n2; + vect_t norm; + vect_t v1, v2; + vect_t diff; + fastf_t angle; + fastf_t dist_to_bend; + point_t bend_start, bend_end, bend_center; + + VSUB2( n1, curr_pt, pp2->pp_coord ); + if ( VNEAR_ZERO( n1, RT_LEN_TOL ) ) { + /* duplicate point, skip to next point */ + goto next_pt; + } + + if ( !pp3 ) { + /* last segment */ + rt_linear_pipe_prep( stp, head, curr_pt, curr_id, curr_od, pp2->pp_coord, pp2->pp_id, pp2->pp_od ); + break; + } + + VSUB2( n2, pp3->pp_coord, pp2->pp_coord ); + VCROSS( norm, n1, n2 ); + VUNITIZE( n1 ); + VUNITIZE( n2 ); + angle = bn_pi - acos( VDOT( n1, n2 ) ); + dist_to_bend = pp2->pp_bendradius * tan( angle/2.0 ); + if ( isnan( dist_to_bend ) || VNEAR_ZERO( norm, SQRT_SMALL_FASTF) || NEAR_ZERO( dist_to_bend, SQRT_SMALL_FASTF) ) { + /* points are colinear, treat as a linear segment */ + rt_linear_pipe_prep( stp, head, curr_pt, curr_id, curr_od, + pp2->pp_coord, pp2->pp_id, pp2->pp_od ); + VMOVE( curr_pt, pp2->pp_coord ); + goto next_pt; + } + + VJOIN1( bend_start, pp2->pp_coord, dist_to_bend, n1 ); + VJOIN1( bend_end, pp2->pp_coord, dist_to_bend, n2 ); + + VUNITIZE( norm ); + + /* linear section */ + VSUB2( diff, curr_pt, bend_start ); + if ( MAGNITUDE( diff ) <= RT_LEN_TOL ) { + /* do not make linear sections that are too small to raytrace */ + VMOVE( bend_start, curr_pt ); + } else { + rt_linear_pipe_prep( stp, head, curr_pt, curr_id, curr_od, + bend_start, pp2->pp_id, pp2->pp_od ); + } + + /* and bend section */ + VCROSS( v1, n1, norm ); + VCROSS( v2, v1, norm ); + VJOIN1( bend_center, bend_start, -pp2->pp_bendradius, v1 ); + rt_bend_pipe_prep( stp, head, bend_center, bend_start, bend_end, pp2->pp_bendradius, angle, + v1, v2, pp2->pp_od, pp2->pp_id, pp1->pp_od, pp3->pp_od ); + + VMOVE( curr_pt, bend_end ); + next_pt: + if (!pp3) break; + curr_id = pp2->pp_id; + curr_od = pp2->pp_od; + pp1 = pp2; + pp2 = pp3; + pp3 = BU_LIST_NEXT( wdb_pipept, &pp3->l ); + if ( BU_LIST_IS_HEAD( &pp3->l, &(pip->pipe_segs_head) ) ) + pp3 = (struct wdb_pipept *)NULL; } - + VSET( stp->st_center, - (stp->st_max[X] + stp->st_min[X])/2, - (stp->st_max[Y] + stp->st_min[Y])/2, - (stp->st_max[Z] + stp->st_min[Z])/2 ); - + (stp->st_max[X] + stp->st_min[X])/2, + (stp->st_max[Y] + stp->st_min[Y])/2, + (stp->st_max[Z] + stp->st_min[Z])/2 ); + dx = (stp->st_max[X] - stp->st_min[X])/2; f = dx; dy = (stp->st_max[Y] - stp->st_min[Y])/2; @@ -438,7 +422,7 @@ if ( dz > f ) f = dz; stp->st_aradius = f; stp->st_bradius = sqrt(dx*dx + dy*dy + dz*dz); - + return( 0 ); } @@ -446,30 +430,28 @@ * R T _ P I P E _ P R I N T */ void -rt_pipe_print(register const struct soltab *stp) -{ -/* register struct bu_list *pipe = - (struct bu_list *)stp->st_specific; */ +rt_pipe_print(register const struct soltab *stp) { + /* register struct bu_list *pipe = + (struct bu_list *)stp->st_specific; */ } /** * R T _ P I P E P T _ P R I N T */ void -rt_pipept_print( const struct wdb_pipept *pipe, double mm2local ) -{ +rt_pipept_print( const struct wdb_pipept *pipe, double mm2local ) { point_t p1; - + bu_log( "Pipe Vertex:\n" ); VSCALE( p1, pipe->pp_coord, mm2local ); bu_log( "\tat (%g %g %g)\n", V3ARGS( p1 ) ); bu_log( "\tbend radius = %g\n", pipe->pp_bendradius*mm2local ); if ( pipe->pp_id > 0.0 ) - bu_log( "\tod=%g, id=%g\n", - pipe->pp_od*mm2local, - pipe->pp_id*mm2local ); + bu_log( "\tod=%g, id=%g\n", + pipe->pp_od*mm2local, + pipe->pp_id*mm2local ); else - bu_log( "\tod=%g\n", pipe->pp_od*mm2local ); + bu_log( "\tod=%g\n", pipe->pp_od*mm2local ); } /** @@ -477,25 +459,24 @@ */ void rt_vls_pipept( - struct bu_vls *vp, - int seg_no, - const struct rt_db_internal *ip, - double mm2local) -{ +struct bu_vls *vp, + int seg_no, + const struct rt_db_internal *ip, + double mm2local) { struct rt_pipe_internal *pint; struct wdb_pipept *pipe; int seg_count=0; char buf[256]; point_t p1; - + pint = (struct rt_pipe_internal *)ip->idb_ptr; RT_PIPE_CK_MAGIC( pint ); - + pipe = BU_LIST_FIRST( wdb_pipept, &pint->pipe_segs_head ); while ( ++seg_count != seg_no && BU_LIST_NOT_HEAD( &pipe->l, &pint->pipe_segs_head ) ) - pipe = BU_LIST_NEXT( wdb_pipept, &pipe->l ); - - + pipe = BU_LIST_NEXT( wdb_pipept, &pipe->l ); + + sprintf( buf, "Pipe Vertex:\n" ); bu_vls_strcat( vp, buf ); VSCALE( p1, pipe->pp_coord, mm2local ); @@ -504,11 +485,11 @@ sprintf( buf, "\tbend radius = %g\n", pipe->pp_bendradius*mm2local ); bu_vls_strcat( vp, buf ); if ( pipe->pp_id > 0.0 ) - sprintf( buf, "\tod=%g, id=%g\n", - pipe->pp_od*mm2local, - pipe->pp_id*mm2local ); + sprintf( buf, "\tod=%g, id=%g\n", + pipe->pp_od*mm2local, + pipe->pp_id*mm2local ); else - sprintf( buf, "\tod=%g\n", pipe->pp_od*mm2local ); + sprintf( buf, "\tod=%g\n", pipe->pp_od*mm2local ); bu_vls_strcat( vp, buf ); } @@ -521,53 +502,53 @@ */ HIDDEN void discont_radius_shot(register struct xray *rp, struct seg *seghead, - point_t center, vect_t norm, - fastf_t or1_sq, fastf_t ir1_sq, fastf_t or2_sq, fastf_t ir2_sq, - struct hit_list *hit_headp, int *hit_count, int seg_no) -{ + point_t center, vect_t norm, + fastf_t or1_sq, fastf_t ir1_sq, fastf_t or2_sq, fastf_t ir2_sq, + struct hit *hits, int *hit_count, int seg_no, struct soltab *stp) { fastf_t dist_to_plane; fastf_t norm_dist; fastf_t slant_factor; fastf_t t_tmp; point_t hit_pt; fastf_t radius_sq; - + /* calculate interstection with plane at center (with normal "norm") */ dist_to_plane = VDOT( norm, center ); norm_dist = dist_to_plane - VDOT( norm, rp->r_pt ); slant_factor = VDOT( norm, rp->r_dir ); if ( !NEAR_ZERO( slant_factor, SMALL_FASTF ) ) { vect_t to_center; - struct hit_list *hitp; - + struct hit *hitp; + t_tmp = norm_dist/slant_factor; VJOIN1( hit_pt, rp->r_pt, t_tmp, rp->r_dir ); VSUB2( to_center, center, hit_pt ); radius_sq = MAGSQ( to_center ); - + /* where the radius ranges overlap, there is no hit */ if ( radius_sq <= or1_sq && radius_sq >= ir1_sq && - radius_sq <= or2_sq && radius_sq >= ir2_sq ) { + radius_sq <= or2_sq && radius_sq >= ir2_sq ) { return; } - + /* if we are within one of the radius ranges, we have a hit */ if ( (radius_sq <= or2_sq && radius_sq >= ir2_sq) || - (radius_sq <= or1_sq && radius_sq >= ir1_sq) ) { - BU_GETSTRUCT( hitp, hit_list ); - BU_GETSTRUCT( hitp->hitp, hit ); - hitp->hitp->hit_magic = RT_HIT_MAGIC; - hitp->hitp->hit_dist = t_tmp; - hitp->hitp->hit_surfno = seg_no*10 + PIPE_RADIUS_CHANGE; - + (radius_sq <= or1_sq && radius_sq >= ir1_sq) ) { + hitp = &hits[*hit_count]; + hitp->hit_magic = RT_HIT_MAGIC; + hitp->hit_dist = t_tmp; + hitp->hit_surfno = seg_no*10 + PIPE_RADIUS_CHANGE; + /* within first range, use norm, otherwise reverse */ if ( radius_sq <= or1_sq && radius_sq >= ir1_sq ) { - VMOVE( hitp->hitp->hit_normal, norm ); + VMOVE( hitp->hit_normal, norm ); } else { - VREVERSE( hitp->hitp->hit_normal, norm ); + VREVERSE( hitp->hit_normal, norm ); } - (*hit_count)++; - BU_LIST_INSERT( &hit_headp->l, &hitp->l ); + if( (*hit_count)++ >= RT_PIPE_MAXHITS ) { + bu_log( "Too many hits (%d) on primitive (%s)\n", *hit_count, stp->st_dp->d_namep); + return; + } } } } @@ -576,16 +557,15 @@ * check if a ray passes within a bounding sphere */ int -rt_in_sph( struct xray *rp, point_t center, fastf_t radius_sq ) -{ +rt_in_sph( struct xray *rp, point_t center, fastf_t radius_sq ) { vect_t toCenter; vect_t toPCA; fastf_t dist_sq; - + VSUB2( toCenter, center, rp->r_pt ); VCROSS( toPCA, toCenter, rp->r_dir ); dist_sq = MAGSQ( toPCA ); - + if ( dist_sq <= radius_sq) { return 1; } else { @@ -594,14 +574,14 @@ } HIDDEN void -bend_pipe_shot(struct soltab *stp, register struct xray *rp, struct application *ap, struct seg *seghead, struct bend_pipe *pipe, struct hit_list *hit_headp, int *hit_count, int seg_no) -{ +bend_pipe_shot(struct soltab *stp, register struct xray *rp, struct application *ap, struct seg *seghead, struct bend_pipe *pipe, struct hit *hits, int *hit_count, int seg_no) { vect_t dprime; /* D' */ vect_t pprime; /* P' */ vect_t work; /* temporary vector */ bn_poly_t C; /* The final equation */ bn_complex_t val[4]; /* The complex roots */ int j; + int root_count=0; bn_poly_t A, Asqr; bn_poly_t X2_Y2; /* X**2 + Y**2 */ @@ -616,34 +596,32 @@ fastf_t tmp; struct id_pipe *prev; struct id_pipe *next; - - *hit_count = 0; - + tmp = VDOT( rp->r_dir, pipe->bend_N ); if ( NEAR_ZERO(tmp, 0.0000005) ) { - /* ray is parallel to plane of bend */ - parallel = 1; - dist = fabs( VDOT(rp->r_pt, pipe->bend_N) - - VDOT(pipe->bend_V, pipe->bend_N) ); - - if ( dist > pipe->bend_or ) { - /* ray is more than outer radius away from plane of bend */ - goto check_discont_radii; - } + /* ray is parallel to plane of bend */ + parallel = 1; + dist = fabs( VDOT(rp->r_pt, pipe->bend_N) - + VDOT(pipe->bend_V, pipe->bend_N) ); + + if ( dist > pipe->bend_or ) { + /* ray is more than outer radius away from plane of bend */ + goto check_discont_radii; + } } else { - parallel = 0; + parallel = 0; } - + or_sq = pipe->bend_or * pipe->bend_or; ir_sq = pipe->bend_ir * pipe->bend_ir; - + /* Convert vector into the space of the unit torus */ MAT4X3VEC( dprime, pipe->bend_SoR, rp->r_dir ); VUNITIZE( dprime ); - + VSUB2( work, rp->r_pt, pipe->bend_V ); MAT4X3VEC( pprime, pipe->bend_SoR, work ); - + /* normalize distance from torus. substitute * corrected pprime which contains a translation along ray * direction to closest approach to vertex of torus. @@ -654,7 +632,7 @@ cor_proj = VDOT( pprime, dprime ); VSCALE( cor_pprime, dprime, cor_proj ); VSUB2( cor_pprime, pprime, cor_pprime ); - + /* * Given a line and a ratio, alpha, finds the equation of the * unit torus in terms of the variable 't'. @@ -674,17 +652,17 @@ X2_Y2.dgr = 2; X2_Y2.cf[0] = dprime[X] * dprime[X] + dprime[Y] * dprime[Y]; X2_Y2.cf[1] = 2.0 * (dprime[X] * cor_pprime[X] + - dprime[Y] * cor_pprime[Y]); + dprime[Y] * cor_pprime[Y]); X2_Y2.cf[2] = cor_pprime[X] * cor_pprime[X] + - cor_pprime[Y] * cor_pprime[Y]; - + cor_pprime[Y] * cor_pprime[Y]; + /* A = X2_Y2 + Z2 */ A.dgr = 2; A.cf[0] = X2_Y2.cf[0] + dprime[Z] * dprime[Z]; A.cf[1] = X2_Y2.cf[1] + 2.0 * dprime[Z] * cor_pprime[Z]; A.cf[2] = X2_Y2.cf[2] + cor_pprime[Z] * cor_pprime[Z] + - 1.0 - pipe->bend_alpha_o * pipe->bend_alpha_o; - + 1.0 - pipe->bend_alpha_o * pipe->bend_alpha_o; + /* Inline expansion of (void) bn_poly_mul( &Asqr, &A, &A ) */ /* Both polys have degree two */ Asqr.dgr = 4; @@ -693,7 +671,7 @@ Asqr.cf[2] = A.cf[0] * A.cf[2] + A.cf[1] * A.cf[1] + A.cf[2] * A.cf[0]; Asqr.cf[3] = A.cf[1] * A.cf[2] + A.cf[2] * A.cf[1]; Asqr.cf[4] = A.cf[2] * A.cf[2]; - + /* Inline expansion of bn_poly_scale( &X2_Y2, 4.0 ) and * bn_poly_sub( &C, &Asqr, &X2_Y2 ). */ @@ -703,78 +681,78 @@ C.cf[2] = Asqr.cf[2] - X2_Y2.cf[0] * 4.0; C.cf[3] = Asqr.cf[3] - X2_Y2.cf[1] * 4.0; C.cf[4] = Asqr.cf[4] - X2_Y2.cf[2] * 4.0; - + /* It is known that the equation is 4th order. Therefore, * if the root finder returns other than 4 roots, error. */ if ( (root_count = rt_poly_roots( &C, val, stp->st_dp->d_namep )) != 4 ) { - if ( root_count > 0 ) { - bu_log("tor: rt_poly_roots() 4!=%d\n", root_count); - bn_pr_roots( stp->st_name, val, root_count ); - } else if (root_count < 0) { - static int reported=0; - bu_log("The root solver failed to converge on a solution for %s\n", stp->st_dp->d_namep); - if (!reported) { - VPRINT("while shooting from:\t", rp->r_pt); - VPRINT("while shooting at:\t", rp->r_dir); - bu_log("Additional pipe convergence failure details will be suppressed.\n"); - reported=1; - } - } - goto check_discont_radii; /* MISSED */ + if ( root_count > 0 ) { + bu_log("pipe: rt_poly_roots() 4!=%d\n", root_count); + bn_pr_roots( stp->st_name, val, root_count ); + } else if (root_count < 0) { + static int reported=0; + bu_log("The root solver failed to converge on a solution for %s\n", stp->st_dp->d_namep); + if (!reported) { + VPRINT("while shooting from:\t", rp->r_pt); + VPRINT("while shooting at:\t", rp->r_dir); + bu_log("Additional pipe convergence failure details will be suppressed.\n"); + reported=1; + } + } + goto check_discont_radii; /* MISSED */ } - + /* Only real roots indicate an intersection in real space. * * Look at each root returned; if the imaginary part is zero * or sufficiently close, then use the real part as one value * of 't' for the intersections */ - for ( j=0, (*hit_count)=0; j < 4; j++ ) { - if ( NEAR_ZERO( val[j].im, 0.0001 ) ) - { - struct hit_list *hitp; - fastf_t normalized_dist; - fastf_t dist; - point_t hit_pt; - vect_t to_hit; - fastf_t angle; - - normalized_dist = val[j].re - cor_proj; - dist = normalized_dist * pipe->bend_radius; - - /* check if this hit is within bend angle */ - VJOIN1( hit_pt, rp->r_pt, dist, rp->r_dir ); - VSUB2( to_hit, hit_pt, pipe->bend_V ); - angle = atan2( VDOT( to_hit, pipe->bend_rb ), VDOT( to_hit, pipe->bend_ra ) ); - if ( angle < 0.0 ) - angle += 2.0 * bn_pi; - if ( angle <= pipe->bend_angle ) - { - BU_GETSTRUCT( hitp, hit_list ); - BU_GETSTRUCT( hitp->hitp, hit ); - hitp->hitp->hit_magic = RT_HIT_MAGIC; - hitp->hitp->hit_dist = dist; - VJOIN1( hitp->hitp->hit_vpriv, pprime, normalized_dist, dprime ); - hitp->hitp->hit_surfno = seg_no*10 + PIPE_BEND_OUTER_BODY; - BU_LIST_INSERT( &hit_headp->l, &hitp->l ); - (*hit_count)++; - } - } + for ( j=0 ; j < 4; j++ ) { + if ( NEAR_ZERO( val[j].im, 0.0001 ) ) { + struct hit *hitp; + fastf_t normalized_dist; + fastf_t dist; + point_t hit_pt; + vect_t to_hit; + fastf_t angle; + + normalized_dist = val[j].re - cor_proj; + dist = normalized_dist * pipe->bend_radius; + + /* check if this hit is within bend angle */ + VJOIN1( hit_pt, rp->r_pt, dist, rp->r_dir ); + VSUB2( to_hit, hit_pt, pipe->bend_V ); + angle = atan2( VDOT( to_hit, pipe->bend_rb ), VDOT( to_hit, pipe->bend_ra ) ); + if ( angle < 0.0 ) + angle += 2.0 * bn_pi; + if ( angle <= pipe->bend_angle ) { + hitp = &hits[*hit_count]; + hitp->hit_magic = RT_HIT_MAGIC; + hitp->hit_dist = dist; + VJOIN1( hitp->hit_vpriv, pprime, normalized_dist, dprime ); + hitp->hit_surfno = seg_no*10 + PIPE_BEND_OUTER_BODY; + + if( (*hit_count)++ >= RT_PIPE_MAXHITS ) { + bu_log( "Too many hits (%d) on primitive (%s)\n", *hit_count, stp->st_dp->d_namep); + return; + } + } + } } - + if ( pipe->bend_alpha_i <= 0.0 ) - goto check_discont_radii; /* no inner torus */ - + goto check_discont_radii; /* no inner torus */ + if ( parallel && dist > pipe->bend_ir ) { - /* ray is parallel to plane of bend and more than inner radius away */ - goto check_discont_radii; + /* ray is parallel to plane of bend and more than inner radius away */ + goto check_discont_radii; } - + /* Now do inner torus */ A.cf[2] = X2_Y2.cf[2] + cor_pprime[Z] * cor_pprime[Z] + - 1.0 - pipe->bend_alpha_i * pipe->bend_alpha_i; - + 1.0 - pipe->bend_alpha_i * pipe->bend_alpha_i; + /* Inline expansion of (void) bn_poly_mul( &Asqr, &A, &A ) */ /* Both polys have degree two */ Asqr.dgr = 4; @@ -783,7 +761,7 @@ Asqr.cf[2] = A.cf[0] * A.cf[2] + A.cf[1] * A.cf[1] + A.cf[2] * A.cf[0]; Asqr.cf[3] = A.cf[1] * A.cf[2] + A.cf[2] * A.cf[1]; Asqr.cf[4] = A.cf[2] * A.cf[2]; - + /* Inline expansion of bn_poly_scale( &X2_Y2, 4.0 ) and * bn_poly_sub( &C, &Asqr, &X2_Y2 ). */ @@ -793,27 +771,27 @@ C.cf[2] = Asqr.cf[2] - X2_Y2.cf[0] * 4.0; C.cf[3] = Asqr.cf[3] - X2_Y2.cf[1] * 4.0; C.cf[4] = Asqr.cf[4] - X2_Y2.cf[2] * 4.0; - + /* It is known that the equation is 4th order. Therefore, * if the root finder returns other than 4 roots, error. */ if ( (root_count = rt_poly_roots( &C, val, stp->st_dp->d_namep)) != 4 ) { - if ( root_count > 0 ) { - bu_log("tor: rt_poly_roots() 4!=%d\n", root_count); - bn_pr_roots( stp->st_name, val, root_count ); - } else if (root_count < 0) { - static int reported=0; - bu_log("The root solver failed to converge on a solution for %s\n", stp->st_dp->d_namep); - if (!reported) { - VPRINT("while shooting from:\t", rp->r_pt); - VPRINT("while shooting at:\t", rp->r_dir); - bu_log("Additional pipe convergence failure details will be suppressed.\n"); - reported=1; - } - } - goto check_discont_radii; /* MISSED */ + if ( root_count > 0 ) { + bu_log("tor: rt_poly_roots() 4!=%d\n", root_count); + bn_pr_roots( stp->st_name, val, root_count ); + } else if (root_count < 0) { + static int reported=0; + bu_log("The root solver failed to converge on a solution for %s\n", stp->st_dp->d_namep); + if (!reported) { + VPRINT("while shooting from:\t", rp->r_pt); + VPRINT("while shooting at:\t", rp->r_dir); + bu_log("Additional pipe convergence failure details will be suppressed.\n"); + reported=1; + } + } + goto check_discont_radii; /* MISSED */ } - + /* Only real roots indicate an intersection in real space. * * Look at each root returned; if the imaginary part is zero @@ -821,526 +799,460 @@ * of 't' for the intersections */ for ( j=0, root_count=0; j < 4; j++ ) { - if ( NEAR_ZERO( val[j].im, 0.0001 ) ) - { - struct hit_list *hitp; - fastf_t normalized_dist; - fastf_t dist; - point_t hit_pt; - vect_t to_hit; - fastf_t angle; - - normalized_dist = val[j].re - cor_proj; - dist = normalized_dist * pipe->bend_radius; - - /* check if this hit is within bend angle */ - VJOIN1( hit_pt, rp->r_pt, dist, rp->r_dir ); - VSUB2( to_hit, hit_pt, pipe->bend_V ); - angle = atan2( VDOT( to_hit, pipe->bend_rb ), VDOT( to_hit, pipe->bend_ra ) ); - if ( angle < 0.0 ) - angle += 2.0 * bn_pi; - if ( angle <= pipe->bend_angle ) - { - BU_GETSTRUCT( hitp, hit_list ); - BU_GETSTRUCT( hitp->hitp, hit ); - hitp->hitp->hit_magic = RT_HIT_MAGIC; - hitp->hitp->hit_dist = dist; - VJOIN1( hitp->hitp->hit_vpriv, pprime, normalized_dist, dprime ); - hitp->hitp->hit_surfno = seg_no*10 + PIPE_BEND_INNER_BODY; - BU_LIST_INSERT( &hit_headp->l, &hitp->l ); - root_count++; - } - } + if ( NEAR_ZERO( val[j].im, 0.0001 ) ) { + struct hit *hitp; + fastf_t normalized_dist; + fastf_t dist; + point_t hit_pt; + vect_t to_hit; + fastf_t angle; + + normalized_dist = val[j].re - cor_proj; + dist = normalized_dist * pipe->bend_radius; + + /* check if this hit is within bend angle */ + VJOIN1( hit_pt, rp->r_pt, dist, rp->r_dir ); + VSUB2( to_hit, hit_pt, pipe->bend_V ); + angle = atan2( VDOT( to_hit, pipe->bend_rb ), VDOT( to_hit, pipe->bend_ra ) ); + if ( angle < 0.0 ) + angle += 2.0 * bn_pi; + if ( angle <= pipe->bend_angle ) { + hitp = &hits[*hit_count]; + hitp->hit_magic = RT_HIT_MAGIC; + hitp->hit_dist = dist; + VJOIN1( hitp->hit_vpriv, pprime, normalized_dist, dprime ); + hitp->hit_surfno = seg_no*10 + PIPE_BEND_INNER_BODY; + + if( (*hit_count)++ >= RT_PIPE_MAXHITS ) { + bu_log( "Too many hits (%d) on primitive (%s)\n", *hit_count, stp->st_dp->d_namep); + return; + } + } + } } - - *hit_count += root_count; - - check_discont_radii: + + + check_discont_radii: /* check for surfaces created by discontinuous changes in radii */ prev = BU_LIST_BACK( id_pipe, &pipe->l ); if ( prev->l.magic != BU_LIST_HEAD_MAGIC ) { - if ( prev->pipe_is_bend ) { - /* do not process previous bend - struct bend_pipe *bend = (struct bend_pipe *)prev; - or2_sq = bend->bend_or*bend->bend_or; - ir2_sq = bend->bend_ir*bend->bend_ir; */ - or2_sq = or_sq; - ir2_sq = ir_sq; - } else { - struct lin_pipe *lin = (struct lin_pipe *)prev; - or2_sq = lin->pipe_rotop_sq; - ir2_sq = lin->pipe_ritop_sq; - if ( !NEAR_ZERO( (or_sq - or2_sq), RT_LEN_TOL) || - !NEAR_ZERO( (ir_sq - ir2_sq), RT_LEN_TOL) ) { - discont_radius_shot( rp, seghead, pipe->bend_start, pipe->bend_startNorm, - or_sq, ir_sq, or2_sq, ir2_sq, hit_headp, hit_count, seg_no); - } - } + if ( prev->pipe_is_bend ) { + /* do not process previous bend + * struct bend_pipe *bend = (struct bend_pipe *)prev; + * or2_sq = bend->bend_or*bend->bend_or; + * ir2_sq = bend->bend_ir*bend->bend_ir; */ + or2_sq = or_sq; + ir2_sq = ir_sq; + } else { + struct lin_pipe *lin = (struct lin_pipe *)prev; + or2_sq = lin->pipe_rotop_sq; + ir2_sq = lin->pipe_ritop_sq; + if ( !NEAR_ZERO( (or_sq - or2_sq), RT_LEN_TOL) || + !NEAR_ZERO( (ir_sq - ir2_sq), RT_LEN_TOL) ) { + discont_radius_shot( rp, seghead, pipe->bend_start, pipe->bend_startNorm, + or_sq, ir_sq, or2_sq, ir2_sq, hits, hit_count, seg_no, stp); + } + } } - + next = BU_LIST_NEXT( id_pipe, &pipe->l ); if ( next->l.magic != BU_LIST_HEAD_MAGIC ) { - if ( next->pipe_is_bend ) { - struct bend_pipe *bend = (struct bend_pipe *)next; - or2_sq = bend->bend_or*bend->bend_or; - ir2_sq = bend->bend_ir*bend->bend_ir; - if ( !NEAR_ZERO( (or_sq - or2_sq), RT_LEN_TOL) || - !NEAR_ZERO( (ir_sq - ir2_sq), RT_LEN_TOL) ) { - discont_radius_shot( rp, seghead, pipe->bend_end, pipe->bend_endNorm, - or_sq, ir_sq, or2_sq, ir2_sq, hit_headp, hit_count, seg_no); - } - } else { - struct lin_pipe *lin = (struct lin_pipe *)next; - or2_sq = lin->pipe_robase_sq; - ir2_sq = lin->pipe_ribase_sq; - if ( !NEAR_ZERO( (or_sq - or2_sq), RT_LEN_TOL) || - !NEAR_ZERO( (ir_sq - ir2_sq), RT_LEN_TOL) ) { - discont_radius_shot( rp, seghead, pipe->bend_end, pipe->bend_endNorm, - or_sq, ir_sq, or2_sq, ir2_sq, hit_headp, hit_count, seg_no); - } - } + if ( next->pipe_is_bend ) { + struct bend_pipe *bend = (struct bend_pipe *)next; + or2_sq = bend->bend_or*bend->bend_or; + ir2_sq = bend->bend_ir*bend->bend_ir; + if ( !NEAR_ZERO( (or_sq - or2_sq), RT_LEN_TOL) || + !NEAR_ZERO( (ir_sq - ir2_sq), RT_LEN_TOL) ) { + discont_radius_shot( rp, seghead, pipe->bend_end, pipe->bend_endNorm, + or_sq, ir_sq, or2_sq, ir2_sq, hits, hit_count, seg_no, stp); + } + } else { + struct lin_pipe *lin = (struct lin_pipe *)next; + or2_sq = lin->pipe_robase_sq; + ir2_sq = lin->pipe_ribase_sq; + if ( !NEAR_ZERO( (or_sq - or2_sq), RT_LEN_TOL) || + !NEAR_ZERO( (ir_sq - ir2_sq), RT_LEN_TOL) ) { + discont_radius_shot( rp, seghead, pipe->bend_end, pipe->bend_endNorm, + or_sq, ir_sq, or2_sq, ir2_sq, hits, hit_count, seg_no, stp); + } + } } - - + + return; - + } HIDDEN void -linear_pipe_shot(struct soltab *stp, register struct xray *rp, struct application *ap, struct seg *seghead, struct lin_pipe *pipe, struct hit_list *hit_headp, int *hit_count, int seg_no) -{ - struct hit_list *hitp; +linear_pipe_shot(struct soltab *stp, register struct xray *rp, struct application *ap, struct seg *seghead, struct lin_pipe *pipe, struct hit *hits, int *hit_count, int seg_no) { + struct hit *hitp; point_t work_pt; point_t ray_start; vect_t ray_dir; double t_tmp; double a, b, c; double descrim; - - if ( pipe->pipe_is_bend ) - { - bu_log( "linear_pipe_shot called for pipe bend\n" ); - bu_bomb( "linear_pipe_shot\n" ); + + if ( pipe->pipe_is_bend ) { + bu_log( "linear_pipe_shot called for pipe bend\n" ); + bu_bomb( "linear_pipe_shot\n" ); } - - *hit_count = 0; - + /* transform ray start point */ VSUB2( work_pt, rp->r_pt, pipe->pipe_V ); MAT4X3VEC( ray_start, pipe->pipe_SoR, work_pt ); - + /* rotate ray direction */ MAT4X3VEC( ray_dir, pipe->pipe_SoR, rp->r_dir ); - + /* Intersect with outer sides */ a = ray_dir[X]*ray_dir[X] - + ray_dir[Y]*ray_dir[Y] - - ray_dir[Z]*ray_dir[Z]*pipe->pipe_rodiff_sq; + + ray_dir[Y]*ray_dir[Y] + - ray_dir[Z]*ray_dir[Z]*pipe->pipe_rodiff_sq; b = 2.0*(ray_start[X]*ray_dir[X] - + ray_start[Y]*ray_dir[Y] - - ray_start[Z]*ray_dir[Z]*pipe->pipe_rodiff_sq - - ray_dir[Z]*pipe->pipe_robase*pipe->pipe_rodiff); + + ray_start[Y]*ray_dir[Y] + - ray_start[Z]*ray_dir[Z]*pipe->pipe_rodiff_sq + - ray_dir[Z]*pipe->pipe_robase*pipe->pipe_rodiff); c = ray_start[X]*ray_start[X] - + ray_start[Y]*ray_start[Y] - - pipe->pipe_robase*pipe->pipe_robase - - ray_start[Z]*ray_start[Z]*pipe->pipe_rodiff_sq - - 2.0*ray_start[Z]*pipe->pipe_robase*pipe->pipe_rodiff; - + + ray_start[Y]*ray_start[Y] + - pipe->pipe_robase*pipe->pipe_robase + - ray_start[Z]*ray_start[Z]*pipe->pipe_rodiff_sq + - 2.0*ray_start[Z]*pipe->pipe_robase*pipe->pipe_rodiff; + descrim = b*b - 4.0*a*c; - - if ( descrim > 0.0 ) - { - fastf_t sqrt_descrim; - point_t hit_pt; - - sqrt_descrim = sqrt( descrim ); - - t_tmp = (-b - sqrt_descrim)/(2.0*a); - VJOIN1( hit_pt, ray_start, t_tmp, ray_dir ); - if ( hit_pt[Z] >= 0.0 && hit_pt[Z] <= 1.0 ) - { - BU_GETSTRUCT( hitp, hit_list ); - BU_GETSTRUCT( hitp->hitp, hit ); - hitp->hitp->hit_magic = RT_HIT_MAGIC; - hitp->hitp->hit_dist = t_tmp; - hitp->hitp->hit_surfno = seg_no*10 + PIPE_LINEAR_OUTER_BODY; - VMOVE( hitp->hitp->hit_vpriv, hit_pt ); - hitp->hitp->hit_vpriv[Z] = (-pipe->pipe_robase - hit_pt[Z] * pipe->pipe_rodiff) * - pipe->pipe_rodiff; - (*hit_count)++; - BU_LIST_INSERT( &hit_headp->l, &hitp->l ); - } - - t_tmp = (-b + sqrt_descrim)/(2.0*a); - VJOIN1( hit_pt, ray_start, t_tmp, ray_dir ); - if ( hit_pt[Z] >= 0.0 && hit_pt[Z] <= 1.0 ) - { - BU_GETSTRUCT( hitp, hit_list ); - BU_GETSTRUCT( hitp->hitp, hit ); - hitp->hitp->hit_magic = RT_HIT_MAGIC; - hitp->hitp->hit_dist = t_tmp; - hitp->hitp->hit_surfno = seg_no*10 + PIPE_LINEAR_OUTER_BODY; - VMOVE( hitp->hitp->hit_vpriv, hit_pt ); - hitp->hitp->hit_vpriv[Z] = (-pipe->pipe_robase - hit_pt[Z] * pipe->pipe_rodiff) * - pipe->pipe_rodiff; - (*hit_count)++; - BU_LIST_INSERT( &hit_headp->l, &hitp->l ); - } + + if ( descrim > 0.0 ) { + fastf_t sqrt_descrim; + point_t hit_pt; + + sqrt_descrim = sqrt( descrim ); + + t_tmp = (-b - sqrt_descrim)/(2.0*a); + VJOIN1( hit_pt, ray_start, t_tmp, ray_dir ); + if ( hit_pt[Z] >= 0.0 && hit_pt[Z] <= 1.0 ) { + hitp = &hits[*hit_count]; + hitp->hit_magic = RT_HIT_MAGIC; + hitp->hit_dist = t_tmp; + hitp->hit_surfno = seg_no*10 + PIPE_LINEAR_OUTER_BODY; + VMOVE( hitp->hit_vpriv, hit_pt ); + hitp->hit_vpriv[Z] = (-pipe->pipe_robase - hit_pt[Z] * pipe->pipe_rodiff) * + pipe->pipe_rodiff; + + if( (*hit_count)++ >= RT_PIPE_MAXHITS ) { + bu_log( "Too many hits (%d) on primitive (%s)\n", *hit_count, stp->st_dp->d_namep); + return; + } + } + + t_tmp = (-b + sqrt_descrim)/(2.0*a); + VJOIN1( hit_pt, ray_start, t_tmp, ray_dir ); + if ( hit_pt[Z] >= 0.0 && hit_pt[Z] <= 1.0 ) { + hitp = &hits[*hit_count]; + hitp->hit_magic = RT_HIT_MAGIC; + hitp->hit_dist = t_tmp; + hitp->hit_surfno = seg_no*10 + PIPE_LINEAR_OUTER_BODY; + VMOVE( hitp->hit_vpriv, hit_pt ); + hitp->hit_vpriv[Z] = (-pipe->pipe_robase - hit_pt[Z] * pipe->pipe_rodiff) * + pipe->pipe_rodiff; + + if( (*hit_count)++ >= RT_PIPE_MAXHITS ) { + bu_log( "Too many hits (%d) on primitive (%s)\n", *hit_count, stp->st_dp->d_namep); + return; + } + } } - - if ( pipe->pipe_ribase > 0.0 || pipe->pipe_ritop > 0.0 ) - { - /* Intersect with inner sides */ - - a = ray_dir[X]*ray_dir[X] - + ray_dir[Y]*ray_dir[Y] - - ray_dir[Z]*ray_dir[Z]*pipe->pipe_ridiff_sq; - b = 2.0*(ray_start[X]*ray_dir[X] - + ray_start[Y]*ray_dir[Y] - - ray_start[Z]*ray_dir[Z]*pipe->pipe_ridiff_sq - - ray_dir[Z]*pipe->pipe_ribase*pipe->pipe_ridiff); - c = ray_start[X]*ray_start[X] - + ray_start[Y]*ray_start[Y] - - pipe->pipe_ribase*pipe->pipe_ribase - - ray_start[Z]*ray_start[Z]*pipe->pipe_ridiff_sq - - 2.0*ray_start[Z]*pipe->pipe_ribase*pipe->pipe_ridiff; - - descrim = b*b - 4.0*a*c; - - if ( descrim > 0.0 ) - { - fastf_t sqrt_descrim; - point_t hit_pt; - - sqrt_descrim = sqrt( descrim ); - - t_tmp = (-b - sqrt_descrim)/(2.0*a); - VJOIN1( hit_pt, ray_start, t_tmp, ray_dir ); - if ( hit_pt[Z] >= 0.0 && hit_pt[Z] <= 1.0 ) - { - BU_GETSTRUCT( hitp, hit_list ); - BU_GETSTRUCT( hitp->hitp, hit ); - hitp->hitp->hit_magic = RT_HIT_MAGIC; - hitp->hitp->hit_dist = t_tmp; - hitp->hitp->hit_surfno = seg_no*10 + PIPE_LINEAR_INNER_BODY; - VMOVE( hitp->hitp->hit_vpriv, hit_pt ); - hitp->hitp->hit_vpriv[Z] = (-pipe->pipe_ribase - hit_pt[Z] * pipe->pipe_ridiff) * - pipe->pipe_ridiff; - (*hit_count)++; - BU_LIST_INSERT( &hit_headp->l, &hitp->l ); - } - - t_tmp = (-b + sqrt_descrim)/(2.0*a); - VJOIN1( hit_pt, ray_start, t_tmp, ray_dir ); - if ( hit_pt[Z] >= 0.0 && hit_pt[Z] <= 1.0 ) - { - BU_GETSTRUCT( hitp, hit_list ); - BU_GETSTRUCT( hitp->hitp, hit ); - hitp->hitp->hit_magic = RT_HIT_MAGIC; - hitp->hitp->hit_dist = t_tmp; - hitp->hitp->hit_surfno = seg_no*10 + PIPE_LINEAR_INNER_BODY; - VMOVE( hitp->hitp->hit_vpriv, hit_pt ); - hitp->hitp->hit_vpriv[Z] = (-pipe->pipe_ribase - hit_pt[Z] * pipe->pipe_ridiff) * - pipe->pipe_ridiff; - (*hit_count)++; - BU_LIST_INSERT( &hit_headp->l, &hitp->l ); - } - } + + if ( pipe->pipe_ribase > 0.0 || pipe->pipe_ritop > 0.0 ) { + /* Intersect with inner sides */ + + a = ray_dir[X]*ray_dir[X] + + ray_dir[Y]*ray_dir[Y] + - ray_dir[Z]*ray_dir[Z]*pipe->pipe_ridiff_sq; + b = 2.0*(ray_start[X]*ray_dir[X] + + ray_start[Y]*ray_dir[Y] + - ray_start[Z]*ray_dir[Z]*pipe->pipe_ridiff_sq + - ray_dir[Z]*pipe->pipe_ribase*pipe->pipe_ridiff); + c = ray_start[X]*ray_start[X] + + ray_start[Y]*ray_start[Y] + - pipe->pipe_ribase*pipe->pipe_ribase + - ray_start[Z]*ray_start[Z]*pipe->pipe_ridiff_sq + - 2.0*ray_start[Z]*pipe->pipe_ribase*pipe->pipe_ridiff; + + descrim = b*b - 4.0*a*c; + + if ( descrim > 0.0 ) { + fastf_t sqrt_descrim; + point_t hit_pt; + + sqrt_descrim = sqrt( descrim ); + + t_tmp = (-b - sqrt_descrim)/(2.0*a); + VJOIN1( hit_pt, ray_start, t_tmp, ray_dir ); + if ( hit_pt[Z] >= 0.0 && hit_pt[Z] <= 1.0 ) { + hitp = &hits[*hit_count]; + hitp->hit_magic = RT_HIT_MAGIC; + hitp->hit_dist = t_tmp; + hitp->hit_surfno = seg_no*10 + PIPE_LINEAR_INNER_BODY; + VMOVE( hitp->hit_vpriv, hit_pt ); + hitp->hit_vpriv[Z] = (-pipe->pipe_ribase - hit_pt[Z] * pipe->pipe_ridiff) * + pipe->pipe_ridiff; + + if( (*hit_count)++ >= RT_PIPE_MAXHITS ) { + bu_log( "Too many hits (%d) on primitive (%s)\n", *hit_count, stp->st_dp->d_namep); + return; + } + } + + t_tmp = (-b + sqrt_descrim)/(2.0*a); + VJOIN1( hit_pt, ray_start, t_tmp, ray_dir ); + if ( hit_pt[Z] >= 0.0 && hit_pt[Z] <= 1.0 ) { + hitp = &hits[*hit_count]; + hitp->hit_magic = RT_HIT_MAGIC; + hitp->hit_dist = t_tmp; + hitp->hit_surfno = seg_no*10 + PIPE_LINEAR_INNER_BODY; + VMOVE( hitp->hit_vpriv, hit_pt ); + hitp->hit_vpriv[Z] = (-pipe->pipe_ribase - hit_pt[Z] * pipe->pipe_ridiff) * + pipe->pipe_ridiff; + + if( (*hit_count)++ >= RT_PIPE_MAXHITS ) { + bu_log( "Too many hits (%d) on primitive (%s)\n", *hit_count, stp->st_dp->d_namep); + return; + } + } + } } - + } HIDDEN void -pipe_start_shot(struct soltab *stp, register struct xray *rp, struct application *ap, struct seg *seghead, struct id_pipe *pipe, struct hit_list *hit_headp, int *hit_count, int seg_no) -{ +pipe_start_shot(struct soltab *stp, register struct xray *rp, struct application *ap, struct seg *seghead, struct id_pipe *pipe, struct hit *hits, int *hit_count, int seg_no) { point_t hit_pt; fastf_t t_tmp; fastf_t radius_sq; - struct hit_list *hitp; - - *hit_count = 0; - - if ( !pipe->pipe_is_bend ) - { - struct lin_pipe *lin=(struct lin_pipe *)(&pipe->l); - fastf_t dist_to_plane; - fastf_t norm_dist; - fastf_t slant_factor; - - dist_to_plane = VDOT( lin->pipe_H, lin->pipe_V ); - norm_dist = dist_to_plane - VDOT( lin->pipe_H, rp->r_pt ); - slant_factor = VDOT( lin->pipe_H, rp->r_dir ); - if ( !NEAR_ZERO( slant_factor, SMALL_FASTF ) ) - { - vect_t to_center; - - t_tmp = norm_dist/slant_factor; - VJOIN1( hit_pt, rp->r_pt, t_tmp, rp->r_dir ); - VSUB2( to_center, lin->pipe_V, hit_pt ); - radius_sq = MAGSQ( to_center ); - if ( radius_sq <= lin->pipe_robase_sq && radius_sq >= lin->pipe_ribase_sq ) - { - BU_GETSTRUCT( hitp, hit_list ); - BU_GETSTRUCT( hitp->hitp, hit ); - hitp->hitp->hit_magic = RT_HIT_MAGIC; - hitp->hitp->hit_dist = t_tmp; - hitp->hitp->hit_surfno = seg_no*10 + PIPE_LINEAR_BASE; - (*hit_count)++; - BU_LIST_INSERT( &hit_headp->l, &hitp->l ); - } - } + struct hit *hitp; + + + if ( !pipe->pipe_is_bend ) { + struct lin_pipe *lin=(struct lin_pipe *)(&pipe->l); + fastf_t dist_to_plane; + fastf_t norm_dist; + fastf_t slant_factor; + + dist_to_plane = VDOT( lin->pipe_H, lin->pipe_V ); + norm_dist = dist_to_plane - VDOT( lin->pipe_H, rp->r_pt ); + slant_factor = VDOT( lin->pipe_H, rp->r_dir ); + if ( !NEAR_ZERO( slant_factor, SMALL_FASTF ) ) { + vect_t to_center; + + t_tmp = norm_dist/slant_factor; + VJOIN1( hit_pt, rp->r_pt, t_tmp, rp->r_dir ); + VSUB2( to_center, lin->pipe_V, hit_pt ); + radius_sq = MAGSQ( to_center ); + if ( radius_sq <= lin->pipe_robase_sq && radius_sq >= lin->pipe_ribase_sq ) { + hitp = &hits[*hit_count]; + hitp->hit_magic = RT_HIT_MAGIC; + hitp->hit_dist = t_tmp; + hitp->hit_surfno = seg_no*10 + PIPE_LINEAR_BASE; + + if( (*hit_count)++ >= RT_PIPE_MAXHITS ) { + bu_log( "Too many hits (%d) on primitive (%s)\n", *hit_count, stp->st_dp->d_namep); + return; + } + } + } } - else if ( pipe->pipe_is_bend ) - { - struct bend_pipe *bend=(struct bend_pipe *)(&pipe->l); - fastf_t dist_to_plane; - fastf_t norm_dist; - fastf_t slant_factor; - - dist_to_plane = VDOT( bend->bend_rb, bend->bend_start ); - norm_dist = dist_to_plane - VDOT( bend->bend_rb, rp->r_pt ); - slant_factor = VDOT( bend->bend_rb, rp->r_dir ); - - if ( !NEAR_ZERO( slant_factor, SMALL_FASTF ) ) - { - vect_t to_center; - - t_tmp = norm_dist/slant_factor; - VJOIN1( hit_pt, rp->r_pt, t_tmp, rp->r_dir ); - VSUB2( to_center, bend->bend_start, hit_pt ); - radius_sq = MAGSQ( to_center ); - if ( radius_sq <= bend->bend_or*bend->bend_or && radius_sq >= bend->bend_ir*bend->bend_ir ) - { - BU_GETSTRUCT( hitp, hit_list ); - BU_GETSTRUCT( hitp->hitp, hit ); - hitp->hitp->hit_magic = RT_HIT_MAGIC; - hitp->hitp->hit_dist = t_tmp; - hitp->hitp->hit_surfno = seg_no*10 + PIPE_BEND_BASE; - (*hit_count)++; - BU_LIST_INSERT( &hit_headp->l, &hitp->l ); - } - } + else if ( pipe->pipe_is_bend ) { + struct bend_pipe *bend=(struct bend_pipe *)(&pipe->l); + fastf_t dist_to_plane; + fastf_t norm_dist; + fastf_t slant_factor; + + dist_to_plane = VDOT( bend->bend_rb, bend->bend_start ); + norm_dist = dist_to_plane - VDOT( bend->bend_rb, rp->r_pt ); + slant_factor = VDOT( bend->bend_rb, rp->r_dir ); + + if ( !NEAR_ZERO( slant_factor, SMALL_FASTF ) ) { + vect_t to_center; + + t_tmp = norm_dist/slant_factor; + VJOIN1( hit_pt, rp->r_pt, t_tmp, rp->r_dir ); + VSUB2( to_center, bend->bend_start, hit_pt ); + radius_sq = MAGSQ( to_center ); + if ( radius_sq <= bend->bend_or*bend->bend_or && radius_sq >= bend->bend_ir*bend->bend_ir ) { + hitp = &hits[*hit_count]; + hitp->hit_magic = RT_HIT_MAGIC; + hitp->hit_dist = t_tmp; + hitp->hit_surfno = seg_no*10 + PIPE_BEND_BASE; + + if( (*hit_count)++ >= RT_PIPE_MAXHITS ) { + bu_log( "Too many hits (%d) on primitive (%s)\n", *hit_count, stp->st_dp->d_namep); + return; + } + } + } } } HIDDEN void -pipe_end_shot(struct soltab *stp, register struct xray *rp, struct application *ap, struct seg *seghead, struct id_pipe *pipe, struct hit_list *hit_headp, int *hit_count, int seg_no) -{ +pipe_end_shot(struct soltab *stp, register struct xray *rp, struct application *ap, struct seg *seghead, struct id_pipe *pipe, struct hit *hits, int *hit_count, int seg_no) { point_t hit_pt; fastf_t t_tmp; fastf_t radius_sq; - struct hit_list *hitp; - - *hit_count = 0; - - if ( !pipe->pipe_is_bend ) - { - struct lin_pipe *lin=(struct lin_pipe *)(&pipe->l); - point_t top; - fastf_t dist_to_plane; - fastf_t norm_dist; - fastf_t slant_factor; - - VJOIN1( top, lin->pipe_V, lin->pipe_len, lin->pipe_H ); - dist_to_plane = VDOT( lin->pipe_H, top ); - norm_dist = dist_to_plane - VDOT( lin->pipe_H, rp->r_pt ); - slant_factor = VDOT( lin->pipe_H, rp->r_dir ); - if ( !NEAR_ZERO( slant_factor, SMALL_FASTF ) ) - { - vect_t to_center; - - t_tmp = norm_dist/slant_factor; - VJOIN1( hit_pt, rp->r_pt, t_tmp, rp->r_dir ); - VSUB2( to_center, top, hit_pt ); - radius_sq = MAGSQ( to_center ); - if ( radius_sq <= lin->pipe_rotop_sq && radius_sq >= lin->pipe_ritop_sq ) - { - BU_GETSTRUCT( hitp, hit_list ); - BU_GETSTRUCT( hitp->hitp, hit ); - hitp->hitp->hit_magic = RT_HIT_MAGIC; - hitp->hitp->hit_dist = t_tmp; - hitp->hitp->hit_surfno = seg_no*10 + PIPE_LINEAR_TOP; - (*hit_count)++; - BU_LIST_INSERT( &hit_headp->l, &hitp->l ); - } - } + struct hit *hitp; + + if ( !pipe->pipe_is_bend ) { + struct lin_pipe *lin=(struct lin_pipe *)(&pipe->l); + point_t top; + fastf_t dist_to_plane; + fastf_t norm_dist; + fastf_t slant_factor; + + VJOIN1( top, lin->pipe_V, lin->pipe_len, lin->pipe_H ); + dist_to_plane = VDOT( lin->pipe_H, top ); + norm_dist = dist_to_plane - VDOT( lin->pipe_H, rp->r_pt ); + slant_factor = VDOT( lin->pipe_H, rp->r_dir ); + if ( !NEAR_ZERO( slant_factor, SMALL_FASTF ) ) { + vect_t to_center; + + t_tmp = norm_dist/slant_factor; + VJOIN1( hit_pt, rp->r_pt, t_tmp, rp->r_dir ); + VSUB2( to_center, top, hit_pt ); + radius_sq = MAGSQ( to_center ); + if ( radius_sq <= lin->pipe_rotop_sq && radius_sq >= lin->pipe_ritop_sq ) { + hitp = &hits[*hit_count]; + hitp->hit_magic = RT_HIT_MAGIC; + hitp->hit_dist = t_tmp; + hitp->hit_surfno = seg_no*10 + PIPE_LINEAR_TOP; + + if( (*hit_count)++ >= RT_PIPE_MAXHITS ) { + bu_log( "Too many hits (%d) on primitive (%s)\n", *hit_count, stp->st_dp->d_namep); + return; + } + } + } } - else if ( pipe->pipe_is_bend ) - { - struct bend_pipe *bend=(struct bend_pipe *)(&pipe->l); - vect_t to_end; - vect_t plane_norm; - fastf_t dist_to_plane; - fastf_t norm_dist; - fastf_t slant_factor; - - VSUB2( to_end, bend->bend_end, bend->bend_V ); - VCROSS( plane_norm, to_end, bend->bend_N ); - VUNITIZE( plane_norm ); - - dist_to_plane = VDOT( plane_norm, bend->bend_end ); - norm_dist = dist_to_plane - VDOT( plane_norm, rp->r_pt ); - slant_factor = VDOT( plane_norm, rp->r_dir ); - - if ( !NEAR_ZERO( slant_factor, SMALL_FASTF ) ) - { - vect_t to_center; - - t_tmp = norm_dist/slant_factor; - VJOIN1( hit_pt, rp->r_pt, t_tmp, rp->r_dir ); - VSUB2( to_center, bend->bend_end, hit_pt ); - radius_sq = MAGSQ( to_center ); - if ( radius_sq <= bend->bend_or*bend->bend_or && radius_sq >= bend->bend_ir*bend->bend_ir ) - { - BU_GETSTRUCT( hitp, hit_list ); - BU_GETSTRUCT( hitp->hitp, hit ); - hitp->hitp->hit_magic = RT_HIT_MAGIC; - hitp->hitp->hit_dist = t_tmp; - hitp->hitp->hit_surfno = seg_no*10 + PIPE_BEND_TOP; - (*hit_count)++; - BU_LIST_INSERT( &hit_headp->l, &hitp->l ); - } - } + else if ( pipe->pipe_is_bend ) { + struct bend_pipe *bend=(struct bend_pipe *)(&pipe->l); + vect_t to_end; + vect_t plane_norm; + fastf_t dist_to_plane; + fastf_t norm_dist; + fastf_t slant_factor; + + VSUB2( to_end, bend->bend_end, bend->bend_V ); + VCROSS( plane_norm, to_end, bend->bend_N ); + VUNITIZE( plane_norm ); + + dist_to_plane = VDOT( plane_norm, bend->bend_end ); + norm_dist = dist_to_plane - VDOT( plane_norm, rp->r_pt ); + slant_factor = VDOT( plane_norm, rp->r_dir ); + + if ( !NEAR_ZERO( slant_factor, SMALL_FASTF ) ) { + vect_t to_center; + + t_tmp = norm_dist/slant_factor; + VJOIN1( hit_pt, rp->r_pt, t_tmp, rp->r_dir ); + VSUB2( to_center, bend->bend_end, hit_pt ); + radius_sq = MAGSQ( to_center ); + if ( radius_sq <= bend->bend_or*bend->bend_or && radius_sq >= bend->bend_ir*bend->bend_ir ) { + hitp = &hits[*hit_count]; + hitp->hit_magic = RT_HIT_MAGIC; + hitp->hit_dist = t_tmp; + hitp->hit_surfno = seg_no*10 + PIPE_BEND_TOP; + + if( (*hit_count)++ >= RT_PIPE_MAXHITS ) { + bu_log( "Too many hits (%d) on primitive (%s)\n", *hit_count, stp->st_dp->d_namep); + return; + } + } + } } } HIDDEN void -rt_pipe_hitsort(struct hit_list *h, int *nh, register struct xray *rp, struct soltab *stp) -{ - struct hit_list *hitp; - struct hit_list *first; - struct hit_list *second; - struct hit_list *prev; - struct hit_list *next_hit; - - hitp = BU_LIST_FIRST( hit_list, &h->l ); - while ( BU_LIST_NEXT_NOT_HEAD( &hitp->l, &h->l ) ) - { - struct hit_list *next_hit; - struct hit_list *prev_hit; - - next_hit = BU_LIST_NEXT( hit_list, &hitp->l ); - if ( hitp->hitp->hit_dist > next_hit->hitp->hit_dist ) - { - struct hit_list *tmp; - - if ( hitp == BU_LIST_FIRST( hit_list, &h->l ) ) - prev_hit = (struct hit_list *)NULL; - else - prev_hit = BU_LIST_PREV( hit_list, &hitp->l ); - - /* move this hit to the end of the list */ - tmp = hitp; - BU_LIST_DEQUEUE( &tmp->l ); - BU_LIST_INSERT( &h->l, &tmp->l ); - - if ( prev_hit ) - hitp = prev_hit; - else - hitp = BU_LIST_FIRST( hit_list, &h->l ); - } - else - hitp = next_hit; - } - +rt_pipe_elim_dups(struct hit *hit, int *nh, register struct xray *rp, struct soltab *stp) { + struct hit *hitp; + struct hit *next_hit; + int hitNo = 0; + /* delete duplicate hits */ - hitp = BU_LIST_FIRST( hit_list, &h->l ); - while ( BU_LIST_NEXT_NOT_HEAD( &hitp->l, &h->l ) ) - { - next_hit = BU_LIST_NEXT( hit_list, &hitp->l ); - - if ( NEAR_ZERO( hitp->hitp->hit_dist - next_hit->hitp->hit_dist, 0.00001) && - hitp->hitp->hit_surfno == next_hit->hitp->hit_surfno ) - { - struct hit_list *tmp; - - tmp = hitp; - hitp = next_hit; - BU_LIST_DEQUEUE( &tmp->l ); - bu_free( (char *)tmp->hitp, "rt_pipe_hitsort: tmp->hitp" ); - bu_free( (char *)tmp, "rt_pipe_hitsort: tmp" ); - (*nh)--; - tmp = hitp; - next_hit = BU_LIST_NEXT( hit_list, &hitp->l ); - hitp = next_hit; - BU_LIST_DEQUEUE( &tmp->l ); - bu_free( (char *)tmp->hitp, "rt_pipe_hitsort: tmp->hitp" ); - bu_free( (char *)tmp, "rt_pipe_hitsort: tmp" ); - (*nh)--; - if ( BU_LIST_IS_HEAD( &hitp->l, &h->l ) ) - break; - } - else - hitp = next_hit; + while ( hitNo < (*nh-1) ) { + hitp = &hit[hitNo]; + next_hit = &hit[hitNo+1]; + + if ( NEAR_ZERO( hitp->hit_dist - next_hit->hit_dist, 0.00001) && + hitp->hit_surfno == next_hit->hit_surfno ) { + int i; + for( i=hitNo ; i<*nh ; i++ ) { + hit[i] = hit[i+1]; + } + *nh--; + } else { + hitNo++; + } } - - if ( *nh == 1 ) - { - while ( BU_LIST_WHILE( hitp, hit_list, &h->l ) ) - { - BU_LIST_DEQUEUE( &hitp->l ); - bu_free( (char *)hitp->hitp, "pipe_hitsort: hitp->hitp" ); - bu_free( (char *)hitp, "pipe_hitsort: hitp" ); - } - (*nh) = 0; - return; + + if ( *nh == 1 ) { + (*nh) = 0; + return; } - + if ( *nh == 0 || *nh == 2 ) - return; - + return; + /* handle cases where this pipe overlaps with itself */ - first = BU_LIST_FIRST( hit_list, &h->l ); - if ( VDOT( first->hitp->hit_normal, rp->r_dir ) > 0.0 ) - { - - bu_log( "ERROR: first hit on %s (surfno = %d) is an exit at (%g %g %g)\n", - stp->st_dp->d_namep, first->hitp->hit_surfno, V3ARGS( first->hitp->hit_point ) ); - bu_log( "\tray start = (%.12e %.12e %.12e), ray dir = (%.12e %.12e %.12e)\n", - V3ARGS( rp->r_pt ),... [truncated message content] |