예제 #1
0
파일: vutil.c 프로젝트: kanzure/brlcad
/**
 * Compute a perspective matrix for a right-handed coordinate system.
 * Reference: SGI Graphics Reference Appendix C
 *
 * (Note: SGI is left-handed, but the fix is done in the Display
 * Manager).
 */
void
ged_persp_mat(mat_t m,
              fastf_t fovy,
              fastf_t aspect,
              fastf_t near1,
              fastf_t far1,
              fastf_t backoff)
{
    mat_t m2, tran;

    fovy *= DEG2RAD;

    MAT_IDN(m2);
    m2[5] = cos(fovy/2.0) / sin(fovy/2.0);
    m2[0] = m2[5]/aspect;
    m2[10] = (far1+near1) / (far1-near1);
    m2[11] = 2*far1*near1 / (far1-near1);	/* This should be negative */

    m2[14] = -1;		/* XXX This should be positive */
    m2[15] = 0;

    /* Move eye to origin, then apply perspective */
    MAT_IDN(tran);
    tran[11] = -backoff;
    bn_mat_mul(m, m2, tran);
}
예제 #2
0
void
bn_wrt_point_direc(mat_t out, const mat_t change, const mat_t in, const point_t point, const vect_t direc, const struct bn_tol *tol)
{
    static mat_t t1;
    static mat_t pt_to_origin, origin_to_pt;
    static mat_t d_to_zaxis, zaxis_to_d;
    static vect_t zaxis;

    /* build "point to origin" matrix */
    MAT_IDN(pt_to_origin);
    MAT_DELTAS_VEC_NEG(pt_to_origin, point);

    /* build "origin to point" matrix */
    MAT_IDN(origin_to_pt);
    MAT_DELTAS_VEC_NEG(origin_to_pt, point);

    /* build "direc to zaxis" matrix */
    VSET(zaxis, 0.0, 0.0, 1.0);
    bn_mat_fromto(d_to_zaxis, direc, zaxis, tol);

    /* build "zaxis to direc" matrix */
    bn_mat_inv(zaxis_to_d, d_to_zaxis);

    /* apply change matrix...
     * t1 = change * d_to_zaxis * pt_to_origin * in
     */
    bn_mat_mul4(t1, change, d_to_zaxis, pt_to_origin, in);

    /* apply origin_to_pt matrix:
     * out = origin_to_pt * zaxis_to_d *
     * change * d_to_zaxis * pt_to_origin * in
     */
    bn_mat_mul3(out, origin_to_pt, zaxis_to_d, t1);
}
예제 #3
0
void
bn_mat_arb_rot(
    mat_t m,
    const point_t pt,
    const vect_t dir,
    const fastf_t ang)
{
    mat_t tran1, tran2, rot;
    double cos_ang, sin_ang, one_m_cosang;
    double n1_sq, n2_sq, n3_sq;
    double n1_n2, n1_n3, n2_n3;

    if (ZERO(ang)) {
	MAT_IDN(m);
	return;
    }

    MAT_IDN(tran1);
    MAT_IDN(tran2);

    /* construct translation matrix to pt */
    tran1[MDX] = (-pt[X]);
    tran1[MDY] = (-pt[Y]);
    tran1[MDZ] = (-pt[Z]);

    /* construct translation back from pt */
    tran2[MDX] = pt[X];
    tran2[MDY] = pt[Y];
    tran2[MDZ] = pt[Z];

    /* construct rotation matrix */
    cos_ang = cos(ang);
    sin_ang = sin(ang);
    one_m_cosang = 1.0 - cos_ang;
    n1_sq = dir[X] * dir[X];
    n2_sq = dir[Y] * dir[Y];
    n3_sq = dir[Z] * dir[Z];
    n1_n2 = dir[X] * dir[Y];
    n1_n3 = dir[X] * dir[Z];
    n2_n3 = dir[Y] * dir[Z];

    MAT_IDN(rot);
    rot[0] = n1_sq + (1.0 - n1_sq) * cos_ang;
    rot[1] = n1_n2 * one_m_cosang - dir[Z] * sin_ang;
    rot[2] = n1_n3 * one_m_cosang + dir[Y] * sin_ang;

    rot[4] = n1_n2 * one_m_cosang + dir[Z] * sin_ang;
    rot[5] = n2_sq + (1.0 - n2_sq) * cos_ang;
    rot[6] = n2_n3 * one_m_cosang - dir[X] * sin_ang;

    rot[8] = n1_n3 * one_m_cosang - dir[Y] * sin_ang;
    rot[9] = n2_n3 * one_m_cosang + dir[X] * sin_ang;
    rot[10] = n3_sq + (1.0 - n3_sq) * cos_ang;

    bn_mat_mul(m, rot, tran1);
    bn_mat_mul2(tran2, m);
}
예제 #4
0
파일: vutil.c 프로젝트: kanzure/brlcad
/**
 * Create a perspective matrix that transforms the +/1 viewing cube,
 * with the actual eye position (not at Z=+1) specified in viewing
 * coords, into a related space where the eye has been sheared onto
 * the Z axis and repositioned at Z=(0, 0, 1), with the same
 * perspective field of view as before.
 *
 * The Zbuffer clips off stuff with negative Z values.
 *
 * pmat = persp * xlate * shear
 */
void
ged_mike_persp_mat(mat_t pmat,
                   const point_t eye)
{
    mat_t shear;
    mat_t persp;
    mat_t xlate;
    mat_t t1, t2;
    point_t sheared_eye;

    if (eye[Z] <= SMALL) {
        VPRINT("mike_persp_mat(): ERROR, z<0, eye", eye);
        return;
    }

    /* Shear "eye" to +Z axis */
    MAT_IDN(shear);
    shear[2] = -eye[X]/eye[Z];
    shear[6] = -eye[Y]/eye[Z];

    MAT4X3VEC(sheared_eye, shear, eye);
    if (!NEAR_ZERO(sheared_eye[X], .01) || !NEAR_ZERO(sheared_eye[Y], .01)) {
        VPRINT("ERROR sheared_eye", sheared_eye);
        return;
    }

    /* Translate along +Z axis to put sheared_eye at (0, 0, 1). */
    MAT_IDN(xlate);
    /* XXX should I use MAT_DELTAS_VEC_NEG()?  X and Y should be 0 now */
    MAT_DELTAS(xlate, 0, 0, 1-sheared_eye[Z]);

    /* Build perspective matrix inline, substituting fov=2*atan(1, Z) */
    MAT_IDN(persp);
    /* From page 492 of Graphics Gems */
    persp[0] = sheared_eye[Z];	/* scaling: fov aspect term */
    persp[5] = sheared_eye[Z];	/* scaling: determines fov */

    /* From page 158 of Rogers Mathematical Elements */
    /* Z center of projection at Z=+1, r=-1/1 */
    persp[14] = -1;

    bn_mat_mul(t1, xlate, shear);
    bn_mat_mul(t2, persp, t1);

    /* Now, move eye from Z=1 to Z=0, for clipping purposes */
    MAT_DELTAS(xlate, 0, 0, -1);

    bn_mat_mul(pmat, xlate, t2);
}
예제 #5
0
  int
  BrepHandler::extractCircularArc(const DirectoryEntry* de, const ParameterData& params) {
    point_t center, start, end;
    double offset_z = params.getReal(1);
    center[X] = params.getReal(2);
    center[Y] = params.getReal(3);
    center[Z] = offset_z;
    start[X]  = params.getReal(4);
    start[Y]  = params.getReal(5);
    start[Z]  = offset_z;
    end[X]    = params.getReal(6);
    end[Y]    = params.getReal(7);
    end[Z]    = offset_z;

    mat_t xform;
    MAT_IDN(xform);
    _iges->getTransformation(de->xform(), xform);

    // choose the circle/interval representation
    // so, calculate the circle params, and then the angle the arc subtends
    double dx = start[X] - center[X];
    double dy = start[Y] - center[Y];
    double radius = sqrt(dx*dx + dy*dy);

    point_t tcenter, tstart, tend;
    MAT4X3PNT(tcenter, xform, center);
    MAT4X3PNT(tstart, xform, start);
    MAT4X3PNT(tend, xform, end);
    vect_t normal = {0,0,1};
    vect_t tnormal;
    MAT4X3VEC(tnormal, xform, normal);

    return handleCircularArc(radius, tcenter, tnormal, tstart, tend);
  }
예제 #6
0
파일: mat.c 프로젝트: cciechad/brlcad
/**
 *			B N _ M A T _ A N G L E S
 *
 * This routine builds a Homogeneous rotation matrix, given
 * alpha, beta, and gamma as angles of rotation, in degrees.
 *
 * Alpha is angle of rotation about the X axis, and is done third.
 * Beta is angle of rotation about the Y axis, and is done second.
 * Gamma is angle of rotation about Z axis, and is done first.
 */
void
bn_mat_angles(register fastf_t *mat, double alpha_in, double beta_in, double ggamma_in)
{
    double alpha, beta, ggamma;
    double calpha, cbeta, cgamma;
    double salpha, sbeta, sgamma;

    if ( alpha_in == 0.0 && beta_in == 0.0 && ggamma_in == 0.0 )  {
	MAT_IDN( mat );
	return;
    }

    alpha = alpha_in * bn_degtorad;
    beta = beta_in * bn_degtorad;
    ggamma = ggamma_in * bn_degtorad;

    calpha = cos( alpha );
    cbeta = cos( beta );
    cgamma = cos( ggamma );

    /* sine of "180*bn_degtorad" will not be exactly zero
     * and will result in errors when some codes try to
     * convert this back to azimuth and elevation.
     * do_frame() uses this technique!!!
     */
    if ( alpha_in == 180.0 )
	salpha = 0.0;
    else
	salpha = sin( alpha );

    if ( beta_in == 180.0 )
	sbeta = 0.0;
    else
	sbeta = sin( beta );

    if ( ggamma_in == 180.0 )
	sgamma = 0.0;
    else
	sgamma = sin( ggamma );

    mat[0] = cbeta * cgamma;
    mat[1] = -cbeta * sgamma;
    mat[2] = sbeta;
    mat[3] = 0.0;

    mat[4] = salpha * sbeta * cgamma + calpha * sgamma;
    mat[5] = -salpha * sbeta * sgamma + calpha * cgamma;
    mat[6] = -salpha * cbeta;
    mat[7] = 0.0;

    mat[8] = salpha * sgamma - calpha * sbeta * cgamma;
    mat[9] = salpha * cgamma + calpha * sbeta * sgamma;
    mat[10] = calpha * cbeta;
    mat[11] = 0.0;
    mat[12] = mat[13] = mat[14] = 0.0;
    mat[15] = 1.0;
}
예제 #7
0
void
bn_mat_lookat(mat_t rot, const vect_t dir, int yflip)
{
    mat_t first;
    mat_t second;
    mat_t prod12;
    mat_t third;
    vect_t x;
    vect_t z;
    vect_t t1;
    fastf_t hypot_xy;
    vect_t xproj;
    vect_t zproj;

    /* First, rotate D around Z axis to match +X axis (azimuth) */
    hypot_xy = hypot(dir[X], dir[Y]);
    bn_mat_zrot(first, -dir[Y] / hypot_xy, dir[X] / hypot_xy);

    /* Next, rotate D around Y axis to match -Z axis (elevation) */
    bn_mat_yrot(second, -hypot_xy, -dir[Z]);
    bn_mat_mul(prod12, second, first);

    /* Produce twist correction, by re-orienting projection of X axis */
    VSET(x, 1, 0, 0);
    MAT4X3VEC(xproj, prod12, x);
    hypot_xy = hypot(xproj[X], xproj[Y]);
    if (hypot_xy < 1.0e-10) {
	bu_log("Warning: bn_mat_lookat:  unable to twist correct, hypot=%g\n", hypot_xy);
	VPRINT("xproj", xproj);
	MAT_COPY(rot, prod12);
	return;
    }
    bn_mat_zrot(third, -xproj[Y] / hypot_xy, xproj[X] / hypot_xy);
    bn_mat_mul(rot, third, prod12);

    if (yflip) {
	VSET(z, 0, 0, 1);
	MAT4X3VEC(zproj, rot, z);
	/* If original Z inverts sign, flip sign on resulting Y */
	if (zproj[Y] < 0.0) {
	    MAT_COPY(prod12, rot);
	    MAT_IDN(third);
	    third[5] = -1;
	    bn_mat_mul(rot, third, prod12);
	}
    }

    /* Check the final results */
    MAT4X3VEC(t1, rot, dir);
    if (t1[Z] > -0.98) {
	bu_log("Error:  bn_mat_lookat final= (%g, %g, %g)\n", V3ARGS(t1));
    }
}
예제 #8
0
/**
 * R T _ D S P _ M I R R O R
 *
 * Given a pointer to an internal GED database object, mirror the
 * object's values about the given transformation matrix.
 */
