Exemplo n.º 1
0
int
ged_v2m_point(struct ged *gedp, int argc, const char *argv[])
{
    point_t view;
    point_t model;
    static const char *usage = "x y z";

    GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
    GED_CHECK_VIEW(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 != 2 && argc != 4) {
	bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
	return GED_ERROR;
    }

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

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

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

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

	/* convert from double to fastf_t */
	VMOVE(view, scan);
    }

    /* Convert the incoming view point to a model point */
    MAT4X3PNT(model, gedp->ged_gvp->gv_view2model, view);
    bn_encode_vect(gedp->ged_result_str, model);

    return GED_OK;
}
Exemplo n.º 2
0
/*
 * Phase 2 setup routine
 */
HIDDEN void
wood_setup_2(struct wood_specific *wd)
{
    mat_t xlate;
    int i;
    vect_t a_vertex, a_dir;

    register struct resource *resp = &rt_uniresource;

    /*
     * See if the user specified absolute coordinates for the vertex and
     * direction.  If so, use those instead of the RPP.
     */

    bn_mat_angles(xlate, V3ARGS(wd->rot));

    if (wd->flags & EXPLICIT_VERTEX) {
	MAT4X3PNT(wd->vertex, xlate, wd->V);
	MAT4X3PNT(wd->dir, xlate, wd->D);
    } else {
	if (wd->dz > 0.0) {
	    for (i = 0; i < 2; i++) {
		a_vertex[i] = wd->b_min[i];
		a_dir[i] = wd->b_max[i];
	    }
	    /* Z component is [2] */
	    a_vertex[2] = ((wd->b_max[2] - wd->b_min[2]) *
			   (bn_rand0to1(resp->re_randptr) * wd->dz)) + wd->b_min[2];
	    a_dir[2]    = ((wd->b_max[2] - wd->b_min[2]) *
			   (bn_rand0to1(resp->re_randptr) * wd->dz)) + wd->b_min[2];
	} else {
	    for (i = 0; i < 3; i++) {
		a_vertex[i] = ((wd->b_max[i] - wd->b_min[i]) *
			       (bn_rand0to1(resp->re_randptr) * wd->dd)) + wd->b_min[i];
		a_dir[i]    = ((wd->b_max[i] - wd->b_min[i]) *
			       (bn_rand0to1(resp->re_randptr) * wd->dd)) + wd->b_max[i];
	    }
	}
	MAT4X3PNT(wd->vertex, xlate, a_vertex);
	MAT4X3PNT(wd->dir, xlate, a_dir);
    }

    VSUB2(wd->dir, wd->dir, wd->vertex);
    VUNITIZE(wd->dir);
}
Exemplo n.º 3
0
int
ged_model2grid_lu(struct ged *gedp, int argc, const char *argv[])
{
    fastf_t f;
    point_t view_pt;
    point_t model_pt;
    point_t mo_view_pt;           /* model origin in view space */
    point_t diff;
    double scan[3];
    static const char *usage = "x y z";

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

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

    if (argc != 4)
	goto bad;

    VSETALL(model_pt, 0.0);
    MAT4X3PNT(mo_view_pt, gedp->ged_gvp->gv_model2view, model_pt);

    if (sscanf(argv[1], "%lf", &scan[X]) != 1 ||
	sscanf(argv[2], "%lf", &scan[Y]) != 1 ||
	sscanf(argv[3], "%lf", &scan[Z]) != 1)
	goto bad;

    VSCALE(model_pt, scan, gedp->ged_wdbp->dbip->dbi_local2base);
    MAT4X3PNT(view_pt, gedp->ged_gvp->gv_model2view, model_pt);
    VSUB2(diff, view_pt, mo_view_pt);
    f = gedp->ged_gvp->gv_scale * gedp->ged_wdbp->dbip->dbi_base2local;
    VSCALE(diff, diff, f);
    bu_vls_printf(gedp->ged_result_str, "%.15e %.15e", diff[X], diff[Y]);

    return GED_OK;

bad:
    bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
    return GED_ERROR;
}
Exemplo n.º 4
0
int
_ged_do_slew(struct ged *gedp, vect_t svec)
{
    point_t model_center;

    MAT4X3PNT(model_center, gedp->ged_gvp->gv_view2model, svec);
    MAT_DELTAS_VEC_NEG(gedp->ged_gvp->gv_center, model_center);
    ged_view_update(gedp->ged_gvp);

    return GED_OK;
}
Exemplo n.º 5
0
int
main(int argc, char *argv[])
{
    int val;
    fastf_t yaw, pitch, roll;
    vect_t temp, point, zero;
    mat_t mat;

    /* intentionally double for scan */
    double time;
    double scan[3];

    VSETALL(temp, 0.0);
    VSETALL(point, 0.0);
    VSETALL(zero, 0.0);

    (void) get_args(argc, argv);


    while (1) {
	/*read line from table */
	val = scanf("%lf%*[^-0123456789]", &time); /*read time, ignore garbage*/
	if (val < 1) {
	    break;
	}

	val = scanf("%lf %lf %lf", &scan[0], &scan[1], &scan[2]);
	if (val < 3) {
	    break;
	}
	/* double to fastf_t */
	VMOVE(point, scan);

	val = scanf("%lf %lf %lf", &scan[0], &scan[1], &scan[2]);
	if (val < 3) {
	    break;
	}
	/* double to fastf_t */
	yaw = scan[0];
	pitch = scan[1];
	roll = scan[2];

	anim_dy_p_r2mat(mat, yaw, pitch, roll);
	anim_add_trans(mat, point, zero);
	MAT4X3PNT(temp, mat, offset);

	printf("%.10g\t%.10g\t%.10g\t%.10g", time, temp[0], temp[1], temp[2]);
	if (full_print)
	    printf("\t%.10g\t%.10g\t%.10g", yaw, pitch, roll);
	printf("\n");
    }
    return 0;
}
Exemplo n.º 6
0
void
draw_e_axes()
{
    point_t v_ap1;                 /* axes position in view coordinates */
    point_t v_ap2;                 /* axes position in view coordinates */
    mat_t rot_mat;
    struct ged_axes_state gas;

    if (STATE == ST_S_EDIT) {
	MAT4X3PNT(v_ap1, view_state->vs_gvp->gv_model2view, e_axes_pos);
	MAT4X3PNT(v_ap2, view_state->vs_gvp->gv_model2view, curr_e_axes_pos);
    } else if (STATE == ST_O_EDIT) {
	point_t m_ap2;

	MAT4X3PNT(v_ap1, view_state->vs_gvp->gv_model2view, es_keypoint);
	MAT4X3PNT(m_ap2, modelchanges, es_keypoint);
	MAT4X3PNT(v_ap2, view_state->vs_gvp->gv_model2view, m_ap2);
    } else
	return;

    memset(&gas, 0, sizeof(struct ged_axes_state));
    VMOVE(gas.gas_axes_pos, v_ap1);
    gas.gas_axes_size = axes_state->ax_edit_size1 * INV_GED;
    VMOVE(gas.gas_axes_color, color_scheme->cs_edit_axes1);
    VMOVE(gas.gas_label_color, color_scheme->cs_edit_axes_label1);
    gas.gas_line_width = axes_state->ax_edit_linewidth1;

    dm_draw_axes(dmp, view_state->vs_gvp->gv_size, view_state->vs_gvp->gv_rotation, &gas);

    memset(&gas, 0, sizeof(struct ged_axes_state));
    VMOVE(gas.gas_axes_pos, v_ap2);
    gas.gas_axes_size = axes_state->ax_edit_size2 * INV_GED;
    VMOVE(gas.gas_axes_color, color_scheme->cs_edit_axes2);
    VMOVE(gas.gas_label_color, color_scheme->cs_edit_axes_label2);
    gas.gas_line_width = axes_state->ax_edit_linewidth2;

    bn_mat_mul(rot_mat, view_state->vs_gvp->gv_rotation, acc_rot_sol);
    dm_draw_axes(dmp, view_state->vs_gvp->gv_size, rot_mat, &gas);
}
Exemplo n.º 7
0
/* beginning of a frame */
void
view_2init( struct application *ap )
{
    extern fastf_t azimuth, elevation;
    fastf_t elvang, aziang;
    vect_t temp, aimpt;
    fastf_t backoff;


    if ( numreflect > MAXREFLECT ) {
	bu_log("Warning: maxreflect too large (%d), using %d\n",
	       numreflect, MAXREFLECT );
	numreflect = MAXREFLECT;
    }

    elvang = elevation * DEG2RAD;
    aziang = azimuth * DEG2RAD;

    uhoriz[0] = (fastf_t) sin(aziang);
    uhoriz[1] = (fastf_t) -cos(aziang);
    uhoriz[3] = (fastf_t) 0.0;
    VUNITIZE( uhoriz );

    unorml[0] = (fastf_t) cos(elvang) * uhoriz[1];
    unorml[1] = (fastf_t) -cos(elvang) * uhoriz[0];
    unorml[2] = (fastf_t) -sin(elvang);
    VUNITIZE( unorml );

    /* this doesn't seem to be quite right emanat.f */
    uvertp[0] = uhoriz[1] * unorml[2] - unorml[1]* uhoriz[2];
    uvertp[1] = uhoriz[2] * unorml[0] - unorml[2]* uhoriz[0];
    uvertp[2] = uhoriz[0] * unorml[1] - unorml[0]* uhoriz[1];
    VUNITIZE( uvertp );
    VPRINT("uhoriz", uhoriz);
    VPRINT("unorml", unorml);
    VPRINT("uvertp", uvertp);
    totali = 0.0;
    totalq = 0.0;

    VSET(temp, 0.0, 0.0, -M_SQRT2);
    MAT4X3PNT( aimpt, view2model, temp);
    bu_log("aim point %f %f %f\n", aimpt[0], aimpt[1], aimpt[2]);
    bu_log("viewsize %f\n", viewsize);
    backoff = M_SQRT1_2*viewsize;
    bu_log("backoff %f\n", backoff);

#ifdef SAR
    sar_2init( ap );
#endif
}
Exemplo n.º 8
0
void
three_dcoord_out(FILE *fp, fastf_t *m)
{
    unsigned char	buf[3*8];
    double	p1[3];
    double	p2[3];

    fread( buf, 1, 3*8, fp );
    ntohd( (unsigned char *)p1, buf, 3 );

    MAT4X3PNT( p2, m, p1 );

    htond( buf, (unsigned char *)p2, 3 );
    fwrite( buf, 1, 3*8, stdout );
}
Exemplo n.º 9
0
void
two_dcoord_out(FILE *fp, fastf_t *m)
{
    unsigned char	buf[2*8];
    double	p1[3];
    double	p2[3];

    fread( buf, 1, 2*8, fp );
    ntohd( (unsigned char *)p1, buf, 2 );
    p1[2] = 0;		/* no Z  */

    MAT4X3PNT( p2, m, p1 );

    htond( buf, (unsigned char *)p2, 3 );
    fwrite( buf, 1, 3*8, stdout );
}
Exemplo n.º 10
0
void
three_coord_out(FILE *fp, fastf_t *m)
{
    point_t	p1;
    short	p2[3];

    p1[0] = getshort(fp);	/* get X */
    p1[1] = getshort(fp);	/* and Y */
    p1[2] = getshort(fp);	/* and Z */

    MAT4X3PNT( p2, m, p1 );

    putsi(p2[0]);		/* put X */
    putsi(p2[1]);		/* and Y */
    putsi(p2[2]);		/* and Z */
}
Exemplo n.º 11
0
/* beginning of a frame */
void
view_2init(struct application *ap)
{
    extern double azimuth, elevation;
    vect_t temp, aimpt;
    union radrec r;

    if ( numreflect > MAXREFLECT ) {
	bu_log("Warning: maxreflect too large (%d), using %d\n",
	       numreflect, MAXREFLECT );
	numreflect = MAXREFLECT;
    }

    bu_log( "Ray Spacing: %f rays/cm\n", 10.0*(width/viewsize) );

    /* Header Record */
    memset((char *)&r, 0, sizeof(r));

    /*XXX*/
    r.h.head[0] = 'h'; r.h.head[1] = 'e';
    r.h.head[2] = 'a'; r.h.head[3] = 'd';

    r.h.id = 1;
    r.h.iview = 1;
    r.h.miview = - r.h.iview;
    VSET( temp, 0.0, 0.0, -1.414 );	/* Point we are looking at */
    MAT4X3PNT( aimpt, view2model, temp );
    r.h.cx = aimpt[0];		/* aimpoint */
    r.h.cy = aimpt[1];
    r.h.cz = aimpt[2];
    r.h.back = 1.414*viewsize/2.0;	/* backoff */
    r.h.e = elevation;
    r.h.a = azimuth;
    r.h.vert = viewsize;
    r.h.horz = viewsize;
    r.h.nvert = height;
    r.h.nhorz = width;
    r.h.maxrfl = numreflect;

    writerec( &r, outfp );

    /* XXX - write extra header records */
    memset((char *)&r, 0, sizeof(r));
    writerec( &r, outfp );
    writerec( &r, outfp );
}
Exemplo n.º 12
0
/**
 * Import an superellipsoid/sphere from the database format to the
 * internal structure.  Apply modeling transformations as wsuperell.
 */
