Exemple #1
0
/*
 * R T _ M E T A B A L L _ S H O T
 */
int
rt_metaball_shot(struct soltab *stp, register struct xray *rp, struct application *ap, struct seg *seghead)
{
    struct rt_metaball_internal *mb = (struct rt_metaball_internal *)stp->st_specific;
    struct seg *segp = NULL;
    int retval = 0;
    fastf_t step, distleft;
    point_t p, inc;
    const point_t *cp = (const point_t *)&p;

    /* switching behavior to retain old code for performance and correctness
     * comparisons. */
#define SHOOTALGO 3

#if SHOOTALGO == 2
    int fhin = 1;
#endif

    step = mb->initstep;
    distleft = (rp->r_max-rp->r_min) + step * 3.0;

    VMOVE(p, rp->r_pt);
    VSCALE(inc, rp->r_dir, step); /* assume it's normalized and we want to creep at step */

    /* walk back out of the solid */
    while(rt_metaball_point_value(cp, mb) >= mb->threshold) {
#if SHOOTALGO == 2
	fhin = -1;
#endif
	distleft += step;
	VSUB2(p, p, inc);
    }

#if SHOOTALGO == 2
    /* we hit, but not as fine-grained as we want. So back up one step,
     * cut the step size in half and start over...
     */
    {
	int mb_stat = 0, segsleft = abs(ap->a_onehit);
	point_t delta;

#define STEPBACK { distleft += step; VSUB2(p, p, inc); step *= .5; VSCALE(inc, inc, .5); }
#define STEPIN(x) { \
    --segsleft; \
    ++retval; \
    VSUB2(delta, p, rp->r_pt); \
    segp->seg_##x.hit_dist = fhin * MAGNITUDE(delta); \
    segp->seg_##x.hit_surfno = 0; }
	while (mb_stat == 0 && distleft >= -0) {
	    int in;

	    distleft -= step;
	    VADD2(p, p, inc);
	    in = rt_metaball_point_value(cp, mb) > mb->threshold;
	    if (mb_stat == 1)
		if ( !in )
		    if (step<=mb->finalstep) {
			STEPIN(out)
			step = mb->initstep;
			mb_stat = 0;
			if (ap->a_onehit != 0 || segsleft <= 0)
			    return retval;
		    } else
			STEPBACK
	    else
		if ( in )
		    if (step<=mb->finalstep) {
			RT_GET_SEG(segp, ap->a_resource);
			segp->seg_stp = stp;
			STEPIN(in)
			fhin = 1;
			BU_LIST_INSERT(&(seghead->l), &(segp->l));
			/* reset the ray-walk stuff */
			mb_stat = 1;
			VADD2(p, p, inc);	/* set p to a point inside */
			step = mb->initstep;
		    } else
			STEPBACK
	}
    }
#undef STEPBACK
#undef STEPIN
#elif SHOOTALGO == 3
    {
	int mb_stat = 0, segsleft = abs(ap->a_onehit);
	point_t lastpoint;

	while (distleft >= 0.0 || mb_stat == 1) {
	    /* advance to the next point */
	    distleft -= step;
	    VMOVE(lastpoint, p);
	    VADD2(p, p, inc);
	    if (mb_stat == 1) {
		if (rt_metaball_point_value(cp, mb) < mb->threshold) {
		    point_t intersect, delta;
		    const point_t *pA = (const point_t *)&lastpoint;
		    const point_t *pB = (const point_t *)&p;
		    rt_metaball_find_intersection(&intersect, mb, pA, pB, step, mb->finalstep);
		    VMOVE(segp->seg_out.hit_point, intersect);
		    --segsleft;
		    ++retval;
		    VSUB2(delta, intersect, rp->r_pt);
		    segp->seg_out.hit_dist = MAGNITUDE(delta);
		    segp->seg_out.hit_surfno = 0;
		    mb_stat = 0;
		    if (ap->a_onehit != 0 && segsleft <= 0)
			return retval;
		}
	    } else {
		if (rt_metaball_point_value(cp, mb) > mb->threshold) {
		    point_t intersect, delta;
		    const point_t *pA = (const point_t *)&lastpoint;
		    const point_t *pB = (const point_t *)&p;
		    rt_metaball_find_intersection(&intersect, mb, pA, pB, step, mb->finalstep);
		    RT_GET_SEG(segp, ap->a_resource);
		    segp->seg_stp = stp;
		    --segsleft;
		    ++retval;
		    VMOVE(segp->seg_in.hit_point, intersect);
		    VSUB2(delta, intersect, rp->r_pt);
		    segp->seg_in.hit_dist = MAGNITUDE(delta);
		    segp->seg_in.hit_surfno = 0;
		    BU_LIST_INSERT(&(seghead->l), &(segp->l));

		    mb_stat = 1;
		    step = mb->initstep;
		}
	    }
	}
    }

#else
# error "pick a valid algo."
#endif

    return retval;
}
Exemple #2
0
extern "C" void
rt_eto_brep(ON_Brep **b, const struct rt_db_internal *ip, const struct bn_tol *)
{
    struct rt_eto_internal *eip;

    RT_CK_DB_INTERNAL(ip);
    eip = (struct rt_eto_internal *)ip->idb_ptr;
    RT_ETO_CK_MAGIC(eip);

    point_t p_origin;
    vect_t v1, v1a, x_dir, y_dir;
    ON_3dPoint plane_origin;
    ON_3dVector plane_x_dir, plane_y_dir;

    double ell_axis_len_1, ell_axis_len_2;

    //  First, find a plane in 3 space with x and y axes
    //  along an axis of the ellipse to be rotated, and its
    //  coordinate origin at the center of the ellipse.
    //
    //  To identify a point on the eto suitable for use (there
    //  are of course infinitely many such points described by
    //  a circle at radius eto_r from the eto vertex) obtain
    //  a vector at a right angle to the eto normal, unitize it
    //  and scale it.

    VCROSS(v1, eip->eto_C, eip->eto_N);
    if (NEAR_ZERO(MAGNITUDE(v1), VUNITIZE_TOL)) {
	vect_t dir_vect;
	VSET(dir_vect, 0, 1, 0);
	VCROSS(v1, dir_vect, eip->eto_N);
	if (NEAR_ZERO(MAGNITUDE(v1), VUNITIZE_TOL)) {
	    VSET(dir_vect, 1, 0, 0);
	    VCROSS(v1, dir_vect, eip->eto_N);
	}
    }
    point_t temp;
    VMOVE(temp, v1);
    VCROSS(v1a, v1, eip->eto_N);
    VSET(v1, -v1a[0], -v1a[1], -v1a[2]);
    VUNITIZE( v1 );
    VSCALE(v1, v1, eip->eto_r);
    VADD2(v1, v1, eip->eto_V);
    VMOVE(x_dir, eip->eto_C);
    VCROSS(y_dir, x_dir, temp);
    VSET(p_origin, v1[0], v1[1], v1[2]);
    plane_origin = ON_3dPoint(p_origin);
    plane_x_dir = ON_3dVector(x_dir);
    plane_y_dir = ON_3dVector(y_dir);

    const ON_Plane ell_plane(plane_origin, plane_x_dir, plane_y_dir);


    //  Once the plane has been created, create the ellipse
    //  within the plane.
    ell_axis_len_1 = MAGNITUDE(eip->eto_C);
    ell_axis_len_2 = eip->eto_rd;
    ON_Ellipse ellipse(ell_plane, ell_axis_len_1, ell_axis_len_2);


    //  Generate an ON_Curve from the ellipse and revolve it
    //  around eto_N

    ON_NurbsCurve ellcurve;
    ellipse.GetNurbForm(ellcurve);
    point_t eto_endvertex;
    VADD2(eto_endvertex, eip->eto_V, eip->eto_N);
    ON_3dPoint eto_vertex_pt = ON_3dPoint(eip->eto_V);
    ON_3dPoint eto_endvertex_pt = ON_3dPoint(eto_endvertex);
    ON_Line revaxis = ON_Line(eto_vertex_pt, eto_endvertex_pt);
    ON_RevSurface* eto_surf = ON_RevSurface::New();
    eto_surf->m_curve = &ellcurve;
    eto_surf->m_axis = revaxis;

    /* Create brep with one face*/
    ON_BrepFace *newface = (*b)->NewFace(*eto_surf);
    (*b)->FlipFace(*newface);
//    (*b)->Standardize();
 //   (*b)->Compact();
}
/*
 * This routine is called (at prep time)
 * once for each region which uses this shader.
 * Any shader-specific initialization should be done here.
 *
 * Returns:
 * 1 success
 * 0 success, but delete region
 * -1 failure
 */