int
rt_dsp_mirror(struct rt_db_internal *ip, register const plane_t plane)
{
    struct rt_dsp_internal *dsp;

    mat_t mirmat;
    mat_t rmat;
    mat_t temp;
    vect_t nvec;
    vect_t xvec;
    vect_t mirror_dir;
    point_t mirror_pt;
    fastf_t ang;

    static point_t origin = {0.0, 0.0, 0.0};

    RT_CK_DB_INTERNAL(ip);

    dsp = (struct rt_dsp_internal *)ip->idb_ptr;
    RT_EBM_CK_MAGIC(dsp);

    MAT_IDN(mirmat);

    VMOVE(mirror_dir, plane);
    VSCALE(mirror_pt, plane, plane[W]);

    /* Build mirror transform matrix, for those who need it. */
    /* First, perform a mirror down the X axis */
    mirmat[0] = -1.0;

    /* Create the rotation matrix */
    VSET(xvec, 1, 0, 0);
    VCROSS(nvec, xvec, mirror_dir);
    VUNITIZE(nvec);
    ang = -acos(VDOT(xvec, mirror_dir));
    bn_mat_arb_rot(rmat, origin, nvec, ang*2.0);

    /* Add the rotation to mirmat */
    MAT_COPY(temp, mirmat);
    bn_mat_mul(mirmat, temp, rmat);

    /* Add the translation to mirmat */
    mirmat[3 + X*4] += mirror_pt[X] * mirror_dir[X];
    mirmat[3 + Y*4] += mirror_pt[Y] * mirror_dir[Y];
    mirmat[3 + Z*4] += mirror_pt[Z] * mirror_dir[Z];

    bn_mat_mul(temp, mirmat, dsp->dsp_mtos);
    MAT_COPY(dsp->dsp_mtos, temp);

    return 0;
}
예제 #9
0
파일: bn_tcl.c 프로젝트: cciechad/brlcad
int
bn_decode_mat(fastf_t *m, const char *str)
{
    if ( strcmp( str, "I" ) == 0 )  {
	MAT_IDN( m );
	return 16;
    }
    if ( *str == '{' )  str++;

    return sscanf(str,
		  "%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf",
		  &m[0], &m[1], &m[2], &m[3], &m[4], &m[5], &m[6], &m[7],
		  &m[8], &m[9], &m[10], &m[11], &m[12], &m[13], &m[14], &m[15]);
}
예제 #10
0
void
bn_mat_xform_about_pt(mat_t mat, const mat_t xform, const point_t pt)
{
    mat_t xlate;
    mat_t tmp;

    MAT_IDN(xlate);
    MAT_DELTAS_VEC_NEG(xlate, pt);

    bn_mat_mul(tmp, xform, xlate);

    MAT_DELTAS_VEC(xlate, pt);
    bn_mat_mul(mat, xlate, tmp);
}
예제 #11
0
int
bn_mat_scale_about_pt(mat_t mat, const point_t pt, const double scale)
{
    mat_t xlate;
    mat_t s;
    mat_t tmp;

    MAT_IDN(xlate);
    MAT_DELTAS_VEC_NEG(xlate, pt);

    MAT_IDN(s);
    if (ZERO(scale)) {
	MAT_ZERO(mat);
	return -1;			/* ERROR */
    }
    s[15] = 1 / scale;

    bn_mat_mul(tmp, s, xlate);

    MAT_DELTAS_VEC(xlate, pt);
    bn_mat_mul(mat, xlate, tmp);
    return 0;				/* OK */
}
예제 #12
0
파일: pyramid.c 프로젝트: cogitokat/brlcad
void
do_tree(char *name, char *lname, int level)
{
    int i;
    char nm[64];
    char *leafp;
    int scale;
    struct wmember head;
    struct wmember *wp;

    BU_LIST_INIT(&head.l);

    if (level <= 1)
	leafp = lname;
    else
	leafp = nm;

    scale = 100;
    for (i=1; i<level; i++)
	scale *= 2;

    snprintf(nm, 64, "%sL", name);
    wp = mk_addmember(leafp, &head.l, NULL, WMOP_UNION);
    MAT_IDN(wp->wm_mat);

    snprintf(nm, 64, "%sR", name);
    wp = mk_addmember(leafp, &head.l, NULL, WMOP_UNION);
    MAT_DELTAS(wp->wm_mat, 1*scale, 0, 0);

    snprintf(nm, 64, "%sB", name);
    wp = mk_addmember(leafp, &head.l, NULL, WMOP_UNION);
    MAT_DELTAS(wp->wm_mat, 0.5*scale, sin60*scale, 0);

    snprintf(nm, 64, "%sT", name);
    wp = mk_addmember(leafp, &head.l, NULL, WMOP_UNION);
    MAT_DELTAS(wp->wm_mat, 0.5*scale, sin60/3*scale, sin60*scale);

    /* Set region flag on lowest level */
    mk_lcomb(outfp, name, &head, level<=1, NULL, NULL, NULL, 0);

    /* Loop for children if level > 1 */
    if (level <= 1)
	return;
    for (i=0; i<4; i++) {
	snprintf(nm, 64, "%s%c", name, "LRBTx"[i]);
	do_tree(nm, lname, level-1);
    }
}
예제 #13
0
int
main(int argc, char** argv)
{
    struct rt_wdb* outfp;
    ON_Brep* brep;
    ON_TextLog error_log;
    const char* id_name = "B-Rep Example";
    const char* geom_name = "cube.s";

    ON::Begin();

    if (argc > 1) {
	printf("Writing a twisted cube b-rep...\n");
	outfp = wdb_fopen("brep_cube1.g");
	mk_id(outfp, id_name);
	brep = MakeTwistedCube(error_log);
	mk_brep(outfp, geom_name, brep);

	//mk_comb1(outfp, "cube.r", geom_name, 1);
	unsigned char rgb[] = {255,255,255};
	mk_region1(outfp, "cube.r", geom_name, "plastic", "", rgb);

	wdb_close(outfp);
	delete brep;
    }

    printf("Reading a twisted cube b-rep...\n");
    struct db_i* dbip = db_open("brep_cube1.g", "r");
    db_dirbuild(dbip);
    struct directory* dirp;
    if ((dirp = db_lookup(dbip, "cube.s", 0)) != DIR_NULL) {
	printf("\tfound cube.s\n");
	struct rt_db_internal ip;
	mat_t mat;
	MAT_IDN(mat);
	if (rt_db_get_internal(&ip, dirp, dbip, mat, &rt_uniresource) >= 0) {
	    printPoints((struct rt_brep_internal*)ip.idb_ptr);
	} else {
	    fprintf(stderr, "problem getting internal object rep\n");
	}
    }
    db_close(dbip);

    ON::End();

    return 0;
}
예제 #14
0
void
do_light(char *name, fastf_t *pos, fastf_t *dir_at, int da_flag, double r, unsigned char *rgb, struct wmember *headp)


    /* direction or aim point */
    /* 0 = direction, !0 = aim point */
    /* radius of light */


{
    char	nbuf[64];
    vect_t	center;
    mat_t	rot;
    mat_t	xlate;
    mat_t	both;
    vect_t	from;
    vect_t	dir;

    if ( da_flag )  {
	VSUB2( dir, dir_at, pos );
	VUNITIZE( dir );
    } else {
	VMOVE( dir, dir_at );
    }

    snprintf( nbuf, 64, "%s.s", name );
    VSETALL( center, 0 );
    mk_sph( outfp, nbuf, center, r );

    /*
     * Need to rotate from 0, 0, -1 to vect "dir",
     * then xlate to final position.
     */
    VSET( from, 0, 0, -1 );
    bn_mat_fromto( rot, from, dir );
    MAT_IDN( xlate );
    MAT_DELTAS_VEC( xlate, pos);
    bn_mat_mul( both, xlate, rot );

    mk_region1( outfp, name, nbuf, "light", "shadows=1", rgb );
    (void)mk_addmember( name, &(headp->l), NULL, WMOP_UNION );
}
예제 #15
0
void
bn_mat_angles_rad(
    register mat_t mat,
    double alpha,
    double beta,
    double ggamma)
{
    double calpha, cbeta, cgamma;
    double salpha, sbeta, sgamma;

    if (ZERO(alpha) && ZERO(beta) && ZERO(ggamma)) {
	MAT_IDN(mat);
	return;
    }

    calpha = cos(alpha);
    cbeta = cos(beta);
    cgamma = cos(ggamma);

    salpha = sin(alpha);
    sbeta = sin(beta);
    sgamma = sin(ggamma);

    mat[0] = cbeta * cgamma;
    mat[1] = -cbeta * sgamma;
    mat[2] = sbeta;
    mat[3] = 0.0;

    mat[4] = salpha * sbeta * cgamma + calpha * sgamma;
    mat[5] = -salpha * sbeta * sgamma + calpha * cgamma;
    mat[6] = -salpha * cbeta;
    mat[7] = 0.0;

    mat[8] = salpha * sgamma - calpha * sbeta * cgamma;
    mat[9] = salpha * cgamma + calpha * sbeta * sgamma;
    mat[10] = calpha * cbeta;
    mat[11] = 0.0;
    mat[12] = mat[13] = mat[14] = 0.0;
    mat[15] = 1.0;
}
예제 #16
0
파일: sh_scloud.c 프로젝트: kanzure/brlcad
HIDDEN int
scloud_setup(register struct region *rp, struct bu_vls *matparm, void **dpp, const struct mfuncs *mfp, struct rt_i *rtip)


/* pointer to reg_udata in *rp */


