示例#1
0
文件: sh_wood.c 项目: kanzure/brlcad
HIDDEN int
wood_setup(register struct region *rp, struct bu_vls *matparm, void **dpp, const struct mfuncs *UNUSED(mfp), struct rt_i *UNUSED(rtip))
/* New since 4.4 release */
{
    register int i;
    register struct wood_specific *wd;

    register struct resource *resp = &rt_uniresource;

    /*
     * Get the impure storage for the control block
     */

    BU_CK_VLS(matparm);
    BU_GET(wd, struct wood_specific);
    *dpp = wd;

    /*
     * Load the default values
     */

    if (rp->reg_mater.ma_color_valid) {
	VSCALE(wd->lt_rgb, rp->reg_mater.ma_color, 255);
    } else {
	wd->lt_rgb[0] = 255;	/* Light yellow */
	wd->lt_rgb[1] = 255;
	wd->lt_rgb[2] = 224;
    }

    wd->dk_rgb[0] = 191;		/* Brownish-red */
    wd->dk_rgb[1] =  97;
    wd->dk_rgb[2] =   0;

    wd->ident     = 0;
    wd->forw      = WOOD_NULL;
    wd->rp	      = rp;
    wd->flags     = 0;
    wd->overlay   = 0;		/* Draw only one ring */
    wd->ns	      = 10;
    wd->jitter    = 0.0;
    wd->scale     = 1.0;
    wd->spacing   = 5;		/* 5mm space between rings */
    wd->dd        = 0.0;		/* no dither of vertex */
    wd->dz        = 0.0;		/* nor of Z-axis */
    wd->qd        = 0;
    wd->qp        = 0;
    wd->phase     = 5;
    wd->depth     = 0;

    wd->dither[0] = bn_rand0to1(resp->re_randptr);
    wd->dither[1] = bn_rand0to1(resp->re_randptr);
    wd->dither[2] = bn_rand0to1(resp->re_randptr);

    VSETALL(wd->rot, 0);
    VSETALL(wd->vertex, 0);
    VSETALL(wd->D, 0);
    VSETALL(wd->V, 0);

    /*
     * Parse the MATPARM field
     */

    if (bu_struct_parse(matparm, wood_parse, (char *)wd) < 0) {
	BU_PUT(wd, struct wood_specific);
	return -1;
    }

    /*
     * Do some sundry range and misc. checking
     */

    for (i = 0; i < 3; i++) {
	if (wd->dither[i] < 0 || wd->dither[i] > 1.0) {
	    bu_log("wood_setup(%s):  dither is out of range.\n",
		    rp->reg_name);
	    return -1;
	}
    }

    if (wd->flags == EXPLICIT_VERTEX) {
	bu_log("wood_setup(%s):  Explicit vertex specified without direction\n", rp->reg_name);
	return -1;
    }

    if (wd->flags == EXPLICIT_DIRECTION) {
	bu_log("wood_setup(%s):  Explicit direction specified without vertex\n", rp->reg_name);
	return -1;
    }

    /*
     * Get the bounding RPP
     */

    if (rt_bound_tree(rp->reg_treetop, wd->b_min, wd->b_max) < 0) return -1;

    /*
     * Add it to the wood chain
     */

    wd->forw   = Wood_Chain;
    Wood_Chain = wd;

    /*
     * See if the user has flagged this region as a member of a larger
     * combination.  If so, go ahead and process it
     */

    if (wd->ident == 0)
	wood_setup_2(wd);

    else {
	register struct wood_specific *wc;
	vect_t c_min, c_max;

	/*
	 * First, process the accumulated chain of wood regions and
	 * process all regions which have the specified ident field.
	 */

	VSETALL(c_min, 0);
	VSETALL(c_max, 0);

	for (wc = Wood_Chain; wc != WOOD_NULL; wc = wc->forw) {
	    if (wc->ident == wd->ident) {
		VMIN(c_min, wc->b_min);
		VMAX(c_max, wc->b_max);
	    }
	}

	/*
	 * Now, loop through the chain again this time updating the
	 * regions' min/max fields with the new values
	 */

	for (wc = Wood_Chain; wc != WOOD_NULL; wc = wc->forw) {
	    if (wc->ident == wd->ident) {
		VMOVE(wc->b_min, c_min);
		VMOVE(wc->b_max, c_max);
		wood_setup_2(wc);
	    }
	}

	/*
	 * End of multi-region processing loop
	 */

    }

    /*
     * Normalize the RGB colors
     */

    for (i = 0; i < 3; i++) {
	wd->lt_rgb[i] /= 255.0;
	wd->dk_rgb[i] /= 255.0;
    }

    /*
     * Return to the caller
     */

    return 1;
}
示例#2
0
/*
 * Process a space command.
 * Behavior depends on setting of several flags.
 *
 * Implicit Returns -
 * In all cases, sets space_min and space_max.
 */
int
model_rpp(const fastf_t *min, const fastf_t *max)
{

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

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

	VADD2SCALE(rot_center, min, max, 0.5);

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

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

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

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

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

    return 1;
}
示例#3
0
int
main(int argc, char **argv)
{
    int faces[15];
    fastf_t vertices[36];
    fastf_t thickness[4];
    struct rt_wdb *outfp = NULL;
    struct bu_bitv *face_mode = NULL;
    static const char *filename = "bot-test.g";

    if (BU_STR_EQUAL(argv[1], "-h") || BU_STR_EQUAL(argv[1], "-?")) {
	printusage();
	return 0;
    }
    if (argc == 1) {
	printusage();
	fprintf(stderr,"       Program continues running (will create file bot-test.g because 'filename' was blank):\n");
    }
    else if (argc > 1)
	filename = argv[1];

    outfp = wdb_fopen(filename);
    mk_id(outfp, "BOT test");

    VSET(vertices, 0.0, 0.0, 0.0);
    VSET(&vertices[3], 0.0, 100.0, 0.0);
    VSET(&vertices[6], 0.0, 100.0, 50.0);
    VSET(&vertices[9], 200.0, 0.0, 0.0);

    /* face #1 */
    faces[0] = 0;
    faces[1] = 1;
    faces[2] = 2;

    /* face #2 */
    faces[3] = 0;
    faces[4] = 2;
    faces[5] = 3;

    /* face #3 */
    faces[6] = 0;
    faces[7] = 1;
    faces[8] = 3;

    /* face #4 */
    faces[9] = 1;
    faces[10] = 2;
    faces[11] = 3;

    mk_bot(outfp, "bot_u_surf", RT_BOT_SURFACE, RT_BOT_UNORIENTED, 0, 4, 4, vertices, faces, (fastf_t *)NULL, (struct bu_bitv *)NULL);

    /* face #1 */
    faces[0] = 0;
    faces[1] = 2;
    faces[2] = 1;

    /* face #2 */
    faces[3] = 0;
    faces[4] = 3;
    faces[5] = 2;

    /* face #3 */
    faces[6] = 0;
    faces[7] = 1;
    faces[8] = 3;

    /* face #4 */
    faces[9] = 1;
    faces[10] = 2;
    faces[11] = 3;

    mk_bot(outfp, "bot_ccw_surf", RT_BOT_SURFACE, RT_BOT_CCW, 0, 4, 4, vertices, faces, (fastf_t *)NULL, (struct bu_bitv *)NULL);


    /* face #1 */
    faces[0] = 1;
    faces[1] = 2;
    faces[2] = 0;

    /* face #2 */
    faces[3] = 2;
    faces[4] = 3;
    faces[5] = 0;

    /* face #3 */
    faces[6] = 3;
    faces[7] = 1;
    faces[8] = 0;

    /* face #4 */
    faces[9] = 3;
    faces[10] = 2;
    faces[11] = 1;

    mk_bot(outfp, "bot_cw_surf", RT_BOT_SURFACE, RT_BOT_CW, 0, 4, 4, vertices, faces, (fastf_t *)NULL, (struct bu_bitv *)NULL);


    /* face #1 */
    faces[0] = 0;
    faces[1] = 1;
    faces[2] = 2;

    /* face #2 */
    faces[3] = 0;
    faces[4] = 2;
    faces[5] = 3;

    /* face #3 */
    faces[6] = 0;
    faces[7] = 1;
    faces[8] = 3;

    /* face #4 */
    faces[9] = 1;
    faces[10] = 2;
    faces[11] = 3;

    mk_bot(outfp, "bot_u_solid", RT_BOT_SOLID, RT_BOT_UNORIENTED, 0, 4, 4, vertices, faces, (fastf_t *)NULL, (struct bu_bitv *)NULL);

    /* face #1 */
    faces[0] = 0;
    faces[1] = 2;
    faces[2] = 1;

    /* face #2 */
    faces[3] = 0;
    faces[4] = 3;
    faces[5] = 2;

    /* face #3 */
    faces[6] = 0;
    faces[7] = 1;
    faces[8] = 3;

    /* face #4 */
    faces[9] = 1;
    faces[10] = 2;
    faces[11] = 3;

    mk_bot(outfp, "bot_ccw_solid", RT_BOT_SOLID, RT_BOT_CCW, 0, 4, 4, vertices, faces, (fastf_t *)NULL, (struct bu_bitv *)NULL);


    /* face #1 */
    faces[0] = 1;
    faces[1] = 2;
    faces[2] = 0;

    /* face #2 */
    faces[3] = 2;
    faces[4] = 3;
    faces[5] = 0;

    /* face #3 */
    faces[6] = 3;
    faces[7] = 1;
    faces[8] = 0;

    /* face #4 */
    faces[9] = 3;
    faces[10] = 2;
    faces[11] = 1;

    mk_bot(outfp, "bot_cw_solid", RT_BOT_SOLID, RT_BOT_CW, 0, 4, 4, vertices, faces, (fastf_t *)NULL, (struct bu_bitv *)NULL);

    face_mode = bu_bitv_new(4);
    BU_BITSET(face_mode, 1);

    thickness[0] = 2.1;
    thickness[1] = 2.2;
    thickness[2] = 2.3;
    thickness[3] = 2.4;

    /* face #1 */
    faces[0] = 0;
    faces[1] = 1;
    faces[2] = 2;

    /* face #2 */
    faces[3] = 0;
    faces[4] = 2;
    faces[5] = 3;

    /* face #3 */
    faces[6] = 0;
    faces[7] = 1;
    faces[8] = 3;

    /* face #4 */
    faces[9] = 1;
    faces[10] = 2;
    faces[11] = 3;

    mk_bot(outfp, "bot_u_plate", RT_BOT_PLATE, RT_BOT_UNORIENTED, 0, 4, 4, vertices, faces, thickness, face_mode);

    /* face #1 */
    faces[0] = 0;
    faces[1] = 2;
    faces[2] = 1;

    /* face #2 */
    faces[3] = 0;
    faces[4] = 3;
    faces[5] = 2;

    /* face #3 */
    faces[6] = 0;
    faces[7] = 1;
    faces[8] = 3;

    /* face #4 */
    faces[9] = 1;
    faces[10] = 2;
    faces[11] = 3;

    mk_bot(outfp, "bot_ccw_plate", RT_BOT_PLATE, RT_BOT_CCW, 0, 4, 4, vertices, faces, thickness, face_mode);


    /* face #1 */
    faces[0] = 1;
    faces[1] = 2;
    faces[2] = 0;

    /* face #2 */
    faces[3] = 2;
    faces[4] = 3;
    faces[5] = 0;

    /* face #3 */
    faces[6] = 3;
    faces[7] = 1;
    faces[8] = 0;

    /* face #4 */
    faces[9] = 3;
    faces[10] = 2;
    faces[11] = 1;

    mk_bot(outfp, "bot_cw_plate", RT_BOT_PLATE, RT_BOT_CW, 0, 4, 4, vertices, faces, thickness, face_mode);

    /* Make a bot with duplicate vertices to test the "fuse" and "condense" code */
    VSET(vertices, 0.0, 0.0, 0.0);
    VSET(&vertices[3], 0.0, 100.0, 0.0);
    VSET(&vertices[6], 0.0, 100.0, 50.0);
    VMOVE(&vertices[9], &vertices[0]);
    VMOVE(&vertices[12], &vertices[6]);
    VSET(&vertices[15], 200.0, 0.0, 0.0);
    VMOVE(&vertices[18], &vertices[0]);
    VMOVE(&vertices[21], &vertices[3]);
    VMOVE(&vertices[24], &vertices[15]);
    VMOVE(&vertices[27], &vertices[3]);
    VMOVE(&vertices[30], &vertices[6]);
    VMOVE(&vertices[33], &vertices[15]);

    /* face #1 */
    faces[0] = 0;
    faces[1] = 1;
    faces[2] = 2;

    /* face #2 */
    faces[3] = 3;
    faces[4] = 4;
    faces[5] = 5;

    /* face #3 */
    faces[6] = 6;
    faces[7] = 7;
    faces[8] = 8;

    /* face #4 */

    faces[9] = 9;
    faces[10] = 10;
    faces[11] = 11;

    mk_bot(outfp, "bot_solid_dup_vs", RT_BOT_SOLID, RT_BOT_UNORIENTED, 0, 12, 4, vertices, faces, (fastf_t *)NULL, (struct bu_bitv *)NULL);

    faces[12] = 9;
    faces[13] = 10;
    faces[14] = 11;

    mk_bot(outfp, "bot_solid_dup_fs", RT_BOT_SOLID, RT_BOT_UNORIENTED, 0, 12, 5, vertices, faces, (fastf_t *)NULL, (struct bu_bitv *)NULL);

    bu_free((char *)face_mode, "bottest: face_mode");

    wdb_close(outfp);

    return 0;
}
HIDDEN int
nmg_brep_face(ON_Brep **b, const struct faceuse *fu, const struct bn_tol *tol, long *brepi) {
    const struct face_g_plane *fg = fu->f_p->g.plane_p;
    struct bu_ptbl vert_table;
    struct vertex **pt;
    int ret = 0;
    int pnt_cnt = 0;
    int pnt_index = 0;
    vect_t u_axis, v_axis;
    point_t obr_center;
    point_t *points_3d = NULL;
    point_t *points_obr = NULL;
    struct loopuse *lu;
    struct edgeuse *eu;

    /* Find out how many points we have, set up any uninitialized ON_Brep vertex
     * structures, and prepare a map of NMG index values to the point array indices */
    nmg_tabulate_face_g_verts(&vert_table, fg);

    for (BU_PTBL_FOR(pt, (struct vertex **), &vert_table)) {
	if (brepi[(*pt)->vg_p->index] == -INT_MAX) {
	    ON_BrepVertex& vert = (*b)->NewVertex((*pt)->vg_p->coord, SMALL_FASTF);
	    brepi[(*pt)->vg_p->index] = vert.m_vertex_index;
	}
	pnt_cnt++;
    }

    /* Prepare the 3D obr input array */
    points_3d = (point_t *)bu_calloc(pnt_cnt + 1, sizeof(point_t), "nmg points");
    for (BU_PTBL_FOR(pt, (struct vertex **), &vert_table)) {
	VSET(points_3d[pnt_index], (*pt)->vg_p->coord[0],(*pt)->vg_p->coord[1],(*pt)->vg_p->coord[2]);
	pnt_index++;
    }
    bu_ptbl_free(&vert_table);


    /* Calculate the 3D coplanar oriented bounding rectangle (obr) */
    ret += bg_3d_coplanar_obr(&obr_center, &u_axis, &v_axis, (const point_t *)points_3d, pnt_cnt);
    if (ret) {
	bu_log("Failed to get oriented bounding rectangle for NMG faceuse #%lu\n", fu->index);
	return -1;
    }
    bu_free(points_3d, "done with obr 3d point inputs");

    /* Use the obr to define the 3D corner points of the NURBS surface */
    points_obr = (point_t *)bu_calloc(3 + 1, sizeof(point_t), "points_3d");
    VADD3(points_obr[2], obr_center, u_axis, v_axis);
    VSCALE(u_axis, u_axis, -1);
    VADD3(points_obr[3], obr_center, u_axis, v_axis);
    VSCALE(v_axis, v_axis, -1);
    VADD3(points_obr[0], obr_center, u_axis, v_axis);
    VSCALE(u_axis, u_axis, -1);
    VADD3(points_obr[1], obr_center, u_axis, v_axis);

    /* We need to orient our surface correctly according to the NMG - using
     * the openNURBS FlipFace function later does not seem to work very
     * well. If an outer loop is found in the NMG with a cw orientation,
     * factor that in in addition to the fu->f_p->flip flag. */
    int ccw = 0;
    vect_t vtmp, uv1, uv2, vnormal;
    point_t center;
    VADD2(center, points_obr[0], points_obr[1]);
    VADD2(center, center, points_obr[2]);
    VADD2(center, center, points_obr[3]);
    VSCALE(center, center, 0.25);
    for (BU_LIST_FOR(lu, loopuse, &fu->lu_hd)) {
	if (lu->orientation == OT_SAME && nmg_loop_is_ccw(lu, fg->N, tol) == -1) ccw = -1;
    }
    if (ccw != -1) {
	VSET(vnormal, fg->N[0], fg->N[1], fg->N[2]);
    } else {
	VSET(vnormal, -fg->N[0], -fg->N[1], -fg->N[2]);
    }
    if (fu->f_p->flip)
	VSET(vnormal, -vnormal[0], -vnormal[1], -vnormal[2]);
    VSUB2(uv1, points_obr[0], center);
    VSUB2(uv2, points_obr[1], center);
    VCROSS(vtmp, uv1, uv2);
    if (VDOT(vtmp, vnormal) < 0) {
	VMOVE(vtmp, points_obr[0]);
	VMOVE(points_obr[0], points_obr[1]);
	VMOVE(points_obr[1], vtmp);
	VMOVE(vtmp, points_obr[3]);
	VMOVE(points_obr[3], points_obr[2]);
	VMOVE(points_obr[2], vtmp);
    }

    /* Now that we've got our points correctly oriented for
     * the NURBS surface, proceed to create it. */
    ON_3dPoint p1 = ON_3dPoint(points_obr[0]);
    ON_3dPoint p2 = ON_3dPoint(points_obr[1]);
    ON_3dPoint p3 = ON_3dPoint(points_obr[2]);
    ON_3dPoint p4 = ON_3dPoint(points_obr[3]);

    (*b)->m_S.Append(sideSurface(p1, p2, p3, p4));
    ON_Surface *surf = (*(*b)->m_S.Last());
    int surfindex = (*b)->m_S.Count();
    ON_BrepFace& face = (*b)->NewFace(surfindex - 1);

    // With the surface and the face defined, make
    // trimming loops and create faces.  To generate UV
    // coordinates for each from and to for the
    // edgecurves, the UV origin is defined to be v1,
    // v1->v2 is defined as the U domain, and v1->v4 is
    // defined as the V domain.
    VSUB2(u_axis, points_obr[2], points_obr[1]);
    VSUB2(v_axis, points_obr[0], points_obr[1]);
    fastf_t u_axis_dist = MAGNITUDE(u_axis);
    fastf_t v_axis_dist = MAGNITUDE(v_axis);

    /* Now that we have the surface and the face, add the loops */
    for (BU_LIST_FOR(lu, loopuse, &fu->lu_hd)) {
	if (BU_LIST_FIRST_MAGIC(&lu->down_hd) != NMG_EDGEUSE_MAGIC) continue; // loop is a single vertex
	// Check if this is an inner or outer loop
	ON_BrepLoop::TYPE looptype = (lu->orientation == OT_SAME) ? ON_BrepLoop::outer : ON_BrepLoop::inner;
	ON_BrepLoop& loop = (*b)->NewLoop(looptype, face);
	for (BU_LIST_FOR(eu, edgeuse, &lu->down_hd)) {
	    vect_t ev1, ev2;
	    struct vertex_g *vg1 = eu->vu_p->v_p->vg_p;
	    struct vertex_g *vg2 = eu->eumate_p->vu_p->v_p->vg_p;
	    NMG_CK_VERTEX_G(vg1);
	    NMG_CK_VERTEX_G(vg2);
	    VMOVE(ev1, vg1->coord);
	    VMOVE(ev2, vg2->coord);
	    // Add edge if not already added
	    if (brepi[eu->e_p->index] == -INT_MAX) {
		/* always add edges with the small vertex index as from */
		int vert1 = (vg1->index <= vg2->index) ? brepi[vg1->index] : brepi[vg2->index];
		int vert2 = (vg1->index > vg2->index) ? brepi[vg1->index] : brepi[vg2->index];
		// Create and add 3D curve
		ON_Curve* c3d = new ON_LineCurve((*b)->m_V[vert1].Point(), (*b)->m_V[vert2].Point());
		c3d->SetDomain(0.0, 1.0);
		(*b)->m_C3.Append(c3d);
		// Create and add 3D edge
		ON_BrepEdge& e = (*b)->NewEdge((*b)->m_V[vert1], (*b)->m_V[vert2] , (*b)->m_C3.Count() - 1);
		e.m_tolerance = 0.0;
		brepi[eu->e_p->index] = e.m_edge_index;
	    }
	    // Regardless of whether the edge existed as an object, it needs to be added to the trimming loop
	    ON_3dPoint vg1pt(vg1->coord);
	    int orientation = ((vg1pt != (*b)->m_V[(*b)->m_E[(int)brepi[eu->e_p->index]].m_vi[0]].Point())) ? 1 : 0;
	    // Make a 2d trimming curve, create a trim, and add the trim to the loop
	    vect_t vect1, vect2, u_component, v_component;
	    double u0, u1, v0, v1;
	    ON_2dPoint from_uv, to_uv;
	    VSUB2(vect1, ev1, points_obr[0]);
	    VSUB2(vect2, ev2, points_obr[0]);
	    surf->GetDomain(0, &u0, &u1);
	    surf->GetDomain(1, &v0, &v1);
	    VPROJECT(vect1, u_axis, u_component, v_component);
	    from_uv.y = u0 + MAGNITUDE(u_component)/u_axis_dist*(u1-u0);
	    from_uv.x = v0 + MAGNITUDE(v_component)/v_axis_dist*(v1-v0);
	    VPROJECT(vect2, u_axis, u_component, v_component);
	    to_uv.y = u0 + MAGNITUDE(u_component)/u_axis_dist*(u1-u0);
	    to_uv.x = v0 + MAGNITUDE(v_component)/v_axis_dist*(v1-v0);
	    ON_Curve* c2d =  new ON_LineCurve(from_uv, to_uv);
	    c2d->SetDomain(0.0, 1.0);
	    int c2i = (*b)->m_C2.Count();
	    (*b)->m_C2.Append(c2d);
	    ON_BrepTrim& trim = (*b)->NewTrim((*b)->m_E[(int)brepi[eu->e_p->index]], orientation, loop, c2i);
	    trim.m_type = ON_BrepTrim::mated;
	    trim.m_tolerance[0] = 0.0;
	    trim.m_tolerance[1] = 0.0;
	}
    }

    bu_free(points_obr, "Done with obr");

    return 0;
}
示例#5
0
文件: arbn.c 项目: kanzure/brlcad
/**
 * Convert from "network" doubles to machine specific.
 * Transform
 */