int
rt_superell_import4(struct rt_db_internal *ip, const struct bu_external *ep, const fastf_t *mat, const struct db_i *dbip)
{
    struct rt_superell_internal *eip;
    union record *rp;
    fastf_t vec[3*4 + 2];

    if (dbip) RT_CK_DBI(dbip);

    BU_CK_EXTERNAL(ep);
    rp = (union record *)ep->ext_buf;
    /* Check record type */
    if (rp->u_id != ID_SOLID) {
        bu_log("rt_superell_import4():  defective record\n");
        return -1;
    }

    RT_CK_DB_INTERNAL(ip);
    ip->idb_major_type = DB5_MAJORTYPE_BRLCAD;
    ip->idb_type = ID_SUPERELL;
    ip->idb_meth = &OBJ[ID_SUPERELL];
    BU_ALLOC(ip->idb_ptr, struct rt_superell_internal);

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

    /* Convert from database to internal format */
    flip_fastf_float(vec, rp->s.s_values, 4, dbip->dbi_version < 0 ? 1 : 0);

    /* Apply modeling transformations */
    if (mat == NULL) mat = bn_mat_identity;
    MAT4X3PNT(eip->v, mat, &vec[0*3]);
    MAT4X3VEC(eip->a, mat, &vec[1*3]);
    MAT4X3VEC(eip->b, mat, &vec[2*3]);
    MAT4X3VEC(eip->c, mat, &vec[3*3]);

    if (dbip->dbi_version < 0) {
        eip->n = flip_dbfloat(rp->s.s_values[12]);
        eip->e = flip_dbfloat(rp->s.s_values[13]);
    } else {
        eip->n = rp->s.s_values[12];
        eip->e = rp->s.s_values[13];
    }

    return 0;		/* OK */
}
Exemplo n.º 13
0
int
ged_savekey(struct ged *gedp, int argc, const char *argv[])
{
    FILE *fp;
    fastf_t timearg;
    vect_t eye_model;
    vect_t temp;
    static const char *usage = "file [time]";

    GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
    GED_CHECK_VIEW(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 < 2 || 3 < argc) {
	bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
	return GED_ERROR;
    }

    if ((fp = fopen(argv[1], "a")) == NULL) {
	perror(argv[1]);
	return TCL_ERROR;
    }
    if (argc > 2) {
	timearg = atof(argv[2]);
	fprintf(fp, "%f\n", timearg);
    }
    /*
     * Eye is in conventional place.
     */
    VSET(temp, 0.0, 0.0, 1.0);
    MAT4X3PNT(eye_model, gedp->ged_gvp->gv_view2model, temp);
    savekey_rt_oldwrite(gedp, fp, eye_model);
    (void)fclose(fp);

    return GED_OK;
}
/**
 * Import an metaball/sphere from the database format to the internal
 * structure. Apply modeling transformations as well.
 */
int
rt_metaball_import5(struct rt_db_internal *ip, const struct bu_external *ep, register const fastf_t *mat, const struct db_i *dbip)
{
    struct wdb_metaballpt *mbpt;
    struct rt_metaball_internal *mb;
    int metaball_count = 0, i;

    /* must be double for import and export */
    double *buf;

    if (dbip) RT_CK_DBI(dbip);

    BU_CK_EXTERNAL(ep);
    metaball_count = ntohl(*(uint32_t *)ep->ext_buf);
    buf = (double *)bu_malloc((metaball_count*5+1)*SIZEOF_NETWORK_DOUBLE, "rt_metaball_import5: buf");
    bu_cv_ntohd((unsigned char *)buf, (unsigned char *)ep->ext_buf+2*SIZEOF_NETWORK_LONG, metaball_count*5+1);

    RT_CK_DB_INTERNAL(ip);
    ip->idb_major_type = DB5_MAJORTYPE_BRLCAD;
    ip->idb_type = ID_METABALL;
    ip->idb_meth = &OBJ[ID_METABALL];
    BU_ALLOC(ip->idb_ptr, struct rt_metaball_internal);

    mb = (struct rt_metaball_internal *)ip->idb_ptr;
    mb->magic = RT_METABALL_INTERNAL_MAGIC;
    mb->method = ntohl(*(uint32_t *)(ep->ext_buf + SIZEOF_NETWORK_LONG));
    mb->threshold = buf[0];

    BU_LIST_INIT(&mb->metaball_ctrl_head);
    if (mat == NULL) mat = bn_mat_identity;
    for (i = 1; i <= metaball_count * 5; i += 5) {
	/* Apply modeling transformations */
	BU_GET(mbpt, struct wdb_metaballpt);
	mbpt->l.magic = WDB_METABALLPT_MAGIC;
	MAT4X3PNT(mbpt->coord, mat, &buf[i]);
	mbpt->fldstr = buf[i+3] / mat[15];
	mbpt->sweat = buf[i+4];
	BU_LIST_INSERT(&mb->metaball_ctrl_head, &mbpt->l);
    }

    bu_free((void *)buf, "rt_metaball_import5: buf");
    return 0;		/* OK */
}
Exemplo n.º 15
0
void
draw_m_axes()
{
    point_t m_ap;			/* axes position in model coordinates, mm */
    point_t v_ap;			/* axes position in view coordinates */
    struct ged_axes_state gas;

    VSCALE(m_ap, axes_state->ax_model_pos, local2base);
    MAT4X3PNT(v_ap, view_state->vs_gvp->gv_model2view, m_ap);

    memset(&gas, 0, sizeof(struct ged_axes_state));
    VMOVE(gas.gas_axes_pos, v_ap);
    gas.gas_axes_size = axes_state->ax_model_size * INV_GED;
    VMOVE(gas.gas_axes_color, color_scheme->cs_model_axes);
    VMOVE(gas.gas_label_color, color_scheme->cs_model_axes_label);
    gas.gas_line_width = axes_state->ax_model_linewidth;

    dm_draw_axes(dmp, view_state->vs_gvp->gv_size, view_state->vs_gvp->gv_rotation, &gas);
}
Exemplo n.º 16
0
void
three_dcoord_out(FILE *fp, fastf_t *m)
{
    unsigned char buf[3*8];
    double p1[3];
    double p2[3];
    size_t ret;

    ret = fread(buf, 1, 3*8, fp);
    if (ret < 3*8)
	perror("fread");

    bu_cv_ntohd((unsigned char *)p1, buf, 3);

    MAT4X3PNT(p2, m, p1);

    bu_cv_htond(buf, (unsigned char *)p2, 3);
    ret = fwrite(buf, 1, 3*8, stdout);
    if (ret < 3*8)
	perror("fwrite");
}
Exemplo n.º 17
0
int
ged_view2model_lu(struct ged *gedp, int argc, const char *argv[])
{
    fastf_t sf;
    point_t view_pt;
    point_t model_pt;
    double scan[3];
    static const char *usage = "x y z";

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

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

    if (argc != 4)
	goto bad;

    if (sscanf(argv[1], "%lf", &scan[X]) != 1 ||
	sscanf(argv[2], "%lf", &scan[Y]) != 1 ||
	sscanf(argv[3], "%lf", &scan[Z]) != 1)
	goto bad;
    /* convert from double to fastf_t */
    VMOVE(view_pt, scan);

    sf = 1.0 / (gedp->ged_gvp->gv_scale * gedp->ged_wdbp->dbip->dbi_base2local);
    VSCALE(view_pt, view_pt, sf);
    MAT4X3PNT(model_pt, gedp->ged_gvp->gv_view2model, view_pt);
    VSCALE(model_pt, model_pt, gedp->ged_wdbp->dbip->dbi_base2local);

    bn_encode_vect(gedp->ged_result_str, model_pt);

    return GED_OK;

bad:
    bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
    return GED_ERROR;
}
Exemplo n.º 18
0
/**
 * Given a point in model space coordinates (in mm) convert it to view
 * (screen) coordinates which must be scaled to correspond to actual
 * screen coordinates. If no input coordinates are supplied, the
 * model2view matrix is displayed.
 */
int
ged_model2view(struct ged *gedp, int argc, const char *argv[])
{
    point_t view_pt;
    double model_pt[3]; /* intentionally double for scan */
    static const char *usage = "[x y z]";

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

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

    /* get the model2view matrix */
    if (argc == 1) {
	bn_encode_mat(gedp->ged_result_str, gedp->ged_gvp->gv_model2view);
	return GED_OK;
    }

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

    if (sscanf(argv[1], "%lf", &model_pt[X]) != 1
	|| sscanf(argv[2], "%lf", &model_pt[Y]) != 1
	|| sscanf(argv[3], "%lf", &model_pt[Z]) != 1)
    {
	bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
	return GED_ERROR;
    }

    MAT4X3PNT(view_pt, gedp->ged_gvp->gv_model2view, model_pt);
    bn_encode_vect(gedp->ged_result_str, view_pt);

    return GED_OK;
}
Exemplo n.º 19
0
/**
 * Import an superellipsoid/sphere from the database format to the
 * internal structure.  Apply modeling transformations as wsuperell.
 */
int
rt_superell_import5(struct rt_db_internal *ip, const struct bu_external *ep, const fastf_t *mat, const struct db_i *dbip)
{
    struct rt_superell_internal *eip;

    /* must be double for import and export */
    double vec[ELEMENTS_PER_VECT*4 + 2];

    if (dbip) RT_CK_DBI(dbip);

    RT_CK_DB_INTERNAL(ip);
    BU_CK_EXTERNAL(ep);

    BU_ASSERT_LONG(ep->ext_nbytes, ==, SIZEOF_NETWORK_DOUBLE * (ELEMENTS_PER_VECT*4 + 2));

    ip->idb_major_type = DB5_MAJORTYPE_BRLCAD;
    ip->idb_type = ID_SUPERELL;
    ip->idb_meth = &OBJ[ID_SUPERELL];
    BU_ALLOC(ip->idb_ptr, struct rt_superell_internal);

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

    /* Convert from database (network) to internal (host) format */
    bu_cv_ntohd((unsigned char *)vec, ep->ext_buf, ELEMENTS_PER_VECT*4 + 2);

    /* Apply modeling transformations */
    if (mat == NULL) mat = bn_mat_identity;
    MAT4X3PNT(eip->v, mat, &vec[0*ELEMENTS_PER_VECT]);
    MAT4X3VEC(eip->a, mat, &vec[1*ELEMENTS_PER_VECT]);
    MAT4X3VEC(eip->b, mat, &vec[2*ELEMENTS_PER_VECT]);
    MAT4X3VEC(eip->c, mat, &vec[3*ELEMENTS_PER_VECT]);
    eip->n = vec[4*ELEMENTS_PER_VECT];
    eip->e = vec[4*ELEMENTS_PER_VECT + 1];

    return 0;		/* OK */
}
Exemplo n.º 20
0
int
ged_view2model_vec(struct ged *gedp, int argc, const char *argv[])
{
    point_t model_vec;
    point_t view_vec;
    mat_t inv_Viewrot;
    double scan[3];
    static const char *usage = "x y z";

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

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

    if (argc != 4)
        goto bad;

    if (sscanf(argv[1], "%lf", &scan[X]) != 1 ||
            sscanf(argv[2], "%lf", &scan[Y]) != 1 ||
            sscanf(argv[3], "%lf", &scan[Z]) != 1)
        goto bad;
    /* convert from double to fastf_t */
    VMOVE(view_vec, scan);

    bn_mat_inv(inv_Viewrot, gedp->ged_gvp->gv_rotation);
    MAT4X3PNT(model_vec, inv_Viewrot, view_vec);

    bn_encode_vect(gedp->ged_result_str, model_vec);

    return GED_OK;

bad:
    bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
    return GED_ERROR;
}
Exemplo n.º 21
0
struct edge_g_cnurb *
Get_cnurb_curve(int curve_de, int *linear)
{
    int i;
    int curve;
    struct edge_g_cnurb *crv;

    *linear = 0;

    curve = (curve_de - 1)/2;
    if (curve >= dirarraylen) {
	bu_log("Get_cnurb_curve: DE=%d is too large, dirarraylen = %d\n", curve_de, dirarraylen);
	return (struct edge_g_cnurb *)NULL;
    }

    switch (dir[curve]->type) {
	case 110: {
	    /* line */
	    int pt_type;
	    int type;
	    point_t pt1;
	    point_t start_pt, end_pt;

	    Readrec(dir[curve]->param);
	    Readint(&type, "");
	    if (type != dir[curve]->type) {
		bu_log("Error in Get_cnurb_curve, looking for curve type %d, found %d\n" ,
		       dir[curve]->type, type);
		return (struct edge_g_cnurb *)NULL;

	    }
	    /* Read first point */
	    for (i = 0; i < 3; i++)
		Readcnv(&pt1[i], "");
	    MAT4X3PNT(start_pt, *dir[curve]->rot, pt1);

	    /* Read second point */
	    for (i = 0; i < 3; i++)
		Readcnv(&pt1[i], "");
	    MAT4X3PNT(end_pt, *dir[curve]->rot, pt1);

	    /* pt_type for rational UVW coords */
	    pt_type = RT_NURB_MAKE_PT_TYPE(3, 3, 1);

	    /* make a linear edge_g_cnurb (order=2) */
	    crv = rt_nurb_new_cnurb(2, 4, 2, pt_type);

	    /* insert control mesh */
	    VMOVE(crv->ctl_points, start_pt);
	    VMOVE(&crv->ctl_points[3], end_pt);

	    /* insert knot values */
	    crv->k.knots[0] = 0.0;
	    crv->k.knots[1] = 0.0;
	    crv->k.knots[2] = 1.0;
	    crv->k.knots[3] = 1.0;

	    *linear = 1;

	    return crv;
	}
	case 126:	/* B-spline */
	    crv = Get_cnurb(curve);
	    if (crv->order < 3)
		*linear = 1;
	    return crv;
	default:
	    bu_log("Not yet handling curves of type: %s\n", iges_type(dir[curve]->type));
	    break;
    }

    return (struct edge_g_cnurb *)NULL;
}
Exemplo n.º 22
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);
}
Exemplo n.º 23
0
/*
 *			F _ H I D E L I N E
 */