{
    register struct scloud_specific *scloud;
    struct db_full_path full_path;
    mat_t region_to_model;
    mat_t model_to_region;
    mat_t tmp;

    BU_CK_VLS(matparm);
    BU_GET(scloud, struct scloud_specific);
    *dpp = scloud;

    if (rp->reg_aircode == 0) {
        bu_log("WARNING(%s): air shader '%s' applied to non-air region.\n%s\n",
               rp->reg_name,
               mfp->mf_name,
               " Set air flag with \"edcodes\" in mged");
        bu_bomb("");
    }

    memcpy(scloud, &scloud_defaults, sizeof(struct scloud_specific));
    if (rdebug&RDEBUG_SHADE)
        bu_log("scloud_setup\n");

    if (bu_struct_parse(matparm, scloud_parse, (char *)scloud) < 0)
        return -1;

    if (rdebug&RDEBUG_SHADE)
        (void)bu_struct_print(rp->reg_name, scloud_parse, (char *)scloud);

    /* get transformation between world and "region" coordinates */
    if (db_string_to_path(&full_path, rtip->rti_dbip, rp->reg_name)) {
        /* bad thing */
        bu_bomb("db_string_to_path() error");
    }
    if (! db_path_to_mat(rtip->rti_dbip, &full_path, region_to_model, 0, &rt_uniresource)) {
        /* bad thing */
        bu_bomb("db_path_to_mat() error");
    }

    /* get matrix to map points from model space to "region" space */
    bn_mat_inv(model_to_region, region_to_model);

    /* add the noise-space scaling */
    MAT_IDN(tmp);
    if (!EQUAL(scloud->scale, 1.0)) {
        tmp[0] = tmp[5] = tmp[10] = 1.0 / scloud->scale;
    } else {
        tmp[0] = 1.0 / (scloud->vscale[0]);
        tmp[5] = 1.0 / (scloud->vscale[1]);
        tmp[10] = 1.0 / (scloud->vscale[2]);
    }

    bn_mat_mul(scloud->mtos, tmp, model_to_region);

    /* add the translation within noise space */
    MAT_IDN(tmp);
    tmp[MDX] = scloud->delta[0];
    tmp[MDY] = scloud->delta[1];
    tmp[MDZ] = scloud->delta[2];
    bn_mat_mul2(tmp, scloud->mtos);
    bn_mat_inv(scloud->stom, scloud->mtos);

    return 1;
}
예제 #17
0
파일: symbol.c 프로젝트: cogitokat/brlcad
/*
 *			T P _ 3 S Y M B O L
 */
void
tp_3symbol(FILE *fp, char *string, fastf_t *origin, fastf_t *rot, double scale)

/* string of chars to be plotted */
/* lower left corner of 1st char */
/* Transform matrix (WARNING: may xlate) */
/* scale factor to change 1x1 char sz */
{
    register unsigned char *cp;
    double	offset;			/* offset of char from given x, y */
    int	ysign;			/* sign of y motion, either +1 or -1 */
    vect_t	temp;
    vect_t	loc;
    mat_t	xlate_to_origin;
    mat_t	mat;

    if ( string == NULL || *string == '\0' )
	return;			/* done before begun! */

    /*
     *  The point "origin" will be the center of the axis rotation.
     *  The text is located in a local coordinate system with the
     *  lower left corner of the first character at (0, 0, 0), with
     *  the text proceeding onward towards +X.
     *  We need to rotate the text around its local (0, 0, 0),
     *  and then translate to the user's designated "origin".
     *  If the user provided translation or
     *  scaling in his matrix, it will *also* be applied.
     */
    MAT_IDN( xlate_to_origin );
    MAT_DELTAS_VEC( xlate_to_origin, origin );
    bn_mat_mul( mat, xlate_to_origin, rot );

    /* Check to see if initialization is needed */
    if ( tp_cindex[040] == 0 )  tp_setup();

    /* Draw each character in the input string */
    offset = 0;
    for ( cp = (unsigned char *)string; *cp; cp++, offset += scale )  {
	register int *p;	/* pointer to stroke table */
	register int stroke;

	VSET( temp, offset, 0, 0 );
	MAT4X3PNT( loc, mat, temp );
	pdv_3move( fp, loc );

	for ( p = tp_cindex[*cp]; (stroke= *p) != LAST; p++ )  {
	    int	draw;

	    if ( stroke==NEGY )  {
		ysign = (-1);
		stroke = *++p;
	    } else
		ysign = 1;

	    /* Detect & process pen control */
	    if ( stroke < 0 )  {
		stroke = -stroke;
		draw = 0;
	    } else
		draw = 1;

	    /* stroke co-ordinates in string coord system */
	    VSET( temp, (stroke/11) * 0.1 * scale + offset,
		  (ysign * (stroke%11)) * 0.1 * scale, 0 );
	    MAT4X3PNT( loc, mat, temp );
	    if ( draw )
		pdv_3cont( fp, loc );
	    else
		pdv_3move( fp, loc );
	}
    }
}
int
ged_copyeval(struct ged *gedp, int argc, const char *argv[])
{
    static const char *usage = "path_to_old_prim new_prim";
    struct _ged_trace_data gtd;
    struct directory *dp;
    struct rt_db_internal *ip;
    struct rt_db_internal internal, new_int;

    char *tok;
    int endpos = 0;
    int i;
    mat_t start_mat;

    GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
    GED_CHECK_READ_ONLY(gedp, GED_ERROR);
    GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);

    /* initialize result */
    bu_vls_trunc(gedp->ged_result_str, 0);

    /* must be wanting help */
    if (argc == 1) {
	bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
	return GED_HELP;
    }

    if (argc != 3) {
	bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
	return GED_ERROR;
    }

    /* initialize gtd */
    gtd.gtd_gedp = gedp;
    gtd.gtd_flag = _GED_CPEVAL;
    gtd.gtd_prflag = 0;

    /* check if new solid name already exists in description */
    GED_CHECK_EXISTS(gedp, argv[2], LOOKUP_QUIET, GED_ERROR);

    MAT_IDN(start_mat);

    /* build directory pointer array for desired path */
    if (strchr(argv[1], '/')) {
	tok = strtok((char *)argv[1], "/");
	while (tok) {
	    GED_DB_LOOKUP(gedp, gtd.gtd_obj[endpos], tok, LOOKUP_NOISY, GED_ERROR & GED_QUIET);
	    endpos++;
	    tok = strtok((char *)NULL, "/");
	}
    } else {
	GED_DB_LOOKUP(gedp, gtd.gtd_obj[endpos], argv[1], LOOKUP_NOISY, GED_ERROR & GED_QUIET);
	endpos++;
    }

    if (endpos < 1) {
	bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
	return GED_ERROR;
    }

    gtd.gtd_objpos = endpos - 1;

    GED_DB_GET_INTERNAL(gedp, &internal, gtd.gtd_obj[endpos - 1], bn_mat_identity, &rt_uniresource, GED_ERROR);

    if (endpos > 1) {
	/* Make sure that final component in path is a solid */
	if (internal.idb_type == ID_COMBINATION) {
	    rt_db_free_internal(&internal);
	    bu_vls_printf(gedp->ged_result_str, "final component on path must be a primitive!\n");
	    return GED_ERROR;
	}

	/* Accumulate the matrices */
	ged_trace(gtd.gtd_obj[0], 0, start_mat, &gtd, 1);

	if (gtd.gtd_prflag == 0) {
	    bu_vls_printf(gedp->ged_result_str, "PATH:  ");

	    for (i = 0; i < gtd.gtd_objpos; i++)
		bu_vls_printf(gedp->ged_result_str, "/%s", gtd.gtd_obj[i]->d_namep);

	    bu_vls_printf(gedp->ged_result_str, "  NOT FOUND\n");
	    rt_db_free_internal(&internal);
	    return GED_ERROR;
	}

	/* Have found the desired path - wdb_xform is the transformation matrix */
	/* wdb_xform matrix calculated in wdb_trace() */

	/* create the new solid */
	RT_DB_INTERNAL_INIT(&new_int);
	if (rt_generic_xform(&new_int, gtd.gtd_xform,
			     &internal, 0, gedp->ged_wdbp->dbip, &rt_uniresource)) {
	    rt_db_free_internal(&internal);
	    bu_vls_printf(gedp->ged_result_str, "ged_copyeval: rt_generic_xform failed\n");
	    return GED_ERROR;
	}

	ip = &new_int;
    } else
	ip = &internal;

    /* should call GED_DB_DIRADD() but need to deal with freeing the
     * internals on failure.
     */
    dp=db_diradd(gedp->ged_wdbp->dbip, argv[2], RT_DIR_PHONY_ADDR, 0, gtd.gtd_obj[endpos-1]->d_flags, (void *)&ip->idb_type);
    if (dp == RT_DIR_NULL) {
	rt_db_free_internal(&internal);
	if (ip == &new_int)
	    rt_db_free_internal(&new_int);
	bu_vls_printf(gedp->ged_result_str, "An error has occurred while adding a new object to the database.");
	return GED_ERROR;
    }

    /* should call GED_DB_DIRADD() but need to deal with freeing the
     * internals on failure.
     */
    if (rt_db_put_internal(dp, gedp->ged_wdbp->dbip, ip, &rt_uniresource) < 0) {
	/* if (ip == &new_int) then new_int gets freed by the rt_db_put_internal above
	 * regardless of whether it succeeds or not. At this point only internal needs
	 * to be freed. On the other hand if (ip == &internal), the internal gets freed
	 * freed by the rt_db_put_internal above. In this case memory for new_int has
	 * not been allocated.
	 */
	if (ip == &new_int)
	    rt_db_free_internal(&internal);

	bu_vls_printf(gedp->ged_result_str, "Database write error, aborting");
	return GED_ERROR;
    }

    /* see previous comment */
    if (ip == &new_int)
	rt_db_free_internal(&internal);

    return GED_OK;
}
예제 #19
0
파일: dm-plot.c 프로젝트: cogitokat/brlcad
/*
 * P L O T _ O P E N
 *
 * Fire up the display manager, and the display processor.
 *
 */