int
rt_arbn_import4(struct rt_db_internal *ip, const struct bu_external *ep, const fastf_t *mat, const struct db_i *dbip)
{
    union record *rp;
    struct rt_arbn_internal *aip;
    size_t i;

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

    if (dbip) RT_CK_DBI(dbip);

    BU_CK_EXTERNAL(ep);
    rp = (union record *)ep->ext_buf;
    if (rp->u_id != DBID_ARBN) {
	bu_log("rt_arbn_import4: defective record, id=x%x\n", rp->u_id);
	return -1;
    }

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

    aip = (struct rt_arbn_internal *)ip->idb_ptr;
    aip->magic = RT_ARBN_INTERNAL_MAGIC;
    aip->neqn = ntohl(*(uint32_t *)rp->n.n_neqn);
    if (aip->neqn <= 0) return -1;

    aip->eqn = (plane_t *)bu_malloc(aip->neqn*sizeof(plane_t), "arbn plane eqn[]");
    scan = (double *)bu_malloc(aip->neqn*sizeof(double)*ELEMENTS_PER_PLANE, "scan array");

    bu_cv_ntohd((unsigned char *)scan, (unsigned char *)(&rp[1]), aip->neqn*ELEMENTS_PER_PLANE);
    for (i = 0; i < aip->neqn; i++) {
	aip->eqn[i][X] = scan[(i*ELEMENTS_PER_PLANE)+0]; /* convert double to fastf_t */
	aip->eqn[i][Y] = scan[(i*ELEMENTS_PER_PLANE)+1]; /* convert double to fastf_t */
	aip->eqn[i][Z] = scan[(i*ELEMENTS_PER_PLANE)+2]; /* convert double to fastf_t */
	aip->eqn[i][W] = scan[(i*ELEMENTS_PER_PLANE)+3]; /* convert double to fastf_t */
    }
    bu_free(scan, "scan array");

    /* Transform by the matrix */
    if (mat == NULL) mat = bn_mat_identity;
    for (i = 0; i < aip->neqn; i++) {
	point_t orig_pt;
	point_t pt;
	vect_t norm;
	fastf_t factor;

	/* unitize the plane equation first */
	factor = 1.0 / MAGNITUDE(aip->eqn[i]);
	VSCALE(aip->eqn[i], aip->eqn[i], factor);
	aip->eqn[i][W] = aip->eqn[i][W] * factor;


	/* Pick a point on the original halfspace */
	VSCALE(orig_pt, aip->eqn[i], aip->eqn[i][W]);

	/* Transform the point, and the normal */
	MAT4X3VEC(norm, mat, aip->eqn[i]);
	MAT4X3PNT(pt, mat, orig_pt);

	/* Measure new distance from origin to new point */
	VUNITIZE(norm);
	VMOVE(aip->eqn[i], norm);
	aip->eqn[i][W] = VDOT(pt, norm);
    }

    return 0;
}
示例#6
0
/* T R E E T H E R M _ S E T U P
 *
 * This routine is called (at prep time)
 * once for each region which uses this shader.
 * Any shader-specific initialization should be done here.
 */
HIDDEN int
tthrm_setup(register struct region *rp, struct bu_vls *matparm, genptr_t *dpp, const struct mfuncs *UNUSED(mfp), struct rt_i *rtip)


/* pointer to reg_udata in *rp */

