int main(int argc, char **argv) { vect_t norm; unsigned char rgb[3]; int ix; double x; double size; int quant; struct wmember head; vect_t bmin, bmax, bthick; vect_t r1min, r1max, r1thick; vect_t lwh; /* length, width, height */ vect_t pbase; BU_LIST_INIT( &head.l ); MAT_IDN( identity ); sin60 = sin(60.0 * 3.14159265358979323846264 / 180.0); outfp = wdb_fopen("room.g"); mk_id( outfp, "Procedural Rooms" ); /* Create the building */ VSET( bmin, 0, 0, 0 ); VSET( bmax, 80000, 60000, HEIGHT ); VSET( bthick, 100, 100, 100 ); make_room( "bldg", bmin, bmax, bthick, &head ); /* Create the first room */ VSET( r1thick, 100, 100, 0 ); VMOVE( r1min, bmin ); VSET( r1max, 40000, 10000, HEIGHT ); VADD2( r1max, r1min, r1max ); make_walls( "rm1", r1min, r1max, r1thick, NORTH|EAST, &head ); make_carpet( "rm1carpet", r1min, r1max, "carpet.pix", &head ); /* Create the golden earth */ VSET( norm, 0, 0, 1 ); mk_half( outfp, "plane", norm, -bthick[Z]-10.0 ); rgb[0] = 240; /* gold/brown */ rgb[1] = 180; rgb[2] = 64; mk_region1( outfp, "plane.r", "plane", NULL, NULL, rgb ); (void)mk_addmember( "plane.r", &head.l, NULL, WMOP_UNION ); /* Create the display pillars */ size = 4000; /* separation between centers */ quant = 5; /* pairs */ VSET( lwh, 400, 400, 1000 ); for ( ix=quant-1; ix>=0; ix-- ) { x = 10000 + ix*size; VSET( pbase, x, 10000*.25, r1min[Z] ); make_pillar( "Pil", ix, 0, pbase, lwh, &head ); VSET( pbase, x, 10000*.75, r1min[Z] ); make_pillar( "Pil", ix, 1, pbase, lwh, &head ); } #ifdef never /* Create some light */ white[0] = white[1] = white[2] = 255; base = size*(quant/2+1); VSET( aim, 0, 0, 0 ); VSET( pos, base, base, minheight+maxheight*bn_rand0to1(randp) ); do_light( "l1", pos, aim, 1, 100.0, white, &head ); VSET( pos, -base, base, minheight+maxheight*bn_rand0to1(randp) ); do_light( "l2", pos, aim, 1, 100.0, white, &head ); VSET( pos, -base, -base, minheight+maxheight*bn_rand0to1(randp) ); do_light( "l3", pos, aim, 1, 100.0, white, &head ); VSET( pos, base, -base, minheight+maxheight*bn_rand0to1(randp) ); do_light( "l4", pos, aim, 1, 100.0, white, &head ); #endif /* Build the overall combination */ mk_lfcomb( outfp, "room", &head, 0 ); return 0; }
/* * G E T S O L I D * * Returns - * -1 error * 0 conversion OK * 1 EOF */ int getsolid(void) { char given_solid_num[16]; char solid_type[16]; int i; double r1, r2; vect_t work; double m1, m2; /* Magnitude temporaries */ char *name=NULL; double dd[4*6]; /* 4 cards of 6 nums each */ point_t tmp[8]; /* 8 vectors of 3 nums each */ int ret; #define D(_i) (&(dd[_i*3])) #define T(_i) (&(tmp[_i][0])) if ( (i = get_line( scard, sizeof(scard), "solid card" )) == EOF ) { printf("getsolid: unexpected EOF\n"); return( 1 ); } switch ( version ) { case 5: bu_strlcpy( given_solid_num, scard+0, sizeof(given_solid_num) ); given_solid_num[5] = '\0'; bu_strlcpy( solid_type, scard+5, sizeof(solid_type) ); solid_type[5] = '\0'; break; case 4: bu_strlcpy( given_solid_num, scard+0, sizeof(given_solid_num) ); given_solid_num[3] = '\0'; bu_strlcpy( solid_type, scard+3, sizeof(solid_type) ); solid_type[7] = '\0'; break; case 1: /* DoE/MORSE version, believed to be original MAGIC format */ bu_strlcpy( given_solid_num, scard+5, sizeof(given_solid_num) ); given_solid_num[4] = '\0'; bu_strlcpy( solid_type, scard+2, sizeof(solid_type) ); break; default: fprintf(stderr, "getsolid() version %d unimplemented\n", version); bu_exit(1, NULL); break; } /* Trim trailing spaces */ trim_trail_spaces( given_solid_num ); trim_trail_spaces( solid_type ); /* another solid - increment solid counter * rather than using number from the card, which may go into * pseudo-hex format in version 4 models (due to 3 column limit). */ sol_work++; if ( version == 5 ) { if ( (i = getint( scard, 0, 5 )) != sol_work ) { printf("expected solid card %d, got %d, abort\n", sol_work, i ); return(1); } } /* Reduce solid type to lower case */ { register char *cp; register char c; cp = solid_type; while ( (c = *cp) != '\0' ) { if ( !isascii(c) ) { *cp++ = '?'; } else if ( isupper(c) ) { *cp++ = tolower(c); } else { cp++; } } } namecvt( sol_work, &name, 's' ); if (verbose) col_pr( name ); if ( strcmp( solid_type, "end" ) == 0 ) { /* DoE/MORSE version 1 format */ bu_free( name, "name" ); return(1); /* END */ } if ( strcmp( solid_type, "ars" ) == 0 ) { int ncurves; int pts_per_curve; double **curve; ncurves = getint( scard, 10, 10 ); pts_per_curve = getint( scard, 20, 10 ); /* Allocate curves pointer array */ curve = (double **)bu_malloc((ncurves+1)*sizeof(double *), "curve"); /* Allocate space for a curve, and read it in */ for ( i=0; i<ncurves; i++ ) { curve[i] = (double *)bu_malloc((pts_per_curve+1)*3*sizeof(double), "curve[i]" ); /* Get data for this curve */ if ( getxsoldata( curve[i], pts_per_curve*3, sol_work ) < 0 ) { printf("ARS %d: getxsoldata failed, curve %d\n", sol_work, i); return(-1); } } if ( (ret = mk_ars( outfp, name, ncurves, pts_per_curve, curve )) < 0 ) { printf("mk_ars(%s) failed\n", name ); /* Need to free memory; 'ret' is returned below */ } for ( i=0; i<ncurves; i++ ) { bu_free( (char *)curve[i], "curve[i]" ); } bu_free( (char *)curve, "curve" ); bu_free( name, "name" ); return(ret); } if ( strcmp( solid_type, "rpp" ) == 0 ) { double min[3], max[3]; if ( getsoldata( dd, 2*3, sol_work ) < 0 ) return(-1); VSET( min, dd[0], dd[2], dd[4] ); VSET( max, dd[1], dd[3], dd[5] ); ret = mk_rpp( outfp, name, min, max ); bu_free( name, "name" ); return(ret); } if ( strcmp( solid_type, "box" ) == 0 ) { if ( getsoldata( dd, 4*3, sol_work ) < 0 ) return(-1); VMOVE( T(0), D(0) ); VADD2( T(1), D(0), D(2) ); VADD3( T(2), D(0), D(2), D(1) ); VADD2( T(3), D(0), D(1) ); VADD2( T(4), D(0), D(3) ); VADD3( T(5), D(0), D(3), D(2) ); VADD4( T(6), D(0), D(3), D(2), D(1) ); VADD3( T(7), D(0), D(3), D(1) ); ret = mk_arb8( outfp, name, &tmp[0][X] ); bu_free( name, "name" ); return(ret); } if ( strcmp( solid_type, "raw" ) == 0 || strcmp( solid_type, "wed" ) == 0 /* DoE name */ ) { if ( getsoldata( dd, 4*3, sol_work ) < 0 ) return(-1); VMOVE( T(0), D(0) ); VADD2( T(1), D(0), D(2) ); VMOVE( T(2), T(1) ); VADD2( T(3), D(0), D(1) ); VADD2( T(4), D(0), D(3) ); VADD3( T(5), D(0), D(3), D(2) ); VMOVE( T(6), T(5) ); VADD3( T(7), D(0), D(3), D(1) ); ret = mk_arb8( outfp, name, &tmp[0][X] ); bu_free( name, "name" ); return(ret); } if ( strcmp( solid_type, "rvw" ) == 0 ) { /* Right Vertical Wedge (Origin: DoE/MORSE) */ double a2, theta, phi, h2; double a2theta; double angle1, angle2; vect_t a, b, c; if ( getsoldata( dd, 1*3+4, sol_work ) < 0 ) return(-1); a2 = dd[3]; /* XY side length */ theta = dd[4]; phi = dd[5]; h2 = dd[6]; /* height in +Z */ angle1 = (phi+theta-90) * bn_degtorad; angle2 = (phi+theta) * bn_degtorad; a2theta = a2 * tan(theta * bn_degtorad); VSET( a, a2theta*cos(angle1), a2theta*sin(angle1), 0 ); VSET( b, -a2*cos(angle2), -a2*sin(angle2), 0 ); VSET( c, 0, 0, h2 ); VSUB2( T(0), D(0), b ); VMOVE( T(1), D(0) ); VMOVE( T(2), D(0) ); VADD2( T(3), T(0), a ); VADD2( T(4), T(0), c ); VADD2( T(5), T(1), c ); VMOVE( T(6), T(5) ); VADD2( T(7), T(3), c ); ret = mk_arb8( outfp, name, &tmp[0][X] ); bu_free( name, "name" ); return(ret); } if ( strcmp( solid_type, "arw" ) == 0) { /* ARbitrary Wedge --- ERIM */ if ( getsoldata( dd, 4*3, sol_work ) < 0) return(-1); VMOVE( T(0), D(0) ); VADD2( T(1), D(0), D(2) ); VADD3( T(2), D(0), D(2), D(3) ); VADD2( T(3), D(0), D(3) ); VADD2( T(4), D(0), D(1) ); VMOVE( T(5), T(4) ); VADD3( T(6), D(0), D(1), D(3) ); VMOVE( T(7), T(6) ); ret = mk_arb8( outfp, name, &tmp[0][X]); bu_free( name, "name" ); return(ret); } if ( strcmp( solid_type, "arb8" ) == 0 ) { if ( getsoldata( dd, 8*3, sol_work ) < 0 ) return(-1); ret = mk_arb8( outfp, name, dd ); bu_free( name, "name" ); return(ret); } if ( strcmp( solid_type, "arb7" ) == 0 ) { if ( getsoldata( dd, 7*3, sol_work ) < 0 ) return(-1); VMOVE( D(7), D(4) ); ret = mk_arb8( outfp, name, dd ); bu_free( name, "name" ); return(ret); } if ( strcmp( solid_type, "arb6" ) == 0 ) { if ( getsoldata( dd, 6*3, sol_work ) < 0 ) return(-1); /* Note that the ordering is important, as data is in D(4), D(5) */ VMOVE( D(7), D(5) ); VMOVE( D(6), D(5) ); VMOVE( D(5), D(4) ); ret = mk_arb8( outfp, name, dd ); bu_free( name, "name" ); return(ret); } if ( strcmp( solid_type, "arb5" ) == 0 ) { if ( getsoldata( dd, 5*3, sol_work ) < 0 ) return(-1); VMOVE( D(5), D(4) ); VMOVE( D(6), D(4) ); VMOVE( D(7), D(4) ); ret = mk_arb8( outfp, name, dd ); bu_free( name, "name" ); return(ret); } if ( strcmp( solid_type, "arb4" ) == 0 ) { if ( getsoldata( dd, 4*3, sol_work ) < 0 ) return(-1); ret = mk_arb4( outfp, name, dd ); bu_free( name, "name" ); return(ret); } if ( strcmp( solid_type, "rcc" ) == 0 ) { /* V, H, r */ if ( getsoldata( dd, 2*3+1, sol_work ) < 0 ) return(-1); ret = mk_rcc( outfp, name, D(0), D(1), dd[6] ); bu_free( name, "name" ); return(ret); } if ( strcmp( solid_type, "rec" ) == 0 ) { /* V, H, A, B */ if ( getsoldata( dd, 4*3, sol_work ) < 0 ) return(-1); ret = mk_tgc( outfp, name, D(0), D(1), D(2), D(3), D(2), D(3) ); bu_free( name, "name" ); return(ret); } if ( strcmp( solid_type, "trc" ) == 0 ) { /* V, H, r1, r2 */ if ( getsoldata( dd, 2*3+2, sol_work ) < 0 ) return(-1); ret = mk_trc_h( outfp, name, D(0), D(1), dd[6], dd[7] ); bu_free( name, "name" ); return(ret); } if ( strcmp( solid_type, "tec" ) == 0 ) { /* V, H, A, B, p */ if ( getsoldata( dd, 4*3+1, sol_work ) < 0 ) return(-1); r1 = 1.0/dd[12]; /* P */ VSCALE( D(4), D(2), r1 ); VSCALE( D(5), D(3), r1 ); ret = mk_tgc( outfp, name, D(0), D(1), D(2), D(3), D(4), D(5) ); bu_free( name, "name" ); return(ret); } if ( strcmp( solid_type, "tgc" ) == 0 ) { /* V, H, A, B, r1, r2 */ if ( getsoldata( dd, 4*3+2, sol_work ) < 0 ) return(-1); r1 = dd[12] / MAGNITUDE( D(2) ); /* A/|A| * C */ r2 = dd[13] / MAGNITUDE( D(3) ); /* B/|B| * D */ VSCALE( D(4), D(2), r1 ); VSCALE( D(5), D(3), r2 ); ret = mk_tgc( outfp, name, D(0), D(1), D(2), D(3), D(4), D(5) ); bu_free( name, "name" ); return(ret); } if ( strcmp( solid_type, "sph" ) == 0 ) { /* V, radius */ if ( getsoldata( dd, 1*3+1, sol_work ) < 0 ) return(-1); ret = mk_sph( outfp, name, D(0), dd[3] ); bu_free( name, "name" ); return(ret); } if ( strncmp( solid_type, "wir", 3 ) == 0 ) { int numpts; /* points per wire */ int num; int i; double dia; double *pts; /* 3 entries per pt */ struct wdb_pipept *ps; struct bu_list head; /* allow a whole struct for head */ /* This might be getint( solid_type, 3, 2 ); for non-V5 */ numpts = getint( scard, 8, 2 ); num = numpts * 3 + 1; /* 3 entries per pt */ /* allocate space for the points array */ pts = ( double *)bu_malloc(num * sizeof( double), "pts" ); if ( getsoldata( pts, num, sol_work ) < 0 ) { return(-1); } dia = pts[num-1] * 2.0; /* radius X 2.0 == diameter */ /* allocate nodes on a list and store all information in * the appropriate location. */ BU_LIST_INIT( &head ); for ( i = 0; i < numpts; i++ ) { /* malloc a new structure */ ps = (struct wdb_pipept *)bu_malloc(sizeof( struct wdb_pipept), "ps"); ps->l.magic = WDB_PIPESEG_MAGIC; VMOVE( ps->pp_coord, &pts[i*3]); /* 3 pts at a time */ ps->pp_id = 0; /* solid */ ps->pp_od = dia; ps->pp_bendradius = dia; BU_LIST_INSERT( &head, &ps->l ); } if ( mk_pipe( outfp, name, &head ) < 0 ) return(-1); mk_pipe_free( &head ); bu_free( name, "name" ); return(0); /* OK */ } if ( strcmp( solid_type, "rpc" ) == 0 ) { /* V, H, B, r */ if ( getsoldata( dd, 3*3+1, sol_work ) < 0 ) return(-1); ret = mk_rpc( outfp, name, D(0), D(1), D(2), dd[9] ); bu_free( name, "name" ); return(ret); } if ( strcmp( solid_type, "rhc" ) == 0 ) { /* V, H, B, r, c */ if ( getsoldata( dd, 3*3+2, sol_work ) < 0 ) return(-1); ret = mk_rhc( outfp, name, D(0), D(1), D(2), dd[9], dd[10] ); bu_free( name, "name" ); return(ret); } if ( strcmp( solid_type, "epa" ) == 0 ) { /* V, H, Au, r1, r2 */ if ( getsoldata( dd, 3*3+2, sol_work ) < 0 ) return(-1); ret = mk_epa( outfp, name, D(0), D(1), D(2), dd[9], dd[10] ); bu_free( name, "name" ); return(ret); } if ( strcmp( solid_type, "ehy" ) == 0 ) { /* V, H, Au, r1, r2, c */ if ( getsoldata( dd, 3*3+3, sol_work ) < 0 ) return(-1); ret = mk_ehy( outfp, name, D(0), D(1), D(2), dd[9], dd[10], dd[11] ); bu_free( name, "name" ); return(ret); } if ( strcmp( solid_type, "eto" ) == 0 ) { /* V, N, C, r, rd */ if ( getsoldata( dd, 3*3+2, sol_work ) < 0 ) return(-1); ret = mk_eto( outfp, name, D(0), D(1), D(2), dd[9], dd[10] ); bu_free( name, "name" ); return(ret); } if ( version <= 4 && strcmp( solid_type, "ell" ) == 0 ) { /* Foci F1, F2, major axis length L */ vect_t v; /* * For simplicity, we convert ELL to ELL1, then * fall through to ELL1 code. * Format of ELL is F1, F2, len * ELL1 format is V, A, r */ if ( getsoldata( dd, 2*3+1, sol_work ) < 0 ) return(-1); VADD2SCALE( v, D(0), D(1), 0.5 ); /* V is midpoint */ VSUB2( work, D(1), D(0) ); /* work holds F2 - F1 */ m1 = MAGNITUDE( work ); r2 = 0.5 * dd[6] / m1; VSCALE( D(1), work, r2 ); /* A */ dd[6] = sqrt( MAGSQ( D(1) ) - (m1 * 0.5)*(m1 * 0.5) ); /* r */ VMOVE( D(0), v ); goto ell1; } if ( (version == 5 && strcmp( solid_type, "ell" ) == 0) || strcmp( solid_type, "ell1" ) == 0 ) { /* V, A, r */ /* GIFT4 name is "ell1", GIFT5 name is "ell" */ if ( getsoldata( dd, 2*3+1, sol_work ) < 0 ) return(-1); ell1: r1 = dd[6]; /* R */ VMOVE( work, D(0) ); work[0] += bn_pi; work[1] += bn_pi; work[2] += bn_pi; VCROSS( D(2), work, D(1) ); m1 = r1/MAGNITUDE( D(2) ); VSCALE( D(2), D(2), m1 ); VCROSS( D(3), D(1), D(2) ); m2 = r1/MAGNITUDE( D(3) ); VSCALE( D(3), D(3), m2 ); /* Now we have V, A, B, C */ ret = mk_ell( outfp, name, D(0), D(1), D(2), D(3) ); bu_free( name, "name" ); return(ret); } if ( strcmp( solid_type, "ellg" ) == 0 ) { /* V, A, B, C */ if ( getsoldata( dd, 4*3, sol_work ) < 0 ) return(-1); ret = mk_ell( outfp, name, D(0), D(1), D(2), D(3) ); bu_free( name, "name" ); return(ret); } if ( strcmp( solid_type, "tor" ) == 0 ) { /* V, N, r1, r2 */ if ( getsoldata( dd, 2*3+2, sol_work ) < 0 ) return(-1); ret = mk_tor( outfp, name, D(0), D(1), dd[6], dd[7] ); bu_free( name, "name" ); return(ret); } if ( strcmp( solid_type, "haf" ) == 0 ) { /* N, d */ if ( getsoldata( dd, 1*3+1, sol_work ) < 0 ) return(-1); ret = mk_half( outfp, name, D(0), -dd[3] ); bu_free( name, "name" ); return(ret); } if ( strcmp( solid_type, "arbn" ) == 0 ) { ret = read_arbn( name ); bu_free( name, "name" ); } /* * The solid type string is defective, * or that solid is not currently supported. */ printf("getsolid: no support for solid type '%s'\n", solid_type ); return(-1); }
void Pipes(void) { vect_t ht; struct points *ptr; fastf_t len; int comblen; struct wmember head; BU_LIST_INIT(&head.l); ptr = root; if ( ptr == NULL ) return; while ( ptr->next != NULL ) { /* Make the basic pipe solids */ VSUB2( ht, ptr->next->p1, ptr->p2); mk_rcc( fdout, ptr->tube, ptr->p2, ht, radius ); /* make a solid record */ if ( !cable ) /* make inside solid */ mk_rcc( fdout, ptr->tubflu, ptr->p2, ht, radius-wall ); if ( torus ) { /* Make tubing region */ mk_addmember( ptr->tube, &head.l, NULL, WMOP_UNION ); /* make 'u' member record */ if ( !cable ) { /* Subtract inside solid */ mk_addmember( ptr->tubflu, &head.l, NULL, WMOP_SUBTRACT ); /* make '-' member record */ /* Make fluid region */ mk_comb1( fdout, ptr->tubflu_r, ptr->tubflu, 1 ); } mk_lfcomb( fdout, ptr->tube_r, &head, 1 ); } else if ( mitre ) { if ( ptr->prev != NULL ) { len = VDOT( ptr->p, ptr->mnorm ); mk_half( fdout, ptr->cut, ptr->mnorm, len ); } comblen = 4 - cable; if ( ptr->next->next == NULL ) comblen--; if ( ptr->prev == NULL ) comblen--; mk_addmember( ptr->tube, &head.l, NULL, WMOP_UNION ); /* make 'u' member record */ if ( !cable ) mk_addmember( ptr->tubflu, &head.l, NULL, WMOP_SUBTRACT ); /* make '-' member record */ if ( ptr->next->next != NULL ) mk_addmember( ptr->next->cut, &head.l, NULL, WMOP_SUBTRACT ); /* make '+' member record */ if ( ptr->prev != NULL ) mk_addmember( ptr->cut, &head.l, NULL, WMOP_INTERSECT ); /* subtract HAF */ mk_lfcomb( fdout, ptr->tube_r, &head, 1 ); if ( !cable ) { /* Make fluid region */ comblen = 3; if ( ptr->next->next == NULL ) comblen--; if ( ptr->prev == NULL ) comblen--; mk_addmember( ptr->tubflu, &head.l, NULL, WMOP_UNION ); /* make 'u' member record */ if ( ptr->next->next != NULL ) mk_addmember( ptr->next->cut, &head.l, NULL, WMOP_SUBTRACT ); /* make '+' member record */ if ( ptr->prev != NULL ) mk_addmember( ptr->cut, &head.l, NULL, WMOP_INTERSECT ); /* subtract */ mk_lfcomb( fdout, ptr->tubflu_r, &head, 1 ); /* make REGION comb record */ } } else if ( sphere ) { /* make REGION comb record for tube */ comblen = 2; if ( cable ) comblen--; if ( ptr->next->tube[0] != '\0' ) comblen++; if ( !cable && ptr->prev != NULL ) comblen++; /* make 'u' member record */ mk_addmember( ptr->tube, &head.l, NULL, WMOP_UNION ); /* make '-' member record */ if ( !cable ) mk_addmember( ptr->tubflu, &head.l, NULL, WMOP_SUBTRACT ); if ( ptr->next->tube[0] != '\0' ) /* subtract outside of next tube */ mk_addmember( ptr->next->tube, &head.l, NULL, WMOP_SUBTRACT ); if ( !cable && ptr->prev != NULL ) /* subtract inside of previous tube */ mk_addmember( ptr->prev->tubflu, &head.l, NULL, WMOP_SUBTRACT ); mk_lfcomb( fdout, ptr->tube_r, &head, REGION ); if ( !cable ) { /* make REGION for fluid */ /* make 'u' member record */ mk_addmember( ptr->tubflu, &head.l, NULL, WMOP_UNION ); if ( ptr->next->tubflu[0] != '\0' ) /* subtract inside of next tube */ mk_addmember( ptr->next->tubflu, &head.l, NULL, WMOP_SUBTRACT ); mk_lfcomb( fdout, ptr->tubflu_r, &head, REGION ); } } else if ( nothing ) { /* make REGION comb record for tube */ comblen = 2; if ( cable ) comblen--; if ( ptr->next->tube[0] != '\0' ) comblen++; if ( !cable && ptr->prev != NULL ) comblen++; /* make 'u' member record */ mk_addmember( ptr->tube, &head.l, NULL, WMOP_UNION ); /* make '-' member record */ if ( !cable ) mk_addmember( ptr->tubflu, &head.l, NULL, WMOP_SUBTRACT ); if ( ptr->next->tube[0] != '\0' ) /* subtract outside of next tube */ mk_addmember( ptr->next->tube, &head.l, NULL, WMOP_SUBTRACT ); if ( !cable && ptr->prev != NULL ) /* subtract inside of previous tube */ mk_addmember( ptr->prev->tubflu, &head.l, NULL, WMOP_SUBTRACT ); mk_lfcomb( fdout, ptr->tube_r, &head, REGION ); if ( !cable ) { /* make REGION for fluid */ /* make 'u' member record */ mk_addmember( ptr->tubflu, &head.l, NULL, WMOP_UNION ); if ( ptr->next->tubflu[0] != '\0' ) /* subtract inside of next tube */ mk_addmember( ptr->next->tubflu, &head.l, NULL, WMOP_SUBTRACT ); mk_lfcomb( fdout, ptr->tubflu_r, &head, REGION ); } } ptr = ptr->next; } }
int main(int argc, char **argv) { int frame; char name[128]; char gname[128]; vect_t normal; struct wmember head, ghead; matp_t matp; mat_t xlate; mat_t rot1, rot2, rot3; vect_t from, to; vect_t offset; if (argc > 0) { bu_log("Usage: %s\n", argv[0]); bu_log(" (Program expects ./pos.dat file to be present)\n"); bu_log(" (Will generate file tube.g)\n"); if (argc == 2) { if ( BU_STR_EQUAL(argv[1],"-h") || BU_STR_EQUAL(argv[1],"-?")) bu_exit(1,NULL); } else if (argc == 1) bu_log(" Program continues running:\n"); } BU_LIST_INIT(&head.l); BU_LIST_INIT(&ghead.l); outfp = wdb_fopen("tube.g"); if ((pos_fp = fopen("pos.dat", "r")) == NULL) perror("pos.dat"); /* Just warn */ mk_id(outfp, "Procedural Gun Tube with Projectile"); VSET(normal, 0, -1, 0); mk_half(outfp, "cut", normal, 0.0); VSET(normal, 0, 1, 0); mk_half(outfp, "bg.s", normal, -1000.0); (void)mk_addmember("bg.s", &head.l, NULL, WMOP_UNION); /* temp use of "head" */ mk_lcomb(outfp, "bg.r", &head, 1, "texture", "file=movie128bw.pix w=128", (unsigned char *)0, 0); #ifdef never /* Numbers for a 105-mm M68 gun */ oradius = 5 * inches2mm / 2; /* 5" outer diameter */ iradius = 4.134 * inches2mm / 2; /* 5" inner (land) diameter */ #else /* Numbers invented to match 125-mm KE (Erline) round */ iradius = 125.0/2; oradius = iradius + (5-4.134) * inches2mm / 2; /* 5" outer diameter */ #endif fprintf(stderr, "inner radius=%gmm, outer radius=%gmm\n", iradius, oradius); length = 187.0 * inches2mm; #ifdef never spacing = 100.; /* mm per sample */ nsamples = ceil(length/spacing); fprintf(stderr, "length=%gmm, spacing=%gmm\n", length, spacing); fprintf(stderr, "nframes=%d\n", nframes); #endif for (frame=0;; frame++) { cur_time = frame * delta_t; #ifdef never /* Generate some dummy sample data */ if (frame < 16) break; for (i=0; i<nsamples; i++) { sample[i][X] = i * spacing; sample[i][Y] = 0; sample[i][Z] = 4 * oradius * sin( ((double)i*i)/nsamples * M_2PI + frame * M_PI_4); } projectile_pos = ((double)frame)/nframes * (sample[nsamples-1][X] - sample[0][X]); /* length */ #else if (read_frame(stdin) < 0) break; if (pos_fp != NULL) read_pos(pos_fp); #endif #define build_spline build_cyl sprintf(name, "tube%do", frame); build_spline(name, nsamples, oradius); (void)mk_addmember(name, &head.l, NULL, WMOP_UNION); sprintf(name, "tube%di", frame); build_spline(name, nsamples, iradius); mk_addmember(name, &head.l, NULL, WMOP_SUBTRACT); mk_addmember("cut", &head.l, NULL, WMOP_SUBTRACT); sprintf(name, "tube%d", frame); mk_lcomb(outfp, name, &head, 1, "plastic", "", (unsigned char *)0, 0); /* Place the tube region and the ammo together. * The origin of the ammo is expected to be the center * of the rearmost plate. */ mk_addmember(name, &ghead.l, NULL, WMOP_UNION); matp = mk_addmember("ke", &ghead.l, NULL, WMOP_UNION)->wm_mat; VSET(from, 0, -1, 0); VSET(to, 1, 0, 0); /* to X axis */ bn_mat_fromto(rot1, from, to, &outfp->wdb_tol); VSET(from, 1, 0, 0); /* Projectile is 480mm long -- use center pt, not end */ xfinddir(to, projectile_pos + 480.0/2, offset); bn_mat_fromto(rot2, from, to, &outfp->wdb_tol); MAT_IDN(xlate); MAT_DELTAS_VEC(xlate, offset); bn_mat_mul(rot3, rot2, rot1); bn_mat_mul(matp, xlate, rot3); (void)mk_addmember("light.r", &ghead.l, NULL, WMOP_UNION); (void)mk_addmember("bg.r", &ghead.l, NULL, WMOP_UNION); sprintf(gname, "g%d", frame); mk_lcomb(outfp, gname, &ghead, 0, (char *)0, "", (unsigned char *)0, 0); fprintf(stderr, "frame %d\n", frame); fflush(stderr); } wdb_close(outfp); fflush(stderr); return 0; }