struct dm *
plot_open(Tcl_Interp *interp, int argc, const char *argv[])
{
    static int count = 0;
    struct dm *dmp;
    Tcl_Obj *obj;

    BU_ALLOC(dmp, struct dm);

    *dmp = dm_plot; /* struct copy */
    dmp->dm_interp = interp;

    BU_ALLOC(dmp->dm_vars.priv_vars, struct plot_vars);

    obj = Tcl_GetObjResult(interp);
    if (Tcl_IsShared(obj))
	obj = Tcl_DuplicateObj(obj);

    bu_vls_init(&((struct plot_vars *)dmp->dm_vars.priv_vars)->vls);
    bu_vls_init(&dmp->dm_pathName);
    bu_vls_init(&dmp->dm_tkName);
    bu_vls_printf(&dmp->dm_pathName, ".dm_plot%d", count++);
    bu_vls_printf(&dmp->dm_tkName, "dm_plot%d", count++);

    /* skip first argument */
    --argc; ++argv;

    /* Process any options */
    ((struct plot_vars *)dmp->dm_vars.priv_vars)->is_3D = 1;          /* 3-D w/color, by default */
    while (argv[0] != (char *)0 && argv[0][0] == '-') {
	switch (argv[0][1]) {
	    case '3':
		break;
	    case '2':
		((struct plot_vars *)dmp->dm_vars.priv_vars)->is_3D = 0;		/* 2-D, for portability */
		break;
	    case 'g':
		((struct plot_vars *)dmp->dm_vars.priv_vars)->grid = 1;
		break;
	    case 'f':
		((struct plot_vars *)dmp->dm_vars.priv_vars)->floating = 1;
		break;
	    case 'z':
	    case 'Z':
		/* Enable Z clipping */
		Tcl_AppendStringsToObj(obj, "Clipped in Z to viewing cube\n", (char *)NULL);

		dmp->dm_zclip = 1;
		break;
	    default:
		Tcl_AppendStringsToObj(obj, "bad PLOT option ", argv[0], "\n", (char *)NULL);
		(void)plot_close(dmp);

		Tcl_SetObjResult(interp, obj);
		return DM_NULL;
	}
	argv++;
    }
    if (argv[0] == (char *)0) {
	Tcl_AppendStringsToObj(obj, "no filename or filter specified\n", (char *)NULL);
	(void)plot_close(dmp);

	Tcl_SetObjResult(interp, obj);
	return DM_NULL;
    }

    if (argv[0][0] == '|') {
	bu_vls_strcpy(&((struct plot_vars *)dmp->dm_vars.priv_vars)->vls, &argv[0][1]);
	while ((++argv)[0] != (char *)0) {
	    bu_vls_strcat(&((struct plot_vars *)dmp->dm_vars.priv_vars)->vls, " ");
	    bu_vls_strcat(&((struct plot_vars *)dmp->dm_vars.priv_vars)->vls, argv[0]);
	}

	((struct plot_vars *)dmp->dm_vars.priv_vars)->is_pipe = 1;
    } else {
	bu_vls_strcpy(&((struct plot_vars *)dmp->dm_vars.priv_vars)->vls, argv[0]);
    }

    if (((struct plot_vars *)dmp->dm_vars.priv_vars)->is_pipe) {
	if ((((struct plot_vars *)dmp->dm_vars.priv_vars)->up_fp =
	     popen(bu_vls_addr(&((struct plot_vars *)dmp->dm_vars.priv_vars)->vls), "w")) == NULL) {
	    perror(bu_vls_addr(&((struct plot_vars *)dmp->dm_vars.priv_vars)->vls));
	    (void)plot_close(dmp);
	    Tcl_SetObjResult(interp, obj);
	    return DM_NULL;
	}

	Tcl_AppendStringsToObj(obj, "piped to ",
			       bu_vls_addr(&((struct plot_vars *)dmp->dm_vars.priv_vars)->vls),
			       "\n", (char *)NULL);
    } else {
	if ((((struct plot_vars *)dmp->dm_vars.priv_vars)->up_fp =
	     fopen(bu_vls_addr(&((struct plot_vars *)dmp->dm_vars.priv_vars)->vls), "wb")) == NULL) {
	    perror(bu_vls_addr(&((struct plot_vars *)dmp->dm_vars.priv_vars)->vls));
	    (void)plot_close(dmp);
	    Tcl_SetObjResult(interp, obj);
	    return DM_NULL;
	}

	Tcl_AppendStringsToObj(obj, "plot stored in ",
			       bu_vls_addr(&((struct plot_vars *)dmp->dm_vars.priv_vars)->vls),
			       "\n", (char *)NULL);
    }

    setbuf(((struct plot_vars *)dmp->dm_vars.priv_vars)->up_fp,
	   ((struct plot_vars *)dmp->dm_vars.priv_vars)->ttybuf);

    if (((struct plot_vars *)dmp->dm_vars.priv_vars)->is_3D)
	pl_3space(((struct plot_vars *)dmp->dm_vars.priv_vars)->up_fp,
		  -2048, -2048, -2048, 2048, 2048, 2048);
    else
	pl_space(((struct plot_vars *)dmp->dm_vars.priv_vars)->up_fp,
		 -2048, -2048, 2048, 2048);

    MAT_IDN(plotmat);

    Tcl_SetObjResult(interp, obj);
    return dmp;
}
예제 #20
0
int
main(int argc, char **argv)
{
    void anim_dir2mat(fastf_t *, const fastf_t *, const fastf_t *), anim_y_p_r2mat(fastf_t *, double, double, double), anim_add_trans(fastf_t *, const fastf_t *, const fastf_t *), anim_mat_print(FILE *, const fastf_t *, int);
    int get_args(int argc, char **argv), track_prep(void), val, frame, go, i, count;
    fastf_t y_rot, distance, yaw, pitch, roll;
    vect_t p1, p2, p3, dir, dir2, wheel_now, wheel_prev;
    vect_t zero, position, vdelta, temp, to_track, to_front;
    mat_t mat_v, wmat, mat_x;
    FILE *stream;
    int last_frame;

    VSETALL(zero, 0.0);
    VSETALL(to_track, 0.0);
    VSETALL(centroid, 0.0);
    VSETALL(rcentroid, 0.0);
    init_dist = y_rot = radius= 0.0;
    first_frame = num_wheels = steer = axes = cent = links_placed=0;
    num_wheels = num_links = last_frame = 0;
    MAT_IDN(mat_v);
    MAT_IDN(mat_x);
    MAT_IDN(wmat);
    MAT_IDN(m_axes);
    MAT_IDN(m_rev_axes);

    if (!get_args(argc, argv)) {
	fprintf(stderr, "anim_hardtrack: argument error.");
	return(-1);
    }

    if (axes || cent ) {
	/* vehicle has own reference frame */
	anim_add_trans(m_axes, centroid, zero);
	anim_add_trans(m_rev_axes, zero, rcentroid);
    }

    /* get track information from specified file */

    if (!(stream = fopen(*(argv+bu_optind), "rb"))) {
	fprintf(stderr, "Anim_hardtrack: Could not open file %s.\n", *(argv+bu_optind));
	return(0);
    }
    num_wheels = -1;
    if (radius) {
	while (!feof(stream)) {
	    fscanf(stream, "%*f %*f %*f");
	    num_wheels++;
	}
    } else {
	while (!feof(stream)) {
	    fscanf(stream, "%*f %*f %*f %*f");
	    num_wheels++;
	}
    }
    rewind(stream);

    /*allocate memory for track information*/
    x = (struct all *) bu_calloc(num_wheels, sizeof(struct all), "struct all");
    /*read rest of track info */
    for (i=0;i<NW;i++) {
	fscanf(stream, "%lf %lf %lf", temp, temp+1, temp+2);
	if (radius)
	    x[i].w.rad = radius;
	else
	    fscanf(stream, "%lf", & x[i].w.rad);
	MAT4X3PNT(x[i].w.pos, m_rev_axes, temp);
	if (i==0)
	    track_y = x[0].w.pos[1];
	else
	    x[i].w.pos[1] = track_y;
    }
    (void) fclose(stream);

    (void) track_prep();

    if (get_circumf) {
	printf("%.10g\n", tracklen);
	return(0);
    }

    /* initialize to_track */
    VSET(to_track, 0.0, track_y, 0.0);
    VSET(to_front, 1.0, 0.0, 0.0);

    if ((!print_link)&&(!print_wheel)) {
	fprintf(stderr, "anim_hardtrack: no ouput requested. Use -l or -w.\n");
	bu_exit(0, NULL);
    }
    /* main loop */
    distance = 0.0;
    if (!steer)
	frame = first_frame;
    else
	frame = first_frame-1;
    for (val = 3; val > 2; frame++) {
	go = 1;
	/*p2 is current position. p3 is next;p1 is previous*/
	VMOVE(p1, p2);
	VMOVE(p2, p3);
	scanf("%*f");/*time stamp*/
	val = scanf("%lf %lf %lf", p3, p3+1, p3 + 2);
	if (!steer) {
	    scanf("%lf %lf %lf", &yaw, &pitch, &roll);
	    anim_dy_p_r2mat(mat_v, yaw, pitch, roll);
	    anim_add_trans(mat_v, p3, rcentroid);
	}
	else {
	    /* analyze positions for steering */
	    /*get useful direction unit vectors*/
	    if (frame == first_frame) {
		/* first frame*/
		VSUBUNIT(dir, p3, p2);
		VMOVE(dir2, dir);
	    }
	    else if (val < 3) {
		/*last frame*/
		VSUBUNIT(dir, p2, p1);
		VMOVE(dir2, dir);
	    }
	    else if (frame > first_frame) {
		/*normal*/
		VSUBUNIT(dir, p3, p1);
		VSUBUNIT(dir2, p2, p1);/*needed for vertical case*/
	    }
	    else go = 0;/*first time through loop;no p2*/

			/*create matrix which would move vehicle*/
	    anim_dir2mat(mat_v, dir, dir2);
	    anim_add_trans(mat_v, p2, rcentroid);
	}

	/*determine distance traveled*/
	VMOVE(wheel_prev, wheel_now);
	MAT4X3PNT(wheel_now, mat_v, to_track);
	if (frame > first_frame) {
	    /* increment distance by distance moved */
	    VSUB2(vdelta, wheel_now, wheel_prev);
	    MAT3X3VEC(temp, mat_v, to_front);/*new front of vehicle*/
	    distance += VDOT(temp, vdelta);/*portion of vdelta in line with track*/
	}

	if (go) {
	    if (print_mode==TRACK_ANIM) {
		printf("start %d;\nclean;\n", frame);
	    } else if (print_mode==TRACK_ARCED) {
		if (frame != arced_frame) continue;
		last_frame = 1;
	    }
	    if (print_link) {
		for (count=0;count<num_links;count++) {
		    (void) get_link(position, &y_rot, distance+tracklen*count/num_links+init_dist);
		    anim_y_p_r2mat(wmat, 0.0, y_rot+r[count].ang, 0.0);
		    anim_add_trans(wmat, position, r[count].pos);
		    if ((axes || cent) && links_placed) {
			/* link moved from vehicle coords */
			bn_mat_mul(mat_x, wmat, m_rev_axes);
			bn_mat_mul(wmat, m_axes, mat_x);
		    }
		    else if (axes || cent) {
			/* link moved to vehicle coords */
			MAT_MOVE(mat_x, wmat);
			bn_mat_mul(wmat, m_axes, mat_x);
		    }
		    if (print_mode==TRACK_ANIM) {
			printf("anim %s.%d matrix %s\n", *(argv+link_nindex), count, link_cmd);
			anim_mat_printf(stdout, wmat, "%.10g ", "\n", ";\n");
		    } else if (print_mode==TRACK_ARCED) {
			printf("arced %s.%d matrix %s ", *(argv+link_nindex), count, link_cmd);
			anim_mat_printf(stdout, wmat, "%.10g ", "", "\n");
		    }
		}
	    }
	    if (print_wheel) {
		for (count = 0;count<num_wheels;count++) {
		    anim_y_p_r2mat(wmat, 0.0, -distance/x[count].w.rad, 0.0);
		    VREVERSE(temp, x[count].w.pos);
		    anim_add_trans(wmat, x[count].w.pos, temp);
		    if (axes || cent) {
			bn_mat_mul(mat_x, wmat, m_rev_axes);
			bn_mat_mul(wmat, m_axes, mat_x);
		    }
		    if (print_mode==TRACK_ANIM) {
			printf("anim %s.%d matrix %s\n", *(argv+wheel_nindex), count, wheel_cmd);
			anim_mat_printf(stdout, wmat, "%.10g ", "\n", ";\n");
		    } else if (print_mode==TRACK_ARCED) {
			printf("arced %s.%d matrix %s ", *(argv+wheel_nindex), count, wheel_cmd);
			anim_mat_printf(stdout, wmat, "%.10g ", "", "\n");
		    }
		}
	    }
	    if (print_mode==TRACK_ANIM)
		printf("end;\n");
	}
	if (last_frame) break;
    }

    if (x) {
	bu_free(x, "struct all");
    }
    if (r) {
	bu_free(r, "struct rlink");
    }
    return( 0 );
}
예제 #21
0
파일: ell_mirror.c 프로젝트: kanzure/brlcad
/**
 * Given a pointer to an internal GED database object, mirror the
 * object's values about the given transformation matrix.
 */
