コード例 #1
0
ファイル: poly.c プロジェクト: cogitokat/brlcad
/**
 * R T _ P G _ P R E P
 *
 * This routine is used to prepare a list of planar faces for
 * being shot at by the triangle routines.
 *
 * Process a PG, which is represented as a vector
 * from the origin to the first point, and many vectors
 * from the first point to the remaining points.
 *
 */
int
rt_pg_prep(struct soltab *stp, struct rt_db_internal *ip, struct rt_i *rtip)
{
    struct rt_pg_internal *pgp;
    size_t i;
    size_t p;

    pgp = (struct rt_pg_internal *)ip->idb_ptr;
    RT_PG_CK_MAGIC(pgp);

    if (rt_pg_bbox(ip, &(stp->st_min), &(stp->st_max), &rtip->rti_tol)) return 1;

    for (p = 0; p < pgp->npoly; p++) {
	vect_t work[3];

	VMOVE(work[0], &pgp->poly[p].verts[0*3]);
	VMOVE(work[1], &pgp->poly[p].verts[1*3]);

	for (i=2; i < pgp->poly[p].npts; i++) {
	    VMOVE(work[2], &pgp->poly[p].verts[i*3]);

	    /* output a face */
	    (void)rt_pgface(stp,
			    work[0], work[1], work[2], &rtip->rti_tol);

	    /* Chop off a triangle, and continue */
	    VMOVE(work[1], work[2]);
	}
    }
    if (stp->st_specific == (genptr_t)0) {
	bu_log("pg(%s):  no faces\n", stp->st_name);
	return -1;		/* BAD */
    }

    {
	fastf_t dx, dy, dz;
	fastf_t f;

	VADD2SCALE(stp->st_center, stp->st_max, stp->st_min, 0.5);

	dx = (stp->st_max[X] - stp->st_min[X])/2;
	f = dx;
	dy = (stp->st_max[Y] - stp->st_min[Y])/2;
	if (dy > f) f = dy;
	dz = (stp->st_max[Z] - stp->st_min[Z])/2;
	if (dz > f) f = dz;
	stp->st_aradius = f;
	stp->st_bradius = sqrt(dx*dx + dy*dy + dz*dz);
    }

    return 0;		/* OK */
}
コード例 #2
0
void
shoot(char *UNUSED(buffer), com_table *UNUSED(ctp), struct rt_i *rtip)
{
    int i;
    double bov = 0.0;	/* back out value */

    extern void init_ovlp();

    if (!rtip)
      return;

    if (need_prep) {
	rt_clean(rtip);
	do_rt_gettrees(rtip, NULL, 0, &need_prep);
    }

    if (do_backout) {
	point_t ray_point;
	vect_t ray_dir;
	vect_t center_bsphere;
	fastf_t dist_to_target;
	vect_t dvec;
	fastf_t delta;

	for (i = 0; i < 3; ++i) {
	    ray_point[i] = target(i);
	    ray_dir[i] = direct(i);
	}

	if (bsphere_diameter < 0)
	    set_diameter(rtip);

	/*
	 * calculate the distance from a plane normal to the ray direction through the center of
	 * the bounding sphere and a plane normal to the ray direction through the aim point.
	 */
	VADD2SCALE(center_bsphere, rtip->mdl_max, rtip->mdl_min, 0.5);

	dist_to_target = DIST_PT_PT(center_bsphere, ray_point);

	VSUB2(dvec, ray_point, center_bsphere);
	VUNITIZE(dvec);
	delta = dist_to_target*VDOT(ray_dir, dvec);

	/*
	 * this should put us about a bounding sphere radius in front of the bounding sphere
	 */
	bov = bsphere_diameter + delta;
    }

    for (i = 0; i < 3; ++i) {
	target(i) = target(i) + (bov * -direct(i));
	ap.a_ray.r_pt[i] = target(i);
	ap.a_ray.r_dir[i] = direct(i);
    }

    if (nirt_debug & DEBUG_BACKOUT) {
	bu_log("Backing out %g units to (%g %g %g), shooting dir is (%g %g %g)\n",
	       bov * base2local,
	       ap.a_ray.r_pt[0] * base2local,
	       ap.a_ray.r_pt[1] * base2local,
	       ap.a_ray.r_pt[2] * base2local,
	       V3ARGS(ap.a_ray.r_dir));
    }

    init_ovlp();
    (void) rt_shootray(&ap);

    /* Restore pre-backout target values */
    if (do_backout) {
	for (i = 0; i < 3; ++i) {
	    target(i) = target(i) - (bov * -direct(i));
	}
    }

}
コード例 #3
0
   -x# -y# -z#    Rotation about axis in degrees\n\
   -X# -Y# -Z#    Translation along axis\n\
   -s#            Scale factor\n\
   -a# -e#        Azimuth/Elevation from front view\n\
		  (usually first, in this order, implies -M)\n\
   -g             MGED front view to display coordinates (usually last)\n\
   -M             Autoscale space command like RT model RPP\n\
   -m#            Takes a 4X4 matrix as an argument\n\
   -v             Verbose\n\
   -S#            Space: takes a quoted string of six floats\n";