int
f_hideline(ClientData clientData, Tcl_Interp *interp, int argc, char **argv)
{
    FILE 	*plotfp;
    char 	visible;
    int 	i, numobjs;
    char 	*objname[MAXOBJECTS], title[1];
    fastf_t 	len, u, step;
    float 	ratio;
    vect_t	last_move;
    struct rt_i	*rtip;
    struct resource resource;
    struct application a;
    vect_t temp;
    vect_t last, dir;
    register struct bn_vlist	*vp;

    CHECK_DBI_NULL;

    if (argc < 2 || 4 < argc) {
	struct bu_vls vls;

	bu_vls_init(&vls);
	bu_vls_printf(&vls, "help H");
	Tcl_Eval(interp, bu_vls_addr(&vls));
	bu_vls_free(&vls);
	return TCL_ERROR;
    }

    if ((plotfp = fopen(argv[1], "w")) == NULL) {
	Tcl_AppendResult(interp, "f_hideline: unable to open \"", argv[1],
			 "\" for writing.\n", (char *)NULL);
	return TCL_ERROR;
    }
    pl_space(plotfp, (int)GED_MIN, (int)GED_MIN, (int)GED_MAX, (int)GED_MAX);

    /*  Build list of objects being viewed */
    numobjs = 0;
    FOR_ALL_SOLIDS(sp) {
	for (i = 0; i < numobjs; i++)  {
	    if ( objname[i] == FIRST_SOLID(sp)->d_namep )
		break;
	}
	if (i == numobjs)
	    objname[numobjs++] = FIRST_SOLID(sp)->d_namep;
    }

    Tcl_AppendResult(interp, "Generating hidden-line drawing of the following regions:\n",
		     (char *)NULL);
    for (i = 0; i < numobjs; i++)
	Tcl_AppendResult(interp, "\t", objname[i], "\n", (char *)NULL);

    /* Initialization for librt */
    if ((rtip = rt_dirbuild(dbip->dbi_filename, title, 0)) == RTI_NULL) {
	Tcl_AppendResult(interp, "f_hideline: unable to open model file \"",
			 dbip->dbi_filename, "\"\n", (char *)NULL);
	return TCL_ERROR;
    }
    a.a_hit = hit_headon;
    a.a_miss = hit_tangent;
    a.a_overlap = hit_overlap;
    a.a_rt_i = rtip;
    a.a_resource = &resource;
    a.a_level = 0;
    a.a_onehit = 1;
    a.a_diverge = 0;
    a.a_rbeam = 0;

    if (argc > 2) {
	sscanf(argv[2], "%f", &step);
	step = view_state->vs_Viewscale/step;
	sscanf(argv[3], "%f", &epsilon);
	epsilon *= view_state->vs_Viewscale/100;
    } else {
	step = view_state->vs_Viewscale/256;
	epsilon = 0.1*view_state->vs_Viewscale;
    }

    for (i = 0; i < numobjs; i++)
	if (rt_gettree(rtip, objname[i]) == -1)
	    Tcl_AppendResult(interp, "f_hideline: rt_gettree failed on \"",
			     objname[i], "\"\n", (char *)NULL);

    /* Crawl along the vectors raytracing as we go */
    VSET(temp, 0.0, 0.0, -1.0);				/* looking at model */
    MAT4X3VEC(a.a_ray.r_dir, view_state->vs_view2model, temp);
    VUNITIZE(a.a_ray.r_dir);

    FOR_ALL_SOLIDS(sp) {

	ratio = sp->s_size / VIEWSIZE;		/* ignore if small or big */
	if (ratio >= dmp->dmr_bound || ratio < 0.001)
	    continue;

	Tcl_AppendResult(interp, "Primitive\n", (char *)NULL);
	for ( BU_LIST_FOR( vp, bn_vlist, &(sp->s_vlist) ) )  {
	    register int	i;
	    register int	nused = vp->nused;
	    register int	*cmd = vp->cmd;
	    register point_t *pt = vp->pt;
	    for ( i = 0; i < nused; i++, cmd++, pt++ )  {
		Tcl_AppendResult(interp, "\tVector\n", (char *)NULL);
		switch ( *cmd )  {
		    case BN_VLIST_POLY_START:
		    case BN_VLIST_POLY_VERTNORM:
			break;
		    case BN_VLIST_POLY_MOVE:
		    case BN_VLIST_LINE_MOVE:
			/* move */
			VMOVE(last, *pt);
			MOVE(last);
			break;
		    case BN_VLIST_POLY_DRAW:
		    case BN_VLIST_POLY_END:
		    case BN_VLIST_LINE_DRAW:
			/* setup direction && length */
			VSUB2(dir, *pt, last);
			len = MAGNITUDE(dir);
			VUNITIZE(dir);
			visible = FALSE;
			{
			    struct bu_vls tmp_vls;

			    bu_vls_init(&tmp_vls);
			    bu_vls_printf(&tmp_vls, "\t\tDraw 0 -> %g, step %g\n", len, step);
			    Tcl_AppendResult(interp, bu_vls_addr(&tmp_vls), (char *)NULL);
			    bu_vls_free(&tmp_vls);
			}
			for (u = 0; u <= len; u += step) {
			    VJOIN1(aim_point, last, u, dir);
			    MAT4X3PNT(temp, view_state->vs_model2view, aim_point);
			    temp[Z] = 100;			/* parallel project */
			    MAT4X3PNT(a.a_ray.r_pt, view_state->vs_view2model, temp);
			    if (rt_shootray(&a)) {
				if (!visible) {
				    visible = TRUE;
				    MOVE(aim_point);
				}
			    } else {
				if (visible) {
				    visible = FALSE;
				    DRAW(aim_point);
				}
			    }
			}
			if (visible)
			    DRAW(aim_point);
			VMOVE(last, *pt); /* new last vertex */
		}
	    }
	}
    }
    fclose(plotfp);
    return TCL_OK;
}
Exemplo n.º 24
0
int
main (int argc, char **argv)
{
    int val;
    fastf_t time, yaw1, pitch1, roll1, yaw2, pitch2, roll2;
    vect_t cen1, cen2, cen_ans, ang_ans, rad_ang_ans, rotated;
    mat_t m_rot1, m_rot2, m_ans;
    int one_time, read_cen1, read_cen2, read_rot1, read_rot2;

    read_cen1 = read_cen2 = read_rot1 = read_rot2 = 1;

    if (!get_args(argc, argv))
	fprintf(stderr, "anim_cascade: Argument error.");

    switch (output_mode) {
	case CASCADE_A:
	    if (cmd_fcen) {
		VMOVE(cen1, fcenter);
		read_cen1 = 0;
	    }
	    if (cmd_rcen) {
		VMOVE(cen2, rcenter);
		read_cen2 = 0;
	    }
	    if (cmd_fypr) {
		anim_dy_p_r2mat(m_rot1, fypr[0], fypr[1], fypr[2]);
		read_rot1 = 0;
	    }
	    if (cmd_rypr) {
		anim_dy_p_r2mat(m_rot2, rypr[0], rypr[1], rypr[2]);
		read_rot2 = 0;
	    }
	    break;
	case CASCADE_R:
	    if (cmd_fcen) {
		VMOVE(cen1, fcenter);
		read_cen1 = 0;
	    }
	    if (cmd_acen) {
		VMOVE(cen2, acenter);
		read_cen2 = 0;
	    }
	    if (cmd_fypr) {
		anim_dy_p_r2mat(m_rot1, fypr[0], fypr[1], fypr[2]);
		read_rot1 = 0;
	    }
	    if (cmd_aypr) {
		anim_dy_p_r2mat(m_rot2, aypr[0], aypr[1], aypr[2]);
		read_rot2 = 0;
	    }
	    break;
	case CASCADE_F:
	    if (cmd_acen) {
		VMOVE(cen1, acenter);
		read_cen1 = 0;
	    }
	    if (cmd_rcen) {
		VMOVE(cen2, rcenter);
		read_cen2 = 0;
	    }
	    if (cmd_aypr) {
		anim_dy_p_r2mat(m_rot1, aypr[0], aypr[1], aypr[2]);
		read_rot1 = 0;
	    }
	    if (cmd_rypr) {
		anim_dy_p_r2mat(m_rot2, rypr[0], rypr[1], rypr[2]);
		read_rot2 = 0;
	    }
	    break;
	default:
	    break;
    }


    one_time = (!(read_cen1||read_cen2||read_rot1||read_rot2));
    read_time = one_time ? 0 : print_time;
    time = 0.0;

    val = 3;
    while (1) {
	if (read_time) {
	    val=scanf("%lf", &time);
	    if (val < 1) break;
	}
	if (read_cen1)
	    val =scanf("%lf %lf %lf", cen1, cen1+1, cen1+2);
	if (read_rot1) {
	    val=scanf("%lf %lf %lf", &yaw1, &pitch1, &roll1);
	    anim_dy_p_r2mat(m_rot1, yaw1, pitch1, roll1);
	}
	if (read_cen2) {
	    val=scanf("%lf %lf %lf", cen2, cen2+1, cen2+2);
	}
	if (read_rot2) {
	    val=scanf("%lf %lf %lf", &yaw2, &pitch2, &roll2);
	    anim_dy_p_r2mat(m_rot2, yaw2, pitch2, roll2);
	}
	if (val<3) break;

	if (output_mode==CASCADE_R) {
	    anim_tran(m_rot1);
	    VSUB2(rotated, cen2, cen1);
	    MAT4X3PNT(cen_ans, m_rot1, rotated);
	    bn_mat_mul(m_ans, m_rot1, m_rot2);
	} else if (output_mode==CASCADE_F) {
	    anim_tran(m_rot2);
	    bn_mat_mul(m_ans, m_rot1, m_rot2);
	    MAT4X3PNT(rotated, m_ans, cen2);
	    VSUB2(cen_ans, cen1, rotated);
	} else {
	    MAT4X3PNT(rotated, m_rot1, cen2);
	    VADD2(cen_ans, rotated, cen1);
	    bn_mat_mul(m_ans, m_rot1, m_rot2);
	}
	anim_mat2ypr(rad_ang_ans, m_ans);
	VSCALE(ang_ans, rad_ang_ans, RTOD);

	if (print_time) {
	    printf("%g", time);
	}
	printf("\t%.12g\t%.12g\t%.12g", cen_ans[0], cen_ans[1], cen_ans[2]);
	printf("\t%.12g\t%.12g\t%.12g", ang_ans[0], ang_ans[1], ang_ans[2]);
	printf("\n");

	if (one_time) break;
    }
    return( 0 );
}
Exemplo n.º 25
0
int
common_dm(int argc, const char *argv[])
{
    int status;
    struct bu_vls vls = BU_VLS_INIT_ZERO;

    if (dbip == DBI_NULL)
	return TCL_OK;

    if (BU_STR_EQUAL(argv[0], "idle")) {

	/* redraw after scaling */
	if (gedp && gedp->ged_gvp &&
	    gedp->ged_gvp->gv_adaptive_plot &&
	    gedp->ged_gvp->gv_redraw_on_zoom &&
	    (am_mode == AMM_SCALE ||
	     am_mode == AMM_CON_SCALE_X ||
	     am_mode == AMM_CON_SCALE_Y ||
	     am_mode == AMM_CON_SCALE_Z))
	{
	    if (redraw_visible_objects() == TCL_ERROR) {
		return TCL_ERROR;
	    }
	}

	am_mode = AMM_IDLE;
	scroll_active = 0;
	if (rubber_band->rb_active) {
	    rubber_band->rb_active = 0;

	    if (mged_variables->mv_mouse_behavior == 'p')
		rb_set_dirty_flag();
	    else if (mged_variables->mv_mouse_behavior == 'r')
		rt_rect_area();
	    else if (mged_variables->mv_mouse_behavior == 'z')
		zoom_rect_area();
	}

	return TCL_OK;
    }

    if (BU_STR_EQUAL(argv[0], "m")) {
	int x;
	int y;
	int old_orig_gui;
	int stolen = 0;
	fastf_t fx, fy;

	if (argc < 3) {
	    Tcl_AppendResult(INTERP, "dm m: need more parameters\n",
			     "dm m xpos ypos\n", (char *)NULL);
	    return TCL_ERROR;
	}

	old_orig_gui = mged_variables->mv_orig_gui;

	fx = dm_Xx2Normal(dmp, atoi(argv[1]));
	fy = dm_Xy2Normal(dmp, atoi(argv[2]), 0);
	x = fx * GED_MAX;
	y = fy * GED_MAX;

	if (mged_variables->mv_faceplate &&
	    mged_variables->mv_orig_gui) {
#define MENUXLIM (-1250)

	    if (x >= MENUXLIM && scroll_select(x, y, 0)) {
		stolen = 1;
		goto end;
	    }

	    if (x < MENUXLIM && mmenu_select(y, 0)) {
		stolen = 1;
		goto end;
	    }
	}

	mged_variables->mv_orig_gui = 0;
	fy = dm_Xy2Normal(dmp, atoi(argv[2]), 1);
	y = fy * GED_MAX;

    end:
	if (mged_variables->mv_mouse_behavior == 'q' && !stolen) {
	    point_t view_pt;
	    point_t model_pt;

	    if (grid_state->gr_snap)
		snap_to_grid(&fx, &fy);

	    if (mged_variables->mv_perspective_mode)
		VSET(view_pt, fx, fy, 0.0);
	    else
		VSET(view_pt, fx, fy, 1.0);

	    MAT4X3PNT(model_pt, view_state->vs_gvp->gv_view2model, view_pt);
	    VSCALE(model_pt, model_pt, base2local);
	    if (dmp->dm_zclip)
		bu_vls_printf(&vls, "qray_nirt %lf %lf %lf",
			      model_pt[X], model_pt[Y], model_pt[Z]);
	    else
		bu_vls_printf(&vls, "qray_nirt -b %lf %lf %lf",
			      model_pt[X], model_pt[Y], model_pt[Z]);
	} else if ((mged_variables->mv_mouse_behavior == 'p' ||
		    mged_variables->mv_mouse_behavior == 'r' ||
		    mged_variables->mv_mouse_behavior == 'z') && !stolen) {

	    if (grid_state->gr_snap)
		snap_to_grid(&fx, &fy);

	    rubber_band->rb_active = 1;
	    rubber_band->rb_x = fx;
	    rubber_band->rb_y = fy;
	    rubber_band->rb_width = 0.0;
	    rubber_band->rb_height = 0.0;
	    rect_view2image();
	    rb_set_dirty_flag();
	} else if (mged_variables->mv_mouse_behavior == 's' && !stolen) {
#if 0
	    if (grid_state->gr_snap) {
		snap_to_grid(&fx, &fy);
		x = fx * GED_MAX;
		y = fy * GED_MAX;
	    }
#endif
	    bu_vls_printf(&vls, "mouse_solid_edit_select %d %d", x, y);
	} else if (mged_variables->mv_mouse_behavior == 'm' && !stolen) {
#if 0
	    if (grid_state->gr_snap) {
		snap_to_grid(&fx, &fy);
		x = fx * GED_MAX;
		y = fy * GED_MAX;
	    }
#endif
	    bu_vls_printf(&vls, "mouse_matrix_edit_select %d %d", x, y);
	} else if (mged_variables->mv_mouse_behavior == 'c' && !stolen) {
#if 0
	    if (grid_state->gr_snap) {
		snap_to_grid(&fx, &fy);
		x = fx * GED_MAX;
		y = fy * GED_MAX;
	    }
#endif
	    bu_vls_printf(&vls, "mouse_comb_edit_select %d %d", x, y);
	} else if (mged_variables->mv_mouse_behavior == 'o' && !stolen) {
#if 0
	    if (grid_state->gr_snap) {
		snap_to_grid(&fx, &fy);
		x = fx * GED_MAX;
		y = fy * GED_MAX;
	    }
#endif
	    bu_vls_printf(&vls, "mouse_rt_obj_select %d %d", x, y);
	} else if (adc_state->adc_draw && mged_variables->mv_transform == 'a' && !stolen) {
	    point_t model_pt;
	    point_t view_pt;

	    if (grid_state->gr_snap)
		snap_to_grid(&fx, &fy);

	    VSET(view_pt, fx, fy, 1.0);
	    MAT4X3PNT(model_pt, view_state->vs_gvp->gv_view2model, view_pt);
	    VSCALE(model_pt, model_pt, base2local);
	    bu_vls_printf(&vls, "adc xyz %lf %lf %lf\n", model_pt[X], model_pt[Y], model_pt[Z]);
	} else if (grid_state->gr_snap && !stolen &&
		   SEDIT_TRAN && mged_variables->mv_transform == 'e') {
	    point_t view_pt;
	    point_t model_pt;

	    snap_to_grid(&fx, &fy);
	    MAT4X3PNT(view_pt, view_state->vs_gvp->gv_model2view, curr_e_axes_pos);
	    view_pt[X] = fx;
	    view_pt[Y] = fy;
	    MAT4X3PNT(model_pt, view_state->vs_gvp->gv_view2model, view_pt);
	    VSCALE(model_pt, model_pt, base2local);
	    bu_vls_printf(&vls, "p %lf %lf %lf", model_pt[X], model_pt[Y], model_pt[Z]);
	} else if (grid_state->gr_snap && !stolen &&
		   OEDIT_TRAN && mged_variables->mv_transform == 'e') {
	    point_t view_pt;
	    point_t model_pt;

	    snap_to_grid(&fx, &fy);
	    MAT4X3PNT(view_pt, view_state->vs_gvp->gv_model2view, curr_e_axes_pos);
	    view_pt[X] = fx;
	    view_pt[Y] = fy;
	    MAT4X3PNT(model_pt, view_state->vs_gvp->gv_view2model, view_pt);
	    VSCALE(model_pt, model_pt, base2local);
	    bu_vls_printf(&vls, "translate %lf %lf %lf", model_pt[X], model_pt[Y], model_pt[Z]);
	} else if (grid_state->gr_snap && !stolen &&
		   STATE != ST_S_PICK && STATE != ST_O_PICK &&
		   STATE != ST_O_PATH && !SEDIT_PICK && !EDIT_SCALE) {
	    point_t view_pt;
	    point_t model_pt;
	    point_t vcenter;

	    snap_to_grid(&fx, &fy);
	    MAT_DELTAS_GET_NEG(vcenter, view_state->vs_gvp->gv_center);
	    MAT4X3PNT(view_pt, view_state->vs_gvp->gv_model2view, vcenter);
	    view_pt[X] = fx;
	    view_pt[Y] = fy;
	    MAT4X3PNT(model_pt, view_state->vs_gvp->gv_view2model, view_pt);
	    VSCALE(model_pt, model_pt, base2local);
	    bu_vls_printf(&vls, "center %lf %lf %lf", model_pt[X], model_pt[Y], model_pt[Z]);
	} else
	    bu_vls_printf(&vls, "M 1 %d %d\n", x, y);

	status = Tcl_Eval(INTERP, bu_vls_addr(&vls));
	mged_variables->mv_orig_gui = old_orig_gui;
	bu_vls_free(&vls);

	return status;
    }

    if (BU_STR_EQUAL(argv[0], "am")) {
	if (argc < 4) {
	    Tcl_AppendResult(INTERP, "dm am: need more parameters\n",
			     "dm am <r|t|s> xpos ypos\n", (char *)NULL);
	    return TCL_ERROR;
	}

	dml_omx = atoi(argv[2]);
	dml_omy = atoi(argv[3]);

	switch (*argv[1]) {
	    case 'r':
		am_mode = AMM_ROT;
		break;
	    case 't':
		am_mode = AMM_TRAN;

		if (grid_state->gr_snap) {
		    int save_edflag;

		    if ((STATE == ST_S_EDIT || STATE == ST_O_EDIT) &&
			mged_variables->mv_transform == 'e') {
			if (STATE == ST_S_EDIT) {
			    save_edflag = es_edflag;
			    if (!SEDIT_TRAN)
				es_edflag = STRANS;
			} else {
			    save_edflag = edobj;
			    edobj = BE_O_XY;
			}

			snap_keypoint_to_grid();

			if (STATE == ST_S_EDIT)
			    es_edflag = save_edflag;
			else
			    edobj = save_edflag;
		    } else
			snap_view_center_to_grid();
		}

		break;
	    case 's':
		if (STATE == ST_S_EDIT && mged_variables->mv_transform == 'e' &&
		    ZERO(acc_sc_sol))
		    acc_sc_sol = 1.0;
		else if (STATE == ST_O_EDIT && mged_variables->mv_transform == 'e') {
		    edit_absolute_scale = acc_sc_obj - 1.0;
		    if (edit_absolute_scale > 0.0)
			edit_absolute_scale /= 3.0;
		}

		am_mode = AMM_SCALE;
		break;
	    default:
		Tcl_AppendResult(INTERP, "dm am: need more parameters\n",
				 "dm am <r|t|s> xpos ypos\n", (char *)NULL);
		return TCL_ERROR;
	}

	return TCL_OK;
    }

    if (BU_STR_EQUAL(argv[0], "adc")) {
	fastf_t fx, fy;
	fastf_t td; /* tick distance */

	if (argc < 4) {
	    Tcl_AppendResult(INTERP, "dm adc: need more parameters\n",
			     "dm adc 1|2|t|d xpos ypos\n", (char *)NULL);
	    return TCL_ERROR;
	}

	dml_omx = atoi(argv[2]);
	dml_omy = atoi(argv[3]);

	switch (*argv[1]) {
	    case '1':
		fx = dm_Xx2Normal(dmp, dml_omx) * GED_MAX - adc_state->adc_dv_x;
		fy = dm_Xy2Normal(dmp, dml_omy, 1) * GED_MAX - adc_state->adc_dv_y;

		bu_vls_printf(&vls, "adc a1 %lf\n", RAD2DEG*atan2(fy, fx));
		Tcl_Eval(INTERP, bu_vls_addr(&vls));
		bu_vls_free(&vls);

		am_mode = AMM_ADC_ANG1;
		break;
	    case '2':
		fx = dm_Xx2Normal(dmp, dml_omx) * GED_MAX - adc_state->adc_dv_x;
		fy = dm_Xy2Normal(dmp, dml_omy, 1) * GED_MAX - adc_state->adc_dv_y;

		bu_vls_printf(&vls, "adc a2 %lf\n", RAD2DEG*atan2(fy, fx));
		Tcl_Eval(INTERP, bu_vls_addr(&vls));
		bu_vls_free(&vls);

		am_mode = AMM_ADC_ANG2;
		break;
	    case 't':
		{
		    point_t model_pt;
		    point_t view_pt;

		    VSET(view_pt, dm_Xx2Normal(dmp, dml_omx), dm_Xy2Normal(dmp, dml_omy, 1), 0.0);

		    if (grid_state->gr_snap)
			snap_to_grid(&view_pt[X], &view_pt[Y]);

		    MAT4X3PNT(model_pt, view_state->vs_gvp->gv_view2model, view_pt);
		    VSCALE(model_pt, model_pt, base2local);

		    bu_vls_printf(&vls, "adc xyz %lf %lf %lf\n", model_pt[X], model_pt[Y], model_pt[Z]);
		    Tcl_Eval(INTERP, bu_vls_addr(&vls));

		    bu_vls_free(&vls);
		    am_mode = AMM_ADC_TRAN;
		}

		break;
	    case 'd':
		fx = (dm_Xx2Normal(dmp, dml_omx) * GED_MAX -
		      adc_state->adc_dv_x) * view_state->vs_gvp->gv_scale * base2local * INV_GED;
		fy = (dm_Xy2Normal(dmp, dml_omy, 1) * GED_MAX -
		      adc_state->adc_dv_y) * view_state->vs_gvp->gv_scale * base2local * INV_GED;

		td = sqrt(fx * fx + fy * fy);

		bu_vls_printf(&vls, "adc dst %lf\n", td);
		Tcl_Eval(INTERP, bu_vls_addr(&vls));
		bu_vls_free(&vls);

		am_mode = AMM_ADC_DIST;
		break;
	    default:
		Tcl_AppendResult(INTERP, "dm adc: unrecognized parameter - ", argv[1],
				 "\ndm adc 1|2|t|d xpos ypos\n", (char *)NULL);
		return TCL_ERROR;
	}

	return TCL_OK;
    }

    if (BU_STR_EQUAL(argv[0], "con")) {
	if (argc < 5) {
	    Tcl_AppendResult(INTERP, "dm con: need more parameters\n",
			     "dm con r|t|s x|y|z xpos ypos\n",
			     "dm con a x|y|1|2|d xpos ypos\n", (char *)NULL);
	    return TCL_ERROR;
	}

	dml_omx = atoi(argv[3]);
	dml_omy = atoi(argv[4]);

	switch (*argv[1]) {
	    case 'a':
		switch (*argv[2]) {
		    case 'x':
			am_mode = AMM_CON_XADC;
			break;
		    case 'y':
			am_mode = AMM_CON_YADC;
			break;
		    case '1':
			am_mode = AMM_CON_ANG1;
			break;
		    case '2':
			am_mode = AMM_CON_ANG2;
			break;
		    case 'd':
			am_mode = AMM_CON_DIST;
			break;
		    default:
			Tcl_AppendResult(INTERP, "dm con: unrecognized parameter - ", argv[2],
					 "\ndm con a x|y|1|2|d xpos ypos\n", (char *)NULL);
		}
		break;
	    case 'r':
		switch (*argv[2]) {
		    case 'x':
			am_mode = AMM_CON_ROT_X;
			break;
		    case 'y':
			am_mode = AMM_CON_ROT_Y;
			break;
		    case 'z':
			am_mode = AMM_CON_ROT_Z;
			break;
		    default:
			Tcl_AppendResult(INTERP, "dm con: unrecognized parameter - ", argv[2],
					 "\ndm con r|t|s x|y|z xpos ypos\n", (char *)NULL);
			return TCL_ERROR;
		}
		break;
	    case 't':
		switch (*argv[2]) {
		    case 'x':
			am_mode = AMM_CON_TRAN_X;
			break;
		    case 'y':
			am_mode = AMM_CON_TRAN_Y;
			break;
		    case 'z':
			am_mode = AMM_CON_TRAN_Z;
			break;
		    default:
			Tcl_AppendResult(INTERP, "dm con: unrecognized parameter - ", argv[2],
					 "\ndm con r|t|s x|y|z xpos ypos\n", (char *)NULL);
			return TCL_ERROR;
		}
		break;
	    case 's':
		switch (*argv[2]) {
		    case 'x':
			if (STATE == ST_S_EDIT && mged_variables->mv_transform == 'e' &&
			    ZERO(acc_sc_sol))
			    acc_sc_sol = 1.0;
			else if (STATE == ST_O_EDIT && mged_variables->mv_transform == 'e') {
			    edit_absolute_scale = acc_sc[0] - 1.0;
			    if (edit_absolute_scale > 0.0)
				edit_absolute_scale /= 3.0;
			}

			am_mode = AMM_CON_SCALE_X;
			break;
		    case 'y':
			if (STATE == ST_S_EDIT && mged_variables->mv_transform == 'e' &&
			    ZERO(acc_sc_sol))
			    acc_sc_sol = 1.0;
			else if (STATE == ST_O_EDIT && mged_variables->mv_transform == 'e') {
			    edit_absolute_scale = acc_sc[1] - 1.0;
			    if (edit_absolute_scale > 0.0)
				edit_absolute_scale /= 3.0;
			}

			am_mode = AMM_CON_SCALE_Y;
			break;
		    case 'z':
			if (STATE == ST_S_EDIT && mged_variables->mv_transform == 'e' &&
			    ZERO(acc_sc_sol))
			    acc_sc_sol = 1.0;
			else if (STATE == ST_O_EDIT && mged_variables->mv_transform == 'e') {
			    edit_absolute_scale = acc_sc[2] - 1.0;
			    if (edit_absolute_scale > 0.0)
				edit_absolute_scale /= 3.0;
			}

			am_mode = AMM_CON_SCALE_Z;
			break;
		    default:
			Tcl_AppendResult(INTERP, "dm con: unrecognized parameter - ", argv[2],
					 "\ndm con r|t|s x|y|z xpos ypos\n", (char *)NULL);
			return TCL_ERROR;
		}
		break;
	    default:
		Tcl_AppendResult(INTERP, "dm con: unrecognized parameter - ", argv[1],
				 "\ndm con r|t|s x|y|z xpos ypos\n", (char *)NULL);
		return TCL_ERROR;
	}

	return TCL_OK;
    }

    if (BU_STR_EQUAL(argv[0], "size")) {
	int width, height;

	/* get the window size */
	if (argc == 1) {
	    bu_vls_printf(&vls, "%d %d", dmp->dm_width, dmp->dm_height);
	    Tcl_AppendResult(INTERP, bu_vls_addr(&vls), (char *)NULL);
	    bu_vls_free(&vls);

	    return TCL_OK;
	}

	/* set the window size */
	if (argc == 3) {
	    width = atoi(argv[1]);
	    height = atoi(argv[2]);

	    dmp->dm_width = width;
	    dmp->dm_height = height;

#if defined(DM_X) || defined(DM_TK) || defined(DM_OGL) || defined(DM_WGL)
#  if 0
	    Tk_ResizeWindow(((struct dm_xvars *)dmp->dm_vars.pub_vars)->xtkwin, width, height);
#  else
#if defined(HAVE_TK)
	    Tk_GeometryRequest(((struct dm_xvars *)dmp->dm_vars.pub_vars)->xtkwin, width, height);
#endif
#  endif
#endif

	    return TCL_OK;
	}

	Tcl_AppendResult(INTERP, "Usage: dm size [width height]\n", (char *)NULL);
	return TCL_ERROR;
    }

#if defined(DM_X) || defined(DM_TK) || defined(DM_OGL) || defined(DM_WGL)
    if (BU_STR_EQUAL(argv[0], "getx")) {
	if (argc == 1) {
	    struct bu_vls tmp_vls = BU_VLS_INIT_ZERO;

	    /* Bare set command, print out current settings */
	    bu_vls_struct_print2(&tmp_vls, "dm internal X variables", dm_xvars_vparse,
				 (const char *)dmp->dm_vars.pub_vars);
	    Tcl_AppendResult(INTERP, bu_vls_addr(&tmp_vls), (char *)NULL);
	    bu_vls_free(&tmp_vls);
	} else if (argc == 2) {
	    bu_vls_struct_item_named(&vls, dm_xvars_vparse, argv[1], (const char *)dmp->dm_vars.pub_vars, COMMA);
	    Tcl_AppendResult(INTERP, bu_vls_addr(&vls), (char *)NULL);
	    bu_vls_free(&vls);
	}

	return TCL_OK;
    }
#endif

    if (BU_STR_EQUAL(argv[0], "bg")) {
	int r, g, b;

	if (argc != 1 && argc != 4) {
	    bu_vls_printf(&vls, "Usage: dm bg [r g b]");
	    Tcl_AppendResult(INTERP, bu_vls_addr(&vls), (char *)NULL);
	    bu_vls_free(&vls);

	    return TCL_ERROR;
	}

	/* return background color of current display manager */
	if (argc == 1) {
	    bu_vls_printf(&vls, "%d %d %d",
			  dmp->dm_bg[0],
			  dmp->dm_bg[1],
			  dmp->dm_bg[2]);
	    Tcl_AppendResult(INTERP, bu_vls_addr(&vls), (char *)NULL);
	    bu_vls_free(&vls);

	    return TCL_OK;
	}

	if (sscanf(argv[1], "%d", &r) != 1 ||
	    sscanf(argv[2], "%d", &g) != 1 ||
	    sscanf(argv[3], "%d", &b) != 1) {
	    bu_vls_printf(&vls, "Usage: dm bg r g b");
	    Tcl_AppendResult(INTERP, bu_vls_addr(&vls), (char *)NULL);
	    bu_vls_free(&vls);

	    return TCL_ERROR;
	}

	dirty = 1;
	return DM_SET_BGCOLOR(dmp, r, g, b);
    }

    Tcl_AppendResult(INTERP, "dm: bad command - ", argv[0], "\n", (char *)NULL);
    return TCL_ERROR;
}
Exemplo n.º 26
0
int
scloud_render(struct application *ap, const struct partition *pp, struct shadework *swp, void *dp)
{
    register struct scloud_specific *scloud_sp =
        (struct scloud_specific *)dp;
    point_t in_pt;	/* point where ray enters scloud solid */
    point_t out_pt; /* point where ray leaves scloud solid */
    point_t pt;
    vect_t v_cloud;/* vector representing ray/solid intersection */
    double thickness; /* magnitude of v_cloud (distance through solid) */
    int steps;	   /* # of samples along ray/solid intersection */
    double step_delta;/* distance between sample points, texture space */
    int i;
    double val;
    double trans;
    point_t incident_light = VINIT_ZERO;
    double delta_dpmm;
    double density;
    struct shadework sub_sw;
    struct light_specific *lp;

    RT_CHECK_PT(pp);
    RT_AP_CHECK(ap);
    RT_CK_REGION(pp->pt_regionp);

    /* compute the ray/solid in and out points,
     * and transform them into "shader space" coordinates
     */
    VJOIN1(pt, ap->a_ray.r_pt, pp->pt_inhit->hit_dist, ap->a_ray.r_dir);
    MAT4X3PNT(in_pt, scloud_sp->mtos, pt);

    VJOIN1(pt, ap->a_ray.r_pt, pp->pt_outhit->hit_dist, ap->a_ray.r_dir);
    MAT4X3PNT(out_pt, scloud_sp->mtos, pt);


    /* get ray/solid intersection vector (in noise space)
     * and compute thickness of solid (in noise space) along ray path
     */
    VSUB2(v_cloud, out_pt, in_pt);
    thickness = MAGNITUDE(v_cloud);

    /* The noise field used by the bn_noise_turb and bn_noise_fbm routines
     * has a maximum frequency of about 1 cycle per integer step in
     * noise space.  Each octave increases this frequency by the
     * "lacunarity" factor.  To sample this space adequately we need
     *
     * 4 samples per integer step for the first octave,
     * lacunarity * 4 samples/step for the second octave,
     * lacunarity^2 * 4 samples/step for the third octave,
     * lacunarity^3 * 4 samples/step for the forth octave,
     *
     * so for a computation with 4 octaves we need something on the
     * order of lacunarity^3 * 4 samples per integer step in noise space.
     */

    steps = pow(scloud_sp->lacunarity, scloud_sp->octaves-1) * 4;
    step_delta = thickness / (double)steps;

    if (rdebug&RDEBUG_SHADE)
        bu_log("steps=%d  delta=%g  thickness=%g\n",
               steps, step_delta, thickness);

    VUNITIZE(v_cloud);
    VMOVE(pt, in_pt);
    trans = 1.0;

    delta_dpmm = scloud_sp->max_d_p_mm - scloud_sp->min_d_p_mm;

    sub_sw = *swp; /* struct copy */
    sub_sw.sw_inputs = MFI_HIT;

    for (i=0; i < steps; i++) {
        /* compute the next point in the cloud space */
        VJOIN1(pt, in_pt, i*step_delta, v_cloud);

        /* get turbulence value (0 .. 1) */
        val = bn_noise_turb(pt, scloud_sp->h_val,
                            scloud_sp->lacunarity, scloud_sp->octaves);

        density = scloud_sp->min_d_p_mm + val * delta_dpmm;

        val = exp(- density * step_delta);
        trans *= val;

        if (swp->sw_xmitonly) continue;

        /* need to set the hit in our fake shadework structure */
        MAT4X3PNT(sub_sw.sw_hit.hit_point, scloud_sp->stom, pt);
        sub_sw.sw_transmit = trans;

        sub_sw.sw_inputs = MFI_HIT;

        light_obs(ap, &sub_sw, swp->sw_inputs);
        /* now we know how much light has arrived from each
         * light source to this point
         */
        for (i=ap->a_rt_i->rti_nlights-1; i >= 0; i--) {
            lp = (struct light_specific *)swp->sw_visible[i];
            if (lp == LIGHT_NULL) continue;

            /* compute how much light has arrived at
             * this location
             */
            incident_light[0] += sub_sw.sw_intensity[3*i+0] *
                                 lp->lt_color[0] * sub_sw.sw_lightfract[i];
            incident_light[1] += sub_sw.sw_intensity[3*i+1] *
                                 lp->lt_color[1] * sub_sw.sw_lightfract[i];
            incident_light[2] += sub_sw.sw_intensity[3*i+2] *
                                 lp->lt_color[2] * sub_sw.sw_lightfract[i];
        }

        VSCALE(incident_light, incident_light, trans);


    }

    /* scloud is basically a white object with partial transparency */
    swp->sw_transmit = trans;
    if (swp->sw_xmitonly) return 1;


    /*
     * At the point of maximum opacity, check light visibility
     * for light color and cloud shadowing.
     * OOPS:  Don't use an interior point, or light_visibility()
     * will see an attenuated light source.
     */
    swp->sw_hit.hit_dist = pp->pt_inhit->hit_dist;
    VJOIN1(swp->sw_hit.hit_point, ap->a_ray.r_pt, swp->sw_hit.hit_dist,
           ap->a_ray.r_dir);
    VREVERSE(swp->sw_hit.hit_normal, ap->a_ray.r_dir);
    swp->sw_inputs |= MFI_HIT | MFI_NORMAL;
    light_obs(ap, swp, swp->sw_inputs);
    VSETALL(incident_light, 0);
    for (i=ap->a_rt_i->rti_nlights-1; i>=0; i--) {
        struct light_specific *lp2;
        if ((lp2 = (struct light_specific *)swp->sw_visible[i]) == LIGHT_NULL)
            continue;
        /* XXX don't have a macro for this */
        incident_light[0] += swp->sw_intensity[3*i+0] * lp2->lt_color[0];
        incident_light[1] += swp->sw_intensity[3*i+1] * lp2->lt_color[1];
        incident_light[2] += swp->sw_intensity[3*i+2] * lp2->lt_color[2];
    }
    VELMUL(swp->sw_color, swp->sw_color, incident_light);


    if (rdebug&RDEBUG_SHADE) {
        pr_shadework("scloud: after light vis, before rr_render", swp);
    }

    if (swp->sw_reflect > 0 || swp->sw_transmit > 0)
        (void)rr_render(ap, pp, swp);

    return 1;
}
Exemplo n.º 27
0
/*
 *			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 );
	}
    }
}
Exemplo n.º 28
0
/*
 *			R A Y H I T
 *
 *  Rayhit() is called by rt_shootray() when the ray hits one or more objects.
 *  A per-shotline header record is written, followed by information about
 *  each object hit.
 *
 *  Note that the GIFT-3 format uses a different convention for the "zero"
 *  distance along the ray.  RT has zero at the ray origin (emanation plain),
 *  while GIFT has zero at the screen plain translated so that it contains
 *  the model origin.  This difference is compensated for by adding the
 *  'dcorrection' distance correction factor.
 *
 *  Also note that the GIFT-3 format requires information about the start
 *  point of the ray in two formats.  First, the h, v coordinates of the
 *  grid cell CENTERS (in screen space coordinates) are needed.
 *  Second, the ACTUAL h, v coordinates fired from are needed.
 *
 *  An optional rtg3.pl UnixPlot file is written, permitting a
 *  color vector display of ray-model intersections.
 */