int
rt_ell_mirror(struct rt_db_internal *ip, register const plane_t plane)
{
    struct rt_ell_internal *ell;

    mat_t mirmat;
    mat_t rmat;
    mat_t temp;
    vect_t nvec;
    vect_t xvec;
    vect_t mirror_dir;
    point_t mirror_pt;
    fastf_t ang;

    mat_t mat;
    point_t pt;
    vect_t a, b, c;
    vect_t n;

    static point_t origin = {0.0, 0.0, 0.0};

    RT_CK_DB_INTERNAL(ip);

    ell = (struct rt_ell_internal *)ip->idb_ptr;
    RT_ELL_CK_MAGIC(ell);

    MAT_IDN(mirmat);

    VMOVE(mirror_dir, plane);
    VSCALE(mirror_pt, plane, plane[W]);

    /* Build mirror transform matrix, for those who need it. */
    /* First, perform a mirror down the X axis */
    mirmat[0] = -1.0;

    /* Create the rotation matrix */
    VSET(xvec, 1, 0, 0);
    VCROSS(nvec, xvec, mirror_dir);
    VUNITIZE(nvec);
    ang = -acos(VDOT(xvec, mirror_dir));
    bn_mat_arb_rot(rmat, origin, nvec, ang*2.0);

    /* Add the rotation to mirmat */
    MAT_COPY(temp, mirmat);
    bn_mat_mul(mirmat, temp, rmat);

    /* Add the translation to mirmat */
    mirmat[3 + X*4] += mirror_pt[X] * mirror_dir[X];
    mirmat[3 + Y*4] += mirror_pt[Y] * mirror_dir[Y];
    mirmat[3 + Z*4] += mirror_pt[Z] * mirror_dir[Z];

    VMOVE(pt, ell->v);
    MAT4X3PNT(ell->v, mirmat, pt);

    VMOVE(a, ell->a);
    VUNITIZE(a);
    VCROSS(n, mirror_dir, ell->a);
    VUNITIZE(n);
    ang = M_PI_2 - acos(VDOT(a, mirror_dir));
    bn_mat_arb_rot(mat, origin, n, ang*2);
    VMOVE(a, ell->a);
    MAT4X3VEC(ell->a, mat, a);

    VMOVE(b, ell->b);
    VUNITIZE(b);
    VCROSS(n, mirror_dir, ell->b);
    VUNITIZE(n);
    ang = M_PI_2 - acos(VDOT(b, mirror_dir));
    bn_mat_arb_rot(mat, origin, n, ang*2);
    VMOVE(b, ell->b);
    MAT4X3VEC(ell->b, mat, b);

    VMOVE(c, ell->c);
    VUNITIZE(c);
    VCROSS(n, mirror_dir, ell->c);
    VUNITIZE(n);
    ang = M_PI_2 - acos(VDOT(c, mirror_dir));
    bn_mat_arb_rot(mat, origin, n, ang*2);
    VMOVE(c, ell->c);
    MAT4X3VEC(ell->c, mat, c);

    return 0;
}
예제 #22
0
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;
}
예제 #23
0
파일: vlist.c 프로젝트: cogitokat/brlcad
int
rt_process_uplot_value(register struct bu_list **vhead,
		       struct bn_vlblock *vbp,
		       FILE *fp,
		       register int c,
		       double char_size,
		       int mode)
{
    mat_t mat;
    const struct uplot *up;
#define CARG_LEN 256
#define ARG_LEN 6
    char carg[CARG_LEN];
    fastf_t arg[ARG_LEN];
    vect_t a, b;
    point_t last_pos;
    static point_t lpnt;		/* last point of a move/draw series */
    static int moved = 0;	/* moved since color change */

    memset(carg, 0, sizeof(char)*CARG_LEN);
    memset(arg, 0, sizeof(fastf_t)*ARG_LEN);
#undef ARG_LEN
#undef CARG_LEN


    /* look it up */
    if (c < 'A' || c > 'z') {
	up = &rt_uplot_error;
    } else {
	up = &rt_uplot_letters[ c - 'A' ];
    }

    if (up->targ == TBAD) {
	fprintf(stderr, "Lee : Bad command '%c' (0x%02x)\n", c, c);
	return -1;
    }

    if (up->narg > 0) {
	if (mode == PL_OUTPUT_MODE_BINARY)
	    rt_uplot_get_args(fp, up, carg, arg);
	else
	    rt_uplot_get_text_args(fp, up, carg, arg);
    }

    switch (c) {
	case 's':
	case 'w':
	case 'S':
	case 'W':
	    /* Space commands, do nothing. */
	    break;
	case 'm':
	case 'o':
	    /* 2-D move */
	    arg[Z] = 0;
	    BN_ADD_VLIST(vbp->free_vlist_hd, *vhead, arg, BN_VLIST_LINE_MOVE);
	    VMOVE(lpnt, arg);
	    moved = 1;
	    break;
	case 'M':
	case 'O':
	    /* 3-D move */
	    BN_ADD_VLIST(vbp->free_vlist_hd, *vhead, arg, BN_VLIST_LINE_MOVE);
	    VMOVE(lpnt, arg);
	    moved = 1;
	    break;
	case 'n':
	case 'q':
	    /*
	     * If no move command was issued since the last color
	     * change, insert one now using the last point from a
	     * move/draw.
	     */
	    if (!moved) {
		BN_ADD_VLIST(vbp->free_vlist_hd, *vhead, lpnt, BN_VLIST_LINE_MOVE);
		moved = 1;
	    }

	    /* 2-D draw */
	    arg[Z] = 0;
	    BN_ADD_VLIST(vbp->free_vlist_hd, *vhead, arg, BN_VLIST_LINE_DRAW);
	    VMOVE(lpnt, arg);
	    break;
	case 'N':
	case 'Q':
	    /*
	     * If no move command was issued since the last color
	     * change, insert one now using the last point from a
	     * move/draw.
	     */
	    if (!moved) {
		BN_ADD_VLIST(vbp->free_vlist_hd, *vhead, lpnt, BN_VLIST_LINE_MOVE);
		moved = 1;
	    }

	    /* 3-D draw */
	    BN_ADD_VLIST(vbp->free_vlist_hd, *vhead, arg, BN_VLIST_LINE_DRAW);
	    VMOVE(lpnt, arg);
	    break;
	case 'l':
	case 'v':
	    /* 2-D line */
	    VSET(a, arg[0], arg[1], 0.0);
	    VSET(b, arg[2], arg[3], 0.0);
	    BN_ADD_VLIST(vbp->free_vlist_hd, *vhead, a, BN_VLIST_LINE_MOVE);
	    BN_ADD_VLIST(vbp->free_vlist_hd, *vhead, b, BN_VLIST_LINE_DRAW);
	    break;
	case 'L':
	case 'V':
	    /* 3-D line */
	    VSET(a, arg[0], arg[1], arg[2]);
	    VSET(b, arg[3], arg[4], arg[5]);
	    BN_ADD_VLIST(vbp->free_vlist_hd, *vhead, a, BN_VLIST_LINE_MOVE);
	    BN_ADD_VLIST(vbp->free_vlist_hd, *vhead, b, BN_VLIST_LINE_DRAW);
	    break;
	case 'p':
	case 'x':
	    /* 2-D point */
	    arg[Z] = 0;
	    BN_ADD_VLIST(vbp->free_vlist_hd, *vhead, arg, BN_VLIST_LINE_MOVE);
	    BN_ADD_VLIST(vbp->free_vlist_hd, *vhead, arg, BN_VLIST_LINE_DRAW);
	    break;
	case 'P':
	case 'X':
	    /* 3-D point */
	    BN_ADD_VLIST(vbp->free_vlist_hd, *vhead, arg, BN_VLIST_LINE_MOVE);
	    BN_ADD_VLIST(vbp->free_vlist_hd, *vhead, arg, BN_VLIST_LINE_DRAW);
	    break;
	case 'C':
	    /* Color */
	    *vhead = rt_vlblock_find(vbp,
				     carg[0], carg[1], carg[2]);
	    moved = 0;
	    break;
	case 't':
	    /* Text string */
	    MAT_IDN(mat);
	    if (BU_LIST_NON_EMPTY(*vhead)) {
		struct bn_vlist *vlp;
		/* Use coordinates of last op */
		vlp = BU_LIST_LAST(bn_vlist, *vhead);
		VMOVE(last_pos, vlp->pt[vlp->nused-1]);
	    } else {
		VSETALL(last_pos, 0);
	    }
	    bn_vlist_3string(*vhead, vbp->free_vlist_hd, carg, last_pos, mat, char_size);
	    break;
    }

    return 0;
}
예제 #24
0
int
ged_otranslate(struct ged *gedp, int argc, const char *argv[])
{
    struct directory *dp;
    struct _ged_trace_data gtd;
    struct rt_db_internal intern;
    vect_t delta;
    double scan[3];
    mat_t dmat;
    mat_t emat;
    mat_t tmpMat;
    mat_t invXform;
    point_t rpp_min;
    point_t rpp_max;
    static const char *usage = "obj dx dy dz";

    GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
    GED_CHECK_READ_ONLY(gedp, GED_ERROR);
    GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);

    /* initialize result */
    bu_vls_trunc(gedp->ged_result_str, 0);

    /* must be wanting help */
    if (argc == 1) {
	bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
	return GED_HELP;
    }

    if (argc != 5) {
	bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
	return GED_ERROR;
    }

    if (_ged_get_obj_bounds2(gedp, 1, argv+1, &gtd, rpp_min, rpp_max) == GED_ERROR)
	return GED_ERROR;

    dp = gtd.gtd_obj[gtd.gtd_objpos-1];
    if (!(dp->d_flags & RT_DIR_SOLID)) {
	if (_ged_get_obj_bounds(gedp, 1, argv+1, 1, rpp_min, rpp_max) == GED_ERROR)
	    return GED_ERROR;
    }

    if (sscanf(argv[2], "%lf", &scan[X]) != 1) {
	bu_vls_printf(gedp->ged_result_str, "%s: bad x value - %s", argv[0], argv[2]);
	return GED_ERROR;
    }

    if (sscanf(argv[3], "%lf", &scan[Y]) != 1) {
	bu_vls_printf(gedp->ged_result_str, "%s: bad y value - %s", argv[0], argv[3]);
	return GED_ERROR;
    }

    if (sscanf(argv[4], "%lf", &scan[Z]) != 1) {
	bu_vls_printf(gedp->ged_result_str, "%s: bad z value - %s", argv[0], argv[4]);
	return GED_ERROR;
    }

    MAT_IDN(dmat);
    VSCALE(delta, scan, gedp->ged_wdbp->dbip->dbi_local2base);
    MAT_DELTAS_VEC(dmat, delta);

    bn_mat_inv(invXform, gtd.gtd_xform);
    bn_mat_mul(tmpMat, invXform, dmat);
    bn_mat_mul(emat, tmpMat, gtd.gtd_xform);

    GED_DB_GET_INTERNAL(gedp, &intern, dp, emat, &rt_uniresource, GED_ERROR);
    RT_CK_DB_INTERNAL(&intern);
    GED_DB_PUT_INTERNAL(gedp, dp, &intern, &rt_uniresource, GED_ERROR);

    return GED_OK;
}
/**
 * Given a pointer to an internal GED database object, mirror the
 * object's values about the given transformation matrix.
 */