/*
 *			M O D E L _ R P P
 *
 *  Process a space command.
 *  Behavior depends on setting of several flags.
 *
 *  Implicit Returns -
 *	In all cases, sets space_min and space_max.
 */
int
model_rpp(const fastf_t *min, const fastf_t *max)
{

    if ( space_set )  {
	fprintf(stderr, "plrot:  additional SPACE command ignored\n");
	fprintf(stderr, "got: space (%g, %g, %g) (%g, %g, %g)\n",
		V3ARGS(min), V3ARGS(max) );
	fprintf(stderr, "still using: space (%g, %g, %g) (%g, %g, %g)\n",
		V3ARGS(space_min), V3ARGS(space_max) );
	return 0;
    }

    if ( rpp )  {
	point_t	rot_center;		/* center of rotation */
	mat_t	xlate;
	mat_t	resize;
	mat_t	t1, t2;

	VADD2SCALE( rot_center, min, max, 0.5 );

	/* Create the matrix which encodes this */
	MAT_IDN( xlate );
	MAT_DELTAS_VEC_NEG( xlate, rot_center);
	MAT_IDN( resize );
	resize[15] = 1/scale;
	bn_mat_mul( t1, resize, xlate );
	bn_mat_mul( t2, rmat, t1 );
	MAT_COPY( rmat, t2 );
	if ( verbose )  {
	    bn_mat_print("rmat", rmat);
	}

	if ( Mflag )  {
	    /*  Don't rebound, just expand size of space
	     *  around center point.
	     *  Has advantage of the output space() not being
	     *  affected by changes in rotation,
	     *  which may be significant for animation scripts.
	     */
	    vect_t	diag;
	    double	v;

	    VSUB2( diag, max, min );
	    v = MAGNITUDE(diag)*0.5 + 0.5;
	    VSET( space_min, -v, -v, -v );
	    VSET( space_max,  v,  v,  v );
	} else {
	    /* re-bound the space() rpp with a tighter one
	     * after rotating & scaling it.
	     */
	    bn_rotate_bbox( space_min, space_max, rmat, min, max );
	}
	space_set = 1;
    } else {
	VMOVE( space_min, min );
	VMOVE( space_max, max );
	space_set = 1;
    }

    if ( forced_space )  {
	/* Put forced space back */
	VMOVE( space_min, forced_space_min );
	VMOVE( space_max, forced_space_max );
	space_set = 1;
    }

    if ( verbose )  {
	fprintf(stderr, "got: space (%g, %g, %g) (%g, %g, %g)\n",
		V3ARGS(min), V3ARGS(max) );
	fprintf(stderr, "put: space (%g, %g, %g) (%g, %g, %g)\n",
		V3ARGS(space_min), V3ARGS(space_max) );
    }

    return( 1 );
}
コード例 #4
0
ファイル: solid.c プロジェクト: cciechad/brlcad
/*
 *			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);
}
コード例 #5
0
/*
 * Process a space command.
 * Behavior depends on setting of several flags.
 *
 * Implicit Returns -
 * In all cases, sets space_min and space_max.
 */
int
model_rpp(const fastf_t *min, const fastf_t *max)
{

    if (space_set) {
	bu_log("plot3rot:  additional SPACE command ignored\n");
	bu_log("got: space (%g, %g, %g) (%g, %g, %g)\n",
	       V3ARGS(min), V3ARGS(max));
	bu_log("still using: space (%g, %g, %g) (%g, %g, %g)\n",
	       V3ARGS(space_min), V3ARGS(space_max));
	return 0;
    }

    if (rpp) {
	point_t rot_center;		/* center of rotation */
	mat_t xlate;
	mat_t resize;
	mat_t t1, t2;

	VADD2SCALE(rot_center, min, max, 0.5);

	/* Create the matrix which encodes this */
	MAT_IDN(xlate);
	MAT_DELTAS_VEC_NEG(xlate, rot_center);
	MAT_IDN(resize);
	resize[15] = 1/scale;
	bn_mat_mul(t1, resize, xlate);
	bn_mat_mul(t2, rmat, t1);
	MAT_COPY(rmat, t2);
	if (verbose) {
	    bn_mat_print("rmat", rmat);
	}

	if (Mflag) {
	    /* Don't rebound, just expand size of space
	     * around center point.
	     * Has advantage of the output space() not being
	     * affected by changes in rotation,
	     * which may be significant for animation scripts.
	     */
	    vect_t diag;
	    double v;

	    VSUB2(diag, max, min);
	    v = MAGNITUDE(diag)*0.5 + 0.5;
	    VSET(space_min, -v, -v, -v);
	    VSET(space_max,  v,  v,  v);
	} else {
	    /* re-bound the space() rpp with a tighter one
	     * after rotating & scaling it.
	     */
	    bn_rotate_bbox(space_min, space_max, rmat, min, max);
	}
	space_set = 1;
    } else {
	VMOVE(space_min, min);
	VMOVE(space_max, max);
	space_set = 1;
    }

    if (forced_space) {
	/* Put forced space back */
	VMOVE(space_min, forced_space_min);
	VMOVE(space_max, forced_space_max);
	space_set = 1;
    }

    if (verbose) {
	bu_log("got: space (%g, %g, %g) (%g, %g, %g)\n",
	       V3ARGS(min), V3ARGS(max));
	bu_log("put: space (%g, %g, %g) (%g, %g, %g)\n",
	       V3ARGS(space_min), V3ARGS(space_max));
    }

    return 1;
}
コード例 #6
0
ファイル: arbn.c プロジェクト: kanzure/brlcad
/**
 * Returns -
 *  0 OK
 * !0 failure
 */