int
rayhit(struct application *ap, register struct partition *PartHeadp, struct seg *segp)
{
    register struct partition *pp = PartHeadp->pt_forw;
    int 			comp_count;	/* component count */
    fastf_t			dfirst, dlast;	/* ray distances */
    static fastf_t		dcorrection = 0; /* RT to GIFT dist corr */
    int			card_count;	/* # comp. on this card */
    const char		*fmt;		/* printf() format string */
    struct bu_vls		str;
    char			buf[128];	/* temp. sprintf() buffer */
    point_t			hv;		/* GIFT h, v coords, in inches */
    point_t			hvcen;
    int			prev_id=-1;
    point_t			first_hit;
    int			first;

    if ( pp == PartHeadp )
	return(0);		/* nothing was actually hit?? */

    if ( ap->a_rt_i->rti_save_overlaps )
	rt_rebuild_overlaps( PartHeadp, ap, 1 );

    part_compact(ap, PartHeadp, TOL);

    /* count components in partitions */
    comp_count = 0;
    for ( pp=PartHeadp->pt_forw; pp!=PartHeadp; pp=pp->pt_forw )  {
	if ( pp->pt_regionp->reg_regionid > 0 ) {
	    prev_id = pp->pt_regionp->reg_regionid;
	    comp_count++;
	} else if ( prev_id <= 0 ) {
	    /* normally air would be output along with a solid partition, but this will require a '111' partition */
	    prev_id = pp->pt_regionp->reg_regionid;
	    comp_count++;
	} else
	    prev_id = pp->pt_regionp->reg_regionid;
    }
    pp = PartHeadp->pt_back;
    if ( pp!=PartHeadp && pp->pt_regionp->reg_regionid <= 0 )
	comp_count++;  /* a trailing '111' ident */
    if ( comp_count == 0 )
	return( 0 );

    /* Set up variable length string, to buffer this shotline in.
     * Note that there is one component per card, and that each card
     * (line) is 80 characters long.  Hence the parameters given to
     * rt-vls-extend().
     */

    bu_vls_init( &str );
    bu_vls_extend( &str, 80 * (comp_count+1) );

    /*
     *  Find the H, V coordinates of the grid cell center.
     *  RT uses the lower left corner of each cell.
     */
    {
	point_t		center;
	fastf_t		dx;
	fastf_t		dy;

	dx = ap->a_x + 0.5;
	dy = ap->a_y + 0.5;
	VJOIN2( center, viewbase_model, dx, dx_model, dy, dy_model );
	MAT4X3PNT( hvcen, model2hv, center );
    }

    /*
     *  Find exact h, v coordinates of actual ray start by
     *  projecting start point into GIFT h, v coordinates.
     */
    MAT4X3PNT( hv, model2hv, ap->a_ray.r_pt );

    /*
     *  In RT, rays are launched from the plane of the screen,
     *  and ray distances are relative to the start point.
     *  In GIFT-3 output files, ray distances are relative to
     *  the (H, V) plane translated so that it contains the origin.
     *  A distance correction is required to convert between the two.
     *  Since this really should be computed only once, not every time,
     *  the trip_count flag was added.
     */
    {

	static int  trip_count;
	vect_t	tmp;
	vect_t	viewZdir;

	if ( trip_count == 0) {

	    VSET( tmp, 0, 0, -1 );		/* viewing direction */
	    MAT4X3VEC( viewZdir, view2model, tmp );
	    VUNITIZE( viewZdir );
	    /* dcorrection will typically be negative */
	    dcorrection = VDOT( ap->a_ray.r_pt, viewZdir );
	    trip_count = 1;
	}
    }

    /* This code is for diagnostics.
     * bu_log("dcorrection=%g\n", dcorrection);
     */

    /* dfirst and dlast have been made negative to account for GIFT looking
     * in the opposite direction of RT.
     */

    dfirst = -(PartHeadp->pt_forw->pt_inhit->hit_dist + dcorrection);
    dlast = -(PartHeadp->pt_back->pt_outhit->hit_dist + dcorrection);
#if 0
    /* This code is to note any occurances of negative distances. */
    if ( PartHeadp->pt_forw->pt_inhit->hit_dist < 0)  {
	bu_log("ERROR: dfirst=%g at partition x%x\n", dfirst, PartHeadp->pt_forw );
	bu_log("\tdcorrection = %f\n", dcorrection );
	bu_log("\tray start point is ( %f %f %f ) in direction ( %f %f %f )\n", V3ARGS( ap->a_ray.r_pt ), V3ARGS( ap->a_ray.r_dir ) );
	VJOIN1( PartHeadp->pt_forw->pt_inhit->hit_point, ap->a_ray.r_pt, PartHeadp->pt_forw->pt_inhit->hit_dist, ap->a_ray.r_dir );
	VJOIN1( PartHeadp->pt_back->pt_outhit->hit_point, ap->a_ray.r_pt, PartHeadp->pt_forw->pt_outhit->hit_dist, ap->a_ray.r_dir );
	rt_pr_partitions(ap->a_rt_i, PartHeadp, "Defective partion:");
    }
    /* End of bug trap. */
#endif
    /*
     *  Output the ray header.  The GIFT statements that
     *  would have generated this are:
     *  410	write(1, 411) hcen, vcen, h, v, ncomp, dfirst, dlast, a, e
     *  411	format(2f7.1, 2f9.3, i3, 2f8.2,' A', f6.1,' E', f6.1)
     */

#define	SHOT_FMT	"%7.1f%7.1f%9.3f%9.3f%3d%8.2f%8.2f A%6.1f E%6.1f"

    if ( rt_perspective > 0 )  {
	bn_ae_vec( &azimuth, &elevation, ap->a_ray.r_dir );
    }

    bu_vls_printf( &str, SHOT_FMT,
		   hvcen[0], hvcen[1],
		   hv[0], hv[1],
		   comp_count,
		   dfirst * MM2IN, dlast * MM2IN,
		   azimuth, elevation );

    /*
     *  As an aid to debugging, take advantage of the fact that
     *  there are more than 80 columns on UNIX "cards", and
     *  add debugging information to the end of the line to
     *  allow this shotline to be reproduced offline.
     *   -b gives the shotline x, y coordinates when re-running RTG3,
     *   -p and -d are used with RTSHOT
     *  The easy way to activate this is with the harmless -!1 option
     *  when running RTG3.
     */
    if ( R_DEBUG || bu_debug || RT_G_DEBUG )  {
	bu_vls_printf( &str, "   -b%d,%d -p %26.20e %26.20e %26.20e -d %26.20e %26.20e %26.20e\n",
		       ap->a_x, ap->a_y,
		       V3ARGS(ap->a_ray.r_pt),
		       V3ARGS(ap->a_ray.r_dir) );
    } else {
	bu_vls_putc( &str, '\n' );
    }

    /* loop here to deal with individual components */
    card_count = 0;
    prev_id = -1;
    first = 1;
    for ( pp=PartHeadp->pt_forw; pp!=PartHeadp; pp=pp->pt_forw )  {
	/*
	 *  The GIFT statements that would have produced
	 *  this output are:
	 *	do 632 i=icomp, iend
	 *	if (clos(icomp).gt.999.99.or.slos(i).gt.999.9) goto 635
	 * 632	continue
	 * 	write(1, 633)(item(i), clos(i), cangi(i), cango(i),
	 * &			kspac(i), slos(i), i=icomp, iend)
	 * 633	format(1x, 3(i4, f6.2, 2f5.1, i1, f5.1))
	 *	goto 670
	 * 635	write(1, 636)(item(i), clos(i), cangi(i), cango(i),
	 * &			kspac(i), slos(i), i=icomp, iend)
	 * 636	format(1x, 3(i4, f6.1, 2f5.1, i1, f5.0))
	 */
	fastf_t	comp_thickness;	/* component line of sight thickness */
	fastf_t	in_obliq;	/* in obliquity angle */
	fastf_t	out_obliq;	/* out obliquity angle */
	int	region_id;	/* solid region's id */
	int	air_id;		/* air id */
	fastf_t	dot_prod;	/* dot product of normal and ray dir */
	fastf_t	air_thickness;	/* air line of sight thickness */
	vect_t	normal;		/* surface normal */
	register struct partition	*nextpp = pp->pt_forw;

	region_id = pp->pt_regionp->reg_regionid;

	if ( region_id <= 0 && prev_id > 0 )
	{
	    /* air region output with previous partition */
	    prev_id = region_id;
	    continue;
	}
	comp_thickness = pp->pt_outhit->hit_dist -
	    pp->pt_inhit->hit_dist;

	/* The below code is meant to catch components with zero or
	 * negative thicknesses.  This is not supposed to be possible,
	 * but the condition has been seen.
	 */
#if 0
	if ( comp_thickness <= 0 )  {
	    VJOIN1( pp->pt_inhit->hit_point, ap->a_ray.r_pt, pp->pt_inhit->hit_dist, ap->a_ray.r_dir );
	    VJOIN1( pp->pt_outhit->hit_point, ap->a_ray.r_pt, pp->pt_outhit->hit_dist, ap->a_ray.r_dir );
	    bu_log("ERROR: comp_thickness=%g for region id = %d at h=%g, v=%g (x=%d, y=%d), partition at x%x\n",
		   comp_thickness, region_id, hv[0], hv[1], ap->a_x, ap->a_y, pp );
	    rt_pr_partitions(ap->a_rt_i, PartHeadp, "Defective partion:");
	    bu_log("Send this output to the BRL-CAD Developers ([email protected])\n");
	    if ( ! (RT_G_DEBUG & DEBUG_ARB8)) {
		rt_g.debug |= DEBUG_ARB8;
		rt_shootray(ap);
		rt_g.debug &= ~DEBUG_ARB8;
	    }
	}
#endif

	if ( nextpp == PartHeadp )  {
	    if ( region_id <= 0 ) {
		/* last partition is air, need a 111 'phantom armor' before AND after */
		bu_log( "WARNING: adding 'phantom armor' (id=111) with zero thickness before and after air region %s\n",
			pp->pt_regionp->reg_name );
		region_id = 111;
		air_id = pp->pt_regionp->reg_aircode;
		air_thickness = comp_thickness;
		comp_thickness = 0.0;
	    } else {
		/* Last partition, no air follows, use code 9 */
		air_id = 9;
		air_thickness = 0.0;
	    }
	} else if ( region_id <= 0 ) {
	    /* air region, need a 111 'phantom armor' */
	    bu_log( "WARNING: adding 'phantom armor' (id=111) with zero thickness before air region %s\n",
		    pp->pt_regionp->reg_name );
	    prev_id = region_id;
	    region_id = 111;
	    air_id = pp->pt_regionp->reg_aircode;
	    air_thickness = comp_thickness;
	    comp_thickness = 0.0;
	} else if ( nextpp->pt_regionp->reg_regionid <= 0 &&
		    nextpp->pt_regionp->reg_aircode != 0 )  {
	    /* Next partition is air region */
	    air_id = nextpp->pt_regionp->reg_aircode;
	    air_thickness = nextpp->pt_outhit->hit_dist -
		nextpp->pt_inhit->hit_dist;
	    prev_id = air_id;
	} else {
	    /* 2 solid regions, maybe with gap */
	    air_id = 0;
	    air_thickness = nextpp->pt_inhit->hit_dist -
		pp->pt_outhit->hit_dist;
	    if ( air_thickness < 0.0 )
		air_thickness = 0.0;
	    if ( !NEAR_ZERO( air_thickness, 0.1 ) )  {
		air_id = 1;	/* air gap */
		if ( R_DEBUG & RDEBUG_HITS )
		    bu_log("air gap added\n");
	    } else {
		air_thickness = 0.0;
	    }
	    prev_id = region_id;
	}

	/*
	 *  Compute the obliquity angles in degrees, ie,
	 *  the "declension" angle down off the normal vector.
	 *  RT normals always point outwards;
	 *  the "inhit" normal points opposite the ray direction,
	 *  the "outhit" normal points along the ray direction.
	 *  Hence the one sign change.
	 *  XXX this should probably be done with atan2()
	 */

	if ( first ) {
	    first = 0;
	    VJOIN1( first_hit, ap->a_ray.r_pt, pp->pt_inhit->hit_dist, ap->a_ray.r_dir );
	}
    out:
	RT_HIT_NORMAL( normal, pp->pt_inhit, pp->pt_inseg->seg_stp, &(ap->a_ray), pp->pt_inflip );
	dot_prod = VDOT( ap->a_ray.r_dir, normal );
	if ( dot_prod > 1.0 )
	    dot_prod = 1.0;
	if ( dot_prod < -1.0 )
	    dot_prod = (-1.0);

	in_obliq = acos( -dot_prod ) *
	    bn_radtodeg;
	RT_HIT_NORMAL( normal, pp->pt_outhit, pp->pt_outseg->seg_stp, &(ap->a_ray), pp->pt_outflip );
	dot_prod = VDOT( ap->a_ray.r_dir, normal );
	if ( dot_prod > 1.0 )
	    dot_prod = 1.0;
	if ( dot_prod < -1.0 )
	    dot_prod = (-1.0);

	out_obliq = acos( dot_prod ) *
	    bn_radtodeg;

	/* Check for exit obliquties greater than 90 degrees. */
#if 0
	if ( in_obliq > 90 || in_obliq < 0 )  {
	    bu_log("ERROR: in_obliquity=%g\n", in_obliq);
	    rt_pr_partitions(ap->a_rt_i, PartHeadp, "Defective partion:");
	}
	if ( out_obliq > 90 || out_obliq < 0 )  {
	    bu_log("ERROR: out_obliquity=%g\n", out_obliq);
	    VPRINT(" r_dir", ap->a_ray.r_dir);
	    VPRINT("normal", normal);
	    bu_log("dot=%g, acos(dot)=%g\n",
		   VDOT( ap->a_ray.r_dir, normal ),
		   acos( VDOT( ap->a_ray.r_dir, normal ) ) );
	    /* Print the defective one */
	    rt_pr_pt( ap->a_rt_i, pp );
	    /* Print the whole ray's partition list */
	    rt_pr_partitions(ap->a_rt_i, PartHeadp, "Defective partion:");
	}
#endif

	if ( in_obliq > 90.0 )
	    in_obliq = 90.0;
	if ( in_obliq < 0.0 )
	    in_obliq = 0.0;
	if ( out_obliq > 90.0 )
	    out_obliq = 90.0;
	if ( out_obliq < 0.0 )
	    out_obliq = 0.0;

	/*
	 *  Handle 3-components per card output format, with
	 *  a leading space in front of the first component.
	 */
	if ( card_count == 0 )  {
	    bu_vls_strcat( &str, " " );
	}
	comp_thickness *= MM2IN;
	/* Check thickness fields for format overflow */
	if ( comp_thickness > 999.99 || air_thickness*MM2IN > 999.9 )
	    fmt = "%4d%6.1f%5.1f%5.1f%1d%5.0f";
	else
	    fmt = "%4d%6.2f%5.1f%5.1f%1d%5.1f";
#ifdef SPRINTF_NOT_PARALLEL
	bu_semaphore_acquire( BU_SEM_SYSCALL );
#endif
	snprintf(buf, 128, fmt,
		 region_id,
		 comp_thickness,
		 in_obliq, out_obliq,
		 air_id, air_thickness*MM2IN );
#ifdef SPRINTF_NOT_PARALLEL
	bu_semaphore_release( BU_SEM_SYSCALL );
#endif
	bu_vls_strcat( &str, buf );
	card_count++;
	if ( card_count >= 3 )  {
	    bu_vls_strcat( &str, "\n" );
	    card_count = 0;
	}

	/* A color rtg3.pl UnixPlot file of output commands
	 * is generated.  This is processed by plot(1)
	 * plotting filters such as pl-fb or pl-sgi.
	 * Portions of a ray passing through air within the
	 * model are represented in blue, while portions
	 * passing through a solid are assigned green.
	 * This will always be done single CPU,
	 * to prevent output garbling.  (See view_init).
	 */
	if (R_DEBUG & RDEBUG_RAYPLOT) {
	    vect_t     inpt;
	    vect_t     outpt;
	    VJOIN1(inpt, ap->a_ray.r_pt, pp->pt_inhit->hit_dist,
		   ap->a_ray.r_dir);
	    VJOIN1(outpt, ap->a_ray.r_pt, pp->pt_outhit->hit_dist,
		   ap->a_ray.r_dir);
	    pl_color(plotfp, 0, 255, 0);	/* green */
	    pdv_3line(plotfp, inpt, outpt);

	    if (air_thickness > 0) {
		vect_t     air_end;
		VJOIN1(air_end, ap->a_ray.r_pt,
		       pp->pt_outhit->hit_dist + air_thickness,
		       ap->a_ray.r_dir);
		pl_color(plotfp, 0, 0, 255);	/* blue */
		pdv_3cont(plotfp, air_end);
	    }
	}
	if ( nextpp == PartHeadp && air_id != 9 ) {
	    /* need to output a 111 'phantom armor' at end of shotline */
	    air_id = 9;
	    air_thickness = 0.0;
	    region_id = 111;
	    comp_thickness = 0.0;
	    goto out;
	}
    }

    /* If partway through building the line, add a newline */
    if ( card_count > 0 )  {
	/*
	 *  Note that GIFT zero-fills the unused component slots,
	 *  but neither COVART II nor COVART III require it,
	 *  so just end the line here.
	 */
	bu_vls_strcat( &str, "\n" );
    }

    /* Single-thread through file output.
     * COVART will accept non-sequential ray data provided the
     * ray header and its associated data are not separated.  CAVEAT:
     * COVART will not accept headers out of sequence.
     */
    bu_semaphore_acquire( BU_SEM_SYSCALL );

    fputs( bu_vls_addr( &str ), outfp );

    if ( shot_fp )
    {
	fprintf( shot_fp, "%.5f %.5f %.5f %.5f %.5f %.5f %.5f %.5f %ld %.5f %.5f %.5f\n",
		 azimuth, elevation, V3ARGS( ap->a_ray.r_pt ), V3ARGS( ap->a_ray.r_dir ),
		 line_num, V3ARGS( first_hit) );

	line_num +=  1 + (comp_count / 3 );
	if ( comp_count % 3 )
	    line_num++;
    }

    /* End of single-thread region */
    bu_semaphore_release( BU_SEM_SYSCALL );

    /* Release vls storage */
    bu_vls_free( &str );

    return(0);
}
Exemplo n.º 29
0
/*
 * Default keypoint in model space is established in "pt". Returns
 * GED_ERROR if unable to determine a keypoint, otherwise returns
 * GED_OK.
 */