/* New since 4.4 release */
{
    register struct tthrm_specific *tthrm_sp;
    struct bu_mapped_file *tt_file;
    char *tt_data;
    long cyl_tot = 0;
    long tseg;
    float *fp;
    float fv[4];
    double min_temp;
    double max_temp;
    point_t center;
    point_t pt;
    vect_t dir;
    static const double inv_nodes = 1.0/8.0;
    int node;
    int i;
    int long_size = 0;
    size_t file_size_long;
    size_t file_size_int;

    /* check the arguments */
    RT_CHECK_RTI(rtip);
    BU_CK_VLS(matparm);
    RT_CK_REGION(rp);

    if (rdebug&RDEBUG_SHADE)
	bu_log("tthrm_setup(Region:\"%s\", tthrm(%s))\n",
	       rp->reg_name, bu_vls_addr(matparm));

    /* Get memory for the shader parameters and shader-specific data */
    BU_GET(tthrm_sp, struct tthrm_specific);
    *dpp = tthrm_sp;
    tthrm_sp->magic = tthrm_MAGIC;

    tthrm_sp->tt_name[0] = '\0';
    tthrm_sp->tt_min_temp = tthrm_sp->tt_max_temp = 0.0;

    if (rdebug&RDEBUG_SHADE)
	bu_log("Parsing: (%s)\n", bu_vls_addr(matparm));

    if (bu_struct_parse(matparm, tthrm_parse, (char *)tthrm_sp) < 0) {
	bu_bomb(__FILE__);
    }
    if (tthrm_sp->tt_name[0] == '\0') {
	bu_log("Must specify file for tthrm shader on %s (got \"%s\"\n",
	       rp->reg_name, bu_vls_addr(matparm));
	bu_bomb(__FILE__);
    }

    tt_file = bu_open_mapped_file(tthrm_sp->tt_name, (char *)NULL);
    if (!tt_file) {
	bu_log("Error mapping \"%s\"\n",  tthrm_sp->tt_name);
	bu_bomb("shader tthrm: can't get thermal data");
    }
    tt_data = tt_file->buf;


    if (rdebug&RDEBUG_SHADE)
	bu_log("tthrm_setup() data: %p total\n",
	       (void *)tt_data);

    /* Compute how big the file should be, so that we can guess
     * at the size of the integer at the front of the file
     */
    file_size_int = sizeof(int) + *((int *)tt_data) *
	(sizeof(short) + sizeof(float) * 4 * NUM_NODES);

    file_size_long = sizeof(long) + *((long *)tt_data) *
	(sizeof(short) + sizeof(float) * 4 * NUM_NODES);

    switch (sizeof(long)) {
	case 8:
	    if (tt_file->buflen == file_size_long) {
		/* 64bit data on 64bit host */
		long_size = sizeof(long);
		tthrm_sp->tt_max_seg = cyl_tot = *((long *)tt_data);
	    } else if (tt_file->buflen == file_size_int) {
		/* 32bit data on 32bit host */
		long_size = sizeof(int);
		tthrm_sp->tt_max_seg = cyl_tot = *((int *)tt_data);
	    }
	    break;
	case 4:
	    if (tt_file->buflen == file_size_long) {
		/* 32bit data on 32bit host */
		long_size = sizeof(long);
		tthrm_sp->tt_max_seg = cyl_tot = *((long *)tt_data);
	    } else if (tt_file->buflen == (file_size_long+4)) {
		/* 64bit data on 32bit host */

		cyl_tot = *((int *)tt_data);
		if (cyl_tot != 0) {
		    bu_log("%s:%d thermal data written on 64bit machine with more that 2^32 segs\n", __FILE__, __LINE__);
		    bu_bomb("");
		}

		long_size = sizeof(long) + 4;
		tthrm_sp->tt_max_seg = cyl_tot =
		    ((int *)tt_data)[1];
	    }
	    break;
	default:
	    bu_log("a long int is %d bytes on this machine\n", sizeof(long));
	    bu_bomb("I can only handle 4 or 8 byte longs\n");
	    break;
    }

    if (rdebug&RDEBUG_SHADE)
	bu_log("cyl_tot = %ld\n", cyl_tot);

    tthrm_sp->tt_segs = (struct thrm_seg *)
	bu_calloc(cyl_tot, sizeof(struct thrm_seg), "thermal segs");

    min_temp = MAX_FASTF;
    max_temp = -MAX_FASTF;

#define CYL_DATA(_n) ((float *) (&tt_data[				\
				     long_size +			\
				     (_n) * (sizeof(short) + sizeof(float) * 4 * NUM_NODES) + \
				     sizeof(short)			\
				     ]))

    for (tseg = 0; tseg < cyl_tot; tseg++) {

	/* compute centerpoint, min/max temperature values */
	fp = CYL_DATA(tseg);
	VSETALL(center, 0.0);
	for (node=0; node < NUM_NODES; node++, fp+=4) {
	    /* this is necessary to assure that all float
	     * values are aligned on 4-byte boundaries
	     */
	    memcpy(fv, fp, sizeof(float)*4);

	    if (rdebug&RDEBUG_SHADE)
		bu_log("tthrm_setup() node %d (%g %g %g) %g\n",
		       node, fv[0], fv[1], fv[2], fv[3]);

	    /* make sure we don't have any "infinity" values */
	    for (i=0; i < 4; i++) {
		if (fv[i] > MAX_FASTF || fv[i] < -MAX_FASTF) {
		    bu_log("%s:%d seg %ld node %d coord %d out of bounds: %g\n",
			   __FILE__, __LINE__, tseg, node, i, fv[i]);
		    bu_bomb("choke, gasp, *croak*\n");
		}
	    }

	    /* copy the values to the segment list, converting
	     * from Meters to Millimeters in the process
	     */
	    VSCALE(tthrm_sp->tt_segs[tseg].node[node], fv, 1000.0);
	    tthrm_sp->tt_segs[tseg].temperature[node] = fv[3];

	    VADD2(center, center, fv);

	    if (fv[3] > max_temp) max_temp = fv[3];
	    if (fv[3] < min_temp) min_temp = fv[3];
	}

	VSCALE(center, center, 1000.0);
	VSCALE(tthrm_sp->tt_segs[tseg].pt, center, inv_nodes);

	if (rdebug&RDEBUG_SHADE) {
	    bu_log("Center: (%g %g %g) (now in mm, not m)\n",
		   V3ARGS(tthrm_sp->tt_segs[tseg].pt));
	}

	/* compute vectors from center pt for each node */
	fp = CYL_DATA(tseg);
	for (node=0; node < NUM_NODES; node++, fp+=4) {
	    /* this is necessary to assure that all float
	     * values are aligned on 4-byte boundaries
	     */
	    memcpy(fv, fp, sizeof(float)*4);

	    VSCALE(pt, fv, 1000.0);
	    VSUB2(tthrm_sp->tt_segs[tseg].vect[node],
		  pt,
		  tthrm_sp->tt_segs[tseg].pt
		);
	}

	/* compute a direction vector for the thermal segment */
	VCROSS(dir, tthrm_sp->tt_segs[tseg].vect[0],
	       tthrm_sp->tt_segs[tseg].vect[2]);
	VUNITIZE(dir);
	VMOVE(tthrm_sp->tt_segs[tseg].dir, dir);
	tthrm_sp->tt_segs[tseg].magic = THRM_SEG_MAGIC;
    }

    bu_close_mapped_file(tt_file);

    if (ZERO(tthrm_sp->tt_min_temp) && EQUAL(tthrm_sp->tt_max_temp, SMALL_FASTF)) {
	tthrm_sp->tt_min_temp = min_temp;
	tthrm_sp->tt_max_temp = max_temp;
	bu_log("computed temp min/max on %s: %g/%g\n", rp->reg_name, min_temp, max_temp);
    } else {
	min_temp =tthrm_sp->tt_min_temp;
	max_temp = tthrm_sp->tt_max_temp;
	bu_log("taking user specified on %s: min/max %g/%g\n", rp->reg_name, min_temp, max_temp);
    }

    if (!EQUAL(max_temp, min_temp)) {
	tthrm_sp->tt_temp_scale = 1.0 / (max_temp - min_temp);
    } else {
	/* min and max are equal, maybe zero */
	if (ZERO(max_temp))
	    tthrm_sp->tt_temp_scale = 0.0;
	else
	    tthrm_sp->tt_temp_scale = 255.0/max_temp;
    }
    /* The shader needs to operate in a coordinate system which stays
     * fixed on the region when the region is moved (as in animation)
     * we need to get a matrix to perform the appropriate transform(s).
     *
     * Shading is done in "region coordinates":
     */
    db_region_mat(tthrm_sp->tthrm_m_to_sh, rtip->rti_dbip, rp->reg_name, &rt_uniresource);

    if (rdebug&RDEBUG_SHADE) {
	bu_log("min_temp: %17.14e  max_temp %17.14e temp_scale: %17.14e\n",
	       tthrm_sp->tt_min_temp,
	       tthrm_sp->tt_max_temp,
	       tthrm_sp->tt_temp_scale);

	bu_log("tthrm_setup(%s, %s)done\n",
	       rp->reg_name, bu_vls_addr(matparm));
	tthrm_print(rp, *dpp);
    }

    return 1;
}
void
bn_vtoh_move(register vect_t h, register const vect_t v)
{
    VMOVE(h, v);
    h[W] = 1.0;
}
示例#8
0
文件: edbot.c 项目: kanzure/brlcad
int
ged_move_botpts(struct ged *gedp, int argc, const char *argv[])
{
    static const char *usage = "bot vec vertex_1 [vertex_2 ... vertex_n]";
    struct directory *dp;
    struct rt_db_internal intern;
    struct rt_bot_internal *botip;
    mat_t mat;
    register int i;
    size_t vertex_i;
    char *last;

    /* must be double for scanf */
    double vec[ELEMENTS_PER_VECT];

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

    if ((last = strrchr(argv[1], '/')) == NULL)
	last = (char *)argv[1];
    else
	++last;

    if (last[0] == '\0') {
	bu_vls_printf(gedp->ged_result_str, "%s: illegal input - %s", argv[0], argv[1]);
	return GED_ERROR;
    }

    dp = db_lookup(gedp->ged_wdbp->dbip, last, LOOKUP_QUIET);
    if (dp == RT_DIR_NULL) {
	bu_vls_printf(gedp->ged_result_str, "%s: failed to find %s", argv[0], argv[1]);
	return GED_ERROR;
    }

    if (bu_sscanf(argv[2], "%lf %lf %lf", &vec[X], &vec[Y], &vec[Z]) != 3) {
	bu_vls_printf(gedp->ged_result_str, "%s: bad vector - %s", argv[0], argv[2]);
	return GED_ERROR;
    }

    VSCALE(vec, vec, gedp->ged_wdbp->dbip->dbi_local2base);

    if (wdb_import_from_path2(gedp->ged_result_str, &intern, argv[1], gedp->ged_wdbp, mat) == GED_ERROR) {
	bu_vls_printf(gedp->ged_result_str, "%s: failed to find %s", argv[0], argv[1]);
	return GED_ERROR;
    }

    if (intern.idb_major_type != DB5_MAJORTYPE_BRLCAD ||
	intern.idb_minor_type != DB5_MINORTYPE_BRLCAD_BOT) {
	bu_vls_printf(gedp->ged_result_str, "Object is not a BOT");
	rt_db_free_internal(&intern);

	return GED_ERROR;
    }

    botip = (struct rt_bot_internal *)intern.idb_ptr;

    for (i = 3; i < argc; ++i) {
	if (bu_sscanf(argv[i], "%zu", &vertex_i) != 1) {
	    bu_vls_printf(gedp->ged_result_str, "%s: bad bot vertex index - %s\n", argv[0], argv[i]);
	    continue;
	}

	if (vertex_i >= botip->num_vertices) {
	    bu_vls_printf(gedp->ged_result_str, "%s: bad bot vertex index - %s\n", argv[0], argv[i]);
	    continue;
	}

	VADD2(&botip->vertices[vertex_i*3], vec, &botip->vertices[vertex_i*3]);
    }

    {
	mat_t invmat;
	point_t curr_pt;
	size_t idx;

	bn_mat_inv(invmat, mat);
	for (idx = 0; idx < botip->num_vertices; idx++) {
	    MAT4X3PNT(curr_pt, invmat, &botip->vertices[idx*3]);
	    VMOVE(&botip->vertices[idx*3], curr_pt);
	}
    }

    GED_DB_PUT_INTERNAL(gedp, dp, &intern, &rt_uniresource, GED_ERROR);
    rt_db_free_internal(&intern);

    return GED_OK;
}
void
_rt_gen_worker(int cpu, void *ptr)
{
    int i, j;
    struct application ap;
    struct rt_parallel_container *state = (struct rt_parallel_container *)ptr;
    point_t min, max;
    int ymin, ymax;
    int dir1, dir2, dir3;
    fastf_t d[3];
    int n[3];
    RT_APPLICATION_INIT(&ap);
    ap.a_rt_i = state->rtip;
    ap.a_hit = add_hit_pnts;
    ap.a_miss = ignore_miss;
    ap.a_onehit = 0;
    ap.a_logoverlap = rt_silent_logoverlap;
    ap.a_resource = &state->resp[cpu];
    ap.a_uptr = (void *)(&state->npts[cpu]);

    /* get min and max points of bounding box */
    VMOVE(min, state->rtip->mdl_min);
    VMOVE(max, state->rtip->mdl_max);

    /* Make sure we've got at least 10 steps in all 3 dimensions,
     * regardless of delta */
    for (i = 0; i < 3; i++) {
	n[i] = (max[i] - min[i])/state->delta;
	if(n[i] < 10) n[i] = 10;
	d[i] = (max[i] - min[i])/n[i];
    }

    dir1 = state->ray_dir;
    dir2 = (state->ray_dir+1)%3;
    dir3 = (state->ray_dir+2)%3;

    if (state->ncpus == 1) {
	ymin = 0;
	ymax = n[dir3];
    } else {
	ymin = n[dir3]/state->ncpus * (cpu - 1) + 1;
	ymax = n[dir3]/state->ncpus * (cpu);
	if (cpu == 1) ymin = 0;
	if (cpu == state->ncpus) ymax = n[dir3];
    }

    ap.a_ray.r_dir[state->ray_dir] = -1;
    ap.a_ray.r_dir[dir2] = 0;
    ap.a_ray.r_dir[dir3] = 0;
    VMOVE(ap.a_ray.r_pt, min);
    ap.a_ray.r_pt[state->ray_dir] = max[state->ray_dir] + 100;

    for (i = 0; i < n[dir2]; i++) {
	ap.a_ray.r_pt[dir3] = min[dir3] + d[dir3] * ymin;
	for (j = ymin; j < ymax; j++) {
	    rt_shootray(&ap);
	    ap.a_ray.r_pt[dir3] += d[dir3];
	}
	ap.a_ray.r_pt[dir2] += d[dir2];
    }
}
示例#10
0
文件: edbot.c 项目: kanzure/brlcad
int
ged_bot_face_split(struct ged *gedp, int argc, const char *argv[])
{
    static const char *usage = "bot face";
    struct directory *dp;
    static fastf_t sf = 1.0 / 3.0;
    struct rt_db_internal intern;
    struct rt_bot_internal *botip;
    mat_t mat;
    char *last;
    size_t face_i;
    size_t last_vi;
    size_t save_vi;
    point_t new_pt;

    GED_CHECK_DATABASE_OPEN(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;
    }

    if ((last = strrchr(argv[1], '/')) == NULL)
	last = (char *)argv[1];
    else
	++last;

    if (last[0] == '\0') {
	bu_vls_printf(gedp->ged_result_str, "%s: illegal input - %s", argv[0], argv[1]);
	return GED_ERROR;
    }

    dp = db_lookup(gedp->ged_wdbp->dbip, last, LOOKUP_QUIET);
    if (dp == RT_DIR_NULL) {
	bu_vls_printf(gedp->ged_result_str, "%s: failed to find %s", argv[0], argv[1]);
	return GED_ERROR;
    }

    if (bu_sscanf(argv[2], "%zu", &face_i) != 1) {
	bu_vls_printf(gedp->ged_result_str, "%s: bad bot vertex index - %s", argv[0], argv[2]);
	return GED_ERROR;
    }

    if (wdb_import_from_path2(gedp->ged_result_str, &intern, last, gedp->ged_wdbp, mat) == GED_ERROR) {
	bu_vls_printf(gedp->ged_result_str, "%s: failed to find %s", argv[0], argv[1]);
	return GED_ERROR;
    }

    if (intern.idb_major_type != DB5_MAJORTYPE_BRLCAD ||
	intern.idb_minor_type != DB5_MINORTYPE_BRLCAD_BOT) {
	bu_vls_printf(gedp->ged_result_str, "Object is not a BOT");
	rt_db_free_internal(&intern);

	return GED_ERROR;
    }

    botip = (struct rt_bot_internal *)intern.idb_ptr;
    last_vi = botip->num_vertices;

    if (face_i >= botip->num_faces) {
	bu_vls_printf(gedp->ged_result_str, "%s: bad bot face index - %s", argv[0], argv[2]);
	rt_db_free_internal(&intern);
	return GED_ERROR;
    }

    /* Create the new point, modify face_i and hook in the two extra faces */
    /* First, create some space */
    botip->num_vertices++;
    botip->num_faces += 2;
    botip->vertices = (fastf_t *)bu_realloc((void *)botip->vertices, botip->num_vertices*3*sizeof(fastf_t), "realloc bot vertices");
    botip->faces = (int *)bu_realloc((void *)botip->faces, botip->num_faces*3*sizeof(int), "realloc bot faces");

    /* Create the new point. For the moment, we're using the average of the face_i's points */
    VADD3(new_pt,
	  &botip->vertices[botip->faces[face_i*3]*3],
	  &botip->vertices[botip->faces[face_i*3+1]*3],
	  &botip->vertices[botip->faces[face_i*3+2]*3]);
    VSCALE(new_pt, new_pt, sf);

    /* Add the new point to the last position in the list of vertices. */
    VMOVE(&botip->vertices[last_vi*3], new_pt);

    /* Update face_i */
    save_vi = botip->faces[face_i*3+2];
    botip->faces[face_i*3+2] = last_vi;

    /* Initialize the two new faces */
    botip->faces[(botip->num_faces-2)*3] = botip->faces[face_i*3+1];
    botip->faces[(botip->num_faces-2)*3+1] = save_vi;
    botip->faces[(botip->num_faces-2)*3+2] = last_vi;
    botip->faces[(botip->num_faces-1)*3] = save_vi;
    botip->faces[(botip->num_faces-1)*3+1] = botip->faces[face_i*3];
    botip->faces[(botip->num_faces-1)*3+2] = last_vi;

    bu_vls_printf(gedp->ged_result_str, "%zu", last_vi);

    GED_DB_PUT_INTERNAL(gedp, dp, &intern, &rt_uniresource, GED_ERROR);
    rt_db_free_internal(&intern);
    return GED_OK;
}
示例#11
0
文件: edbot.c 项目: kanzure/brlcad
int
ged_bot_edge_split(struct ged *gedp, int argc, const char *argv[])
{
    static const char *usage = "bot edge";
    struct directory *dp;
    struct rt_db_internal intern;
    struct rt_bot_internal *botip;
    mat_t mat;
    char *last;
    size_t v1_i;
    size_t v2_i;
    size_t last_fi;
    size_t last_vi;
    size_t save_vi;
    size_t i;
    point_t new_pt;

    GED_CHECK_DATABASE_OPEN(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;
    }

    if ((last = strrchr(argv[1], '/')) == NULL)
	last = (char *)argv[1];
    else
	++last;

    if (last[0] == '\0') {
	bu_vls_printf(gedp->ged_result_str, "%s: illegal input - %s", argv[0], argv[1]);
	return GED_ERROR;
    }

    dp = db_lookup(gedp->ged_wdbp->dbip, last, LOOKUP_QUIET);
    if (dp == RT_DIR_NULL) {
	bu_vls_printf(gedp->ged_result_str, "%s: failed to find %s", argv[0], argv[1]);
	return GED_ERROR;
    }

    if (bu_sscanf(argv[2], "%zu %zu", &v1_i, &v2_i) != 2) {
	bu_vls_printf(gedp->ged_result_str, "%s: bad bot edge - %s", argv[0], argv[2]);
	return GED_ERROR;
    }

    if (wdb_import_from_path2(gedp->ged_result_str, &intern, last, gedp->ged_wdbp, mat) == GED_ERROR) {
	bu_vls_printf(gedp->ged_result_str, "%s: failed to find %s", argv[0], argv[1]);
	return GED_ERROR;
    }

    if (intern.idb_major_type != DB5_MAJORTYPE_BRLCAD ||
	intern.idb_minor_type != DB5_MINORTYPE_BRLCAD_BOT) {
	bu_vls_printf(gedp->ged_result_str, "Object is not a BOT");
	rt_db_free_internal(&intern);

	return GED_ERROR;
    }

    botip = (struct rt_bot_internal *)intern.idb_ptr;
    last_fi = botip->num_faces;
    last_vi = botip->num_vertices;

    if (v1_i >= botip->num_vertices || v2_i >= botip->num_vertices) {
	bu_vls_printf(gedp->ged_result_str, "%s: bad bot edge - %s", argv[0], argv[2]);
	rt_db_free_internal(&intern);
	return GED_ERROR;
    }

    /*
     * Create the new point, modify all faces (should only be two)
     * that share the specified edge and hook in the two extra faces.
     */

    /* First, create some space */
    botip->num_vertices++;
    botip->num_faces += 2;
    botip->vertices = (fastf_t *)bu_realloc((void *)botip->vertices, botip->num_vertices*3*sizeof(fastf_t), "realloc bot vertices");
    botip->faces = (int *)bu_realloc((void *)botip->faces, botip->num_faces*3*sizeof(int), "realloc bot faces");

    /* Create the new point. We're using the average of the edge's points */
    VADD2(new_pt, &botip->vertices[v1_i*3], &botip->vertices[v2_i*3]);
    VSCALE(new_pt, new_pt, 0.5);

    /* Add the new point to the last position in the list of vertices. */
    VMOVE(&botip->vertices[last_vi*3], new_pt);

    /* Update faces associated with the specified edge */
    for (i = 0; i < last_fi; ++i) {
	if (((size_t)botip->faces[i*3] == v1_i && (size_t)botip->faces[i*3+1] == v2_i) ||
	    ((size_t)botip->faces[i*3] == v2_i && (size_t)botip->faces[i*3+1] == v1_i)) {

	    save_vi = botip->faces[i*3+1];
	    botip->faces[i*3+1] = last_vi;

	    /* Initialize a new face */
	    botip->faces[last_fi*3] = last_vi;
	    botip->faces[last_fi*3+1] = save_vi;
	    botip->faces[last_fi*3+2] = botip->faces[i*3+2];

	    ++last_fi;
	} else if (((size_t)botip->faces[i*3] == v1_i && (size_t)botip->faces[i*3+2] == v2_i) ||
		   ((size_t)botip->faces[i*3] == v2_i && (size_t)botip->faces[i*3+2] == v1_i)) {
	    save_vi = botip->faces[i*3];
	    botip->faces[i*3] = last_vi;

	    /* Initialize a new face */
	    botip->faces[last_fi*3] = last_vi;
	    botip->faces[last_fi*3+1] = save_vi;
	    botip->faces[last_fi*3+2] = botip->faces[i*3+1];

	    ++last_fi;
	} else if (((size_t)botip->faces[i*3+1] == v1_i && (size_t)botip->faces[i*3+2] == v2_i) ||
		   ((size_t)botip->faces[i*3+1] == v2_i && (size_t)botip->faces[i*3+2] == v1_i)) {
	    save_vi = botip->faces[i*3+2];
	    botip->faces[i*3+2] = last_vi;

	    /* Initialize a new face */
	    botip->faces[last_fi*3] = botip->faces[i*3];
	    botip->faces[last_fi*3+1] = last_vi;
	    botip->faces[last_fi*3+2] = save_vi;

	    ++last_fi;
	}

	if (last_fi >= botip->num_faces)
	    break;
    }

    GED_DB_PUT_INTERNAL(gedp, dp, &intern, &rt_uniresource, GED_ERROR);
    rt_db_free_internal(&intern);
    return GED_OK;
}
示例#12
0
/**
 * Given a pointer to an internal GED database object, mirror the
 * object's values about the given transformation matrix.
 */