int
rt_arbn_prep(struct soltab *stp, struct rt_db_internal *ip, struct rt_i *rtip)
{
    struct rt_arbn_internal *aip;
    vect_t work;
    fastf_t f;
    size_t i;
    size_t j;
    size_t k;
    int *used = (int *)0;	/* plane eqn use count */
    const struct bn_tol *tol = &rtip->rti_tol;

    RT_CK_DB_INTERNAL(ip);
    aip = (struct rt_arbn_internal *)ip->idb_ptr;
    RT_ARBN_CK_MAGIC(aip);

    used = (int *)bu_malloc(aip->neqn*sizeof(int), "arbn used[]");

    /*
     * ARBN must be convex.  Test for concavity.
     * Byproduct is an enumeration of all the vertices,
     * which are used to make the bounding RPP.  No need
     * to call the bbox routine, as the work must be duplicated
     * here to count faces.
     */

    /* Zero face use counts
     * and make sure normal vectors are unit vectors
     */
    for (i = 0; i < aip->neqn; i++) {
	double normalLen = MAGNITUDE(aip->eqn[i]);
	double scale;
	if (ZERO(normalLen)) {
	    bu_log("arbn has zero length normal vector\n");
	    return 1;
	}
	scale = 1.0 / normalLen;
	HSCALE(aip->eqn[i], aip->eqn[i], scale);
	used[i] = 0;
    }
    for (i = 0; i < aip->neqn-2; i++) {
	for (j=i+1; j<aip->neqn-1; j++) {
	    double dot;

	    /* If normals are parallel, no intersection */
	    dot = VDOT(aip->eqn[i], aip->eqn[j]);
	    if (BN_VECT_ARE_PARALLEL(dot, tol)) continue;

	    /* Have an edge line, isect with higher numbered planes */
	    for (k=j+1; k<aip->neqn; k++) {
		size_t m;
		size_t next_k;
		point_t pt;

		next_k = 0;

		if (bn_mkpoint_3planes(pt, aip->eqn[i], aip->eqn[j], aip->eqn[k]) < 0) continue;

		/* See if point is outside arb */
		for (m = 0; m < aip->neqn; m++) {
		    if (i == m || j == m || k == m)
			continue;
		    if (VDOT(pt, aip->eqn[m])-aip->eqn[m][3] > tol->dist) {
			next_k = 1;
			break;
		    }
		}
		if (next_k != 0) continue;

		VMINMAX(stp->st_min, stp->st_max, pt);

		/* Increment "face used" counts */
		used[i]++;
		used[j]++;
		used[k]++;
	    }
	}
    }

    /* If any planes were not used, then arbn is not convex */
    for (i = 0; i < aip->neqn; i++) {
	if (used[i] != 0) continue;	/* face was used */
	bu_log("arbn(%s) face %zu unused, solid is not convex\n",
	       stp->st_name, i);
	bu_free((char *)used, "arbn used[]");
	return -1;		/* BAD */
    }
    bu_free((char *)used, "arbn used[]");

    stp->st_specific = (void *)aip;
    ip->idb_ptr = ((void *)0);	/* indicate we stole it */

    VADD2SCALE(stp->st_center, stp->st_min, stp->st_max, 0.5);
    VSUB2SCALE(work, stp->st_max, stp->st_min, 0.5);

    f = work[X];
    if (work[Y] > f) f = work[Y];
    if (work[Z] > f) f = work[Z];
    stp->st_aradius = f;
    stp->st_bradius = MAGNITUDE(work);
    return 0;			/* OK */
}