int
rt_half_mirror(struct rt_db_internal *ip, register const plane_t plane)
{
    struct rt_half_internal *half;

    mat_t mirmat;
    mat_t rmat;
    mat_t temp;
    vect_t nvec;
    vect_t xvec;
    vect_t mirror_dir;
    point_t mirror_pt;
    fastf_t ang;

    vect_t n1;
    vect_t n2;

    static fastf_t tol_dist_sq = 0.0005 * 0.0005;
    static point_t origin = {0.0, 0.0, 0.0};

    RT_CK_DB_INTERNAL(ip);

    half = (struct rt_half_internal *)ip->idb_ptr;
    RT_HALF_CK_MAGIC(half);

    MAT_IDN(mirmat);

    VMOVE(mirror_dir, plane);
    VSCALE(mirror_pt, plane, plane[W]);

    /* Build mirror transform matrix, for those who need it. */
    /* First, perform a mirror down the X axis */
    mirmat[0] = -1.0;

    /* Create the rotation matrix */
    VSET(xvec, 1, 0, 0);
    VCROSS(nvec, xvec, mirror_dir);
    VUNITIZE(nvec);
    ang = -acos(VDOT(xvec, mirror_dir));
    bn_mat_arb_rot(rmat, origin, nvec, ang*2.0);

    /* Add the rotation to mirmat */
    MAT_COPY(temp, mirmat);
    bn_mat_mul(mirmat, temp, rmat);

    /* Add the translation to mirmat */
    mirmat[3 + X*4] += mirror_pt[X] * mirror_dir[X];
    mirmat[3 + Y*4] += mirror_pt[Y] * mirror_dir[Y];
    mirmat[3 + Z*4] += mirror_pt[Z] * mirror_dir[Z];

    /* FIXME: this is not using the mirmat we just computed, not clear
     * it's even right given it's only taking the mirror direction
     * into account and not the mirror point.
     */

    VMOVE(n1, half->eqn);
    VCROSS(n2, mirror_dir, n1);
    VUNITIZE(n2);
    ang = M_PI_2 - acos(VDOT(n1, mirror_dir));
    bn_mat_arb_rot(rmat, origin, n2, ang*2);
    MAT4X3VEC(half->eqn, rmat, n1);

    if (!NEAR_EQUAL(VDOT(n1, half->eqn), 1.0, tol_dist_sq)) {
	point_t ptA;
	point_t ptB;
	point_t ptC;
	vect_t h;
	fastf_t mag;
	fastf_t cosa;

	VSCALE(ptA, n1, half->eqn[H]);
	VADD2(ptB, ptA, mirror_dir);
	VSUB2(h, ptB, ptA);
	mag = MAGNITUDE(h);
	VUNITIZE(h);

	cosa = VDOT(h, mirror_dir);

	VSCALE(ptC, half->eqn, -mag * cosa);
	VADD2(ptC, ptC, ptA);
	half->eqn[H] = VDOT(half->eqn, ptC);
    }

    return 0;
}
예제 #26
0
파일: superell.c 프로젝트: kanzure/brlcad
/**
 * Calculate a bounding RPP for a superell
 */
int
rt_superell_bbox(struct rt_db_internal *ip, point_t *min, point_t *max, const struct bn_tol *UNUSED(tol)) {

    struct rt_superell_internal *eip;
    fastf_t magsq_a, magsq_b, magsq_c;
    vect_t Au, Bu, Cu;
    mat_t R;
    vect_t w1, w2, P;	/* used for bounding RPP */
    fastf_t f;

    eip = (struct rt_superell_internal *)ip->idb_ptr;
    RT_SUPERELL_CK_MAGIC(eip);

    magsq_a = MAGSQ(eip->a);
    magsq_b = MAGSQ(eip->b);
    magsq_c = MAGSQ(eip->c);


    /* Create unit length versions of A, B, C */
    f = 1.0/sqrt(magsq_a);
    VSCALE(Au, eip->a, f);
    f = 1.0/sqrt(magsq_b);
    VSCALE(Bu, eip->b, f);
    f = 1.0/sqrt(magsq_c);
    VSCALE(Cu, eip->c, f);

    MAT_IDN(R);
    VMOVE(&R[0], Au);
    VMOVE(&R[4], Bu);
    VMOVE(&R[8], Cu);

    /* Compute bounding RPP */
    VSET(w1, magsq_a, magsq_b, magsq_c);

    /* X */
    VSET(P, 1.0, 0, 0);		/* bounding plane normal */
    MAT3X3VEC(w2, R, P);		/* map plane to local coord syst */
    VELMUL(w2, w2, w2);		/* square each term */
    f = VDOT(w1, w2);
    f = sqrt(f);
    (*min)[X] = eip->v[X] - f;	/* V.P +/- f */
    (*max)[X] = eip->v[X] + f;

    /* Y */
    VSET(P, 0, 1.0, 0);		/* bounding plane normal */
    MAT3X3VEC(w2, R, P);		/* map plane to local coord syst */
    VELMUL(w2, w2, w2);		/* square each term */
    f = VDOT(w1, w2);
    f = sqrt(f);
    (*min)[Y] = eip->v[Y] - f;	/* V.P +/- f */
    (*max)[Y] = eip->v[Y] + f;

    /* Z */
    VSET(P, 0, 0, 1.0);		/* bounding plane normal */
    MAT3X3VEC(w2, R, P);		/* map plane to local coord syst */
    VELMUL(w2, w2, w2);		/* square each term */
    f = VDOT(w1, w2);
    f = sqrt(f);
    (*min)[Z] = eip->v[Z] - f;	/* V.P +/- f */
    (*max)[Z] = eip->v[Z] + f;

    return 0;
}
static void
log_Run(void)
{
    time_t clock_time;
    mat_t model2hv;		/* model to h, v matrix */
    mat_t hv2model;		/* h, v tp model matrix */
    quat_t orient;			/* orientation */
    point_t hv_eye;			/* eye position in h, v coords */
    point_t m_eye;			/* eye position in model coords */
    fastf_t hv_viewsize;		/* size of view in h, v coords */
    fastf_t m_viewsize;		/* size of view in model coords. */

    /* Current date and time get printed in header comment */
    (void) time(&clock_time);

    (void) printf("# Log information produced by cell-fb %s\n",
		  ctime(&clock_time));
    (void) printf("az_el: %f %f\n", az, el);
    (void) printf("view_extrema: %f %f %f %f\n",
		  SCRX2H(0), SCRX2H(fb_width), SCRY2V(0), SCRY2V(fb_height));
    (void) printf("fb_size: %d %d\n", fb_width, fb_height);

    /* Produce the orientation, the model eye_pos, and the model
     * view size for input into rtregis.
     * First use the azimuth and elevation to produce the model2hv
     * matrix and use that to find the orientation.
     */

    MAT_IDN(model2hv);
    MAT_IDN(hv2model);

    /* Print out the "view" just to keep rtregis from belly-aching */

    printf("View: %g azimuth, %g elevation\n", az, el);

    /** mat_ae(model2hv, az, el); **/
    /* Formula from rt/do.c */
    bn_mat_angles(model2hv, 270.0+el, 0.0, 270.0-az);
    model2hv[15] = 25.4;		/* input is in inches */
    bn_mat_inv(hv2model, model2hv);

    quat_mat2quat(orient, model2hv);

    printf("Orientation: %.6f, %.6f, %.6f, %.6f\n", V4ARGS(orient));

    /* Now find the eye position in h, v space.  Note that the eye
     * is located at the center of the image; in this case, the center
     * of the screen space, i.e., the framebuffer.)
     * Also find the hv_viewsize at this time.
     */
    hv_viewsize = SCRX2H((double)fb_width) - SCRX2H(0.0);
    hv_eye[0] = SCRX2H((double)fb_width/2);
    hv_eye[1] = SCRY2V((double)fb_height/2);
    hv_eye[2] = hv_viewsize/2;

    /* Debugging */
    printf("hv_viewsize= %g\n", hv_viewsize);
    printf("hv_eye= %.6f, %.6f, %.6f\n", V3ARGS(hv_eye));

    /* Now find the model eye_position and report on that */
    MAT4X3PNT(m_eye, hv2model, hv_eye);
    printf("Eye_pos: %.6f, %.6f, %.6f\n", V3ARGS(m_eye));

    /*
     * Find the view size in model coordinates and print that as well.
     * Important:  Don't use %g format, it may round to nearest integer!
     */
    m_viewsize = hv_viewsize/hv2model[15];
    printf("Size: %.6f\n", m_viewsize);
}
예제 #28
0
파일: superell.c 프로젝트: kanzure/brlcad
/**
 * Given a pointer to a GED database record, and a transformation
 * matrix, determine if this is a valid superellipsoid, and if so,
 * precompute various terms of the formula.
 *
 * Returns -
 * 0 SUPERELL is OK
 * !0 Error in description
 *
 * Implicit return - A struct superell_specific is created, and its
 * address is stored in stp->st_specific for use by rt_superell_shot()
 */