int
rt_epa_mirror(struct rt_db_internal *ip, register const plane_t plane)
{
    struct rt_epa_internal *epa;

    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;

    point_t pt;
    vect_t h;
    vect_t au;
    vect_t n;

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

    RT_CK_DB_INTERNAL(ip);

    epa = (struct rt_epa_internal *)ip->idb_ptr;
    RT_EPA_CK_MAGIC(epa);

    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, epa->epa_V);
    MAT4X3PNT(epa->epa_V, mirmat, pt);

    VMOVE(h, epa->epa_H);
    VMOVE(au, epa->epa_Au);
    VUNITIZE(h);
    VUNITIZE(au);

    VCROSS(n, mirror_dir, epa->epa_H);
    VUNITIZE(n);
    ang = M_PI_2 - acos(VDOT(h, mirror_dir));
    bn_mat_arb_rot(rmat, origin, n, ang*2);
    VMOVE(h, epa->epa_H);
    MAT4X3VEC(epa->epa_H, rmat, h);

    VCROSS(n, mirror_dir, epa->epa_Au);
    VUNITIZE(n);
    ang = M_PI_2 - acos(VDOT(au, mirror_dir));
    bn_mat_arb_rot(rmat, origin, n, ang*2);
    VMOVE(au, epa->epa_Au);
    MAT4X3VEC(epa->epa_Au, rmat, au);

    return 0;
}
示例#13
0
static int
radhit( struct application *ap, struct partition *PartHeadp )
{
    register struct partition *pp;
    register struct hit *hitp;
    struct application sub_ap;
    struct rayinfo *rayp;
    fastf_t	f;
    vect_t	to_eye, work;
    int	depth;
    int	cpu_num;


    for ( pp=PartHeadp->pt_forw; pp != PartHeadp; pp = pp->pt_forw )
	if ( pp->pt_outhit->hit_dist >= 0.0 )  break;
    if ( pp == PartHeadp )  {
	bu_log("radhit:  no hit out front?\n");
	return 0;
    }

    if (R_DEBUG&RDEBUG_HITS)  {
	rt_pr_pt( ap->a_rt_i, pp );
    }

    hitp = pp->pt_inhit;
    if ( hitp->hit_dist >= INFINITY )  {
	bu_log("radhit:  entry beyond infinity\n");
	return 1;
    }
    /* Check to see if eye is "inside" the solid */
    if ( hitp->hit_dist < 0 )  {
	/* XXX */
	return 0;
    }

    if (R_DEBUG&RDEBUG_HITS)  {
	rt_pr_hit( " In", hitp );
    }

    if ( ap->a_resource == RESOURCE_NULL)
	cpu_num = 0;
    else
	cpu_num = ap->a_resource->re_cpu;

    rayp = &rayinfo[cpu_num][ ap->a_level +1 ];
    rayp->x = ap->a_x;
    rayp->y = ap->a_y;
    rayp->dist = hitp->hit_dist;
    rayp->reg = pp->pt_regionp->reg_regionid;
    rayp->sol = pp->pt_inseg->seg_stp->st_id;
    rayp->surf = hitp->hit_surfno;
    RT_HIT_NORMAL( rayp->norm, hitp, pp->pt_inseg->seg_stp, &(ap->a_ray), pp->pt_inflip );
    RT_CURVATURE( &(rayp->curvature), hitp, pp->pt_inflip, pp->pt_inseg->seg_stp );
    if ( VDOT( hitp->hit_normal, ap->a_ray.r_dir ) < 0 ) {
	bu_log(" debug: curvature flip\n");
	rayp->curvature.crv_c1 = - rayp->curvature.crv_c1;
	rayp->curvature.crv_c2 = - rayp->curvature.crv_c2;
    }
    VMOVE( rayp->ip, hitp->hit_point );
    VMOVE( rayp->dir, ap->a_ray.r_dir);

    /* Compute the specular direction */
    VREVERSE( to_eye, ap->a_ray.r_dir );
    f = 2 * VDOT( to_eye, rayp->norm );
    VSCALE( work, rayp->norm, f );
    /* I have been told this has unit length */
    VSUB2( rayp->spec, work, to_eye );
    VUNITIZE( rayp->spec );

    /* Save info for 1st ray */
    if ( ap->a_level == 0 ) {
	firstray[cpu_num] = ap->a_ray;	/* struct copy */
	rayp->sight = 1;	/* the 1st intersect is always visible */
    } else {
	/* Check for visibility */
	rayp->sight = isvisible( ap, hitp, rayp->norm );
    }

    /*
     * Shoot another ray in the specular direction.
     */
    if ( ap->a_level < numreflect-1 ) {
	sub_ap = *ap;	/* struct copy */
	sub_ap.a_level = ap->a_level+1;
	sub_ap.a_purpose = "secondary ray";
	VMOVE( sub_ap.a_ray.r_pt, hitp->hit_point );
	VMOVE( sub_ap.a_ray.r_dir, rayp->spec );
	depth = rt_shootray( &sub_ap );
    } else {
	depth = 0;
    }

    if ( ap->a_level == 0 ) {
	rayinfo[cpu_num][0].x = ap->a_x;
	rayinfo[cpu_num][0].y = ap->a_y;
	rayinfo[cpu_num][0].surf = depth+1;
	rayinfo[cpu_num][0].ip[0] = ap->a_ray.r_pt[0];
	rayinfo[cpu_num][0].ip[1] = ap->a_ray.r_pt[1];
	rayinfo[cpu_num][0].ip[2] = ap->a_ray.r_pt[2];
	radar_physics( cpu_num, depth + 1 );
#ifdef SAR
	dumpall( ap, cpu_num, depth + 1);
#endif
    }

    return depth+1;	/* report hit to main routine */
}
示例#14
0
文件: sh_wood.c 项目: kanzure/brlcad
/*
 * Given an XYZ hit point, compute the concentric ring structure.  We do
 * this by computing the dot-product of the hit point vs. the ring vertex,
 * which is then used to compute the distance from the ring center.  This
 * distance is then multiplied by a velocity coefficient that is signed.
 */