HIDDEN int
bbd_setup(struct region *rp, struct bu_vls *matparm, void **dpp, const struct mfuncs *mfp, struct rt_i *rtip)
{
    register struct bbd_specific *bbd_sp;
    struct rt_db_internal intern;
    struct rt_tgc_internal *tgc;
    int s;
    mat_t mat;
    struct bbd_img *bi;
    double angle;
    vect_t vtmp;
    int img_num;
    vect_t vv;

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


    if (rdebug&RDEBUG_SHADE) bu_log("bbd_setup(%s)\n", rp->reg_name);

    RT_CK_TREE(rp->reg_treetop);

    if (rp->reg_treetop->tr_a.tu_op != OP_SOLID) {
	bu_log("--- Warning: Region %s shader %s", rp->reg_name, mfp->mf_name);
	bu_bomb("Shader should be used on region of single (rec/rcc) primitive\n");
    }

    RT_CK_SOLTAB(rp->reg_treetop->tr_a.tu_stp);
    if (rp->reg_treetop->tr_a.tu_stp->st_id != ID_REC) {
	bu_log("--- Warning: Region %s shader %s", rp->reg_name, mfp->mf_name);
	bu_log("Shader should be used on region of single REC/RCC primitive %d\n",
	       rp->reg_treetop->tr_a.tu_stp->st_id);
	bu_bomb("oops\n");
    }


    /* Get memory for the shader parameters and shader-specific data */
    BU_GET(bbd_sp, struct bbd_specific);
    *dpp = bbd_sp;

    /* initialize the default values for the shader */
    memcpy(bbd_sp, &bbd_defaults, sizeof(struct bbd_specific));
    bu_vls_init(&bbd_sp->img_filename);
    BU_LIST_INIT(&bbd_sp->imgs);
    bbd_sp->rtip = rtip; /* because new_image() needs this */
    bbd_sp->img_count = 0;

    /* parse the user's arguments for this use of the shader. */
    if (bu_struct_parse(matparm, bbd_parse_tab, (char *)bbd_sp, NULL) < 0)
	return -1;

    if (bbd_sp->img_count > MAX_IMAGES) {
	bu_log("too many images (%zu) in shader for %s sb < %d\n",
	       bbd_sp->img_count, rp->reg_name, MAX_IMAGES);
	bu_bomb("excessive image count\n");
    }


    MAT_IDN(mat);
    RT_DB_INTERNAL_INIT(&intern);
    s = rt_db_get_internal(&intern, rp->reg_treetop->tr_a.tu_stp->st_dp, rtip->rti_dbip,
			   mat, &rt_uniresource);

    if (intern.idb_minor_type != ID_TGC &&
	intern.idb_minor_type != ID_REC) {
	bu_log("What did I get? %d\n", intern.idb_minor_type);
    }

    if (s < 0) {
	bu_log("%s:%d didn't get internal", __FILE__, __LINE__);
	bu_bomb("");
    }
    tgc = (struct rt_tgc_internal *)intern.idb_ptr;
    RT_TGC_CK_MAGIC(tgc);

    angle = M_PI / (double)bbd_sp->img_count;
    img_num = 0;
    VMOVE(vv, tgc->h);
    VUNITIZE(vv);
    for (BU_LIST_FOR(bi, bbd_img, &bbd_sp->imgs)) {
	static const point_t o = VINIT_ZERO;
	bn_mat_arb_rot(mat, o, vv, angle*img_num);

	/* compute plane equation */
	MAT4X3VEC(bi->img_plane, mat, tgc->a);
	VUNITIZE(bi->img_plane);
	bi->img_plane[H] = VDOT(tgc->v, bi->img_plane);

	MAT4X3VEC(vtmp, mat, tgc->b);
	VADD2(bi->img_origin, tgc->v, vtmp); /* image origin in 3d space */
	/* calculate image u vector */
	VREVERSE(bi->img_x, vtmp);
	VUNITIZE(bi->img_x);
	bi->img_xlen = MAGNITUDE(vtmp) * 2;

	/* calculate image v vector */
	VMOVE(bi->img_y, tgc->h);
	VUNITIZE(bi->img_y);
	bi->img_ylen = MAGNITUDE(tgc->h);

	if (rdebug&RDEBUG_SHADE) {
	    HPRINT("\nimg_plane", bi->img_plane);
	    VPRINT("vtmp", vtmp);
	    VPRINT("img_origin", bi->img_origin);
	    bu_log("img_xlen:%g  ", bi->img_xlen);
	    VPRINT("img_x", bi->img_x);
	    bu_log("img_ylen:%g  ", bi->img_ylen);
	    VPRINT("img_y", bi->img_y);
	}

	img_num++;
    }

    rt_db_free_internal(&intern);

    if (rdebug&RDEBUG_SHADE) {
	bu_struct_print(" Parameters:", bbd_print_tab, (char *)bbd_sp);
    }

    return 1;
}
struct faceuse *
Make_planar_face(struct shell *s, int entityno, int face_orient)
{

    int sol_num;	/* IGES solid type number */
    int no_of_edges;	/* edge count for this loop */
    int no_of_param_curves;
    int vert_count = 0;	/* Actual number of vertices used to make face */
    struct iges_edge_use *edge_list;	/* list of edgeuses from iges loop entity */
    struct faceuse *fu = NULL;	/* NMG face use */
    struct loopuse *lu;		/* NMG loop use */
    struct vertex ***verts;	/* list of vertices */
    struct iges_vertex_list *v_list;
    int done;
    int i, j, k;

    /* Acquiring Data */

    if (dir[entityno]->param <= pstart) {
	bu_log("Illegal parameter pointer for entity D%07d (%s)\n" ,
	       dir[entityno]->direct, dir[entityno]->name);
	return 0;
    }

    Readrec(dir[entityno]->param);
    Readint(&sol_num, "");
    if (sol_num != 508) {
	bu_exit(1, "ERROR: Entity #%d is not a loop (it's a %s)\n", entityno, iges_type(sol_num));
    }

    Readint(&no_of_edges, "");
    edge_list = (struct iges_edge_use *)bu_calloc(no_of_edges, sizeof(struct iges_edge_use) ,
						  "Make_face (edge_list)");
    for (i = 0; i < no_of_edges; i++) {
	Readint(&edge_list[i].edge_is_vertex, "");
	Readint(&edge_list[i].edge_de, "");
	Readint(&edge_list[i].index, "");
	Readint(&edge_list[i].orient, "");
	if (!face_orient) {
	    /* need opposite orientation of edge */
	    if (edge_list[i].orient)
		edge_list[i].orient = 0;
	    else
		edge_list[i].orient = 1;
	}
	edge_list[i].root = (struct iges_param_curve *)NULL;
	Readint(&no_of_param_curves, "");
	for (j = 0; j < no_of_param_curves; j++) {
	    struct iges_param_curve *new_crv;
	    struct iges_param_curve *crv;

	    Readint(&k, "");	/* ignore iso-parametric flag */

	    BU_ALLOC(new_crv, struct iges_param_curve);
	    if (edge_list[i].root == (struct iges_param_curve *)NULL)
		edge_list[i].root = new_crv;
	    else {
		crv = edge_list[i].root;
		while (crv->next != (struct iges_param_curve *)NULL)
		    crv = crv->next;
		crv->next = new_crv;
	    }
	    Readint(&new_crv->curve_de, "");
	    new_crv->next = (struct iges_param_curve *)NULL;
	}
    }

    verts = (struct vertex ***)bu_calloc(no_of_edges, sizeof(struct vertex **) ,
					 "Make_face: vertex_list **");

    for (i = 0; i < no_of_edges; i++) {
	if (face_orient)
	    verts[i] = Get_vertex(&edge_list[i]);
	else
	    verts[no_of_edges-1-i] = Get_vertex(&edge_list[i]);
    }

    /* eliminate zero length edges */
    vert_count = no_of_edges;
    done = 0;
    while (!done) {
	done = 1;
	for (i = 0; i < vert_count; i++) {
	    k = i + 1;
	    if (k == vert_count)
		k = 0;

	    if (verts[i] == verts[k]) {
		bu_log("Ignoring zero length edge\n");
		done = 0;
		vert_count--;
		for (j = i; j < vert_count; j++)
		    verts[j] = verts[j+1];
	    }
	}
    }

    if (vert_count) {
	plane_t pl;		/* Plane equation for face */
	fastf_t area;		/* area of loop */
	fastf_t dist;
	vect_t min2max;
	point_t outside_pt;

	fu = nmg_cmface(s, verts, vert_count);

	/* associate geometry */
	v_list = vertex_root;
	while (v_list != NULL) {
	    for (i = 0; i < v_list->no_of_verts; i++) {
		if (v_list->i_verts[i].v != NULL && v_list->i_verts[i].v->vg_p == NULL) {
		    NMG_CK_VERTEX(v_list->i_verts[i].v);
		    nmg_vertex_gv(v_list->i_verts[i].v ,
				  v_list->i_verts[i].pt);
		}
	    }
	    v_list = v_list->next;
	}

	lu = BU_LIST_FIRST(loopuse, &fu->lu_hd);
	NMG_CK_LOOPUSE(lu);

	area = nmg_loop_plane_area(lu, pl);
	if (area < 0.0) {
	    bu_log("Could not calculate area for face (entityno = %d)\n", entityno);
	    nmg_pr_fu_briefly(fu, "");
	    nmg_kfu(fu);
	    fu = (struct faceuse *)NULL;
	    goto err;
	}

	nmg_face_g(fu, pl);
	nmg_face_bb(fu->f_p, &tol);

	/* find a point that is surely outside the loop */
	VSUB2(min2max, fu->f_p->max_pt, fu->f_p->min_pt);
	VADD2(outside_pt, fu->f_p->max_pt, min2max);

	/* move it to the plane of the face */
	dist = DIST_PT_PLANE(outside_pt, pl);
	VJOIN1(outside_pt, outside_pt, -dist, pl);

	if (nmg_class_pt_lu_except(outside_pt, lu, (struct edge *)NULL, &tol) != NMG_CLASS_AoutB) {
	    nmg_reverse_face(fu);
	    if (fu->orientation != OT_SAME) {
		fu = fu->fumate_p;
		if (fu->orientation != OT_SAME)
		    bu_exit(1, "ERROR: no OT_SAME use for a face!\n");
	    }
	}
    } else
	bu_log("No edges left!\n");

err:
    bu_free((char *)edge_list, "Make_face (edge_list)");
    bu_free((char *)verts, "Make_face (vertexlist)");
    return fu;
}
Exemple #5
0
void
nmg_2_vrml(FILE *fp, const struct db_full_path *pathp, struct model *m, struct mater_info *mater)
{
    struct nmgregion *reg;
    struct bu_ptbl verts;
    struct vrml_mat mat;
    struct bu_vls vls = BU_VLS_INIT_ZERO;
    char *tok;
    int i;
    int first=1;
    int is_light=0;
    float r, g, b;
    point_t ave_pt;
    char *full_path;
    /*There may be a better way to capture the region_id, than getting the rt_comb_internal structure,
     * (and may be a better way to capture the rt_comb_internal struct), but for now I just copied the
     * method used in select_lights/select_non_lights above, could have used a global variable but I noticed
     * none other were used, so I didn't want to be the first
     */
    struct directory *dp;
    struct rt_db_internal intern;
    struct rt_comb_internal *comb;
    int id;

    NMG_CK_MODEL( m );

    BARRIER_CHECK;

    full_path = db_path_to_string( pathp );

    /* replace all occurrences of '.' with '_' */
    char_replace(full_path, '.', '_');

    RT_CK_FULL_PATH( pathp );
    dp = DB_FULL_PATH_CUR_DIR( pathp );

    if ( !(dp->d_flags & RT_DIR_COMB) )
	return;

    id = rt_db_get_internal( &intern, dp, dbip, (matp_t)NULL, &rt_uniresource );
    if ( id < 0 )
    {
	bu_log( "Cannot internal form of %s\n", dp->d_namep );
	return;
    }

    if ( id != ID_COMBINATION )
    {
	bu_log( "Directory/database mismatch!\n\t is '%s' a combination or not?\n",
		dp->d_namep );
	return;
    }

    comb = (struct rt_comb_internal *)intern.idb_ptr;
    RT_CK_COMB( comb );

    if ( mater->ma_color_valid )
    {
	r = mater->ma_color[0];
	g = mater->ma_color[1];
	b = mater->ma_color[2];
    }
    else
    {
	r = g = b = 0.5;
    }

    if ( mater->ma_shader )
    {
	tok = strtok( mater->ma_shader, tok_sep );
	bu_strlcpy( mat.shader, tok, TXT_NAME_SIZE );
    }
    else
	mat.shader[0] = '\0';
    mat.shininess = -1;
    mat.transparency = -1.0;
    mat.lt_fraction = -1.0;
    VSETALL( mat.lt_dir, 0.0 );
    mat.lt_angle = -1.0;
    mat.tx_file[0] = '\0';
    mat.tx_w = -1;
    mat.tx_n = -1;

    bu_vls_strcpy( &vls, &mater->ma_shader[strlen(mat.shader)] );
    (void)bu_struct_parse( &vls, vrml_mat_parse, (char *)&mat );

    if ( bu_strncmp( "light", mat.shader, 5 ) == 0 )
    {
	/* this is a light source */
	is_light = 1;
    }
    else
    {
	fprintf( fp, "\t<Shape DEF=\"%s\">\n", full_path);
	fprintf( fp, "\t\t<Appearance>\n");

	if ( bu_strncmp( "plastic", mat.shader, 7 ) == 0 )
	{
	    if ( mat.shininess < 0 )
		mat.shininess = 10;
	    if ( mat.transparency < 0.0 )
		mat.transparency = 0.0;

	    fprintf( fp, "\t\t\t<Material diffuseColor=\"%g %g %g\" shininess=\"%g\" transparency=\"%g\" specularColor=\"%g %g %g\"/>\n", r, g, b, 1.0-exp(-(double)mat.shininess/20.0), mat.transparency, 1.0, 1.0, 1.0);
	}
	else if ( bu_strncmp( "glass", mat.shader, 5 ) == 0 )
	{
	    if ( mat.shininess < 0 )
		mat.shininess = 4;
	    if ( mat.transparency < 0.0 )
		mat.transparency = 0.8;

	    fprintf( fp, "\t\t\t<Material diffuseColor=\"%g %g %g\" shininess=\"%g\" transparency=\"%g\" specularColor=\"%g %g %g\"/>\n", r, g, b, 1.0-exp(-(double)mat.shininess/20.0), mat.transparency, 1.0, 1.0, 1.0);
	}
	else if ( mater->ma_color_valid )
	{
	    fprintf( fp, "\t\t\t<Material diffuseColor=\"%g %g %g\"/>\n", r, g, b);
	}
	else
	{
	    /* If no color was defined set the colors according to the thousands groups */
	    int thou = comb->region_id/1000;
	    thou == 0 ? fprintf( fp, "\t\t\t<Material USE=\"Material_999\"/>\n")
		: thou == 1 ? fprintf( fp, "\t\t\t<Material USE=\"Material_1999\"/>\n")
		: thou == 2 ? fprintf( fp, "\t\t\t<Material USE=\"Material_2999\"/>\n")
		: thou == 3 ? fprintf( fp, "\t\t\t<Material USE=\"Material_3999\"/>\n")
		: thou == 4 ? fprintf( fp, "\t\t\t<Material USE=\"Material_4999\"/>\n")
		: thou == 5 ? fprintf( fp, "\t\t\t<Material USE=\"Material_5999\"/>\n")
		: thou == 6 ? fprintf( fp, "\t\t\t<Material USE=\"Material_6999\"/>\n")
		: thou == 7 ? fprintf( fp, "\t\t\t<Material USE=\"Material_7999\"/>\n")
		: thou == 8 ? fprintf( fp, "\t\t\t<Material USE=\"Material_8999\"/>\n")
		: fprintf( fp, "\t\t\t<Material USE=\"Material_9999\"/>\n");
	}
    }

    if ( !is_light )
    {
	process_non_light(m);
	fprintf( fp, "\t\t</Appearance>\n");
    }

    /* FIXME: need code to handle light */

    /* get list of vertices */
    nmg_vertex_tabulate( &verts, &m->magic );

    fprintf( fp, "\t\t<IndexedFaceSet coordIndex=\"\n");
    first = 1;
    if ( !is_light )
    {
	for ( BU_LIST_FOR( reg, nmgregion, &m->r_hd ) )
	{
	    struct shell *s;

	    NMG_CK_REGION( reg );
	    for ( BU_LIST_FOR( s, shell, &reg->s_hd ) )
	    {
		struct faceuse *fu;

		NMG_CK_SHELL( s );
		for ( BU_LIST_FOR( fu, faceuse, &s->fu_hd ) )
		{
		    struct loopuse *lu;

		    NMG_CK_FACEUSE( fu );

		    if ( fu->orientation != OT_SAME )
			continue;

		    for ( BU_LIST_FOR( lu, loopuse, &fu->lu_hd ) )
		    {
			struct edgeuse *eu;

			NMG_CK_LOOPUSE( lu );

			if ( BU_LIST_FIRST_MAGIC( &lu->down_hd ) != NMG_EDGEUSE_MAGIC )
			    continue;

			if ( !first )
			    fprintf( fp, ",\n" );
			else
			    first = 0;

			fprintf( fp, "\t\t\t\t" );
			for ( BU_LIST_FOR( eu, edgeuse, &lu->down_hd ) )
			{
			    struct vertex *v;

			    NMG_CK_EDGEUSE( eu );

			    v = eu->vu_p->v_p;
			    NMG_CK_VERTEX( v );
			    fprintf( fp, " %d,", bu_ptbl_locate( &verts, (long *)v ) );
			}
			fprintf( fp, "-1" );
		    }
		}
	    }
	}
	/* close coordIndex */
	fprintf( fp, "\" ");
	fprintf( fp, "normalPerVertex=\"false\" ");
	fprintf( fp, "convex=\"false\" ");
	fprintf( fp, "creaseAngle=\"0.5\" ");
	/* close IndexedFaceSet open tag */
	fprintf( fp, ">\n");
    }

    fprintf( fp, "\t\t\t<Coordinate point=\"");

    for ( i=0; i<BU_PTBL_END( &verts ); i++ )
    {
	struct vertex *v;
	struct vertex_g *vg;
	point_t pt_meters;

	v = (struct vertex *)BU_PTBL_GET( &verts, i );
	NMG_CK_VERTEX( v );
	vg = v->vg_p;
	NMG_CK_VERTEX_G( vg );

	/* convert to desired units */
	VSCALE( pt_meters, vg->coord, scale_factor );

	if ( is_light )
	    VADD2( ave_pt, ave_pt, pt_meters );
	if ( first )
	{
	    if ( !is_light )
		fprintf( fp, " %10.10e %10.10e %10.10e, ", V3ARGS(pt_meters));
	    first = 0;
	}
	else
	    if ( !is_light )
		fprintf( fp, "%10.10e %10.10e %10.10e, ", V3ARGS( pt_meters ));
    }

    /* close point */
    fprintf(fp, "\"");
    /* close Coordinate */
    fprintf(fp, "/>\n");
    /* IndexedFaceSet end tag */
    fprintf( fp, "\t\t</IndexedFaceSet>\n");
    /* Shape end tag */
    fprintf( fp, "\t</Shape>\n");

    BARRIER_CHECK;
}
Exemple #6
0
void
render_cut_work(render_t *render, struct tie_s *tiep, struct tie_ray_s *ray, vect_t *pixel)
{
    render_cut_t *rd;
    render_cut_hit_t hit;
    vect_t color;
    struct tie_id_s id;
    tfloat t, dot;

    rd = (render_cut_t *)render->data;

    /* Draw Arrow - Blue */
    if (tie_work(&rd->tie, ray, &id, render_arrow_hit, NULL)) {
	VSET(*pixel, 0.0, 0.0, 1.0);
	return;
    }

    /*
     * I don't think this needs to be done for every pixel?
     * Flip plane normal to face us.
     */
    t = ray->pos[0]*rd->plane[0] + ray->pos[1]*rd->plane[1] + ray->pos[2]*rd->plane[2] + rd->plane[3];
    hit.mod = t < 0 ? 1 : -1;


    /*
     * Optimization:
     * First intersect this ray with the plane and fire the ray from there
     * Plane: Ax + By + Cz + D = 0
     * Ray = O + td
     * t = -(Pn · R0 + D) / (Pn · Rd)
     */
    t = (rd->plane[0]*ray->pos[0] + rd->plane[1]*ray->pos[1] + rd->plane[2]*ray->pos[2] + rd->plane[3]) /
	(rd->plane[0]*ray->dir[0] + rd->plane[1]*ray->dir[1] + rd->plane[2]*ray->dir[2]);

    /* Ray never intersects plane */
    if (t > 0)
	return;

    ray->pos[0] += -t * ray->dir[0];
    ray->pos[1] += -t * ray->dir[1];
    ray->pos[2] += -t * ray->dir[2];
    HMOVE(hit.plane, rd->plane);

    /* Render Geometry */
    if (!tie_work(tiep, ray, &id, render_cut_hit, &hit))
	return;

    /*
     * If the point after the splitting plane is an outhit, fill it in as if it were solid.
     * If the point after the splitting plane is an inhit, then just shade as usual.
     */

    /* flipped normal */
    dot = fabs(VDOT( ray->dir,  hit.id.norm));

    if (hit.mesh->flags & (ADRT_MESH_SELECT|ADRT_MESH_HIT)) {
	VSET(color, hit.mesh->flags & ADRT_MESH_HIT ? (tfloat)0.9 : (tfloat)0.2, (tfloat)0.2, hit.mesh->flags & ADRT_MESH_SELECT ? (tfloat)0.9 : (tfloat)0.2);
    } else {
	/* Mix actual color with white 4:1, shade 50% darker */
#if 0
	VSET(color, 1.0, 1.0, 1.0);
	VSCALE(color,  color,  3.0);
	VADD2(color,  color,  hit.mesh->attributes->color);
	VSCALE(color,  color,  0.125);
#else
	VSET(color, (tfloat)0.8, (tfloat)0.8, (tfloat)0.7);
#endif
    }

#if 0
    if (dot < 0) {
#endif
	/* Shade using inhit */
	VSCALE((*pixel),  color,  (dot*0.90));
#if 0
    } else {
	TIE_3 vec;
	fastf_t angle;
	/* shade solid */
	VSUB2(vec,  ray->pos,  hit.id.pos);
	VUNITIZE(vec);
	angle = vec[0]*hit.mod*-hit.plane[0] + vec[1]*-hit.mod*hit.plane[1] + vec[2]*-hit.mod*hit.plane[2];
	VSCALE((*pixel),  color,  (angle*0.90));
    }
#endif

    *pixel[0] += (tfloat)0.1;
    *pixel[1] += (tfloat)0.1;
    *pixel[2] += (tfloat)0.1;
}
Exemple #7
0
int
_ged_translate_tgc(struct ged *gedp, struct rt_tgc_internal *tgc, const char *attribute, vect_t tvec, int rflag)
{
    fastf_t la, lb, lc, ld;
    vect_t hvec;

    RT_TGC_CK_MAGIC(tgc);

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

    switch (attribute[0]) {
	case 'h':
	case 'H':
	    switch (attribute[1]) {
		case '\0':
		    if (rflag) {
			VADD2(hvec, tgc->h, tvec);
		    } else {
			VSUB2(hvec, tvec, tgc->v);
		    }

		    /* check for zero H vector */
		    if (MAGNITUDE(hvec) <= SQRT_SMALL_FASTF) {
			bu_vls_printf(gedp->ged_result_str, "Zero H vector not allowed.");
			return GED_ERROR;
		    }

		    VMOVE(tgc->h, hvec);

		    break;
		case 'r':
		case 'R':
		    if (attribute[2] != '\0') {
			bu_vls_printf(gedp->ged_result_str, "bad tgc attribute - %s", attribute);
			return GED_ERROR;
		    }

		    if (rflag) {
			VADD2(hvec, tgc->h, tvec);
		    } else {
			VSUB2(hvec, tvec, tgc->v);
		    }

		    /* check for zero H vector */
		    if (MAGNITUDE(hvec) <= SQRT_SMALL_FASTF) {
			bu_vls_printf(gedp->ged_result_str, "Zero H vector not allowed.");
			return GED_ERROR;
		    }

		    VMOVE(tgc->h, hvec);

		    /* have new height vector -- redefine rest of tgc */
		    la = MAGNITUDE(tgc->a);
		    lb = MAGNITUDE(tgc->b);
		    lc = MAGNITUDE(tgc->c);
		    ld = MAGNITUDE(tgc->d);

		    /* find 2 perpendicular vectors normal to H for new A, B */
		    VCROSS(tgc->b, tgc->h, tgc->a);
		    VCROSS(tgc->a, tgc->b, tgc->h);

		    VUNITIZE(tgc->a);
		    VUNITIZE(tgc->b);

		    /* Create new C, D from unit length A, B, with previous len */
		    VSCALE(tgc->c, tgc->a, lc);
		    VSCALE(tgc->d, tgc->b, ld);

		    /* Restore original vector lengths to A, B */
		    VSCALE(tgc->a, tgc->a, la);
		    VSCALE(tgc->b, tgc->b, lb);

		    break;
		default:
		    bu_vls_printf(gedp->ged_result_str, "bad tgc attribute - %s", attribute);
		    return GED_ERROR;
	    }

	    break;
	default:
	    bu_vls_printf(gedp->ged_result_str, "bad tgc attribute - %s", attribute);
	    return GED_ERROR;
    }

    return GED_OK;
}
Exemple #8
0
extern "C" void
rt_revolve_brep(ON_Brep **b, const struct rt_db_internal *ip, const struct bn_tol *tol)
{
    struct rt_db_internal *tmp_internal;
    struct rt_revolve_internal *rip;
    struct rt_sketch_internal *eip;

    BU_ALLOC(tmp_internal, struct rt_db_internal);
    RT_DB_INTERNAL_INIT(tmp_internal);

    rip = (struct rt_revolve_internal *)ip->idb_ptr;
    RT_REVOLVE_CK_MAGIC(rip);
    eip = rip->skt;
    RT_SKETCH_CK_MAGIC(eip);

    ON_3dPoint plane_origin;
    ON_3dVector plane_x_dir, plane_y_dir;

    bool full_revolve = true;
    if (rip->ang < 2*ON_PI && rip->ang > 0)
	full_revolve = false;

    //  Find plane in 3 space corresponding to the sketch.

    vect_t startpoint;
    VADD2(startpoint, rip->v3d, rip->r);
    plane_origin = ON_3dPoint(startpoint);
    plane_x_dir = ON_3dVector(eip->u_vec);
    plane_y_dir = ON_3dVector(eip->v_vec);
    const ON_Plane sketch_plane = ON_Plane(plane_origin, plane_x_dir, plane_y_dir);

    //  For the brep, need the list of 3D vertex points.  In sketch, they
    //  are stored as 2D coordinates, so use the sketch_plane to define 3 space
    //  points for the vertices.
    for (size_t i = 0; i < eip->vert_count; i++) {
	(*b)->NewVertex(sketch_plane.PointAt(eip->verts[i][0], eip->verts[i][1]), 0.0);
    }

    // Create the brep elements corresponding to the sketch lines, curves
    // and bezier segments. Create 2d, 3d and BrepEdge elements for each segment.
    // Will need to use the bboxes of each element to
    // build the overall bounding box for the face. Use bGrowBox to expand
    // a single box.
    struct line_seg *lsg;
    struct carc_seg *csg;
    struct bezier_seg *bsg;
    uint32_t *lng;
    for (size_t i = 0; i < (&eip->curve)->count; i++) {
	lng = (uint32_t *)(&eip->curve)->segment[i];
	switch (*lng) {
	    case CURVE_LSEG_MAGIC: {
		lsg = (struct line_seg *)lng;
		ON_Curve* lsg3d = new ON_LineCurve((*b)->m_V[lsg->start].Point(), (*b)->m_V[lsg->end].Point());
		lsg3d->SetDomain(0.0, 1.0);
		(*b)->m_C3.Append(lsg3d);
	    }
		break;
	    case CURVE_CARC_MAGIC:
		csg = (struct carc_seg *)lng;
		if (csg->radius < 0) { {
		    ON_3dPoint cntrpt = (*b)->m_V[csg->end].Point();
		    ON_3dPoint edgept = (*b)->m_V[csg->start].Point();
		    ON_Plane cplane = ON_Plane(cntrpt, plane_x_dir, plane_y_dir);
		    ON_Circle c3dcirc = ON_Circle(cplane, cntrpt.DistanceTo(edgept));
		    ON_Curve* c3d = new ON_ArcCurve((const ON_Circle)c3dcirc);
		    c3d->SetDomain(0.0, 1.0);
		    (*b)->m_C3.Append(c3d);
		}
		} else {
		    // need to calculated 3rd point on arc - look to sketch.c around line 581 for
		    // logic
		}
		break;
	    case CURVE_BEZIER_MAGIC:
		bsg = (struct bezier_seg *)lng;
		{
		    ON_3dPointArray bezpoints = ON_3dPointArray(bsg->degree + 1);
		    for (int j = 0; j < bsg->degree + 1; j++) {
			bezpoints.Append((*b)->m_V[bsg->ctl_points[j]].Point());
		    }
		    ON_BezierCurve bez3d = ON_BezierCurve((const ON_3dPointArray)bezpoints);
		    ON_NurbsCurve* beznurb3d = ON_NurbsCurve::New();
		    bez3d.GetNurbForm(*beznurb3d);
		    beznurb3d->SetDomain(0.0, 1.0);
		    (*b)->m_C3.Append(beznurb3d);
		}
		break;
	    default:
		bu_log("Unhandled sketch object\n");
		break;
	}
    }

    vect_t endpoint;
    VADD2(endpoint, rip->v3d, rip->axis3d);
    const ON_Line& revaxis = ON_Line(ON_3dPoint(rip->v3d), ON_3dPoint(endpoint));

    FindLoops(b, &revaxis, rip->ang);

    // Create the two boundary surfaces, if it's not a full revolution
    if (!full_revolve) {
	// First, deduce the transformation matrices to calculate the position of the end surface
	// The transformation matrices are to rotate an arbitrary point around an arbitrary axis
	// Let the point A = (x, y, z), the rotation axis is p1p2 = (x2,y2,z2)-(x1,y1,z1) = (a,b,c)
	// Then T1 is to translate p1 to the origin
	// Rx is to rotate p1p2 around the X axis to the plane XOZ
	// Ry is to rotate p1p2 around the Y axis to be coincident to Z axis
	// Rz is to rotate A with the angle around Z axis (the new p1p2)
	// RxInv, RyInv, T1Inv are the inverse transformation of Rx, Ry, T1, respectively.
	// The whole transformation is A' = A*T1*Rx*Ry*Rz*Ry*Inv*Rx*Inv = A*R
	vect_t end_plane_origin, end_plane_x_dir, end_plane_y_dir;
	mat_t R;
	MAT_IDN(R);
	mat_t T1, Rx, Ry, Rz, RxInv, RyInv, T1Inv;
	MAT_IDN(T1);
	VSET(&T1[12], -rip->v3d[0], -rip->v3d[1], -rip->v3d[2]);
	MAT_IDN(Rx);
	fastf_t v = sqrt(rip->axis3d[1]*rip->axis3d[1]+rip->axis3d[2]*rip->axis3d[2]);
	VSET(&Rx[4], 0, rip->axis3d[2]/v, rip->axis3d[1]/v);
	VSET(&Rx[8], 0, -rip->axis3d[1]/v, rip->axis3d[2]/v);
	MAT_IDN(Ry);
	fastf_t u = MAGNITUDE(rip->axis3d);
	VSET(&Ry[0], v/u, 0, -rip->axis3d[0]/u);
	VSET(&Ry[8], rip->axis3d[0]/u, 0, v/u);
	MAT_IDN(Rz);
	fastf_t C, S;
	C = cos(rip->ang);
	S = sin(rip->ang);
	VSET(&Rz[0], C, S, 0);
	VSET(&Rz[4], -S, C, 0);
	bn_mat_inv(RxInv, Rx);
	bn_mat_inv(RyInv, Ry);
	bn_mat_inv(T1Inv, T1);
	mat_t temp;
	bn_mat_mul4(temp, T1, Rx, Ry, Rz);
	bn_mat_mul4(R, temp, RyInv, RxInv, T1Inv);
	VEC3X3MAT(end_plane_origin, plane_origin, R);
	VADD2(end_plane_origin, end_plane_origin, &R[12]);
	VEC3X3MAT(end_plane_x_dir, plane_x_dir, R);
	VEC3X3MAT(end_plane_y_dir, plane_y_dir, R);

	// Create the start and end surface with rt_sketch_brep()
	struct rt_sketch_internal sketch;
	sketch = *(rip->skt);
	ON_Brep *b1 = ON_Brep::New();
	VMOVE(sketch.V, plane_origin);
	VMOVE(sketch.u_vec, plane_x_dir);
	VMOVE(sketch.v_vec, plane_y_dir);
	tmp_internal->idb_ptr = (void *)(&sketch);
	rt_sketch_brep(&b1, tmp_internal, tol);
	(*b)->Append(*b1->Duplicate());

	ON_Brep *b2 = ON_Brep::New();
	VMOVE(sketch.V, end_plane_origin);
	VMOVE(sketch.u_vec, end_plane_x_dir);
	VMOVE(sketch.v_vec, end_plane_y_dir);
	tmp_internal->idb_ptr = (void *)(&sketch);
	rt_sketch_brep(&b2, tmp_internal, tol);
	(*b)->Append(*b2->Duplicate());
	(*b)->FlipFace((*b)->m_F[(*b)->m_F.Count()-1]);
    }
    bu_free(tmp_internal, "free temporary rt_db_internal");
}
int
main (int argc, char *argv[])
{
    int val;
    /* intentionally double for scan */
    double elapsed, yaw1, pitch1, roll1, yaw2, pitch2, roll2;
    double cen1[3], cen2[3];

    vect_t rad_ang_ans, cen_ans, ang_ans, rotated = VINIT_ZERO;
    mat_t m_rot1, m_rot2, m_ans;
    int one_time, read_cen1, read_cen2, read_rot1, read_rot2;

    if (argc == 1 && isatty(fileno(stdin)) && isatty(fileno(stdout))) {
	usage();
	return 0;
    }

    if (!get_args(argc, argv)) {
	usage();
	return 0;
    }

    read_cen1 = read_cen2 = read_rot1 = read_rot2 = 1;

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


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

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

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

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

	if (one_time) break;
    }
    return 0;
}
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;
}
int
block(int entityno)
{

    fastf_t xscale = 0.0;
    fastf_t yscale = 0.0;
    fastf_t zscale = 0.0;
    fastf_t x_1, y_1, z_1;		/* First vertex components */
    fastf_t x_2, y_2, z_2;		/* xdir vector components */
    fastf_t x_3, y_3, z_3;		/* zdir vector components */
    point_t v;			/* the first vertex */
    vect_t xdir;			/* a unit vector */
    vect_t xvec;			/* vector along x-axis */
    vect_t ydir;			/* a unit vector */
    vect_t yvec;			/* vector along y-axis */
    vect_t zdir;			/* a unit vector */
    vect_t zvec;			/* vector along z-axis */
    point_t pts[9];			/* array of points */
    int sol_num;		/* IGES solid type number */

    /* Default values */
    x_1 = 0.0;
    y_1 = 0.0;
    z_1 = 0.0;
    x_2 = 1.0;
    y_2 = 0.0;
    z_2 = 0.0;
    x_3 = 0.0;
    y_3 = 0.0;
    z_3 = 1.0;


    /* Acquiring Data */

    if (dir[entityno]->param <= pstart) {
	bu_log("Illegal parameter pointer for entity D%07d (%s)\n" ,
	       dir[entityno]->direct, dir[entityno]->name);
	return 0;
    }

    Readrec(dir[entityno]->param);
    Readint(&sol_num, "");
    Readcnv(&xscale, "");
    Readcnv(&yscale, "");
    Readcnv(&zscale, "");
    Readcnv(&x_1, "");
    Readcnv(&y_1, "");
    Readcnv(&z_1, "");
    Readflt(&x_2, "");
    Readflt(&y_2, "");
    Readflt(&z_2, "");
    Readflt(&x_3, "");
    Readflt(&y_3, "");
    Readflt(&z_3, "");

    if (xscale <= 0.0 || yscale <= 0.0 || zscale <= 0.0) {
	bu_log("Illegal parameters for entity D%07d (%s)\n" ,
	       dir[entityno]->direct, dir[entityno]->name);
	return 0;
    }

    /*
     * Making the necessaries. First an id is made for the new entity.
     * Then the vertices for the bottom and top faces are found.  Point
     * is located in the lower left corner of the solid, and the vertices are
     * counted in the counter-clockwise direction, around the bottom face.
     * Next these vertices are extruded to form the top face.  The points
     * thus made are loaded into an array of points and handed off to mk_arb8().
     * Make and unitize necessary vectors.
     */

    VSET(xdir, x_2, y_2, z_2);			/* Makes x-dir vector */
    VUNITIZE(xdir);
    VSET(zdir, x_3, y_3, z_3);			/* Make z-dir vector */
    VUNITIZE(zdir);
    VCROSS(ydir, zdir, xdir);		/* Make y-dir vector */

    /* Scale all vectors */

    VSCALE(xvec, xdir, xscale);
    VSCALE(zvec, zdir, zscale);
    VSCALE(yvec, ydir, yscale);

    /* Make the bottom face. */

    VSET(v, x_1, y_1, z_1);			/* Yields first vertex */
    VMOVE(pts[0], v);			/* put first vertex into array */
    VADD2(pts[1], v, xvec);			/* Finds second vertex */
    VADD3(pts[2], v, xvec, yvec);		/* Finds third vertex */
    VADD2(pts[3], v, yvec);			/* Finds fourth vertex */

    /* Now extrude the bottom face to make the top.
     */

    VADD2(pts[4], v, zvec);			/* Finds fifth vertex */
    VADD2(pts[5], pts[1], zvec);		/* Finds sixth vertex */
    VADD2(pts[6], pts[2], zvec);		/* Finds seventh vertex */
    VADD2(pts[7], pts[3], zvec);		/* Find eighth vertex */


    /* Now the information is handed off to mk_arb8(). */

    mk_arb8(fdout, dir[entityno]->name, &pts[0][X]);

    return 1;


}
Exemple #12
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;
}
Exemple #13
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;
}
Exemple #14
0
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;
}
Exemple #15
0
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;
}
Exemple #16
0
/*
 * 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;
}