int
rt_superell_prep(struct soltab *stp, struct rt_db_internal *ip, struct rt_i *rtip)
{

    struct superell_specific *superell;
    struct rt_superell_internal *eip;
    fastf_t magsq_a, magsq_b, magsq_c;
    mat_t R, TEMP;
    vect_t Au, Bu, Cu;	/* A, B, C with unit length */
    fastf_t f;

    eip = (struct rt_superell_internal *)ip->idb_ptr;
    RT_SUPERELL_CK_MAGIC(eip);

    /* Validate that |A| > 0, |B| > 0, |C| > 0 */
    magsq_a = MAGSQ(eip->a);
    magsq_b = MAGSQ(eip->b);
    magsq_c = MAGSQ(eip->c);

    if (magsq_a < rtip->rti_tol.dist_sq || magsq_b < rtip->rti_tol.dist_sq || magsq_c < rtip->rti_tol.dist_sq) {
        bu_log("rt_superell_prep():  superell(%s) near-zero length A(%g), B(%g), or C(%g) vector\n",
               stp->st_name, magsq_a, magsq_b, magsq_c);
        return 1;		/* BAD */
    }
    if (eip->n < rtip->rti_tol.dist || eip->e < rtip->rti_tol.dist) {
        bu_log("rt_superell_prep():  superell(%s) near-zero length <n, e> curvature (%g, %g) causes problems\n",
               stp->st_name, eip->n, eip->e);
        /* BAD */
    }
    if (eip->n > 10000.0 || eip->e > 10000.0) {
        bu_log("rt_superell_prep():  superell(%s) very large <n, e> curvature (%g, %g) causes problems\n",
               stp->st_name, eip->n, eip->e);
        /* BAD */
    }

    /* Create unit length versions of A, B, C */
    f = 1.0/sqrt(magsq_a);
    VSCALE(Au, eip->a, f);
    f = 1.0/sqrt(magsq_b);
    VSCALE(Bu, eip->b, f);
    f = 1.0/sqrt(magsq_c);
    VSCALE(Cu, eip->c, f);

    /* Validate that A.B == 0, B.C == 0, A.C == 0 (check dir only) */
    f = VDOT(Au, Bu);
    if (! NEAR_ZERO(f, rtip->rti_tol.dist)) {
        bu_log("rt_superell_prep():  superell(%s) A not perpendicular to B, f=%f\n", stp->st_name, f);
        return 1;		/* BAD */
    }
    f = VDOT(Bu, Cu);
    if (! NEAR_ZERO(f, rtip->rti_tol.dist)) {
        bu_log("rt_superell_prep():  superell(%s) B not perpendicular to C, f=%f\n", stp->st_name, f);
        return 1;		/* BAD */
    }
    f = VDOT(Au, Cu);
    if (! NEAR_ZERO(f, rtip->rti_tol.dist)) {
        bu_log("rt_superell_prep():  superell(%s) A not perpendicular to C, f=%f\n", stp->st_name, f);
        return 1;		/* BAD */
    }

    /* Solid is OK, compute constant terms now */

    BU_GET(superell, struct superell_specific);
    stp->st_specific = (void *)superell;

    superell->superell_n = eip->n;
    superell->superell_e = eip->e;

    VMOVE(superell->superell_V, eip->v);

    VSET(superell->superell_invsq, 1.0/magsq_a, 1.0/magsq_b, 1.0/magsq_c);
    VMOVE(superell->superell_Au, Au);
    VMOVE(superell->superell_Bu, Bu);
    VMOVE(superell->superell_Cu, Cu);

    /* compute the inverse magnitude square for equations during shot */
    superell->superell_invmsAu = 1.0 / magsq_a;
    superell->superell_invmsBu = 1.0 / magsq_b;
    superell->superell_invmsCu = 1.0 / magsq_c;

    /* compute the rotation matrix */
    MAT_IDN(R);
    VMOVE(&R[0], Au);
    VMOVE(&R[4], Bu);
    VMOVE(&R[8], Cu);
    bn_mat_trn(superell->superell_invR, R);

    /* computer invRSSR */
    MAT_IDN(superell->superell_invRSSR);
    MAT_IDN(TEMP);
    TEMP[0] = superell->superell_invsq[0];
    TEMP[5] = superell->superell_invsq[1];
    TEMP[10] = superell->superell_invsq[2];
    bn_mat_mul(TEMP, TEMP, R);
    bn_mat_mul(superell->superell_invRSSR, superell->superell_invR, TEMP);

    /* compute Scale(Rotate(vect)) */
    MAT_IDN(superell->superell_SoR);
    VSCALE(&superell->superell_SoR[0], eip->a, superell->superell_invsq[0]);
    VSCALE(&superell->superell_SoR[4], eip->b, superell->superell_invsq[1]);
    VSCALE(&superell->superell_SoR[8], eip->c, superell->superell_invsq[2]);

    /* Compute bounding sphere */
    VMOVE(stp->st_center, eip->v);
    f = magsq_a;
    if (magsq_b > f)
        f = magsq_b;
    if (magsq_c > f)
        f = magsq_c;
    stp->st_aradius = stp->st_bradius = sqrt(f);

    /* Compute bounding RPP */
    if (rt_superell_bbox(ip, &(stp->st_min), &(stp->st_max), &rtip->rti_tol)) return 1;

    return 0;			/* OK */
}
예제 #29
0
bool STEPWrapper::convert(BRLCADWrapper *dot_g)
{
    MAP_OF_PRODUCT_NAME_TO_ENTITY_ID name2id_map;
    MAP_OF_ENTITY_ID_TO_PRODUCT_NAME id2name_map;
    MAP_OF_ENTITY_ID_TO_PRODUCT_ID id2productid_map;
    MAP_OF_PRODUCT_NAME_TO_ENTITY_ID::iterator niter = name2id_map.end();

    if (!dot_g) {
	return false;
    }

    this->dotg = dot_g;

    int num_ents = instance_list->InstanceCount();
    for (int i = 0; i < num_ents; i++) {
	SDAI_Application_instance *sse = instance_list->GetSTEPentity(i);
	if (sse == NULL) {
	    continue;
	}
	std::string name = sse->EntityName();
	std::transform(name.begin(), name.end(), name.begin(), (int(*)(int))std::tolower);

	if ((sse->STEPfile_id > 0) && (sse->IsA(SCHEMA_NAMESPACE::e_shape_definition_representation))) {
	    ShapeDefinitionRepresentation *sdr = dynamic_cast<ShapeDefinitionRepresentation *>(Factory::CreateObject(this, (SDAI_Application_instance *)sse));

	    if (!sdr) {
		bu_exit(1, "ERROR: unable to allocate a 'ShapeDefinitionRepresentation' entity\n");
	    } else {
		int sdr_id = sdr->GetId();
		std::string pname  = sdr->GetProductName();
		int product_id = sdr->GetProductId();

		id2productid_map[sdr_id] = product_id;

		if (pname.empty()) {
		    std::string str = "ShapeDefinitionRepresentation@";
		    str = dotg->GetBRLCADName(str);
		    id2name_map[sdr_id] = pname;
		} else {
		    std::string temp = pname;
		    int index = 2;
		    while ((niter=name2id_map.find(temp)) != name2id_map.end()) {
			temp = pname + "_" + static_cast<ostringstream*>( &(ostringstream() << (index++)) )->str();
		    }
		    pname = temp;
		    if ((niter=name2id_map.find(pname)) == name2id_map.end()) {
			id2name_map[sdr_id] = pname;
			name2id_map[pname] = product_id;
			id2name_map[product_id] = pname;
		    }
		}

		AdvancedBrepShapeRepresentation *aBrep = sdr->GetAdvancedBrepShapeRepresentation();
		if (aBrep) {
		    if (pname.empty()) {
			std::string str = "product@";
			pname = dotg->GetBRLCADName(str);
			id2name_map[aBrep->GetId()] = pname;
			id2name_map[product_id] = pname;
		    } else {
			id2name_map[aBrep->GetId()] = pname;
			id2name_map[product_id] = pname;
		    }
		    id2productid_map[aBrep->GetId()] = product_id;

		    if (Verbose()) {
			if (!pname.empty()) {
			    std::cerr << std::endl << "     Generating Product -" << pname ;
			} else {
			    std::cerr << std::endl << "     Generating Product";
			}
		    }

		    LocalUnits::length = aBrep->GetLengthConversionFactor();
		    LocalUnits::planeangle = aBrep->GetPlaneAngleConversionFactor();
		    LocalUnits::solidangle = aBrep->GetSolidAngleConversionFactor();
		    ON_Brep *onBrep = aBrep->GetONBrep();
		    if (!onBrep) {
			delete sdr;
			bu_exit(1, "ERROR: failure creating advanced boundary representation from %s\n", stepfile.c_str());
		    } else {
			ON_TextLog tl;

			if (!onBrep->IsValid(&tl)) {
			    bu_log("WARNING: %s is not valid\n", name.c_str());
			}

			//onBrep->SpSplitClosedFaces();
			//ON_Brep *tbrep = TightenBrep(onBrep);

			mat_t mat;
			MAT_IDN(mat);

			Axis2Placement3D *axis = aBrep->GetAxis2Placement3d();
			if (axis != NULL) {
			    //assign matrix values
			    double translate_to[3];
			    const double *toXaxis = axis->GetXAxis();
			    const double *toYaxis = axis->GetYAxis();
			    const double *toZaxis = axis->GetZAxis();
			    mat_t rot_mat;

			    VMOVE(translate_to,axis->GetOrigin());
			    VSCALE(translate_to,translate_to,LocalUnits::length);

			    MAT_IDN(rot_mat);
			    VMOVE(&rot_mat[0], toXaxis);
			    VMOVE(&rot_mat[4], toYaxis);
			    VMOVE(&rot_mat[8], toZaxis);
			    bn_mat_inv(mat, rot_mat);
			    MAT_DELTAS_VEC(mat, translate_to);
			}

			dotg->WriteBrep(pname, onBrep,mat);

			delete onBrep;
		    }
		} else { // must be an assembly
		    if (pname.empty()) {
			std::string str = "assembly@";
			pname = dotg->GetBRLCADName(str);
		    }
		    ShapeRepresentation *aSR = sdr->GetShapeRepresentation();
		    if (aSR) {
			int sr_id = aSR->GetId();
			id2name_map[sr_id] = pname;
			id2name_map[product_id] = pname;
			id2productid_map[sr_id] = product_id;
		    }
		}
		Factory::DeleteObjects();
	    }
	}
    }
    /*
     * Pickup BREP related to SHAPE_REPRESENTATION through SHAPE_REPRESENTATION_RELATIONSHIP
     *
     * like the following found in OpenBook Part 'C':
     *    #21281=SHAPE_DEFINITION_REPRESENTATION(#21280,#21270);
     *        #21280=PRODUCT_DEFINITION_SHAPE('','SHAPE FOR C.',#21279);
     *            #21279=PRODUCT_DEFINITION('design','',#21278,#21275);
     *                #21278=PRODUCT_DEFINITION_FORMATION_WITH_SPECIFIED_SOURCE('1','LAST_VERSION',#21277,.MADE.);
     *                    #21277=PRODUCT('C','C','NOT SPECIFIED',(#21276));
     *        #21270=SHAPE_REPRESENTATION('',(#21259),#21267);
     *            #21259=AXIS2_PLACEMENT_3D('DANTE_BX_CPU_TOP_1',#21256,#21257,#21258);
     *            #21267=(GEOMETRIC_REPRESENTATION_CONTEXT(3)GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#21266))
     *                GLOBAL_UNIT_ASSIGNED_CONTEXT((#21260,#21264,#21265))REPRESENTATION_CONTEXT('ID1','3'));
     *
     *    #21271=SHAPE_REPRESENTATION_RELATIONSHIP('','',#21270,#21268);
     *        #21268=ADVANCED_BREP_SHAPE_REPRESENTATION('',(#21254),#21267);
     *    #21272=SHAPE_REPRESENTATION_RELATIONSHIP('','',#21270,#21269);
     *        #21269=MANIFOLD_SURFACE_SHAPE_REPRESENTATION('',(#21255),#21267);
     *
     */
    for (int i = 0; i < num_ents; i++) {
	SDAI_Application_instance *sse = instance_list->GetSTEPentity(i);
	if (sse == NULL) {
	    continue;
	}
	std::string name = sse->EntityName();
	std::transform(name.begin(), name.end(), name.begin(), (int(*)(int))std::tolower);

	if ((sse->STEPfile_id > 0) && (sse->IsA(SCHEMA_NAMESPACE::e_shape_representation_relationship))) {
	    ShapeRepresentationRelationship *srr = dynamic_cast<ShapeRepresentationRelationship *>(Factory::CreateObject(this, (SDAI_Application_instance *)sse));

	    if (srr) {
		ShapeRepresentation *aSR = dynamic_cast<ShapeRepresentation *>(srr->GetRepresentationRelationshipRep_1());
		AdvancedBrepShapeRepresentation *aBrep = dynamic_cast<AdvancedBrepShapeRepresentation *>(srr->GetRepresentationRelationshipRep_2());
		if (!aBrep) { //try rep_1
		    aBrep = dynamic_cast<AdvancedBrepShapeRepresentation *>(srr->GetRepresentationRelationshipRep_1());
		    aSR = dynamic_cast<ShapeRepresentation *>(srr->GetRepresentationRelationshipRep_2());
		}
		if ((aSR) && (aBrep)) {
		    int sr_id = aSR->GetId();
		    MAP_OF_ENTITY_ID_TO_PRODUCT_ID::iterator it = id2productid_map.find(sr_id);
		    if (it != id2productid_map.end()) { // product found
			int product_id = (*it).second;
			int brep_id = aBrep->GetId();

			it = id2productid_map.find(brep_id);
			if (it == id2productid_map.end()) { // brep not loaded yet so lets do that here.
			    string pname = id2name_map[product_id];
			    id2productid_map[brep_id] = product_id;

			    if (Verbose()) {
				if (!pname.empty()) {
				    std::cerr << std::endl << "     Generating Product -" << pname ;
				} else {
				    std::cerr << std::endl << "     Generating Product";
				}
			    }

			    LocalUnits::length = aBrep->GetLengthConversionFactor();
			    LocalUnits::planeangle = aBrep->GetPlaneAngleConversionFactor();
			    LocalUnits::solidangle = aBrep->GetSolidAngleConversionFactor();
			    ON_Brep *onBrep = aBrep->GetONBrep();
			    if (!onBrep) {
				bu_exit(1, "ERROR: failure creating advanced boundary representation from %s\n", stepfile.c_str());
			    } else {
				ON_TextLog tl;

				if (!onBrep->IsValid(&tl)) {
				    bu_log("WARNING: %s is not valid\n", name.c_str());
				}

				//onBrep->SpSplitClosedFaces();
				//ON_Brep *tbrep = TightenBrep(onBrep);

				mat_t mat;
				MAT_IDN(mat);

				Axis2Placement3D *axis = aBrep->GetAxis2Placement3d();
				if (axis != NULL) {
				    //assign matrix values
				    double translate_to[3];
				    const double *toXaxis = axis->GetXAxis();
				    const double *toYaxis = axis->GetYAxis();
				    const double *toZaxis = axis->GetZAxis();
				    mat_t rot_mat;

				    VMOVE(translate_to,axis->GetOrigin());
				    VSCALE(translate_to,translate_to,LocalUnits::length);

				    MAT_IDN(rot_mat);
				    VMOVE(&rot_mat[0], toXaxis);
				    VMOVE(&rot_mat[4], toYaxis);
				    VMOVE(&rot_mat[8], toZaxis);
				    bn_mat_inv(mat, rot_mat);
				    MAT_DELTAS_VEC(mat, translate_to);
				}

				dotg->WriteBrep(pname, onBrep,mat);

				delete onBrep;
			    }
			}
		    }
		}
		Factory::DeleteObjects();
	    }
	}
    }
    if (Verbose()) {
	std::cerr << std::endl << "     Generating BRL-CAD hierarchy." << std::endl;
    }

    for (int i = 0; i < num_ents; i++) {
	SDAI_Application_instance *sse = instance_list->GetSTEPentity(i);
	if (sse == NULL) {
	    continue;
	}
	std::string name = sse->EntityName();
	std::transform(name.begin(), name.end(), name.begin(), (int(*)(int))std::tolower);

	if ((sse->STEPfile_id > 0) && (sse->IsA(SCHEMA_NAMESPACE::e_context_dependent_shape_representation))) {
	    ContextDependentShapeRepresentation *aCDSR = dynamic_cast<ContextDependentShapeRepresentation *>(Factory::CreateObject(this, (SDAI_Application_instance *)sse));
	    if (aCDSR) {
		int rep_1_id = aCDSR->GetRepresentationRelationshipRep_1()->GetId();
		int rep_2_id = aCDSR->GetRepresentationRelationshipRep_2()->GetId();
		int pid_1 = id2productid_map[rep_1_id];
		int pid_2 = id2productid_map[rep_2_id];
		Axis2Placement3D *axis1 = NULL;
		Axis2Placement3D *axis2 = NULL;
		if ((id2name_map.find(rep_1_id) != id2name_map.end()) && (id2name_map.find(rep_2_id) != id2name_map.end())) {
		    string comb = id2name_map[rep_1_id];
		    string member = id2name_map[rep_2_id];
		    mat_t mat;
		    MAT_IDN(mat);

		    ProductDefinition *relatingProduct = aCDSR->GetRelatingProductDefinition();
		    ProductDefinition *relatedProduct = aCDSR->GetRelatedProductDefinition();
		    if (relatingProduct && relatedProduct) {
			string relatingName = relatingProduct->GetProductName();
			int relatingID = relatingProduct->GetProductId();
			string relatedName = relatedProduct->GetProductName();
			int relatedID = relatedProduct->GetProductId();

			if ((relatingID == pid_1) && (relatedID == pid_2)) {
			    axis1 = aCDSR->GetTransformItem_1();
			    axis2 = aCDSR->GetTransformItem_2();
			    comb = id2name_map[rep_1_id];
			    member = id2name_map[rep_2_id];
			} else if ((relatingID == pid_2) && (relatedID == pid_1)) {
			    axis1 = aCDSR->GetTransformItem_2();
			    axis2 = aCDSR->GetTransformItem_1();
			    comb = id2name_map[rep_2_id];
			    member = id2name_map[rep_1_id];
			} else {
			    std::cerr << "Error: Found Representation Relationship Rep_1(name=" << comb << ",Id=" << rep_1_id << ")" << std::endl;
			    std::cerr << "Error: Found Representation Relationship Rep_2(name=" << member << ",Id=" << rep_2_id << ")" << std::endl;
			    std::cerr << "Error: but Relating ProductDefinition (name=" << relatingName << ",Id=" << relatingID << ")"  << std::endl;
			    std::cerr << "Error:     Related ProductDefinition (name=" << relatedName << ",Id=" << relatedID << ")"  << std::endl;
			}
		    }

		    if ((axis1 != NULL) && (axis2 != NULL)) {
			mat_t to_mat;
			mat_t from_mat;
			mat_t toinv_mat;

			//assign matrix values
			double translate_to[3];
			double translate_from[3];
			const double *toXaxis = axis1->GetXAxis();
			const double *toYaxis = axis1->GetYAxis();
			const double *toZaxis = axis1->GetZAxis();
			const double *fromXaxis = axis2->GetXAxis();
			const double *fromYaxis = axis2->GetYAxis();
			const double *fromZaxis = axis2->GetZAxis();
			VMOVE(translate_to,axis1->GetOrigin());
			VSCALE(translate_to,translate_to,LocalUnits::length);

			VMOVE(translate_from,axis2->GetOrigin());
			VSCALE(translate_from,translate_from,-LocalUnits::length);

			// undo from trans/rot
			MAT_IDN(from_mat);
			VMOVE(&from_mat[0], fromXaxis);
			VMOVE(&from_mat[4], fromYaxis);
			VMOVE(&from_mat[8], fromZaxis);
			MAT_DELTAS_VEC(from_mat, translate_from);

			// do to trans/rot
			MAT_IDN(to_mat);
			VMOVE(&to_mat[0], toXaxis);
			VMOVE(&to_mat[4], toYaxis);
			VMOVE(&to_mat[8], toZaxis);
			bn_mat_inv(toinv_mat, to_mat);
			MAT_DELTAS_VEC(toinv_mat, translate_to);

			bn_mat_mul(mat, toinv_mat, from_mat);
		    }

		    dotg->AddMember(comb,member,mat);
		}
		Factory::DeleteObjects();
	    }
	}
    }
    if (!dotg->WriteCombs()) {
	std::cerr << "Error writing BRL-CAD hierarchy." << std::endl;
    }

    return true;
}
예제 #30
0
/**
 * Given a pointer to an internal GED database object, mirror the
 * object's values about the given transformation matrix.
 */