HIDDEN int
wood_render(struct application *UNUSED(ap), const struct partition *UNUSED(partp), struct shadework *swp, void *dp)
{
    register struct wood_specific *wd =
	(struct wood_specific *)dp;

    vect_t g, h;
    point_t dprod, lprod;
    double c, A, B, C;
    double x, y, z, xd, yd, zd;
    double mixture, pp, pq, wt;

    /*
     * Compute the normalized hit point
     */

    xd = wd->b_max[0] - wd->b_min[0] + 1.0;
    yd = wd->b_max[1] - wd->b_min[1] + 1.0;
    zd = wd->b_max[2] - wd->b_min[2] + 1.0;

    x = wd->dither[X] + ((swp->sw_hit.hit_point[0] - wd->b_min[0]) / xd);
    y = wd->dither[Y] + ((swp->sw_hit.hit_point[1] - wd->b_min[1]) / yd);
    z = wd->dither[Z] + ((swp->sw_hit.hit_point[2] - wd->b_min[2]) / zd);

    /*
     * Compute the distance from the ring center to the hit
     * point by formulating a triangle between the hit point,
     * the ring vertex, and ring's local X-axis.
     */

    VSUB2(h, swp->sw_hit.hit_point, wd->vertex);
    VMOVE(g, h);
    VUNITIZE(g);				/* xlate to ray */

    wt = wood_turb(x, y, z, wd) * wd->depth;	/* used in two places */

    c = fabs(VDOT(g, wd->dir));
    A = MAGNITUDE(h) + wt;
    B = c * A;				/* abscissa */
    C = sqrt(pow(A, 2.0) - pow(B, 2.0));	/* ordinate */

    /*
     * Divide the ordinate by the spacing coefficient, and
     * compute the sine from that product.
     */

    c = fabs(sin((C / wd->spacing) * M_PI));

    /*
     * Dither the "q" control
     */

    pq = cos(((wd->qd * wt) + wd->qp + wd->phase) * DEG2RAD);
    pp = cos(wd->phase * DEG2RAD);

    /*
     * Color the hit point based on the phase of the ring
     */

    if (c < pq) {
	VMOVE(swp->sw_color, wd->lt_rgb);
    } else if (c >= pp) {
	VMOVE(swp->sw_color, wd->dk_rgb);
    } else {
	mixture = (c - pq) / (pp - pq);
	VSCALE(lprod, wd->lt_rgb, (1.0 - mixture));
	VSCALE(dprod, wd->dk_rgb, mixture);
	VADD2(swp->sw_color, lprod, dprod);
    }

    /*
     * All done.  Return to the caller
     */

    return 1;
}
int
negative_polygon(struct subbrep_object_data *data)
{
    int io_state = 0;
    int all_faces_cnt = 0;
    std::vector<int> all_faces;
    int *final_faces = NULL;
    std::set<int> fol_faces;

    /* This will get reused for all faces, so make it once */
    point_t *all_verts = (point_t *)bu_calloc(data->brep->m_V.Count(), sizeof(point_t), "bot verts");
    for (int vi = 0; vi < data->brep->m_V.Count(); vi++) {
        VMOVE(all_verts[vi], data->brep->m_V[vi].Point());
    }

    array_to_set(&fol_faces, data->fol, data->fol_cnt);

    // Check each face to see if it is fil or fol - the first fol face, stash its
    // normal - don't even need the triangle face normal, we can just use the face's normal and
    // a point from the center of one of the fol triangles on that particular face.
    ON_3dPoint origin_pnt;
    ON_3dVector triangle_normal;
    int have_hit_pnt = 0;

    /* Get triangles from the faces */
    ON_BoundingBox vert_bbox;
    ON_MinMaxInit(&vert_bbox.m_min, &vert_bbox.m_max);
    for (int i = 0; i < data->loops_cnt; i++) {
	const ON_BrepLoop *b_loop = &(data->brep->m_L[data->loops[i]]);
	int *ffaces = NULL;
	int num_faces = subbrep_polygon_tri(data->brep, all_verts, (int *)&(b_loop->m_loop_index), 1, &ffaces);
	if (!num_faces) {
	    bu_log("Error - triangulation failed for loop %d!\n", b_loop->m_loop_index);
	    return 0;
	}
	if (!have_hit_pnt) {
	    const ON_BrepFace *b_face = b_loop->Face();
	    if (fol_faces.find(b_face->m_face_index) != fol_faces.end()) {
		ON_3dPoint p1 = data->brep->m_V[ffaces[0]].Point();
		ON_3dPoint p2 = data->brep->m_V[ffaces[1]].Point();
		ON_3dPoint p3 = data->brep->m_V[ffaces[2]].Point();
		ON_Plane fp;
		ON_Surface *ts = b_face->SurfaceOf()->Duplicate();
		(void)ts->IsPlanar(&fp, BREP_PLANAR_TOL);
		delete ts;
		triangle_normal = fp.Normal();
		if (b_face->m_bRev) triangle_normal = triangle_normal * -1;
		origin_pnt = (p1 + p2 + p3) / 3;
		have_hit_pnt = 1;
	    }
	}

	for (int f_ind = 0; f_ind < num_faces*3; f_ind++) {
	    all_faces.push_back(ffaces[f_ind]);
	    vert_bbox.Set(data->brep->m_V[ffaces[f_ind]].Point(), true);
	}
	if (ffaces) bu_free(ffaces, "free polygon face array");
	all_faces_cnt += num_faces;

    }

    /* Now we can build the final faces array */
    final_faces = (int *)bu_calloc(all_faces_cnt * 3, sizeof(int), "final bot verts");
    for (int i = 0; i < all_faces_cnt*3; i++) {
	final_faces[i] = all_faces[i];
    }

    // Scale bounding box to make sure corners are away from the volume
    vert_bbox.m_min = vert_bbox.m_min * 1.1;
    vert_bbox.m_max = vert_bbox.m_max * 1.1;

    // Pick a ray direction
    ON_3dVector rdir;
    ON_3dPoint box_corners[8];
    vert_bbox.GetCorners(box_corners);
    int have_dir = 0;
    int corner = 0;
    double dotp;
    while (!have_dir && corner < 8) {
	rdir = box_corners[corner] - origin_pnt;
	dotp = ON_DotProduct(triangle_normal, rdir);
	(NEAR_ZERO(dotp, 0.01)) ? corner++ : have_dir = 1;
    }
    if (!have_dir) {
	bu_log("Error: NONE of the corners worked??\n");
	return 0;
    }
    point_t origin, dir;
    VMOVE(origin, origin_pnt);
    VMOVE(dir, rdir);
#if 0
    std::cout << "working: " << bu_vls_addr(data->key) << "\n";
    bu_log("in origin.s sph %f %f %f 1\n", origin[0], origin[1], origin[2]);
    bu_log("in triangle_normal.s rcc %f %f %f %f %f %f 1 \n", origin_pnt.x, origin_pnt.y, origin_pnt.z, triangle_normal.x, triangle_normal.y, triangle_normal.z);
    bu_log("in ray.s rcc %f %f %f %f %f %f 1 \n", origin[0], origin[1], origin[2], dir[0], dir[1], dir[2]);
#endif
    // Test the ray against the triangle set
    int hit_cnt = 0;
    point_t p1, p2, p3, isect;
    ON_3dPointArray hit_pnts;
    for (int i = 0; i < all_faces_cnt; i++) {
	ON_3dPoint onp1, onp2, onp3, hit_pnt;
	VMOVE(p1, all_verts[all_faces[i*3+0]]);
	VMOVE(p2, all_verts[all_faces[i*3+1]]);
	VMOVE(p3, all_verts[all_faces[i*3+2]]);
	onp1.x = p1[0];
	onp1.y = p1[1];
	onp1.z = p1[2];
	onp2.x = p2[0];
	onp2.y = p2[1];
	onp2.z = p2[2];
	onp3.x = p3[0];
	onp3.y = p3[1];
	onp3.z = p3[2];
	ON_Plane fplane(onp1, onp2, onp3);
	int is_hit = bg_isect_tri_ray(origin, dir, p1, p2, p3, &isect);
	VMOVE(hit_pnt, isect);
	// Don't count the point on the ray origin
	if (hit_pnt.DistanceTo(origin_pnt) < 0.0001) is_hit = 0;
	if (is_hit) {
	    // No double-counting
	    for (int j = 0; j < hit_pnts.Count(); j++) {
		if (hit_pnts[j].DistanceTo(hit_pnt) < 0.001) is_hit = 0;
	    }
	    if (is_hit) {
		//bu_log("in hit_cnt%d.s sph %f %f %f 0.1\n", hit_pnts.Count()+1, isect[0], isect[1], isect[2]);
		hit_pnts.Append(hit_pnt);
	    }
	}
    }
    hit_cnt = hit_pnts.Count();
    //bu_log("hit count: %d\n", hit_cnt);
    //bu_log("dotp : %f\n", dotp);

    // Final inside/outside determination
    if (hit_cnt % 2) {
	io_state = (dotp > 0) ? -1 : 1;
    } else {
	io_state = (dotp < 0) ? -1 : 1;
    }

    //bu_log("inside out state: %d\n", io_state);

    bu_free(all_verts, "free top level vertex array");
    bu_free(final_faces, "free face array");
    return io_state;
}
HIDDEN int
_rt_generate_points(int **faces, int *num_faces, point_t **points, int *num_pnts, struct bu_ptbl *hit_pnts, struct db_i *dbip, const char *obj, fastf_t delta)
{
    int i, dir1, j;
    point_t min, max;
    int ncpus = bu_avail_cpus();
    struct rt_parallel_container *state;
    struct bu_vls vlsstr;
    bu_vls_init(&vlsstr);

    if (!hit_pnts || !dbip || !obj) return -1;

    BU_GET(state, struct rt_parallel_container);

    state->rtip = rt_new_rti(dbip);
    state->delta = delta;

    if (rt_gettree(state->rtip, obj) < 0) return -1;
    rt_prep_parallel(state->rtip, 1);

    state->resp = (struct resource *)bu_calloc(ncpus+1, sizeof(struct resource), "resources");
    for (i = 0; i < ncpus+1; i++) {
	rt_init_resource(&(state->resp[i]), i, state->rtip);
    }

    state->npts = (struct rt_point_container *)bu_calloc(ncpus+1, sizeof(struct rt_point_container), "point container arrays");
    int n[3];
    VMOVE(min, state->rtip->mdl_min);
    VMOVE(max, state->rtip->mdl_max);
    for (i = 0; i < 3; i++) {
	n[i] = (int)((max[i] - min[i])/state->delta) + 2;
	if(n[i] < 12) n[i] = 12;
    }
    int total = 0;
    for (i = 0; i < 3; i++) total += n[i]*n[(i+1)%3];
    if (total > 1e6) total = 1e6;
    for (i = 0; i < ncpus+1; i++) {
	state->npts[i].pts = (struct npoints *)bu_calloc(total, sizeof(struct npoints), "npoints arrays");
	state->npts[i].pnt_cnt = 0;
	state->npts[i].capacity = total;
    }

    for (dir1 = 0; dir1 < 3; dir1++) {
	state->ray_dir = dir1;
	state->ncpus = ncpus;
	state->delta = delta;
	bu_parallel(_rt_gen_worker, ncpus, (void *)state);
    }

    int out_cnt = 0;
    for (i = 0; i < ncpus+1; i++) {
	bu_log("%d, pnt_cnt: %d\n", i, state->npts[i].pnt_cnt);
	for (j = 0; j < state->npts[i].pnt_cnt; j++) {
	    struct npoints *npt = &(state->npts[i].pts[j]);
	    if (npt->in.is_set) out_cnt++;
	    if (npt->out.is_set) out_cnt++;
	}
    }

    struct rt_vert **rt_verts = (struct rt_vert **)bu_calloc(out_cnt, sizeof(struct rt_vert *), "output array");
    int curr_ind = 0;
    for (i = 0; i < ncpus+1; i++) {
	for (j = 0; j < state->npts[i].pnt_cnt; j++) {
	    struct npoints *npt = &(state->npts[i].pts[j]);
	    if (npt->in.is_set) {
		rt_verts[curr_ind] = &(npt->in);
		curr_ind++;
	    }
	    if (npt->out.is_set) {
		rt_verts[curr_ind] = &(npt->out);
		curr_ind++;
	    }
	}
    }

    struct spr_options opts = SPR_OPTIONS_DEFAULT_INIT;
    (void)spr_surface_build(faces, num_faces, (double **)points, num_pnts, (const struct cvertex **)rt_verts, out_cnt, &opts);

    return 0;
}
示例#17
0
int
main (int argc, char **argv)
{
    char	buf[BUF_LEN];	/* Contents of current input line */
    char	*bp;		/* Pointer into buf */
    char	*nlp;		/* Location of newline in buf */
    char	rname[BUF_LEN];	/* Name of current region */
    char	rayname[BUF_LEN];	/* Name of ray */
    fastf_t	ray_radius = 1.0;	/* Thickness of the RCC */
    point_t	entryp;		/* Ray's entry into current region */
    point_t	exitp;		/* Ray's exit from current region */
    point_t	first_entryp;	/* Ray's entry into the entire geometry */
    int		i;		/* Index into rname */
    int		line_nm = 0;	/* Number of current line of input */
    int		opt;		/* Command-line option returned by bu_getopt */
    int		pid;		/* Process ID for unique group name */

    extern char *bu_optarg;
    extern int  bu_optind, bu_opterr;

    int         bu_getopt(int, char *const *, const char *);

    pid = bu_process_id();

    *rayname = '\0';
    /* Handle command-line options */
    while ((opt = bu_getopt(argc, argv, OPT_STRING)) != -1)
	switch (opt) {
	    case 'n':
		bu_strlcpy(rayname, bu_optarg, BUF_LEN);
		break;
	    case 'r':
		if (sscanf(bu_optarg, "%F", &ray_radius) != 1) {
		    bu_exit(1, "Illegal radius: '%s'\n", bu_optarg);
		}
		break;
	    case '?':
		print_usage();
	}

    /* Ensure proper command-line syntax */
    if (bu_optind != argc) {
	print_usage();
    }

    /* Construct the names of the objects to add to the database */
    if (*rayname == '\0')	/* Was one given on command line? */
	sprintf(rayname, "ray.%d", pid);

    if (strlen(rayname) > NAMESIZE) {
	fprintf(stderr,
		"Name '%s.s' for ray solid may not exceed %d characters\n",
		rayname, NAMESIZE);
	bu_exit(1, "Use the '-n name' option to specify a different name\n");
    }

    printf("in %s.s sph 0 0 0 1\n", rayname);
    printf("r %s.r u %s.s\n", rayname, rayname);
    printf("mater %s.r\n\n\n%s\n\n", rayname, RAY_COLOR);
    printf("g %s", rayname);

    /* Read the input */
    while (bu_fgets(buf, BUF_LEN, stdin) != NULL) {
	++line_nm;
	bp = buf;
	if ((nlp = index(bp, '\n')) != 0)
	    *nlp = '\0';

	/* Skip initial white space */
	while (isspace(*bp))
	    ++bp;

	/* Get region name */
	for (i = 0; ! isspace(*bp) && (*bp != '\0'); ++i, ++bp)
	    rname[i] = *bp;
	rname[i] = '\0';

	/* Read entry and exit coordinates for this partition */
	if (sscanf(bp, "%F%F%F%F%F%F",
		   &entryp[X], &entryp[Y], &entryp[Z],
		   &exitp[X], &exitp[Y], &exitp[Z]) != 6) {
	    bu_exit(1, "Illegal data on line %d: '%s'\n", line_nm, bp);
	}

	printf(" %s", rname);

	if (line_nm == 1) {
	    VMOVE(first_entryp, entryp);
	}
    }
    if (! feof(stdin)) {
	bu_exit(1, "Error from bu_fgets().  This shouldn't happen");
    }

    printf("\nkill %s.s\nin %s.s rcc\n\t%f %f %f\n\t%f %f %f\n\t%f\n",
	   rayname, rayname,
	   first_entryp[X], first_entryp[Y], first_entryp[Z],
	   exitp[X] - first_entryp[X],
	   exitp[Y] - first_entryp[Y],
	   exitp[Z] - first_entryp[Z],
	   ray_radius);
    printf("g %s %s.r\n", rayname, rayname);
    fprintf(stderr, "Group is '%s'\n", rayname);
}
示例#18
0
int
main(int argc, char **argv)
{
    int c;
    int i;
    struct pshell *psh;
    struct pbar *pb;
    struct wmember head;
    struct wmember all_head;
    char *nastran_file = "Converted from NASTRAN file (stdin)";

    fpin = stdin;

    units = INCHES;

    /* XXX These need to be improved */
    tol.magic = BN_TOL_MAGIC;
    tol.dist = 0.005;
    tol.dist_sq = tol.dist * tol.dist;
    tol.perp = 1e-6;
    tol.para = 1 - tol.perp;

    while ( (c=bu_getopt( argc, argv, "x:X:t:ni:o:m")) != EOF )
    {
	switch ( c )
	{
	    case 'x':
		sscanf( bu_optarg, "%x", (unsigned int *)&rt_g.debug );
		bu_printb( "librt RT_G_DEBUG", RT_G_DEBUG, DEBUG_FORMAT );
		bu_log("\n");
		break;
	    case 'X':
		sscanf( bu_optarg, "%x", (unsigned int *)&rt_g.NMG_debug );
		bu_printb( "librt rt_g.NMG_debug", rt_g.NMG_debug, NMG_DEBUG_FORMAT );
		bu_log("\n");
		break;
	    case 't':		/* calculational tolerance */
		tol.dist = atof( bu_optarg );
		tol.dist_sq = tol.dist * tol.dist;
	    case 'n':
		polysolids = 0;
		break;
	    case 'm':
		units = MM;
		break;
	    case 'i':
		nastran_file = bu_optarg;
		fpin = fopen( bu_optarg, "rb" );
		if ( fpin == (FILE *)NULL )
		{
		    bu_log( "Cannot open NASTRAN file (%s) for reading!\n", bu_optarg );
		    bu_exit(1, Usage, argv[0] );
		}
		break;
	    case 'o':
		output_file = bu_optarg;
		break;
	}
    }

    fpout = wdb_fopen( output_file );
    if ( fpout == NULL )
    {
	bu_log( "Cannot open BRL-CAD file (%s) for writing!\n", output_file );
	bu_exit(1, Usage, argv[0] );
    }

    if ( !fpin || !fpout )
    {
	bu_exit(1, Usage, argv[0] );
    }

    line = (char *)bu_malloc( MAX_LINE_SIZE, "line" );
    next_line = (char *)bu_malloc( MAX_LINE_SIZE, "next_line" );
    prev_line = (char *)bu_malloc( MAX_LINE_SIZE, "prev_line" );
    curr_rec = (char **)bu_calloc( NO_OF_FIELDS, sizeof( char *), "curr_rec" );
    for ( i=0; i<NO_OF_FIELDS; i++ )
	curr_rec[i] = (char *)bu_malloc( sizeof( char )*FIELD_LENGTH, "curr_rec[i]" );
    prev_rec = (char **)bu_calloc( NO_OF_FIELDS, sizeof( char *), "prev_rec" );
    for ( i=0; i<NO_OF_FIELDS; i++ )
	prev_rec[i] = (char *)bu_malloc( sizeof( char )*FIELD_LENGTH, "prev_rec[i]" );

    /* first pass, find start of NASTRAN "bulk data" */
    start_off = (-1);
    bulk_data_start_line = 0;
    while ( bu_fgets( line, MAX_LINE_SIZE, fpin ) )
    {
	bulk_data_start_line++;
	if ( strncmp( line, "BEGIN BULK", 10 ) )
	    continue;

	start_off = ftell( fpin );
	break;
    }

    if ( start_off < 0 )
    {
	bu_log( "Cannot find start of bulk data in NASTRAN file!\n" );
	bu_exit(1, Usage, argv[0] );
    }

    /* convert BULK data deck into something reasonable */
    fptmp = bu_temp_file(NULL, 0);
    if ( fptmp == NULL )
    {
	perror( argv[0] );
	bu_exit(1, "Cannot open temporary file\n" );
    }
    convert_input();

    /* initialize some lists */
    BU_LIST_INIT( &coord_head.l );
    BU_LIST_INIT( &pbar_head.l );
    BU_LIST_INIT( &pshell_head.l );
    BU_LIST_INIT( &all_head.l );

    nmg_model = (struct model *)NULL;

    /* count grid points */
    fseek( fptmp, 0, SEEK_SET );
    while ( bu_fgets( line, MAX_LINE_SIZE, fptmp  ) )
    {
	if ( !strncmp( line, "GRID", 4 ) )
	    grid_count++;
    }
    if ( !grid_count )
    {
	bu_exit(1, "No geometry in this NASTRAN file!\n" );
    }

    /* get default values and properties */
    fseek( fptmp, 0, SEEK_SET );
    while ( get_next_record( fptmp, 1, 0 ) )
    {
	if ( !strncmp( curr_rec[0], "BAROR", 5 ) )
	{
	    /* get BAR defaults */
	    bar_def_pid = atoi( curr_rec[2] );
	}
	else if ( !strncmp( curr_rec[0], "PBAR", 4 ) )
	{
	    struct pbar *pb;

	    BU_GETSTRUCT( pb, pbar );

	    pb->pid = atoi( curr_rec[1] );
	    pb->mid = atoi( curr_rec[2] );
	    pb->area = atof( curr_rec[3] );

	    BU_LIST_INIT( &pb->head.l );

	    BU_LIST_INSERT( &pbar_head.l, &pb->l );
	}
	else if ( !strncmp( curr_rec[0], "PSHELL", 6 ) )
	{
	    BU_GETSTRUCT( psh, pshell );

	    psh->s = (struct shell *)NULL;
	    psh->pid = atoi( curr_rec[1] );
	    psh->mid = atoi( curr_rec[2] );
	    psh->thick = atof( curr_rec[3] );
	    BU_LIST_INSERT( &pshell_head.l, &psh->l );
	    pshell_count++;
	}
    }

    /* allocate storage for grid points */
    g_pts = (struct grid_point *)bu_calloc( grid_count, sizeof( struct grid_point ), "grid points" );

    /* get all grid points */
    fseek( fptmp, 0, SEEK_SET );
    while ( get_next_record( fptmp, 1, 0 ) )
    {
	int gid;
	int cid;
	double tmp[3];

	if ( strncmp( curr_rec[0], "GRID", 4 ) )
	    continue;

	gid = atoi( curr_rec[1] );
	cid = atoi( curr_rec[2] );

	for ( i=0; i<3; i++ )
	{
	    tmp[i] = atof( curr_rec[i+3] );
	}

	g_pts[grid_used].gid = gid;
	g_pts[grid_used].cid = cid;
	g_pts[grid_used].v = (struct vertex **)bu_calloc( pshell_count + 1, sizeof( struct vertex *), "g_pts vertex array" );;
	VMOVE( g_pts[grid_used].pt, tmp );
	grid_used++;
    }


    /* find coordinate systems */
    fseek( fptmp, 0, SEEK_SET );
    while ( get_next_record( fptmp, 1, 0 ) )
    {
	if ( strncmp( curr_rec[0], "CORD", 4 ) )
	    continue;

	get_coord_sys();
    }
#if 0
    bu_log( "Original grid:\n" );
    for ( i=0; i<grid_used; i++ )
    {
	bu_log( "Grid point: gid=%d, cid=%d, (%g %g %g)\n", g_pts[i].gid,
		g_pts[i].cid, V3ARGS( g_pts[i].pt ) );
    }

    bu_log( "\nOriginal coordinate systems:\n" );
    for ( BU_LIST_FOR( cs, coord_sys, &coord_head.l ) )
    {
	bu_log( "cid=%d, type=%c, rid=%d\n", cs->cid, cs->type, cs->rid );
	bu_log( "\torigin=(%g %g %g)\n", V3ARGS( cs->origin ) );
	bu_log( "\tv1=(%g %g %g)\n", V3ARGS( cs->v1 ) );
	bu_log( "\tv2=(%g %g %g)\n", V3ARGS( cs->v2 ) );
	bu_log( "\tv3=(%g %g %g)\n", V3ARGS( cs->v3 ) );
    }
#endif
    /* convert everything to BRL-CAD coordinate system */
    i = 0;
    while ( convert_all_cs() || convert_all_pts() )
    {
	i++;
	if ( i > 10 )
	{
	    bu_exit(1, "Cannot convert to default coordinate system, check for circular definition\n" );
	}
    }

#if 0
    bu_log( "Converted grid:\n" );
    for ( i=0; i<grid_used; i++ )
    {
	bu_log( "Grid point: gid=%d, cid=%d, (%g %g %g)\n", g_pts[i].gid,
		g_pts[i].cid, V3ARGS( g_pts[i].pt ) );
    }

    bu_log( "\nConverted coordinate systems:\n" );
    for ( BU_LIST_FOR( cs, coord_sys, &coord_head.l ) )
    {
	bu_log( "cid=%d, type=%c, rid=%d\n", cs->cid, cs->type, cs->rid );
	bu_log( "\torigin=(%g %g %g)\n", V3ARGS( cs->origin ) );
	bu_log( "\tv1=(%g %g %g)\n", V3ARGS( cs->v1 ) );
	bu_log( "\tv2=(%g %g %g)\n", V3ARGS( cs->v2 ) );
	bu_log( "\tv3=(%g %g %g)\n", V3ARGS( cs->v3 ) );
    }
#endif

    mk_id( fpout, nastran_file );

    /* get elements */
    fseek( fptmp, 0, SEEK_SET );
    while ( get_next_record( fptmp, 1, 0 ) )
    {
	if ( !strncmp( curr_rec[0], "CBAR", 4 ) )
	    get_cbar();
	else if ( !strncmp( curr_rec[0], "CROD", 4 ) )
	    get_cbar();
	else if ( !strncmp( curr_rec[0], "CTRIA3", 6 ) )
	    get_ctria3();
	else if ( !strncmp( curr_rec[0], "CQUAD4", 6 ) )
	    get_cquad4();
    }

    if ( nmg_model )
    {
	nmg_rebound( nmg_model, &tol );
	if ( polysolids )
	    mk_bot_from_nmg( fpout, "pshell.0", nmg_shell );
	else
	    mk_nmg( fpout, "pshell.0", nmg_model );
    }

    BU_LIST_INIT( &head.l );
    for ( BU_LIST_FOR( psh, pshell, &pshell_head.l ) )
    {
	struct model *m;
	char name[NAMESIZE+1];

	if ( !psh->s )
	    continue;

	m = nmg_find_model( &psh->s->l.magic );
	nmg_rebound( m, &tol );
	nmg_fix_normals( psh->s, &tol );
	if ( psh->thick > tol.dist )
	{
	    nmg_model_face_fuse( m, &tol );
	    nmg_hollow_shell( psh->s, psh->thick*conv[units], 1, &tol );
	}
	sprintf( name, "pshell.%d", psh->pid );
	if ( polysolids )
	    mk_bot_from_nmg( fpout, name, psh->s );
	else
	    mk_nmg( fpout, name, m );

	mk_addmember( name, &head.l, NULL, WMOP_UNION );
    }
    if ( BU_LIST_NON_EMPTY( &head.l ) )
    {
	mk_lfcomb( fpout, "shells", &head, 0 );
	mk_addmember( "shells", &all_head.l, NULL, WMOP_UNION );
    }

    BU_LIST_INIT( &head.l );
    for ( BU_LIST_FOR( pb, pbar, &pbar_head.l ) )
    {
	char name[NAMESIZE+1];

	if ( BU_LIST_IS_EMPTY( &pb->head.l ) )
	    continue;

	sprintf( name, "pbar_group.%d", pb->pid );
	mk_lfcomb( fpout, name, &pb->head, 0 );

	mk_addmember( name, &head.l, NULL, WMOP_UNION );
    }
    if ( BU_LIST_NON_EMPTY( &head.l ) )
    {
	mk_lfcomb( fpout, "pbars", &head, 0 );
	mk_addmember( "pbars", &all_head.l, NULL, WMOP_UNION );
    }

    if ( BU_LIST_NON_EMPTY( &all_head.l ) )
    {
	mk_lfcomb( fpout, "all", &all_head, 0 );
    }
    wdb_close(fpout);
    return 0;
}
示例#19
0
文件: mirror.c 项目: kanzure/brlcad
int
ged_mirror(struct ged *gedp, int argc, const char *argv[])
{
    /* trailing x|y|z intentionally not documented */
    static const char *usage = "[-h] [-p \"point\"] [-d \"dir\"] [-x|-y|-z] [-o offset] old new";

    int k;

    point_t mirror_pt = {0.0, 0.0, 0.0};
    vect_t mirror_dir = {1.0, 0.0, 0.0};

    /* intentionally double for scanning */
    double scanpt[3];
    double scandir[3];
    double mirror_offset = 0.0;

    int ret;
    struct rt_db_internal *ip;
    struct rt_db_internal internal;
    struct directory *dp;

    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;
    }

    bu_optind = 1;
    while ((k = bu_getopt(argc, (char * const *)argv, (const char *)"d:D:hHo:O:p:P:xXyYzZ")) != -1) {
	switch (k) {
	    case 'p':
	    case 'P':
		if (sscanf(bu_optarg, "%lf %lf %lf",
			   &scanpt[X],
			   &scanpt[Y],
			   &scanpt[Z]) != 3) {
		    bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
		    return GED_ERROR;
		}

		/* convert from double to fastf_t */
		VMOVE(mirror_pt, scanpt);

		break;
	    case 'd':
	    case 'D':
		if (sscanf(bu_optarg, "%lf %lf %lf",
			   &scandir[X],
			   &scandir[Y],
			   &scandir[Z]) != 3) {
		    bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
		    return GED_ERROR;
		}

		/* convert from double to fastf_t */
		VMOVE(mirror_dir, scandir);

		break;
	    case 'o':
	    case 'O':
		if (sscanf(bu_optarg, "%lf", &mirror_offset) != 1) {
		    bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
		    return GED_ERROR;
		}
		break;
	    case 'x':
	    case 'X':
		VSET(mirror_dir, 1.0, 0.0, 0.0);
		break;
	    case 'y':
	    case 'Y':
		VSET(mirror_dir, 0.0, 1.0, 0.0);
		break;
	    case 'z':
	    case 'Z':
		VSET(mirror_dir, 0.0, 0.0, 1.0);
		break;
	    case 'h':
	    case 'H':
		bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
		return GED_HELP;
	    default:
		bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
		return GED_ERROR;
		break;
	}
    }

    argc -= bu_optind;

    if (argc < 2 || argc > 4) {
	bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
	return GED_ERROR;
    } else if (argc == 3) {
	/* support a trailing x|y|z option as classic command
	 * behavior.  THIS IS INTENTIONALLY UNDOCUMENTED.  if users
	 * have to read the usage, they can learn the new form.
	 */
	switch (argv[bu_optind+2][0]) {
	    case 'x':
	    case 'X':
		VSET(mirror_dir, 1.0, 0.0, 0.0);
		break;
	    case 'y':
	    case 'Y':
		VSET(mirror_dir, 0.0, 1.0, 0.0);
		break;
	    case 'z':
	    case 'Z':
		VSET(mirror_dir, 0.0, 0.0, 1.0);
		break;
	    default:
		bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
		return GED_ERROR;
		break;
	}
    }

    /* make sure object mirroring to does not already exist */
    if (db_lookup(gedp->ged_wdbp->dbip, argv[bu_optind+1], LOOKUP_QUIET) != RT_DIR_NULL) {
	bu_vls_printf(gedp->ged_result_str, "%s already exists\n", argv[bu_optind+1]);
	return GED_ERROR;
    }

    /* look up the object being mirrored */
    if ((dp = db_lookup(gedp->ged_wdbp->dbip, argv[bu_optind], LOOKUP_NOISY)) == RT_DIR_NULL) {
	bu_vls_printf(gedp->ged_result_str, "Unable to find solid [%s]\n", argv[bu_optind]);
	return GED_ERROR;
    }

    /* get object being mirrored */
    ret = rt_db_get_internal(&internal, dp, gedp->ged_wdbp->dbip, NULL, gedp->ged_wdbp->wdb_resp);
    if (ret < 0) {
	bu_vls_printf(gedp->ged_result_str, "Unable to load solid [%s]\n", argv[bu_optind]);
	return GED_ERROR;
    }

    mirror_offset *= gedp->ged_wdbp->dbip->dbi_local2base;
    VUNITIZE(mirror_dir);
    VJOIN1(mirror_pt, mirror_pt, mirror_offset, mirror_dir);

    /* mirror the object */
    ip = rt_mirror(gedp->ged_wdbp->dbip,
		   &internal,
		   mirror_pt,
		   mirror_dir,
		   gedp->ged_wdbp->wdb_resp);
    if (ip == NULL) {
	bu_vls_printf(gedp->ged_result_str, "Unable to mirror [%s]", argv[bu_optind]);
	return GED_ERROR;
    }

    /* add the mirrored object to the directory */
    dp = db_diradd(gedp->ged_wdbp->dbip, argv[bu_optind+1], RT_DIR_PHONY_ADDR, 0, dp->d_flags, (void *)&ip->idb_type);
    if (dp == RT_DIR_NULL) {
	bu_vls_printf(gedp->ged_result_str, "Unable to add [%s] to the database directory", argv[bu_optind+1]);
	return GED_ERROR;
    }
    /* save the mirrored object to disk */
    if (rt_db_put_internal(dp, gedp->ged_wdbp->dbip, ip, gedp->ged_wdbp->wdb_resp) < 0) {
	bu_vls_printf(gedp->ged_result_str, "Unable to store [%s] to the database", argv[bu_optind+1]);
	return GED_ERROR;
    }

    {
	/* draw the new object */
	const char *object = (const char *)argv[bu_optind+1];
	const char *e_argv[3] = {0, 0, 0};

	e_argv[0] = "draw";
	e_argv[1] = object;
	e_argv[2] = NULL;

	(void)ged_draw(gedp, 2, e_argv);
	ged_view_update(gedp->ged_gvp);
    }

    return GED_OK;
}
示例#20
0
HIDDEN void
get_coord_sys(void)
{
    int form;
    char type;
    char *ptr;
    struct coord_sys *cs;
    int i, gid;
    double tmp[3];
    point_t tmp_pt;

    form = atoi( &curr_rec[0][4] );
    if ( form != 1 && form != 2 )
    {
	bu_log( "unrecognized form for coordinate system definition (%d):\n", form );
	bu_log( "%s\n", line );
	return;
    }
    type = curr_rec[0][5];

    if ( type != CORD_CYL && type != CORD_RECT && type != CORD_SPH )
    {
	bu_log( "unrecognized coordinate system type (%c):\n", type );
	bu_log( "%s\n", line );
	return;
    }

    ptr = strtok( line, delims );
    ptr = strtok( (char *)NULL, delims );
    if ( !ptr )
    {
	log_line( "Incomplete coordinate system definition" );
	return;
    }

    BU_GETSTRUCT( cs, coord_sys );

    switch ( form )
    {
	case 1:
	    cs->type = type;
	    cs->cid = atoi( curr_rec[1] );
	    gid = atoi( curr_rec[2] );
	    get_grid( gid, cs->origin );
	    gid = atoi( curr_rec[3] );
	    get_grid( gid, tmp_pt );
	    VSUB2( cs->v3, tmp_pt, cs->origin );
	    VUNITIZE( cs->v3 );
	    gid = atoi( curr_rec[4] );
	    get_grid( gid, tmp_pt );
	    VSUB2( cs->v1, tmp_pt, cs->origin );
	    VCROSS( cs->v2, cs->v3, cs->v1 );
	    VUNITIZE( cs->v2 );
	    VCROSS( cs->v1, cs->v2, cs->v3 );
	    BU_LIST_INSERT( &coord_head.l, &cs->l );

	    if ( !strlen( curr_rec[5] ) )
		break;

	    BU_GETSTRUCT( cs, coord_sys );
	    cs->type = type;
	    cs->cid = atoi( curr_rec[5] );
	    gid = atoi( curr_rec[6] );
	    get_grid( gid, cs->origin );
	    gid = atoi( curr_rec[7] );
	    get_grid( gid, tmp_pt );
	    VSUB2( cs->v3, tmp_pt, cs->origin );
	    VUNITIZE( cs->v3 );
	    gid = atoi( curr_rec[8] );
	    get_grid( gid, tmp_pt );
	    VSUB2( cs->v1, tmp_pt, cs->origin );
	    VCROSS( cs->v2, cs->v3, cs->v1 );
	    VUNITIZE( cs->v2 );
	    VCROSS( cs->v1, cs->v2, cs->v3 );
	    BU_LIST_INSERT( &coord_head.l, &cs->l );

	    break;
	case 2:
	    cs->type = type;
	    cs->cid = atoi( curr_rec[1] );
	    cs->rid = atoi( curr_rec[2] );
	    for ( i=0; i<3; i++ )
		tmp[i] = atof( curr_rec[3+i] );
	    VMOVE( cs->origin, tmp );
	    for ( i=0; i<3; i++ )
		tmp[i] = atof( curr_rec[6+i] );
	    VMOVE( cs->v1, tmp );
	    for ( i=0; i<3; i++ )
		tmp[i] = atof( curr_rec[9+i] );
	    VMOVE( cs->v2, tmp );

	    if ( !cs->rid )
	    {
		point_t tmp_pt1, tmp_pt2;

		/* this coordinate system is defined in terms of the default */
		VMOVE( tmp_pt1, cs->v1 );
		VMOVE( tmp_pt2, cs->v2 );

		VSUB2( cs->v3, tmp_pt1, cs->origin );
		VUNITIZE( cs->v3 );
		VSUB2( cs->v1, tmp_pt2, cs->origin );
		VCROSS( cs->v2, cs->v3, cs->v1 );
		VUNITIZE( cs->v2 );
		VCROSS( cs->v1, cs->v3, cs->v2 );
	    }

	    BU_LIST_INSERT( &coord_head.l, &cs->l );
	    break;
    }
}
示例#21
0
void
bn_mat_fromto(
    mat_t m,
    const fastf_t *from,
    const fastf_t *to,
    const struct bn_tol *tol)
{
    vect_t test_to;
    vect_t unit_from, unit_to;
    fastf_t dot;
    point_t origin = VINIT_ZERO;

    /**
     * The method used here is from Graphics Gems, A. Glassner, ed.
     * page 531, "The Use of Coordinate Frames in Computer Graphics",
     * by Ken Turkowski, Example 6.
     */
    mat_t Q, Qt;
    mat_t R;
    mat_t A;
    mat_t temp;
    vect_t N, M;
    vect_t w_prime;		/* image of "to" ("w") in Qt */

    VMOVE(unit_from, from);
    VUNITIZE(unit_from);		/* aka "v" */
    VMOVE(unit_to, to);
    VUNITIZE(unit_to);		/* aka "w" */

    /* If from and to are the same or opposite, special handling is
     * needed, because the cross product isn't defined.  asin(0.00001)
     * = 0.0005729 degrees (1/2000 degree)
     */
    if (bn_lseg3_lseg3_parallel(origin, from, origin, to, tol)) {
	dot = VDOT(from, to);
	if (dot > SMALL_FASTF) {
	    MAT_IDN(m);
	    return;
	} else {
	    bn_vec_perp(N, unit_from);
	}
    } else {
	VCROSS(N, unit_from, unit_to);
	VUNITIZE(N);			/* should be unnecessary */
    }
    VCROSS(M, N, unit_from);
    VUNITIZE(M);			/* should be unnecessary */

    /* Almost everything here is done with pre-multiplys:  vector * mat */
    MAT_IDN(Q);
    VMOVE(&Q[0], unit_from);
    VMOVE(&Q[4], M);
    VMOVE(&Q[8], N);
    bn_mat_trn(Qt, Q);

    /* w_prime = w * Qt */
    MAT4X3VEC(w_prime, Q, unit_to);	/* post-multiply by transpose */

    MAT_IDN(R);
    VMOVE(&R[0], w_prime);
    VSET(&R[4], -w_prime[Y], w_prime[X], w_prime[Z]);
    VSET(&R[8], 0, 0, 1);		/* is unnecessary */

    bn_mat_mul(temp, R, Q);
    bn_mat_mul(A, Qt, temp);
    bn_mat_trn(m, A);		/* back to post-multiply style */

    /* Verify that it worked */
    MAT4X3VEC(test_to, m, unit_from);
    if (UNLIKELY(!bn_lseg3_lseg3_parallel(origin, unit_to, origin, test_to, tol))) {
	dot = VDOT(unit_to, test_to);
	bu_log("bn_mat_fromto() ERROR!  from (%g, %g, %g) to (%g, %g, %g) went to (%g, %g, %g), dot=%g?\n",
	       V3ARGS(from), V3ARGS(to), V3ARGS(test_to), dot);
    }
}
示例#22
0
文件: dm-plot.c 项目: cciechad/brlcad
/*
 *  			P L O T _ O B J E C T
 *
 *  Set up for an object, transformed as indicated, and with an
 *  object center as specified.  The ratio of object to screen size
 *  is passed in as a convienience.
 *
 *  Returns 0 if object could be drawn, !0 if object was omitted.
 */