int
_ged_get_solid_keypoint(struct ged *const gedp,
			fastf_t *const pt,
			const struct rt_db_internal *const ip,
			const fastf_t *const mat)
{
    point_t mpt;

    RT_CK_DB_INTERNAL(ip);

    switch (ip->idb_type) {
	case ID_CLINE:
	    {
		struct rt_cline_internal *cli =
		    (struct rt_cline_internal *)ip->idb_ptr;

		RT_CLINE_CK_MAGIC(cli);

		VMOVE(mpt, cli->v);
		break;
	    }
	case ID_PARTICLE:
	    {
		struct rt_part_internal *part =
		    (struct rt_part_internal *)ip->idb_ptr;

		RT_PART_CK_MAGIC(part);

		VMOVE(mpt, part->part_V);
		break;
	    }
	case ID_PIPE:
	    {
		struct rt_pipe_internal *pipeip;
		struct wdb_pipept *pipe_seg;

		pipeip = (struct rt_pipe_internal *)ip->idb_ptr;

		RT_PIPE_CK_MAGIC(pipeip);

		pipe_seg = BU_LIST_FIRST(wdb_pipept, &pipeip->pipe_segs_head);
		VMOVE(mpt, pipe_seg->pp_coord);
		break;
	    }
	case ID_METABALL:
	    {
		struct rt_metaball_internal *metaball =
		    (struct rt_metaball_internal *)ip->idb_ptr;
		struct wdb_metaballpt *metaballpt;

		RT_METABALL_CK_MAGIC(metaball);

		VSETALL(mpt, 0.0);
		metaballpt = BU_LIST_FIRST(wdb_metaballpt,
					   &metaball->metaball_ctrl_head);
		VMOVE(mpt, metaballpt->coord);
		break;
	    }
	case ID_ARBN:
	    {
		struct rt_arbn_internal *arbn =
		    (struct rt_arbn_internal *)ip->idb_ptr;
		size_t i, j, k;
		int good_vert = 0;

		RT_ARBN_CK_MAGIC(arbn);
		for (i = 0; i < arbn->neqn; i++) {
		    for (j = i + 1; j < arbn->neqn; j++) {
			for (k = j + 1; k < arbn->neqn; k++) {
			    if (!bn_mkpoint_3planes(mpt, arbn->eqn[i],
						    arbn->eqn[j],
						    arbn->eqn[k])) {
				size_t l;

				good_vert = 1;
				for (l = 0; l < arbn->neqn; l++) {
				    if (l == i || l == j || l == k)
					continue;

				    if (DIST_PT_PLANE(mpt,
					arbn->eqn[l]) >
					gedp->ged_wdbp->wdb_tol.dist) {
					good_vert = 0;
					break;
				    }
				}

				if (good_vert)
				    break;
			    }
			}
			if (good_vert)
			    break;
		    }
		    if (good_vert)
			break;
		}

		break;
	    }
	case ID_EBM:
	    {
		struct rt_ebm_internal *ebm =
		    (struct rt_ebm_internal *)ip->idb_ptr;
		point_t pnt;

		RT_EBM_CK_MAGIC(ebm);

		VSETALL(pnt, 0.0);
		MAT4X3PNT(mpt, ebm->mat, pnt);
		break;
	    }
	case ID_BOT:
	    {
		struct rt_bot_internal *bot =
		    (struct rt_bot_internal *)ip->idb_ptr;

		    VMOVE(mpt, bot->vertices);
		break;
	    }
	case ID_DSP:
	    {
		struct rt_dsp_internal *dsp =
		    (struct rt_dsp_internal *)ip->idb_ptr;
		point_t pnt;

		RT_DSP_CK_MAGIC(dsp);

		VSETALL(pnt, 0.0);
		MAT4X3PNT(mpt, dsp->dsp_stom, pnt);
		break;
	    }
	case ID_HF:
	    {
		struct rt_hf_internal *hf =
		    (struct rt_hf_internal *)ip->idb_ptr;

		RT_HF_CK_MAGIC(hf);

		VMOVE(mpt, hf->v);
		break;
	    }
	case ID_VOL:
	    {
		struct rt_vol_internal *vol =
		    (struct rt_vol_internal *)ip->idb_ptr;
		point_t pnt;

		RT_VOL_CK_MAGIC(vol);

		VSETALL(pnt, 0.0);
		MAT4X3PNT(mpt, vol->mat, pnt);
		break;
	    }
	case ID_HALF:
	    {
		struct rt_half_internal *haf =
		    (struct rt_half_internal *)ip->idb_ptr;
		RT_HALF_CK_MAGIC(haf);

		VSCALE(mpt, haf->eqn, haf->eqn[H]);
		break;
	    }
	case ID_ARB8:
	    {
		struct rt_arb_internal *arb =
		    (struct rt_arb_internal *)ip->idb_ptr;
		RT_ARB_CK_MAGIC(arb);

		VMOVE(mpt, arb->pt[0]);
		break;
	    }
	case ID_ELL:
	case ID_SPH:
	    {
		struct rt_ell_internal *ell =
		    (struct rt_ell_internal *)ip->idb_ptr;
		RT_ELL_CK_MAGIC(ell);

		VMOVE(mpt, ell->v);
		break;
	    }
	case ID_SUPERELL:
	    {
		struct rt_superell_internal *superell =
		    (struct rt_superell_internal *)ip->idb_ptr;
		RT_SUPERELL_CK_MAGIC(superell);

		VMOVE(mpt, superell->v);
		break;
	    }
	case ID_TOR:
	    {
		struct rt_tor_internal *tor =
		    (struct rt_tor_internal *)ip->idb_ptr;
		RT_TOR_CK_MAGIC(tor);

		VMOVE(mpt, tor->v);
		break;
	    }
	case ID_TGC:
	case ID_REC:
	    {
		struct rt_tgc_internal *tgc =
		    (struct rt_tgc_internal *)ip->idb_ptr;
		RT_TGC_CK_MAGIC(tgc);

		VMOVE(mpt, tgc->v);
		break;
	    }
	case ID_GRIP:
	    {
		struct rt_grip_internal *gip =
		    (struct rt_grip_internal *)ip->idb_ptr;
		RT_GRIP_CK_MAGIC(gip);
		VMOVE(mpt, gip->center);
		break;
	    }
	case ID_ARS:
	    {
		struct rt_ars_internal *ars =
		    (struct rt_ars_internal *)ip->idb_ptr;
		RT_ARS_CK_MAGIC(ars);

		VMOVE(mpt, &ars->curves[0][0]);
		break;
	    }
	case ID_RPC:
	    {
		struct rt_rpc_internal *rpc =
		    (struct rt_rpc_internal *)ip->idb_ptr;
		RT_RPC_CK_MAGIC(rpc);

		VMOVE(mpt, rpc->rpc_V);
		break;
	    }
	case ID_RHC:
	    {
		struct rt_rhc_internal *rhc =
		    (struct rt_rhc_internal *)ip->idb_ptr;
		RT_RHC_CK_MAGIC(rhc);

		VMOVE(mpt, rhc->rhc_V);
		break;
	    }
	case ID_EPA:
	    {
		struct rt_epa_internal *epa =
		    (struct rt_epa_internal *)ip->idb_ptr;
		RT_EPA_CK_MAGIC(epa);

		VMOVE(mpt, epa->epa_V);
		break;
	    }
	case ID_EHY:
	    {
		struct rt_ehy_internal *ehy =
		    (struct rt_ehy_internal *)ip->idb_ptr;
		RT_EHY_CK_MAGIC(ehy);

		VMOVE(mpt, ehy->ehy_V);
		break;
	    }
	case ID_HYP:
	    {
		struct rt_hyp_internal *hyp =
		    (struct rt_hyp_internal *)ip->idb_ptr;
		RT_HYP_CK_MAGIC(hyp);

		VMOVE(mpt, hyp->hyp_Vi);
		break;
	    }
	case ID_ETO:
	    {
		struct rt_eto_internal *eto =
		    (struct rt_eto_internal *)ip->idb_ptr;
		RT_ETO_CK_MAGIC(eto);

		VMOVE(mpt, eto->eto_V);
		break;
	    }
	case ID_POLY:
	    {
		struct rt_pg_face_internal *_poly;
		struct rt_pg_internal *pg =
		    (struct rt_pg_internal *)ip->idb_ptr;
		RT_PG_CK_MAGIC(pg);

		_poly = pg->poly;
		VMOVE(mpt, _poly->verts);
		break;
	    }
	case ID_SKETCH:
	    {
		struct rt_sketch_internal *skt =
		    (struct rt_sketch_internal *)ip->idb_ptr;
		RT_SKETCH_CK_MAGIC(skt);

		VMOVE(mpt, skt->V);
		break;
	    }
	case ID_EXTRUDE:
	    {
		struct rt_extrude_internal *extr =
		    (struct rt_extrude_internal *)ip->idb_ptr;
		RT_EXTRUDE_CK_MAGIC(extr);

		if (extr->skt && extr->skt->verts) {
		    VJOIN2(mpt, extr->V, extr->skt->verts[0][0], extr->u_vec,
			   extr->skt->verts[0][1], extr->v_vec);
		} else {
		    VMOVE(mpt, extr->V);
		}
		break;
	    }
	case ID_NMG:
	    {
		struct vertex *v;
		struct vertexuse *vu;
		struct edgeuse *eu;
		struct loopuse *lu;
		struct faceuse *fu;
		struct shell *s;
		struct nmgregion *r;
		struct model *m =
		    (struct model *) ip->idb_ptr;
		NMG_CK_MODEL(m);

		/* set default first */
		VSETALL(mpt, 0.0);

		if (BU_LIST_IS_EMPTY(&m->r_hd))
		    break;

		r = BU_LIST_FIRST(nmgregion, &m->r_hd);
		if (!r)
		    break;
		NMG_CK_REGION(r);

		if (BU_LIST_IS_EMPTY(&r->s_hd))
		    break;

		s = BU_LIST_FIRST(shell, &r->s_hd);
		if (!s)
		    break;
		NMG_CK_SHELL(s);

		if (BU_LIST_IS_EMPTY(&s->fu_hd))
		    fu = (struct faceuse *)NULL;
		else
		    fu = BU_LIST_FIRST(faceuse, &s->fu_hd);
		if (fu) {
		    NMG_CK_FACEUSE(fu);
		    lu = BU_LIST_FIRST(loopuse, &fu->lu_hd);
		    NMG_CK_LOOPUSE(lu);
		    if (BU_LIST_FIRST_MAGIC(&lu->down_hd) == NMG_EDGEUSE_MAGIC) {
			eu = BU_LIST_FIRST(edgeuse, &lu->down_hd);
			NMG_CK_EDGEUSE(eu);
			NMG_CK_VERTEXUSE(eu->vu_p);
			v = eu->vu_p->v_p;
		    } else {
			vu = BU_LIST_FIRST(vertexuse, &lu->down_hd);
			NMG_CK_VERTEXUSE(vu);
			v = vu->v_p;
		    }
		    NMG_CK_VERTEX(v);
		    if (!v->vg_p)
			break;
		    VMOVE(mpt, v->vg_p->coord);
		    break;
		}
		if (BU_LIST_IS_EMPTY(&s->lu_hd))
		    lu = (struct loopuse *)NULL;
		else
		    lu = BU_LIST_FIRST(loopuse, &s->lu_hd);
		if (lu) {
		    NMG_CK_LOOPUSE(lu);
		    if (BU_LIST_FIRST_MAGIC(&lu->down_hd) == NMG_EDGEUSE_MAGIC) {
			eu = BU_LIST_FIRST(edgeuse, &lu->down_hd);
			NMG_CK_EDGEUSE(eu);
			NMG_CK_VERTEXUSE(eu->vu_p);
			v = eu->vu_p->v_p;
		    } else {
			vu = BU_LIST_FIRST(vertexuse, &lu->down_hd);
			NMG_CK_VERTEXUSE(vu);
			v = vu->v_p;
		    }
		    NMG_CK_VERTEX(v);
		    if (!v->vg_p)
			break;
		    VMOVE(mpt, v->vg_p->coord);
		    break;
		}
		if (BU_LIST_IS_EMPTY(&s->eu_hd))
		    eu = (struct edgeuse *)NULL;
		else
		    eu = BU_LIST_FIRST(edgeuse, &s->eu_hd);
		if (eu) {
		    NMG_CK_EDGEUSE(eu);
		    NMG_CK_VERTEXUSE(eu->vu_p);
		    v = eu->vu_p->v_p;
		    NMG_CK_VERTEX(v);
		    if (!v->vg_p)
			break;
		    VMOVE(mpt, v->vg_p->coord);
		    break;
		}
		vu = s->vu_p;
		if (vu) {
		    NMG_CK_VERTEXUSE(vu);
		    v = vu->v_p;
		    NMG_CK_VERTEX(v);
		    if (!v->vg_p)
			break;
		    VMOVE(mpt, v->vg_p->coord);
		    break;
		}
	    }
	default:
	    VSETALL(mpt, 0.0);
	    bu_vls_printf(gedp->ged_result_str,
			  "get_solid_keypoint: unrecognized solid type");
	    return GED_ERROR;
    }
    MAT4X3PNT(pt, mat, mpt);
    return GED_OK;
}
Exemplo n.º 30
0
/**
 * R T _ P G _ I M P O R T
 *
 * Read all the polygons in as a complex dynamic structure.
 * The caller is responsible for freeing the dynamic memory.
 * (vid rt_pg_ifree).
 */