int
rt_nurb_mirror(struct rt_db_internal *ip, register const plane_t plane)
{
    struct rt_nurb_internal *nurb;

    mat_t mirmat;
    mat_t rmat;
    mat_t temp;
    vect_t nvec;
    vect_t xvec;
    vect_t mirror_dir;
    point_t mirror_pt;
    fastf_t ang;

    int i;
    int j;

    static point_t origin = {0.0, 0.0, 0.0};

    RT_CK_DB_INTERNAL(ip);

    nurb = (struct rt_nurb_internal *)ip->idb_ptr;
    RT_PG_CK_MAGIC(nurb);

    MAT_IDN(mirmat);

    VMOVE(mirror_dir, plane);
    VSCALE(mirror_pt, plane, plane[W]);

    /* Build mirror transform matrix, for those who need it. */
    /* First, perform a mirror down the X axis */
    mirmat[0] = -1.0;

    /* Create the rotation matrix */
    VSET(xvec, 1, 0, 0);
    VCROSS(nvec, xvec, mirror_dir);
    VUNITIZE(nvec);
    ang = -acos(VDOT(xvec, mirror_dir));
    bn_mat_arb_rot(rmat, origin, nvec, ang*2.0);

    /* Add the rotation to mirmat */
    MAT_COPY(temp, mirmat);
    bn_mat_mul(mirmat, temp, rmat);

    /* Add the translation to mirmat */
    mirmat[3 + X*4] += mirror_pt[X] * mirror_dir[X];
    mirmat[3 + Y*4] += mirror_pt[Y] * mirror_dir[Y];
    mirmat[3 + Z*4] += mirror_pt[Z] * mirror_dir[Z];

    for (i=0; i<nurb->nsrf; i++) {
	fastf_t *ptr;
	int tmp;
	int orig_size[2];
	int ncoords;
	int m;
	int l;

	/* swap knot vectors between u and v */
	ptr = nurb->srfs[i]->u.knots;
	tmp = nurb->srfs[i]->u.k_size;

	nurb->srfs[i]->u.knots = nurb->srfs[i]->v.knots;
	nurb->srfs[i]->u.k_size = nurb->srfs[i]->v.k_size;
	nurb->srfs[i]->v.knots = ptr;
	nurb->srfs[i]->v.k_size = tmp;

	/* swap order */
	tmp = nurb->srfs[i]->order[0];
	nurb->srfs[i]->order[0] = nurb->srfs[i]->order[1];
	nurb->srfs[i]->order[1] = tmp;

	/* swap mesh size */
	orig_size[0] = nurb->srfs[i]->s_size[0];
	orig_size[1] = nurb->srfs[i]->s_size[1];

	nurb->srfs[i]->s_size[0] = orig_size[1];
	nurb->srfs[i]->s_size[1] = orig_size[0];

	/* allocate memory for a new control mesh */
	ncoords = RT_NURB_EXTRACT_COORDS(nurb->srfs[i]->pt_type);
	ptr = (fastf_t *)bu_calloc(orig_size[0]*orig_size[1]*ncoords, sizeof(fastf_t), "rt_mirror: ctl mesh ptr");

	/* mirror each control point */
	for (j=0; j<orig_size[0]*orig_size[1]; j++) {
	    point_t pt;

	    VMOVE(pt, &nurb->srfs[i]->ctl_points[j*ncoords]);
	    MAT4X3PNT(&nurb->srfs[i]->ctl_points[j*ncoords], mirmat, pt);
	}

	/* copy mirrored control points into new mesh
	 * while swapping u and v */
	m = 0;
	for (j=0; j<orig_size[0]; j++) {
	    for (l=0; l<orig_size[1]; l++) {
		VMOVEN(&ptr[(l*orig_size[0]+j)*ncoords], &nurb->srfs[i]->ctl_points[m*ncoords], ncoords);
		m++;
	    }
	}

	/* free old mesh */
	bu_free((char *)nurb->srfs[i]->ctl_points, "rt_mirror: ctl points");

	/* put new mesh in place */
	nurb->srfs[i]->ctl_points = ptr;
    }

    return 0;
}