static int
plot_drawVList(struct dm *dmp, register struct bn_vlist *vp)
{
    static vect_t			last;
    register struct bn_vlist	*tvp;
    register point_t		*pt_prev=NULL;
    register fastf_t		dist_prev=1.0;
    register fastf_t		dist;
    fastf_t				delta;
    int				useful = 0;

    if (((struct plot_vars *)dmp->dm_vars.priv_vars)->floating) {
	rt_vlist_to_uplot(((struct plot_vars *)dmp->dm_vars.priv_vars)->up_fp, &vp->l);

	return TCL_OK;
    }

    /* delta is used in clipping to insure clipped endpoint is slightly
     * in front of eye plane (perspective mode only).
     * This value is a SWAG that seems to work OK.
     */
    delta = plotmat[15]*0.0001;
    if (delta < 0.0)
	delta = -delta;
    if (delta < SQRT_SMALL_FASTF)
	delta = SQRT_SMALL_FASTF;

    for (BU_LIST_FOR(tvp, bn_vlist, &vp->l)) {
	register int	i;
	register int	nused = tvp->nused;
	register int	*cmd = tvp->cmd;
	register point_t *pt = tvp->pt;
	for (i = 0; i < nused; i++, cmd++, pt++) {
	    static vect_t	start, fin;
	    switch (*cmd) {
		case BN_VLIST_POLY_START:
		case BN_VLIST_POLY_VERTNORM:
		    continue;
		case BN_VLIST_POLY_MOVE:
		case BN_VLIST_LINE_MOVE:
		    /* Move, not draw */
		    if (dmp->dm_perspective > 0) {
			/* cannot apply perspective transformation to
			 * points behind eye plane!!!!
			 */
			dist = VDOT( *pt, &plotmat[12] ) + plotmat[15];
			if (dist <= 0.0) {
			    pt_prev = pt;
			    dist_prev = dist;
			    continue;
			} else {
			    MAT4X3PNT(last, plotmat, *pt);
			    dist_prev = dist;
			    pt_prev = pt;
			}
		    } else
			MAT4X3PNT(last, plotmat, *pt);
		    continue;
		case BN_VLIST_POLY_DRAW:
		case BN_VLIST_POLY_END:
		case BN_VLIST_LINE_DRAW:
		    /* draw */
		    if (dmp->dm_perspective > 0) {
			/* cannot apply perspective transformation to
			 * points behind eye plane!!!!
			 */
			dist = VDOT( *pt, &plotmat[12] ) + plotmat[15];
			if (dist <= 0.0) {
			    if (dist_prev <= 0.0) {
				/* nothing to plot */
				dist_prev = dist;
				pt_prev = pt;
				continue;
			    } else {
				fastf_t alpha;
				vect_t diff;
				point_t tmp_pt;

				/* clip this end */
				VSUB2( diff, *pt, *pt_prev );
				alpha = (dist_prev - delta) / (dist_prev - dist);
				VJOIN1(tmp_pt, *pt_prev, alpha, diff);
				MAT4X3PNT(fin, plotmat, tmp_pt);
			    }
			} else {
			    if (dist_prev <= 0.0) {
				fastf_t alpha;
				vect_t diff;
				point_t tmp_pt;

				/* clip other end */
				VSUB2( diff, *pt, *pt_prev );
				alpha = (-dist_prev + delta) / ( dist - dist_prev );
				VJOIN1( tmp_pt, *pt_prev, alpha, diff );
				MAT4X3PNT( last, plotmat, tmp_pt );
				MAT4X3PNT( fin, plotmat, *pt );
			    } else {
				MAT4X3PNT( fin, plotmat, *pt );
			    }
			}
		    } else
			MAT4X3PNT( fin, plotmat, *pt );
		    VMOVE( start, last );
		    VMOVE( last, fin );
		    break;
	    }
	    if (vclip(start, fin, dmp->dm_clipmin, dmp->dm_clipmax) == 0)
		continue;

	    if (((struct plot_vars *)dmp->dm_vars.priv_vars)->is_3D)
		pl_3line(((struct plot_vars *)dmp->dm_vars.priv_vars)->up_fp,
			 (int)(start[X] * 2047),
			 (int)(start[Y] * 2047),
			 (int)(start[Z] * 2047),
			 (int)(fin[X] * 2047),
			 (int)(fin[Y] * 2047),
			 (int)(fin[Z] * 2047));
	    else
		pl_line(((struct plot_vars *)dmp->dm_vars.priv_vars)->up_fp,
			(int)(start[X] * 2047),
			(int)(start[Y] * 2047),
			(int)(fin[X] * 2047),
			(int)(fin[Y] * 2047));

	    useful = 1;
	}
    }

    if (useful)
	return TCL_OK;

    return TCL_ERROR;
}
示例#23
0
文件: arbn.c 项目: kanzure/brlcad
/**
 * Brute force through all possible plane intersections.
 * Generate all edge lines, then intersect the line with all
 * the other faces to find the vertices on that line.
 * If the geometry is correct, there will be no more than two.
 * While not the fastest strategy, this will produce an accurate
 * plot without requiring extra bookkeeping.
 * Note that the vectors will be drawn in no special order.
 */