int
rt_pg_import4(struct rt_db_internal *ip, const struct bu_external *ep, const fastf_t *mat, const struct db_i *dbip)
{
    struct rt_pg_internal *pgp;
    union record *rp;
    size_t i;
    size_t rno;		/* current record number */
    size_t p;		/* current polygon index */

    if (dbip) RT_CK_DBI(dbip);

    BU_CK_EXTERNAL(ep);
    rp = (union record *)ep->ext_buf;
    if (rp->u_id != ID_P_HEAD) {
	bu_log("rt_pg_import4: defective header record\n");
	return -1;
    }

    RT_CK_DB_INTERNAL(ip);
    ip->idb_major_type = DB5_MAJORTYPE_BRLCAD;
    ip->idb_type = ID_POLY;
    ip->idb_meth = &rt_functab[ID_POLY];
    BU_ALLOC(ip->idb_ptr, struct rt_pg_internal);

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

    pgp->npoly = (ep->ext_nbytes - sizeof(union record)) /
	sizeof(union record);
    if (pgp->npoly <= 0) {
	bu_log("rt_pg_import4: polysolid with no polygons!\n");
	return -1;
    }
    if (pgp->npoly)
	pgp->poly = (struct rt_pg_face_internal *)bu_malloc(
	    pgp->npoly * sizeof(struct rt_pg_face_internal), "rt_pg_face_internal");
    pgp->max_npts = 0;

    if (mat == NULL) mat = bn_mat_identity;
    for (p=0; p < pgp->npoly; p++) {
	struct rt_pg_face_internal *pp;

	pp = &pgp->poly[p];
	rno = p+1;
	if (rp[rno].q.q_id != ID_P_DATA) {
	    bu_log("rt_pg_import4: defective data record\n");
	    return -1;
	}
	pp->npts = rp[rno].q.q_count;
	pp->verts = (fastf_t *)bu_malloc(pp->npts * 3 * sizeof(fastf_t), "pg verts[]");
	pp->norms = (fastf_t *)bu_malloc(pp->npts * 3 * sizeof(fastf_t), "pg norms[]");
	for (i=0; i < pp->npts; i++) {
	    point_t pnt;
	    vect_t vec;

	    if (dbip->dbi_version < 0) {
		flip_fastf_float(pnt, rp[rno].q.q_verts[i], 1, 1);
		flip_fastf_float(vec, rp[rno].q.q_norms[i], 1, 1);
	    } else {
		VMOVE(pnt, rp[rno].q.q_verts[i]);
		VMOVE(vec, rp[rno].q.q_norms[i]);
	    }

	    /* Note:  side effect of importing dbfloat_t */
	    MAT4X3PNT(&pp->verts[i*3], mat, pnt);
	    MAT4X3VEC(&pp->norms[i*3], mat, vec);
	}
	if (pp->npts > pgp->max_npts) pgp->max_npts = pp->npts;
    }
    if (pgp->max_npts < 3) {
	bu_log("rt_pg_import4: polysolid with all polygons of less than %zu vertices!\n", pgp->max_npts);
	/* XXX free storage */
	return -1;
    }
    return 0;
}