int
rt_arbn_plot(struct bu_list *vhead, struct rt_db_internal *ip, const struct rt_tess_tol *UNUSED(ttol), const struct bn_tol *tol, const struct rt_view_info *UNUSED(info))
{
    struct rt_arbn_internal *aip;
    size_t i;
    size_t j;
    size_t k;

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

    for (i = 0; i < aip->neqn - 1; i++) {
	for (j = i + 1; j < aip->neqn; j++) {
	    double dot;
	    int point_count;	/* # points on this line */
	    point_t a, b;		/* start and end points */
	    vect_t dist;

	    VSETALL(a, 0);
	    VSETALL(b, 0);

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

	    /* Have an edge line, isect with all other planes */
	    point_count = 0;
	    for (k = 0; k < aip->neqn; k++) {
		size_t m;
		point_t pt;
		size_t next_k;

		next_k = 0;

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

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

		if (next_k != 0) continue;

		if (point_count <= 0) {
		    RT_ADD_VLIST(vhead, pt, BN_VLIST_LINE_MOVE);
		    VMOVE(a, pt);
		} else if (point_count == 1) {
		    VSUB2(dist, pt, a);
		    if (MAGSQ(dist) < tol->dist_sq) continue;
		    RT_ADD_VLIST(vhead, pt, BN_VLIST_LINE_DRAW);
		    VMOVE(b, pt);
		} else {
		    VSUB2(dist, pt, a);
		    if (MAGSQ(dist) < tol->dist_sq) continue;
		    VSUB2(dist, pt, b);
		    if (MAGSQ(dist) < tol->dist_sq) continue;
		    bu_log("rt_arbn_plot() error, point_count=%d (>2) on edge %zu/%zu, non-convex\n",
			   point_count+1,
			   i, j);
		    VPRINT(" a", a);
		    VPRINT(" b", b);
		    VPRINT("pt", pt);
		    RT_ADD_VLIST(vhead, pt, BN_VLIST_LINE_DRAW);	/* draw it */
		}
		point_count++;
	    }
	    /* Point counts of 1 are (generally) not harmful,
	     * occurring on pyramid peaks and the like.
	     */
	}
    }
    return 0;
}
示例#24
0
static int
radhit(register struct application *ap, struct partition *PartHeadp, struct seg *segHeadp)
{
    register struct partition *pp;
    register struct hit *hitp;
    struct application sub_ap;
    fastf_t	f;
    vect_t	to_eye, work;
    int	depth;

    for ( pp=PartHeadp->pt_forw; pp != PartHeadp; pp = pp->pt_forw )
	if ( pp->pt_outhit->hit_dist >= 0.0 )  break;
    if ( pp == PartHeadp )  {
	bu_log("radhit:  no hit out front?\n");
	return(0);
    }

    if (R_DEBUG&RDEBUG_HITS)  {
	rt_pr_pt( ap->a_rt_i, pp );
    }

    hitp = pp->pt_inhit;
    if ( hitp->hit_dist >= INFINITY )  {
	bu_log("radhit:  entry beyond infinity\n");
	return(1);
    }
    /* Check to see if eye is "inside" the solid */
    if ( hitp->hit_dist < 0 )  {
	/* XXX */
	bu_log("radhit:  GAK, eye inside solid (%g)\n", hitp->hit_dist );
	for ( pp=PartHeadp->pt_forw; pp != PartHeadp; pp = pp->pt_forw )
	    rt_pr_pt( ap->a_rt_i, pp );
	return(0);
    }

    rayp = &rayinfo[ ap->a_level ];

    RT_HIT_NORMAL( rayp->norm, hitp, pp->pt_inseg->seg_stp, &(ap->a_ray), pp->pt_inflip );

    if (R_DEBUG&RDEBUG_HITS)  {
	rt_pr_hit( " In", hitp );
    }

    rayp->dist = hitp->hit_dist;
    rayp->reg = pp->pt_regionp->reg_regionid;
    rayp->sol = pp->pt_inseg->seg_stp->st_id;
    rayp->surf = hitp->hit_surfno;
    RT_CURVATURE( &(rayp->curvature), hitp, pp->pt_inflip, pp->pt_inseg->seg_stp );
    if ( VDOT( rayp->norm, ap->a_ray.r_dir ) < 0 ) {
	bu_log(" debug: flipping curvature\n");
	rayp->curvature.crv_c1 = - rayp->curvature.crv_c1;
	rayp->curvature.crv_c2 = - rayp->curvature.crv_c2;
    }
    VMOVE( rayp->ip, hitp->hit_point );

    /* Compute the specular direction */
    VREVERSE( to_eye, ap->a_ray.r_dir );
    f = 2 * VDOT( to_eye, rayp->norm );
    VSCALE( work, rayp->norm, f );
    /* I have been told this has unit length */
    VSUB2( rayp->spec, work, to_eye );

    /* Save info for 1st ray */
    if ( ap->a_level == 0 ) {
	firstray = ap->a_ray;	/* struct copy */
	rayp->sight = 1;	/* the 1st intersect is always visible */
    } else {
	/* Check for visibility */
	rayp->sight = isvisible( ap, hitp, rayp->norm );
    }

    /*
     * Shoot another ray in the specular direction.
     */
    if ( ap->a_level < numreflect-1 ) {
	sub_ap = *ap;	/* struct copy */
	sub_ap.a_level = ap->a_level+1;
	VMOVE( sub_ap.a_ray.r_pt, hitp->hit_point );
	VMOVE( sub_ap.a_ray.r_dir, rayp->spec );
	depth = rt_shootray( &sub_ap );
    } else {
	bu_log( "radhit:  max reflections exceeded [%d %d]\n",
		ap->a_x, ap->a_y );
	depth = 0;
    }

    if ( ap->a_level == 0 ) {
	/* We're the 1st ray, output the raylist */
	dumpall( ap, depth+1 );
    }
    return(depth+1);	/* report hit to main routine */
}
示例#25
0
文件: arbn.c 项目: kanzure/brlcad
/**
 * Convert from "network" doubles to machine specific.
 * Transform
 */
int
rt_arbn_import5(struct rt_db_internal *ip, const struct bu_external *ep, const fastf_t *mat, const struct db_i *dbip)
{
    struct rt_arbn_internal *aip;
    size_t i;
    unsigned long neqn;
    int double_count;
    size_t byte_count;

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

    RT_CK_DB_INTERNAL(ip);
    BU_CK_EXTERNAL(ep);
    if (dbip) RT_CK_DBI(dbip);

    neqn = ntohl(*(uint32_t *)ep->ext_buf);
    double_count = neqn * ELEMENTS_PER_PLANE;
    byte_count = double_count * SIZEOF_NETWORK_DOUBLE;

    BU_ASSERT_LONG(ep->ext_nbytes, ==, 4+ byte_count);

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

    aip = (struct rt_arbn_internal *)ip->idb_ptr;
    aip->magic = RT_ARBN_INTERNAL_MAGIC;
    aip->neqn = neqn;
    if (aip->neqn <= 0) return -1;

    eqn = (double *)bu_malloc(byte_count, "arbn plane eqn[] temp buf");
    bu_cv_ntohd((unsigned char *)eqn, (unsigned char *)ep->ext_buf + ELEMENTS_PER_PLANE, double_count);
    aip->eqn = (plane_t *)bu_malloc(double_count * sizeof(fastf_t), "arbn plane eqn[]");
    for (i = 0; i < aip->neqn; i++) {
	HMOVE(aip->eqn[i], &eqn[i*ELEMENTS_PER_PLANE]);
    }
    bu_free(eqn, "arbn plane eqn[] temp buf");

    /* Transform by the matrix, if we have one that is not the identity */
    if (mat && !bn_mat_is_identity(mat)) {
	for (i = 0; i < aip->neqn; i++) {
	    point_t orig_pt;
	    point_t pt;
	    vect_t norm;
	    fastf_t factor;

	    /* unitize the plane equation first */
	    factor = 1.0 / MAGNITUDE(aip->eqn[i]);
	    VSCALE(aip->eqn[i], aip->eqn[i], factor);
	    aip->eqn[i][W] = aip->eqn[i][W] * factor;

	    /* Pick a point on the original halfspace */
	    VSCALE(orig_pt, aip->eqn[i], aip->eqn[i][W]);

	    /* Transform the point, and the normal */
	    MAT4X3VEC(norm, mat, aip->eqn[i]);
	    MAT4X3PNT(pt, mat, orig_pt);

	    /* Measure new distance from origin to new point */
	    VUNITIZE(norm);
	    VMOVE(aip->eqn[i], norm);
	    aip->eqn[i][W] = VDOT(pt, norm);
	}
    }

    return 0;
}
示例#26
0
void do_pixel(int cpu,
	      int pat_num,
	      int pixelnum)
{
    int i;
    struct	application	a;
    struct	pixel_ext	pe;
    vect_t			stereo_point;		/* Ref point on eye or view plane */
    vect_t			point;		/* Ref point on eye or view plane */
    vect_t			colorsum = {(fastf_t)0.0, (fastf_t)0.0, (fastf_t)0.0};
    int				samplenum = 0;
    static const double one_over_255 = 1.0 / 255.0;
    register RGBpixel		pixel = {0, 0, 0};
    const int pindex = (pixelnum * sizeof(RGBpixel));

    /* Obtain fresh copy of global application struct */
    a = ap;				/* struct copy */
    a.a_resource = &resource[cpu];

    if ( incr_mode )  {
	register int i = 1<<incr_level;
	a.a_y = pixelnum/i;
	a.a_x = pixelnum - (a.a_y * i);
	/*	a.a_x = pixelnum%i; */
	if ( incr_level != 0 )  {
	    /* See if already done last pass */
	    if ( ((a.a_x & 1) == 0 ) &&
		 ((a.a_y & 1) == 0 ) )
		return;
	}
	a.a_x <<= (incr_nlevel-incr_level);
	a.a_y <<= (incr_nlevel-incr_level);
    } else {
	a.a_y = pixelnum/width;
	a.a_x = pixelnum - (a.a_y * width);
	/*	a.a_x = pixelnum%width; */
    }

    if (Query_one_pixel) {
	if (a.a_x == query_x && a.a_y == query_y) {
	    rdebug = query_rdebug;
	    rt_g.debug = query_debug;
	} else {
	    rt_g.debug = rdebug = 0;
	}
    }

    if ( sub_grid_mode )  {
	if ( a.a_x < sub_xmin || a.a_x > sub_xmax )
	    return;
	if ( a.a_y < sub_ymin || a.a_y > sub_ymax )
	    return;
    }
    if ( fullfloat_mode )  {
	register struct floatpixel	*fp;
	fp = &curr_float_frame[a.a_y*width + a.a_x];
	if ( fp->ff_frame >= 0 )  {
	    return;	/* pixel was reprojected */
	}
    }

    /* Check the pixel map to determine if this image should be rendered or not */
    if (pixmap) {
	a.a_user= 1;	/* Force Shot Hit */

	if (pixmap[pindex + RED] + pixmap[pindex + GRN] + pixmap[pindex + BLU]) {
	    /* non-black pixmap pixel */

	    a.a_color[RED]= (double)(pixmap[pindex + RED]) * one_over_255;
	    a.a_color[GRN]= (double)(pixmap[pindex + GRN]) * one_over_255;
	    a.a_color[BLU]= (double)(pixmap[pindex + BLU]) * one_over_255;

	    /* we're done */
	    view_pixel( &a );
	    if ( a.a_x == width-1 ) {
		view_eol( &a );		/* End of scan line */
	    }
	    return;
	}
    }

    /* our starting point, used for non-jitter */
    VJOIN2 (point, viewbase_model, a.a_x, dx_model, a.a_y, dy_model);

    /* not tracing the corners of a prism by default */
    a.a_pixelext=(struct pixel_ext *)NULL;

    /* black or no pixmap, so compute the pixel(s) */

    /* LOOP BELOW IS UNROLLED ONE SAMPLE SINCE THAT'S THE COMMON CASE.
     *
     * XXX - If you edit the unrolled or non-unrolled section, be sure
     * to edit the other section.
     */
    if (hypersample == 0) {
	/* not hypersampling, so just do it */

	/****************/
	/* BEGIN UNROLL */
	/****************/

	if (jitter & JITTER_CELL ) {
	    jitter_start_pt(point, &a, samplenum, pat_num);
	}

	if (a.a_rt_i->rti_prismtrace) {
	    /* compute the four corners */
	    pe.magic = PIXEL_EXT_MAGIC;
	    VJOIN2(pe.corner[0].r_pt, viewbase_model, a.a_x, dx_model, a.a_y, dy_model );
	    VJOIN2(pe.corner[1].r_pt, viewbase_model, (a.a_x+1), dx_model, a.a_y, dy_model );
	    VJOIN2(pe.corner[2].r_pt, viewbase_model, (a.a_x+1), dx_model, (a.a_y+1), dy_model );
	    VJOIN2(pe.corner[3].r_pt, viewbase_model, a.a_x, dx_model, (a.a_y+1), dy_model );
	    a.a_pixelext = &pe;
	}

	if ( rt_perspective > 0.0 )  {
	    VSUB2( a.a_ray.r_dir, point, eye_model );
	    VUNITIZE( a.a_ray.r_dir );
	    VMOVE( a.a_ray.r_pt, eye_model );
	    if (a.a_rt_i->rti_prismtrace) {
		VSUB2(pe.corner[0].r_dir, pe.corner[0].r_pt, eye_model);
		VSUB2(pe.corner[1].r_dir, pe.corner[1].r_pt, eye_model);
		VSUB2(pe.corner[2].r_dir, pe.corner[2].r_pt, eye_model);
		VSUB2(pe.corner[3].r_dir, pe.corner[3].r_pt, eye_model);
	    }
	} else {
	    VMOVE( a.a_ray.r_pt, point );
	    VMOVE( a.a_ray.r_dir, ap.a_ray.r_dir );

	    if (a.a_rt_i->rti_prismtrace) {
		VMOVE(pe.corner[0].r_dir, a.a_ray.r_dir);
		VMOVE(pe.corner[1].r_dir, a.a_ray.r_dir);
		VMOVE(pe.corner[2].r_dir, a.a_ray.r_dir);
		VMOVE(pe.corner[3].r_dir, a.a_ray.r_dir);
	    }
	}
	if ( report_progress )  {
	    report_progress = 0;
	    bu_log("\tframe %d, xy=%d,%d on cpu %d, samp=%d\n", curframe, a.a_x, a.a_y, cpu, samplenum );
	}

	a.a_level = 0;		/* recursion level */
	a.a_purpose = "main ray";
	(void)rt_shootray( &a );

	if ( stereo )  {
	    fastf_t right, left;

	    right = CRT_BLEND(a.a_color);

	    VSUB2( stereo_point, point, left_eye_delta );
	    if ( rt_perspective > 0.0 )  {
		VSUB2( a.a_ray.r_dir, stereo_point, eye_model );
		VUNITIZE( a.a_ray.r_dir );
		VADD2( a.a_ray.r_pt, eye_model, left_eye_delta );
	    } else {
		VMOVE( a.a_ray.r_pt, stereo_point );
	    }
	    a.a_level = 0;		/* recursion level */
	    a.a_purpose = "left eye ray";
	    (void)rt_shootray( &a );

	    left = CRT_BLEND(a.a_color);
	    VSET( a.a_color, left, 0, right );
	}
	VADD2( colorsum, colorsum, a.a_color );

	/**************/
	/* END UNROLL */
	/**************/

    } else {
	/* hypersampling, so iterate */

	for ( samplenum=0; samplenum<=hypersample; samplenum++ )  {
	    /* shoot at a point based on the jitter pattern number */

	    /**********************/
	    /* BEGIN NON-UNROLLED */
	    /**********************/

	    if (jitter & JITTER_CELL ) {
		jitter_start_pt(point, &a, samplenum, pat_num);
	    }

	    if (a.a_rt_i->rti_prismtrace) {
		/* compute the four corners */
		pe.magic = PIXEL_EXT_MAGIC;
		VJOIN2(pe.corner[0].r_pt, viewbase_model, a.a_x, dx_model, a.a_y, dy_model );
		VJOIN2(pe.corner[1].r_pt, viewbase_model, (a.a_x+1), dx_model, a.a_y, dy_model );
		VJOIN2(pe.corner[2].r_pt, viewbase_model, (a.a_x+1), dx_model, (a.a_y+1), dy_model );
		VJOIN2(pe.corner[3].r_pt, viewbase_model, a.a_x, dx_model, (a.a_y+1), dy_model );
		a.a_pixelext = &pe;
	    }

	    if ( rt_perspective > 0.0 )  {
		VSUB2( a.a_ray.r_dir, point, eye_model );
		VUNITIZE( a.a_ray.r_dir );
		VMOVE( a.a_ray.r_pt, eye_model );
		if (a.a_rt_i->rti_prismtrace) {
		    VSUB2(pe.corner[0].r_dir, pe.corner[0].r_pt, eye_model);
		    VSUB2(pe.corner[1].r_dir, pe.corner[1].r_pt, eye_model);
		    VSUB2(pe.corner[2].r_dir, pe.corner[2].r_pt, eye_model);
		    VSUB2(pe.corner[3].r_dir, pe.corner[3].r_pt, eye_model);
		}
	    } else {
		VMOVE( a.a_ray.r_pt, point );
		VMOVE( a.a_ray.r_dir, ap.a_ray.r_dir );

		if (a.a_rt_i->rti_prismtrace) {
		    VMOVE(pe.corner[0].r_dir, a.a_ray.r_dir);
		    VMOVE(pe.corner[1].r_dir, a.a_ray.r_dir);
		    VMOVE(pe.corner[2].r_dir, a.a_ray.r_dir);
		    VMOVE(pe.corner[3].r_dir, a.a_ray.r_dir);
		}
	    }
	    if ( report_progress )  {
		report_progress = 0;
		bu_log("\tframe %d, xy=%d,%d on cpu %d, samp=%d\n", curframe, a.a_x, a.a_y, cpu, samplenum );
	    }

	    a.a_level = 0;		/* recursion level */
	    a.a_purpose = "main ray";
	    (void)rt_shootray( &a );

	    if ( stereo )  {
		fastf_t right, left;

		right = CRT_BLEND(a.a_color);

		VSUB2( stereo_point, point, left_eye_delta );
		if ( rt_perspective > 0.0 )  {
		    VSUB2( a.a_ray.r_dir, stereo_point, eye_model );
		    VUNITIZE( a.a_ray.r_dir );
		    VADD2( a.a_ray.r_pt, eye_model, left_eye_delta );
		} else {
		    VMOVE( a.a_ray.r_pt, stereo_point );
		}
		a.a_level = 0;		/* recursion level */
		a.a_purpose = "left eye ray";
		(void)rt_shootray( &a );

		left = CRT_BLEND(a.a_color);
		VSET( a.a_color, left, 0, right );
	    }
	    VADD2( colorsum, colorsum, a.a_color );

	    /********************/
	    /* END NON-UNROLLED */
	    /********************/
	} /* for samplenum <= hypersample */

	{
	    /* scale the hypersampled results */
	    fastf_t f;
	    f = 1.0 / (hypersample+1);
	    VSCALE( a.a_color, colorsum, f );
	}
    } /* end unrolling else case */

    /* bu_log("2: [%d,%d] : [%.2f,%.2f,%.2f]\n", pixelnum%width, pixelnum/width, a.a_color[0], a.a_color[1], a.a_color[2]); */

    /* we're done */
    view_pixel( &a );
    if ( a.a_x == width-1 ) {
	view_eol( &a );		/* End of scan line */
    }
    return;
}
示例#27
0
文件: sh_fire.c 项目: kanzure/brlcad
/*
 * This is called (from viewshade() in shade.c) once for each hit point
 * to be shaded.  The purpose here is to fill in values in the shadework
 * structure.
 */
int
fire_render(struct application *ap, const struct partition *pp, struct shadework *swp, void *dp)
/* defined in material.h */
/* ptr to the shader-specific struct */
{
#define DEBUG_SPACE_PRINT(str, i_pt, o_pt)			\
    if (rdebug&RDEBUG_SHADE || fire_sp->fire_debug) {		\
	bu_log("fire_render() %s space \n", str);		\
	bu_log("fire_render() i_pt(%g %g %g)\n", V3ARGS(i_pt)); \
	bu_log("fire_render() o_pt(%g %g %g)\n", V3ARGS(o_pt)); \
    }

#define SHADER_TO_NOISE(n_pt, sh_pt, fire_sp, zdelta) {			\
	point_t tmp_pt;							\
	tmp_pt[X] = sh_pt[X];						\
	tmp_pt[Y] = sh_pt[Y];						\
	if (! NEAR_ZERO(fire_sp->fire_stretch, SQRT_SMALL_FASTF))	\
	    tmp_pt[Z] = exp((sh_pt[Z]+0.125) * -fire_sp->fire_stretch); \
	else								\
	    tmp_pt[Z] = sh_pt[Z];					\
	MAT4X3PNT(n_pt, fire_sp->fire_sh_to_noise, tmp_pt);		\
	n_pt[Z] += zdelta;						\
    }


    register struct fire_specific *fire_sp =
	(struct fire_specific *)dp;
    point_t m_i_pt, m_o_pt;	/* model space in/out points */
    point_t sh_i_pt, sh_o_pt;	/* shader space in/out points */
    point_t noise_i_pt, noise_o_pt;	/* shader space in/out points */
    point_t noise_pt;
    double color[3];
    vect_t noise_r_dir;
    double noise_r_thick;
    int i;
    double samples_per_unit_noise;
    double noise_dist_per_sample;
    point_t shader_pt;
    vect_t shader_r_dir;
    double shader_r_thick;
    double shader_dist_per_sample;
    double noise_zdelta;

    int samples;
    double dist;
    double noise_val;
    double lumens;

    /* check the validity of the arguments we got */
    RT_AP_CHECK(ap);
    RT_CHECK_PT(pp);
    CK_fire_SP(fire_sp);

    if (rdebug&RDEBUG_SHADE || fire_sp->fire_debug) {
/* bu_struct_print("fire_render Parameters:", fire_print_tab, (char *)fire_sp); */
	bu_log("fire_render()\n");
    }
    /* If we are performing the shading in "region" space, we must
     * transform the hit point from "model" space to "region" space.
     * See the call to db_region_mat in fire_setup().
     */

    /*
     * Compute the ray/solid in and out points,
     */
    VMOVE(m_i_pt, swp->sw_hit.hit_point);
    VJOIN1(m_o_pt, ap->a_ray.r_pt, pp->pt_outhit->hit_dist, ap->a_ray.r_dir);
    DEBUG_SPACE_PRINT("model", m_i_pt, m_o_pt);

    /* map points into shader space */
    MAT4X3PNT(sh_i_pt, fire_sp->fire_m_to_sh, m_i_pt);
    MAT4X3PNT(sh_o_pt, fire_sp->fire_m_to_sh, m_o_pt);
    DEBUG_SPACE_PRINT("shader", sh_i_pt, sh_o_pt);

    noise_zdelta = fire_sp->fire_flicker * swp->sw_frametime;

    SHADER_TO_NOISE(noise_i_pt, sh_i_pt, fire_sp, noise_zdelta);
    SHADER_TO_NOISE(noise_o_pt, sh_o_pt, fire_sp, noise_zdelta);

    VSUB2(noise_r_dir, noise_o_pt, noise_i_pt);

    noise_r_thick = MAGNITUDE(noise_r_dir);

    if (rdebug&RDEBUG_SHADE || fire_sp->fire_debug) {
	bu_log("fire_render() noise_r_dir (%g %g %g)\n",
	       V3ARGS(noise_r_dir));
	bu_log("fire_render() noise_r_thick %g\n", noise_r_thick);
    }


    /* compute number of samples per unit length in noise space.
     *
     * 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, nyquist
     * tells us we need at least 4 samples/cycle at the highest octave
     * rate.
     */

    samples_per_unit_noise =
	pow(fire_sp->noise_lacunarity, fire_sp->noise_octaves-1) * 4.0;

    noise_dist_per_sample = 1.0 / samples_per_unit_noise;

    samples = samples_per_unit_noise * noise_r_thick;

    if (samples < 1) samples = 1;

    if (rdebug&RDEBUG_SHADE || fire_sp->fire_debug) {
	bu_log("samples:%d\n", samples);
	bu_log("samples_per_unit_noise %g\n", samples_per_unit_noise);
	bu_log("noise_dist_per_sample %g\n", noise_dist_per_sample);
    }

    /* To do the exponential stretch and decay properly we need to
     * do the computations in shader space, and convert the points
     * to noise space.  Performance pig.
     */

    VSUB2(shader_r_dir, sh_o_pt, sh_i_pt);
    shader_r_thick = MAGNITUDE(shader_r_dir);
    VUNITIZE(shader_r_dir);

    shader_dist_per_sample = shader_r_thick / samples;

    lumens = 0.0;
    for (i = 0; i < samples; i++) {
	dist = (double)i * shader_dist_per_sample;
	VJOIN1(shader_pt, sh_i_pt, dist, shader_r_dir);

	SHADER_TO_NOISE(noise_pt, shader_pt, fire_sp, noise_zdelta);

	noise_val = bn_noise_turb(noise_pt, fire_sp->noise_h_val,
				  fire_sp->noise_lacunarity, fire_sp->noise_octaves);

	if (rdebug&RDEBUG_SHADE || fire_sp->fire_debug)
	    bu_log("bn_noise_turb(%g %g %g) = %g\n",
		   V3ARGS(noise_pt),
		   noise_val);

	/* XXX
	 * When doing the exponential stretch, we scale the noise
	 * value by the height in shader space
	 */

	if (NEAR_ZERO(fire_sp->fire_stretch, SQRT_SMALL_FASTF))
	    lumens += noise_val * 0.025;
	else {
	    register double t;
	    t = lumens;
	    lumens += noise_val * 0.025 * (1.0 -shader_pt[Z]);
	    if (rdebug&RDEBUG_SHADE || fire_sp->fire_debug)
		bu_log("lumens:%g = %g + %g * %g\n",
		       lumens, t, noise_val,
		       0.025 * (1.0 - shader_pt[Z]));

	}
	if (lumens >= 1.0) {
	    lumens = 1.0;
	    if (rdebug&RDEBUG_SHADE || fire_sp->fire_debug)
		bu_log("early exit from lumens loop\n");
	    break;
	}

    }

    if (rdebug&RDEBUG_SHADE || fire_sp->fire_debug)
	bu_log("lumens = %g\n", lumens);

    if (lumens < 0.0) lumens = 0.0;
    else if (lumens > 1.0) lumens = 1.0;


    rt_dspline_n(color, fire_sp->fire_colorspline_mat, (double *)flame_colors,
		 18, 3, lumens);

    VMOVE(swp->sw_color, color);
/* VSETALL(swp->sw_basecolor, 1.0);*/

    swp->sw_transmit = 1.0 - (lumens * 4.0);
    if (swp->sw_reflect > 0 || swp->sw_transmit > 0)
	(void)rr_render(ap, pp, swp);

    return 1;
}
示例#28
0
文件: trie.c 项目: kanzure/brlcad
int
read_Trie(FILE *fp)
{
    static char	name_buf[MAX_TRIE_LEVEL+1];
    Trie	*triep;
    F_Hdr_Ptlist	hdr_ptlist;
    int		min, max;
    /* Read temperature range information.				*/
    if (	fread( (char *) &min, (int) sizeof(int), 1, fp ) != 1
		||	fread( (char *) &max, (int) sizeof(int), 1, fp ) != 1
	)
    {
	bu_log( "Could not read min/max info.\n" );
	rewind( fp );
    }
    else
    {
	bu_log( "IR data base temperature range is %d to %d\n",
		min, max
	    );
	if ( ir_min == ABSOLUTE_ZERO )
	{
	    /* Temperature range not set.			*/
	    ir_min = min;
	    ir_max = max;
	}
	else
	{
	    /* Merge with existing range.			*/
	    V_MIN( ir_min, min );
	    V_MAX( ir_max, max );
	    bu_log(	"Global temperature range is %d to %d\n",
			ir_min, ir_max
		);
	    (void) fflush( stdout );
	}
    }
    if ( ! init_Temp_To_RGB() )
    {
	return	0;
    }
    while ( bu_fgets( name_buf, MAX_TRIE_LEVEL, fp ) != NULL )
    {
	name_buf[strlen(name_buf)-1] = '\0'; /* Clobber new-line.*/
	triep = add_Trie( name_buf, &reg_triep );
	if ( fread( (char *) &hdr_ptlist, (int) sizeof(F_Hdr_Ptlist), 1, fp )
	     != 1
	    )
	{
	    bu_log( "\"%s\"(%d) Read failed!\n", __FILE__, __LINE__ );
	    return	0;
	}
	for (; hdr_ptlist.f_length > 0; hdr_ptlist.f_length-- )
	{
	    fastf_t		point[3];
	    float		c_point[3];
	    Octree		*octreep;
	    if ( fread( (char *) c_point, (int) sizeof(c_point), 1, fp ) != 1 )
	    {
		bu_log(	"\"%s\"(%d) Read failed.\n",
			__FILE__, __LINE__ );
		return	0;
	    }
	    VMOVE( point, c_point );
	    if ( (octreep = add_Region_Octree(	&ir_octree,
						point,
						triep,
						hdr_ptlist.f_temp,
						0
		      )
		     ) != OCTREE_NULL
		)
		append_Octp( triep, octreep );
	}
    }
    return	1;
}
示例#29
0
static void
make_bot_object(const char *name,
		struct rt_wdb *wdbp)
{
    int i;
    int max_pt=0, min_pt=999999;
    int num_vertices;
    struct bu_bitv *bv=NULL;
    int bot_mode;
    int count;
    struct rt_bot_internal bot_ip;

    bot_ip.magic = RT_BOT_INTERNAL_MAGIC;
    for (i = 0; i < face_count; i++) {
	V_MIN(min_pt, faces[i*3]);
	V_MAX(max_pt, faces[i*3]);
	V_MIN(min_pt, faces[i*3+1]);
	V_MAX(max_pt, faces[i*3+1]);
	V_MIN(min_pt, faces[i*3+2]);
	V_MAX(max_pt, faces[i*3+2]);
    }

    num_vertices = max_pt - min_pt + 1;
    bot_ip.num_vertices = num_vertices;
    bot_ip.vertices = (fastf_t *)bu_calloc(num_vertices*3, sizeof(fastf_t), "BOT vertices");
    for (i = 0; i < num_vertices; i++)
	VMOVE(&bot_ip.vertices[i*3], grid_pts[min_pt+i]);

    for (i = 0; i < face_count * 3; i++)
	faces[i] -= min_pt;
    bot_ip.num_faces = face_count;
    bot_ip.faces = bu_calloc(face_count*3, sizeof(int), "BOT faces");
    for (i = 0; i < face_count*3; i++)
	bot_ip.faces[i] = faces[i];

    bot_ip.face_mode = (struct bu_bitv *)NULL;
    bot_ip.thickness = (fastf_t *)NULL;
    if (mode == PLATE_MODE) {
	bot_mode = RT_BOT_PLATE;
	bv = bu_bitv_new(face_count);
	for (i = 0; i < face_count; i++) {
	    if (facemode[i] == POS_FRONT)
		BU_BITSET(bv, i);
	}
	bot_ip.face_mode = bv;
	bot_ip.thickness = (fastf_t *)bu_calloc(face_count, sizeof(fastf_t), "BOT thickness");
	for (i = 0; i < face_count; i++)
	    bot_ip.thickness[i] = thickness[i];
    } else
	bot_mode = RT_BOT_SOLID;

    bot_ip.mode = bot_mode;
    bot_ip.orientation = RT_BOT_UNORIENTED;
    bot_ip.bot_flags = 0;

    count = rt_bot_vertex_fuse(&bot_ip, &wdbp->wdb_tol);
    count = rt_bot_face_fuse(&bot_ip);
    if (count)
	bu_log("WARNING: %d duplicate faces eliminated from group %d component %d\n", count, group_id, comp_id);

    rt_mk_bot(wdbp, name, bot_mode, RT_BOT_UNORIENTED, 0,
	      bot_ip.num_vertices, bot_ip.num_faces, bot_ip.vertices,
	      bot_ip.faces, bot_ip.thickness, bot_ip.face_mode);

    if (mode == PLATE_MODE) {
	bu_free((char *)bot_ip.thickness, "BOT thickness");
	bu_free((char *)bot_ip.face_mode, "BOT face_mode");
    }
    bu_free((char *)bot_ip.vertices, "BOT vertices");
    bu_free((char *)bot_ip.faces, "BOT faces");
}
示例#30
0
int bn_tri_tri_isect_with_line(point_t V0, point_t V1, point_t V2,
			       point_t U0, point_t U1, point_t U2,
			       int *coplanar, point_t *isectpt1, point_t *isectpt2)
{
    point_t E1, E2;
    point_t N1, N2;
    fastf_t d1, d2;
    fastf_t du0, du1, du2, dv0, dv1, dv2;
    fastf_t D[3];
    fastf_t isect1[2] = {0, 0};
    fastf_t isect2[2] = {0, 0};
    point_t isectpointA1 = VINIT_ZERO;
    point_t isectpointA2 = VINIT_ZERO;
    point_t isectpointB1 = VINIT_ZERO;
    point_t isectpointB2 = VINIT_ZERO;
    fastf_t du0du1, du0du2, dv0dv1, dv0dv2;
    short index;
    fastf_t vp0, vp1, vp2;
    fastf_t up0, up1, up2;
    fastf_t b, c, max;
    int smallest1, smallest2;

    /* compute plane equation of triangle(V0, V1, V2) */
    VSUB2(E1, V1, V0);
    VSUB2(E2, V2, V0);
    VCROSS(N1, E1, E2);
    d1=-VDOT(N1, V0);
    /* plane equation 1: N1.X+d1=0 */

    /* put U0, U1, U2 into plane equation 1 to compute signed distances to the plane*/
    du0=VDOT(N1, U0)+d1;
    du1=VDOT(N1, U1)+d1;
    du2=VDOT(N1, U2)+d1;

    /* coplanarity robustness check */
#if USE_EPSILON_TEST
    if (fabs(du0)<EPSILON) du0=0.0;
    if (fabs(du1)<EPSILON) du1=0.0;
    if (fabs(du2)<EPSILON) du2=0.0;
#endif
    du0du1=du0*du1;
    du0du2=du0*du2;

    if (du0du1>0.0f && du0du2>0.0f) /* same sign on all of them + not equal 0 ? */
	return 0;                    /* no intersection occurs */

    /* compute plane of triangle (U0, U1, U2) */
    VSUB2(E1, U1, U0);
    VSUB2(E2, U2, U0);
    VCROSS(N2, E1, E2);
    d2=-VDOT(N2, U0);
    /* plane equation 2: N2.X+d2=0 */

    /* put V0, V1, V2 into plane equation 2 */
    dv0=VDOT(N2, V0)+d2;
    dv1=VDOT(N2, V1)+d2;
    dv2=VDOT(N2, V2)+d2;

#if USE_EPSILON_TEST
    if (fabs(dv0)<EPSILON) dv0=0.0;
    if (fabs(dv1)<EPSILON) dv1=0.0;
    if (fabs(dv2)<EPSILON) dv2=0.0;
#endif

    dv0dv1=dv0*dv1;
    dv0dv2=dv0*dv2;

    if (dv0dv1>0.0f && dv0dv2>0.0f) /* same sign on all of them + not equal 0 ? */
	return 0;                    /* no intersection occurs */

    /* compute direction of intersection line */
    VCROSS(D, N1, N2);

    /* compute and index to the largest component of D */
    max=fabs(D[0]);
    index=0;
    b=fabs(D[1]);
    c=fabs(D[2]);
    if (b>max) max=b, index=1;
    if (c>max) index=2;

    /* this is the simplified projection onto L*/
    vp0=V0[index];
    vp1=V1[index];
    vp2=V2[index];

    up0=U0[index];
    up1=U1[index];
    up2=U2[index];

    /* compute interval for triangle 1 */
    *coplanar=compute_intervals_isectline(V0, V1, V2, vp0, vp1, vp2, dv0, dv1, dv2,
					  dv0dv1, dv0dv2, &isect1[0], &isect1[1], isectpointA1, isectpointA2);
    if (*coplanar) return coplanar_tri_tri(N1, V0, V1, V2, U0, U1, U2);


    /* compute interval for triangle 2 */
    compute_intervals_isectline(U0, U1, U2, up0, up1, up2, du0, du1, du2,
				du0du1, du0du2, &isect2[0], &isect2[1], isectpointB1, isectpointB2);

    SORT2(isect1[0], isect1[1], smallest1);
    SORT2(isect2[0], isect2[1], smallest2);

    if (isect1[1]<isect2[0] || isect2[1]<isect1[0]) return 0;

    /* at this point, we know that the triangles intersect */

    if (isect2[0]<isect1[0]) {
	if (smallest1==0) { VMOVE(*isectpt1, isectpointA1); } else { VMOVE(*isectpt1, isectpointA2); }

	if (isect2[1]<isect1[1]) {
	    if (smallest2==0) { VMOVE(*isectpt2, isectpointB2); } else { VMOVE(*isectpt2, isectpointB1); }
	} else {
	    if (smallest1==0) { VMOVE(*isectpt2, isectpointA2); } else { VMOVE(*isectpt2, isectpointA1); }
	}
    } else {
	if (smallest2==0) { VMOVE(*isectpt1, isectpointB1); } else { VMOVE(*isectpt1, isectpointB2); }

	if (isect2[1]>isect1[1]) {
	    if (smallest1==0) { VMOVE(*isectpt2, isectpointA2); } else { VMOVE(*isectpt2, isectpointA1); }
	} else {
	    if (smallest2==0) { VMOVE(*isectpt2, isectpointB2); } else { VMOVE(*isectpt2, isectpointB1); }
	}
    }
    return 1;
}