Example #1
0
int
_ged_scale_extrude(struct ged *gedp, struct rt_extrude_internal *extrude, const char *attribute, fastf_t sf, int rflag)
{
    vect_t hvec;

    RT_EXTRUDE_CK_MAGIC(extrude);

    switch (attribute[0]) {
	case 'h':
	case 'H':
	    if (!rflag)
		sf /= MAGNITUDE(extrude->h);

	    VSCALE(hvec, extrude->h, sf);

	    /* Make sure hvec is not zero length */
	    if (MAGNITUDE(hvec) > SQRT_SMALL_FASTF) {
		VMOVE(extrude->h, hvec);
	    }

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

    return GED_OK;
}
Example #2
0
int
_ged_scale_rpc(struct ged *gedp, struct rt_rpc_internal *rpc, const char *attribute, fastf_t sf, int rflag)
{
    RT_RPC_CK_MAGIC(rpc);

    switch (attribute[0]) {
	case 'b':
	case 'B':
	    if (!rflag)
		sf /= MAGNITUDE(rpc->rpc_B);

	    VSCALE(rpc->rpc_B, rpc->rpc_B, sf);
	    break;
	case 'h':
	case 'H':
	    if (!rflag)
		sf /= MAGNITUDE(rpc->rpc_H);

	    VSCALE(rpc->rpc_H, rpc->rpc_H, sf);
	    break;
	case 'r':
	case 'R':
	    if (rflag)
		rpc->rpc_r *= sf;
	    else
		rpc->rpc_r = sf;

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

    return GED_OK;
}
Example #3
0
File: hyp.c Project: kanzure/brlcad
struct hyp_specific *
hyp_internal_to_specific(struct rt_hyp_internal *hyp_in) {
    struct hyp_specific *hyp;
    BU_GET(hyp, struct hyp_specific);

    hyp->hyp_r1 = hyp_in->hyp_bnr * MAGNITUDE(hyp_in->hyp_A);
    hyp->hyp_r2 = hyp_in->hyp_bnr * hyp_in->hyp_b;
    hyp->hyp_c = sqrt(4 * MAGSQ(hyp_in->hyp_A) / MAGSQ(hyp_in->hyp_Hi) * (1 - hyp_in->hyp_bnr * hyp_in->hyp_bnr));

    VSCALE(hyp->hyp_H, hyp_in->hyp_Hi, 0.5);
    VADD2(hyp->hyp_V, hyp_in->hyp_Vi, hyp->hyp_H);
    VMOVE(hyp->hyp_Au, hyp_in->hyp_A);
    VUNITIZE(hyp->hyp_Au);

    hyp->hyp_rx = 1.0 / (hyp->hyp_r1 * hyp->hyp_r1);
    hyp->hyp_ry = 1.0 / (hyp->hyp_r2 * hyp->hyp_r2);
    hyp->hyp_rz = (hyp->hyp_c * hyp->hyp_c) / (hyp->hyp_r1 * hyp->hyp_r1);

    /* calculate height to use for top/bottom intersection planes */
    hyp->hyp_Hmag = MAGNITUDE(hyp->hyp_H);
    hyp->hyp_bounds = hyp->hyp_rz*hyp->hyp_Hmag*hyp->hyp_Hmag + 1.0;

    /* setup unit vectors for hyp_specific */
    VMOVE(hyp->hyp_Hunit, hyp->hyp_H);
    VMOVE(hyp->hyp_Aunit, hyp->hyp_Au);
    VCROSS(hyp->hyp_Bunit, hyp->hyp_Hunit, hyp->hyp_Aunit);

    VUNITIZE(hyp->hyp_Aunit);
    VUNITIZE(hyp->hyp_Bunit);
    VUNITIZE(hyp->hyp_Hunit);

    return hyp;
}
Example #4
0
void
top(fastf_t *vec1, fastf_t *vec2, fastf_t *t)
{
    fastf_t	tooch, mag;
    vect_t	del, tvec;
    int i, j;

    tooch = t[2] * .25;
    del[0] = vec2[0] - vec1[0];
    del[1] = 0.0;
    del[2] = vec2[2] - vec1[2];
    mag = MAGNITUDE( del );
    VSCALE(tvec, del, tooch/mag);
    VSUB2(&sol.s_values[0], vec1, tvec);
    VADD2(del, del, tvec);
    VADD2(&sol.s_values[3], del, tvec);
    tvec[0] = tvec[2] = 0.0;
    tvec[1] = t[1] - t[0];
    VCROSS(del, tvec, &sol.s_values[3]);
    mag = MAGNITUDE( del );
    if (del[2] < 0)
	mag *= -1.0;
    VSCALE(&sol.s_values[9], del, t[2]/mag);
    VADD2(&sol.s_values[6], &sol.s_values[3], &sol.s_values[9]);
    VMOVE(&sol.s_values[12], tvec);

    for (i=3; i<=9; i+=3) {
	j = i + 12;
	VADD2(&sol.s_values[j], &sol.s_values[i], tvec);
    }
}
Example #5
0
EXPR *ExprFindCommensurate( EXPR *expr )
    {
    unsigned int i, j ;
    EXPR *tmp, *tmp2 ;

    for( i = 0 ; i < U(UnitList)->used ; i++ )
	{
	if( U(UN(i))->used != U(expr)->used )
	    continue ;
	for( j = 1 ; j < U(expr)->used ; j++ )
	    {
	    if( !BooleanValue( (BOOL*) OP3( "?=", U(UN(i))->list[j], U(expr)->list[j] ) ) )
		break ;
	    }
	if( j == U(expr)->used )			/* found one */
	    {
	    tmp = OP3( "/", U(expr)->list[0], U(UN(i))->list[0] ) ;
	    tmp2 = Real( MAGNITUDE( tmp ), i ) ;
	    delete tmp ;
	    delete expr ;
	    return tmp2 ;
	    }
	}

    for( i = 1 ; i < U(expr)->used ; i++ )
	{
	if( IS_ZERO( U(expr)->list[i] ) )
	    continue ;
	if( MAGNITUDE( U(expr)->list[i] ) == 1.0 )
	    tmp = U(UN(i))->Ehead->Copy() ;
	else
	    {
	    tmp = Operator( OPER_POW ) ;
	    D(tmp)->Eleft = U(UN(i))->Ehead->Copy() ;
	    D(tmp)->Eright = U(expr)->list[i]->Copy() ;
	    }
	if( U(expr)->Eeval )
	    {
	    tmp2 = Operator( OPER_MULTIPLY ) ;
	    D(tmp2)->Eleft = U(expr)->Eeval ;
	    D(tmp2)->Eright = tmp ;
	    U(expr)->Eeval = tmp2 ;
	    }
	else
	    U(expr)->Eeval = tmp ;
	}

    tmp = Real( MAGNITUDE( U(expr)->list[0] ), U(UnitList)->used ) ;
    delete U(expr)->list[0] ;
    U(expr)->list[0] = Real(1,0) ;
    ListAppend( UnitList, expr ) ;
    return tmp ;
    }
Example #6
0
void
rt_superell_surf_area(fastf_t *area, const struct rt_db_internal *ip)
{
    struct rt_superell_internal *sip;
    vect_t mags;

    RT_CK_DB_INTERNAL(ip);
    sip = (struct rt_superell_internal *)ip->idb_ptr;

    mags[0] = MAGNITUDE(sip->a);
    mags[1] = MAGNITUDE(sip->b);
    mags[2] = MAGNITUDE(sip->c);

    /* The parametric representation does not work correctly at n = e
     * = 0, so this uses a special calculation for boxes.
     */
    if ((NEAR_EQUAL(sip->e, 0, BN_TOL_DIST)) && NEAR_EQUAL(sip->n, 0, BN_TOL_DIST)) {
        *area = superell_surf_area_box(mags);
    } else {
        /* This number specifies the initial precision used. The
         * precision is roughly the number of chunks that the uv-space
         * is divided into during the approximation; the larger the
         * number the higher the accuracy and the lower the
         * performance.
         */
        int precision = 1024;

        fastf_t previous_area = 0;
        fastf_t current_area = superell_surf_area_general(sip, mags, M_PI / precision);
        while (!(NEAR_EQUAL(current_area, previous_area, BN_TOL_DIST))) {
            /* The precision is multiplied by a constant on each round
             * through the loop to make sure that the precision
             * continues to increase until a satisfactory value is
             * found. If this value is very small, this approximation
             * will likely converge fairly quickly and with lower
             * accuracy: the smaller the distance between the inputs
             * the more likely that the outputs will be within
             * BN_TOL_DIST. A large value will result in slow
             * convergence, but in high accuracy: when the values are
             * finally within BN_TOL_DIST of each other the
             * approximation must be very good, because a large
             * increase in input precision resulted in a small
             * increase in accuracy.
             */
            precision *= 2;
            previous_area = current_area;
            current_area = superell_surf_area_general(sip, mags, M_PI / precision);
        }
        *area = current_area;
    }
}
HIDDEN int
rt_pattern_rect_orthogrid(fastf_t **rays, size_t *ray_cnt, const point_t center_pt, const vect_t dir,
		const vect_t a_vec, const vect_t b_vec, const fastf_t da, const fastf_t db)
{
    int count = 0;
    point_t pt;
    vect_t a_dir;
    vect_t b_dir;
    fastf_t x, y;
    fastf_t a_length = MAGNITUDE(a_vec);
    fastf_t b_length = MAGNITUDE(b_vec);

    if (!rays || !ray_cnt) return -1;

    VMOVE(a_dir, a_vec);
    VUNITIZE(a_dir);

    VMOVE(b_dir, b_vec);
    VUNITIZE(b_dir);

    /* Find out how much memory we'll need and get it */
    for (y = -b_length; y <= b_length; y += db) {
	for (x = -a_length; x <= a_length; x += da) {
	    count++;
	}
    }
    *(rays) = (fastf_t *)bu_calloc(sizeof(fastf_t) * 6, count + 1, "rays");

    /* Now that we have memory, reset count so it can
     * be used to index into the array */
    count = 0;

    /* Build the rays */
    for (y = -b_length; y <= b_length; y += db) {
	for (x = -a_length; x <= a_length; x += da) {
	    VJOIN2(pt, center_pt, x, a_dir, y, b_dir);
	    (*rays)[6*count] = pt[0];
	    (*rays)[6*count+1] = pt[1];
	    (*rays)[6*count+2] = pt[2];
	    (*rays)[6*count+3] = dir[0];
	    (*rays)[6*count+4] = dir[1];
	    (*rays)[6*count+5] = dir[2];
	    count++;
	}
    }
    *(ray_cnt) = count;
    return count;
}
Example #8
0
static int
hit_headon(struct application *ap, struct partition *PartHeadp)
{
    register char diff_solid;
    vect_t	diff;
    register fastf_t len;

    if (PartHeadp->pt_forw->pt_forw != PartHeadp)
	Tcl_AppendResult(interp, "hit_headon: multiple partitions\n", (char *)NULL);

    VJOIN1(PartHeadp->pt_forw->pt_inhit->hit_point, ap->a_ray.r_pt,
	   PartHeadp->pt_forw->pt_inhit->hit_dist, ap->a_ray.r_dir);
    VSUB2(diff, PartHeadp->pt_forw->pt_inhit->hit_point, aim_point);

    diff_solid = (FIRST_SOLID(sp) !=
		  PartHeadp->pt_forw->pt_inseg->seg_stp->st_dp);
    len = MAGNITUDE(diff);

    if (	NEAR_ZERO(len, epsilon)
		||
		( diff_solid &&
		  VDOT(diff, ap->a_ray.r_dir) > 0 )
	)
	return(1);
    else
	return(0);
}
/**
 * For a hit on the surface of an METABALL, return the (u, v)
 * coordinates of the hit point, 0 <= u, v <= 1.
 *
 * u = azimuth
 * v = elevation
 */
void
rt_metaball_uv(struct application *ap, struct soltab *stp, struct hit *hitp, struct uvcoord *uvp)
{
    struct rt_metaball_internal *metaball = (struct rt_metaball_internal *)stp->st_specific;
    vect_t work, pprime;
    fastf_t r;

    if (ap) RT_CK_APPLICATION(ap);
    if (stp) RT_CK_SOLTAB(stp);
    if (hitp) RT_CK_HIT(hitp);
    if (!uvp) return;
    if (!metaball) return;

    /* stuff stolen from sph */
    VSUB2(work, hitp->hit_point, stp->st_center);
    VSCALE(pprime, work, 1.0/MAGNITUDE(work));
    /* Assert that pprime has unit length */

    /* U is azimuth, atan() range: -pi to +pi */
    uvp->uv_u = bn_atan2(pprime[Y], pprime[X]) * M_1_2PI;
    if (uvp->uv_u < 0)
	uvp->uv_u += 1.0;
    /*
     * V is elevation, atan() range: -pi/2 to +pi/2, because sqrt()
     * ensures that X parameter is always >0
     */
    uvp->uv_v = bn_atan2(pprime[Z],
			 sqrt(pprime[X] * pprime[X] + pprime[Y] * pprime[Y])) * M_1_2PI;

    /* approximation: r / (circumference, 2 * pi * aradius) */
    r = ap->a_rbeam + ap->a_diverge * hitp->hit_dist;
    uvp->uv_du = uvp->uv_dv =
	M_1_2PI * r / stp->st_aradius;
    return;
}
int
_ged_scale_part(struct ged *gedp, struct rt_part_internal *part, const char *attribute, fastf_t sf, int rflag)
{
    RT_PART_CK_MAGIC(part);

    switch (attribute[0]) {
	case 'H':
	    if (!rflag)
		sf /= MAGNITUDE(part->part_H);

	    VSCALE(part->part_H, part->part_H, sf);
	    break;
	case 'v':
	    if (rflag)
		part->part_vrad *= sf;
	    else
		part->part_vrad = sf;

	    break;
	case 'h':
	    if (rflag)
		part->part_hrad *= sf;
	    else
		part->part_hrad = sf;

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

    return GED_OK;
}
Example #11
0
double ExprCommensurate( int U1, int U2 )
    {
    unsigned int i ;
    double scale ;
    EXPR *tmp ;

return 1.0 ;						// EVIL HACK

    if( U1 == U2 )
	return 1.0 ;

    if( U(UN(U1))->used != U(UN(U2))->used )
	return 0.0 ;

    for( i = 1 ; i < U(UN(U1))->used ; i++ )
	{
	if( !BooleanValue( (BOOL*) OP3( "?=", U(UN(U1))->list[i], U(UN(U2))->list[i] ) ) )
	    return 0.0 ;
	}

    tmp = OP3( "/", U(UN(U2))->list[0], U(UN(U1))->list[0] ) ;
    scale = MAGNITUDE( tmp ) ;
    delete tmp ;
    return scale ;
    }
Example #12
0
void
tancir(register fastf_t *cir1, register fastf_t *cir2)
{
    static fastf_t mag;
    vect_t	work;
    fastf_t f;
    static fastf_t	temp, tempp, ang, angc;

    work[0] = cir2[0] - cir1[0];
    work[2] = cir2[1] - cir1[1];
    work[1] = 0.0;
    mag = MAGNITUDE( work );
    if ( mag > 1.0e-20 || mag < -1.0e-20 )  {
	f = 1.0/mag;
    }  else {
	Tcl_AppendResult(interp, "tancir():  0-length vector!\n", (char *)NULL);
	return;
    }
    VSCALE(work, work, f);
    temp = acos( work[0] );
    if ( work[2] < 0.0 )
	temp = 6.28318512717958646 - temp;
    tempp = acos( (cir1[2] - cir2[2]) * f );
    ang = temp + tempp;
    angc = temp - tempp;
    if ( (cir1[1] + cir1[2] * sin(ang)) >
	 (cir1[1] + cir1[2] * sin(angc)) )
	ang = angc;
    plano[0] = cir1[0] + cir1[2] * cos(ang);
    plano[1] = cir1[1] + cir1[2] * sin(ang);
    plant[0] = cir2[0] + cir2[2] * cos(ang);
    plant[1] = cir2[1] + cir2[2] * sin(ang);

    return;
}
Example #13
0
int
coplanar_3d_to_2d(point2d_t **points_2d, const point_t *origin_pnt,
		     const vect_t *u_axis, const vect_t *v_axis,
		     const point_t *points_3d, int n)
{
    int i = 0;
    for (i = 0; i < n; i++) {
	vect_t temp, c, d;
	fastf_t u, v;
	VSUB2(temp, points_3d[i], *origin_pnt);
	VPROJECT(temp, *u_axis, c, d);
	u = (VDOT(c, *u_axis) > 0.0) ? (MAGNITUDE(c)) : (-1.0 * MAGNITUDE(c));
	v = (VDOT(d, *v_axis) > 0.0) ? (MAGNITUDE(d)) : (-1.0 * MAGNITUDE(d));
	V2SET((*points_2d)[i], u, v);
    }

    return 0;
}
int
rt_gen_elliptical_grid(struct xrays *rays, const struct xray *center_ray, const fastf_t *avec, const fastf_t *bvec, fastf_t gridsize)
{
    register struct xrays *xrayp;
    int count = 0;
    point_t C;
    vect_t dir;
    vect_t a_dir;
    vect_t b_dir;

    fastf_t a = MAGNITUDE(avec);
    fastf_t b = MAGNITUDE(bvec);
    fastf_t x, y;

    int acpr = a / gridsize;
    int bcpr = b / gridsize;

    VMOVE(a_dir, avec);
    VUNITIZE(a_dir);

    VMOVE(b_dir, bvec);
    VUNITIZE(b_dir);

    VMOVE(C, center_ray->r_pt);
    VMOVE(dir, center_ray->r_dir);
    /* make sure avec perpendicular to bvec perpendicular to ray direction */
    BU_ASSERT(NEAR_ZERO(VDOT(avec, bvec), VUNITIZE_TOL));
    BU_ASSERT(NEAR_ZERO(VDOT(avec, dir), VUNITIZE_TOL));

    for (y=gridsize * (-bcpr); y <= b; y=y+gridsize) {
	for (x= gridsize * (-acpr); x <= a; x=x+gridsize) {
	    if (((x*x)/(a*a) + (y*y)/(b*b)) < 1) {
		BU_ALLOC(xrayp, struct xrays);
		VJOIN2(xrayp->ray.r_pt, C, x, a_dir, y, b_dir);
		VMOVE(xrayp->ray.r_dir, dir);
		xrayp->ray.index = count++;
		xrayp->ray.magic = RT_RAY_MAGIC;
		BU_LIST_APPEND(&rays->l, &xrayp->l);
	    }
	}
    }
    return count;
}
int rt_gen_rect(struct xrays *rays, const struct xray *center_ray,
		const vect_t a_vec, const vect_t b_vec,
		const fastf_t da, const fastf_t db)
{
    int count = 0;

    point_t orig_start;
    vect_t dir;

    fastf_t x, y;

    fastf_t a_length = MAGNITUDE(a_vec);
    fastf_t b_length = MAGNITUDE(b_vec);

    vect_t a_dir;
    vect_t b_dir;

    register struct xrays *xrayp;

    VMOVE(orig_start, center_ray->r_pt);
    VMOVE(dir, center_ray->r_dir);

    VMOVE(a_dir, a_vec);
    VUNITIZE(a_dir);

    VMOVE(b_dir, b_vec);
    VUNITIZE(b_dir);

    for (y = -b_length; y <= b_length; y += db) {
	for (x = -a_length; x <= a_length; x += da) {
	    BU_ALLOC(xrayp, struct xrays);
	    VJOIN2(xrayp->ray.r_pt, orig_start, x, a_dir, y, b_dir);
	    VMOVE(xrayp->ray.r_dir, dir);
	    xrayp->ray.index = count++;
	    xrayp->ray.magic = RT_RAY_MAGIC;
	    BU_LIST_APPEND(&rays->l, &xrayp->l);
	}
    }
    return count;
}
Example #16
0
/**
 * Classify a point vs a vertex (touching/missed)
 */
static int
nmg_class_pt_vu(struct fpi *fpi, struct vertexuse *vu)
{
    vect_t delta;
    struct ve_dist *ved;

    NMG_CK_VERTEXUSE(vu);

    /* see if we've classified this vertex WRT the point already */
    for (BU_LIST_FOR(ved, ve_dist, &fpi->ve_dh)) {
	NMG_CK_VED(ved);
	if (ved->magic_p == &vu->v_p->magic) {
	    goto found;
	}
    }

    /* if we get here, we didn't find the vertex in the list of
     * previously classified geometry.  Create an entry in the
     * face's list of processed geometry.
     */
    VSUB2(delta, vu->v_p->vg_p->coord, fpi->pt);

    BU_ALLOC(ved, struct ve_dist);
    ved->magic_p = &vu->v_p->magic;
    ved->dist = MAGNITUDE(delta);
    if (ved->dist < fpi->tol->dist_sq) {
	ved->status = NMG_FPI_TOUCHED;
	if (fpi->hits == NMG_FPI_PERGEOM) {
	    /* need to cast vu_func pointer for actual use as a function */
	    void (*cfp)(struct vertexuse *, point_t, const char*);
	    cfp = (void (*)(struct vertexuse *, point_t, const char *))fpi->vu_func;
	    cfp(vu, fpi->pt, fpi->priv);
	}
    } else ved->status = NMG_FPI_MISSED;

    ved->v1 = ved->v2 = vu->v_p;

    BU_LIST_MAGIC_SET(&ved->l, NMG_VE_DIST_MAGIC);
    BU_LIST_APPEND(&fpi->ve_dh, &ved->l);
found:

    if (fpi->vu_func  &&
	ved->status == NMG_FPI_TOUCHED &&
	fpi->hits == NMG_FPI_PERUSE) {
	/* need to cast vu_func pointer for actual use as a function */
	void (*cfp)(struct vertexuse *, point_t, const char*);
	cfp = (void (*)(struct vertexuse *, point_t, const char *))fpi->vu_func;
	cfp(vu, fpi->pt, fpi->priv);
    }

    return ved->status;
}
Example #17
0
/**
 * R T _ P G F A C E
 *
 * This function is called with pointers to 3 points,
 * and is used to prepare PG faces.
 * ap, bp, cp point to vect_t points.
 *
 * Return -
 * 0 if the 3 points didn't form a plane (e.g., colinear, etc.).
 * # pts (3) if a valid plane resulted.
 */
HIDDEN int
rt_pgface(struct soltab *stp, fastf_t *ap, fastf_t *bp, fastf_t *cp, const struct bn_tol *tol)
{
    struct tri_specific *trip;
    vect_t work;
    fastf_t m1, m2, m3, m4;

    BU_GET(trip, struct tri_specific);
    VMOVE(trip->tri_A, ap);
    VSUB2(trip->tri_BA, bp, ap);
    VSUB2(trip->tri_CA, cp, ap);
    VCROSS(trip->tri_wn, trip->tri_BA, trip->tri_CA);

    /* Check to see if this plane is a line or pnt */
    m1 = MAGNITUDE(trip->tri_BA);
    m2 = MAGNITUDE(trip->tri_CA);
    VSUB2(work, bp, cp);
    m3 = MAGNITUDE(work);
    m4 = MAGNITUDE(trip->tri_wn);
    if (m1 < tol->dist || m2 < tol->dist ||
	m3 < tol->dist || m4 < tol->dist) {
	BU_PUT(trip, struct tri_specific);
	if (RT_G_DEBUG & DEBUG_ARB8)
	    bu_log("pg(%s): degenerate facet\n", stp->st_name);
	return 0;			/* BAD */
    }

    /* wn is a normal of not necessarily unit length.
     * N is an outward pointing unit normal.
     * We depend on the points being given in CCW order here.
     */
    VMOVE(trip->tri_N, trip->tri_wn);
    VUNITIZE(trip->tri_N);

    /* Add this face onto the linked list for this solid */
    trip->tri_forw = (struct tri_specific *)stp->st_specific;
    stp->st_specific = (genptr_t)trip;
    return 3;				/* OK */
}
/**
 *@brief
 * Draw a vector between points "from" and "to", with the option of
 * having an arrowhead on either or both ends.
 *
 * The fromheadfract and toheadfract values indicate the length of the
 * arrowheads relative to the length of the vector to-from.  A typical
 * value is 0.1, making the head 10% of the size of the vector.  The
 * sign of the "fract" values indicates the pointing direction.
 * Positive points towards the "to" point, negative points towards
 * "from".  Upon return, the virtual pen is left at the "to" position.
 */
void
tp_3vector(FILE *plotfp, fastf_t *from, fastf_t *to, double fromheadfract, double toheadfract)
{
    register fastf_t len;
    register fastf_t hooklen;
    vect_t diff;
    vect_t c1, c2;
    vect_t h1, h2;
    vect_t backup;
    point_t tip;

    pdv_3line(plotfp, from, to);
    /* "pen" is left at "to" position */

    VSUB2(diff, to, from);
    if ((len = MAGNITUDE(diff)) < SMALL)  return;
    VSCALE(diff, diff, 1/len);
    bn_vec_ortho(c1, diff);
    VCROSS(c2, c1, diff);

    if (!ZERO(fromheadfract)) {
	hooklen = fromheadfract*len;
	VSCALE(backup, diff, -hooklen);

	VSCALE(h1, c1, hooklen);
	VADD3(tip, from, h1, backup);
	pdv_3move(plotfp, from);
	pdv_3cont(plotfp, tip);

	VSCALE(h2, c2, hooklen);
	VADD3(tip, from, h2, backup);
	pdv_3move(plotfp, tip);
    }
    if (!ZERO(toheadfract)) {
	hooklen = toheadfract*len;
	VSCALE(backup, diff, -hooklen);

	VSCALE(h1, c1, hooklen);
	VADD3(tip, to, h1, backup);
	pdv_3move(plotfp, to);
	pdv_3cont(plotfp, tip);

	VSCALE(h2, c2, hooklen);
	VADD3(tip, to, h2, backup);
	pdv_3move(plotfp, tip);
    }
    /* Be certain "pen" is left at "to" position */
    if (!ZERO(fromheadfract) || !ZERO(toheadfract))
	pdv_3cont(plotfp, to);

}
Example #19
0
void
quat_log(fastf_t *out, const fastf_t *in)
{
    fastf_t	theta;
    fastf_t	scale;

    if ( (scale = MAGNITUDE(in)) > VDIVIDE_TOL )  {
	theta = atan2( scale, in[W] );
	scale = theta/scale;
    }

    VSCALE( out, in, scale );
    out[W] = 0.0;
}
Example #20
0
void
quat_exp(fastf_t *out, const fastf_t *in)
{
    fastf_t	theta;
    fastf_t	scale;

    if ( (theta = MAGNITUDE( in )) > VDIVIDE_TOL )
	scale = sin(theta)/theta;
    else
	scale = 1.0;

    VSCALE( out, in, scale );
    out[W] = cos(theta);
}
Example #21
0
/**
 * Computes the volume of a superellipsoid
 *
 * Volume equation from http://lrv.fri.uni-lj.si/~franc/SRSbook/geometry.pdf
 * which also includes a derivation on page 32.
 */
void
rt_superell_volume(fastf_t *volume, const struct rt_db_internal *ip)
{
#ifdef HAVE_TGAMMA
    struct rt_superell_internal *sip;
    double mag_a, mag_b, mag_c;
#endif

    if (volume == NULL || ip == NULL) {
        return;
    }

#ifdef HAVE_TGAMMA
    RT_CK_DB_INTERNAL(ip);
    sip = (struct rt_superell_internal *)ip->idb_ptr;
    RT_SUPERELL_CK_MAGIC(sip);

    mag_a = MAGNITUDE(sip->a);
    mag_b = MAGNITUDE(sip->b);
    mag_c = MAGNITUDE(sip->c);

    *volume = 2.0 * mag_a * mag_b * mag_c * sip->e * sip->n * (tgamma(sip->n/2.0 + 1.0) * tgamma(sip->n) / tgamma(3.0 * sip->n/2.0 + 1.0)) * (tgamma(sip->e / 2.0) * tgamma(sip->e / 2.0) / tgamma(sip->e));
#endif
}
Example #22
0
/*
 * Replica of STEP function:
 *   FUNCTION first_proj_axis()
 */
void
Axis2Placement3D::FirstProjAxis(double *proj,double *zaxis, double *refdir) {
    double z[3] = VINIT_ZERO;
    double v[3] = VINIT_ZERO;
    double TOL = 1e-9;

    if (zaxis == NULL)
	return;

    VMOVE(z,zaxis);
    VUNITIZE(z);
    if (refdir == NULL) {
	double xplus[3]=  {1.0,0.0,0.0};
	double xminus[3]=  {-1.0,0.0,0.0};
	if (!VNEAR_EQUAL(z, xplus, TOL) &&
	    !VNEAR_EQUAL(z, xminus, TOL))  {
	    VSET(v,1.0,0.0,0.0);
	} else {
	    VSET(v,0.0,1.0,0.0);
	}
    } else {
	double cross[3];
	double mag;

	VCROSS(cross, refdir, z);
	mag = MAGNITUDE(cross);
	if (NEAR_ZERO(mag,TOL)) {
	    return;
	} else {
	    VMOVE(v,refdir);
	    VUNITIZE(v);
	}

    }
    double x_vec[3];
    double aproj[3];
    double dot = VDOT(v,z);
    ScalarTimesVector(x_vec, dot, z);
    VectorDifference(aproj,v,x_vec);
    VSCALE(x_vec,z,dot);
    VSUB2(aproj,v, x_vec);
    VUNITIZE(aproj);
    VMOVE(proj,aproj);

    return;
}
Example #23
0
/**
 * Given ONE ray distance, return the normal and entry/exit point.
 */
void
rt_superell_norm(struct hit *hitp, struct soltab *stp, struct xray *rp)
{
    struct superell_specific *superell =
        (struct superell_specific *)stp->st_specific;

    vect_t xlated;
    fastf_t scale;

    VJOIN1(hitp->hit_point, rp->r_pt, hitp->hit_dist, rp->r_dir);
    VSUB2(xlated, hitp->hit_point, superell->superell_V);
    MAT4X3VEC(hitp->hit_normal, superell->superell_invRSSR, xlated);
    scale = 1.0 / MAGNITUDE(hitp->hit_normal);
    VSCALE(hitp->hit_normal, hitp->hit_normal, scale);

    return;
}
/*
 *	Convert an ascii nmg description into a BRL-CAD data base.
 */
static int
ascii_to_brlcad(FILE *fpin, struct rt_wdb *fpout, char *reg_name, char *grp_name)
{
    struct model	*m;
    struct nmgregion	*r;
    struct bn_tol	tol;
    struct shell	*s;
    vect_t		Ext;
    struct faceuse *fu;
    plane_t		pl;

    VSETALL(Ext, 0.);

    m = nmg_mm();		/* Make nmg model. */
    r = nmg_mrsv(m);	/* Make region, empty shell, vertex */
    s = BU_LIST_FIRST(shell, &r->s_hd);
    descr_to_nmg(s, fpin, Ext);	/* Convert ascii description to nmg. */

    /* Copied from proc-db/nmgmodel.c */
    tol.magic = BN_TOL_MAGIC;
    tol.dist = 0.01;
    tol.dist_sq = tol.dist * tol.dist;
    tol.perp = 0.001;
    tol.para = 0.999;

    /* Associate the face geometry. */
    fu = BU_LIST_FIRST( faceuse, &s->fu_hd );
    if (nmg_loop_plane_area(BU_LIST_FIRST(loopuse, &fu->lu_hd), pl) < 0.0)
	return -1;
    else
	nmg_face_g( fu, pl );

    if (!NEAR_ZERO(MAGNITUDE(Ext), 0.001))
	nmg_extrude_face(BU_LIST_FIRST(faceuse, &s->fu_hd), Ext, &tol);

    nmg_region_a(r, &tol);	/* Calculate geometry for region and shell. */

    nmg_fix_normals( s, &tol ); /* insure that faces have outward pointing normals */

    create_brlcad_db(fpout, m, reg_name, grp_name);

    return 0;
}
Example #25
0
int
coplanar_2d_to_3d(point_t **points_3d, const point_t *origin_pnt,
		     const vect_t *u_axis, const vect_t *v_axis,
		     const point2d_t *points_2d, int n)
{
int i;
    vect_t u_x_component, u_y_component, u_z_component;
    vect_t v_x_component, v_y_component, v_z_component;
    vect_t x_axis, y_axis, z_axis;
    vect_t temp;
    fastf_t mag_u_x, mag_u_y, mag_u_z;
    fastf_t mag_v_x, mag_v_y, mag_v_z;
    VSET(x_axis, 1.0, 0.0, 0.0);
    VSET(y_axis, 0.0, 1.0, 0.0);
    VSET(z_axis, 0.0, 0.0, 1.0);
    /* Step 1 - find the 3d X, Y and Z components of u_axis and v_axis */
    VPROJECT(*u_axis, x_axis, u_x_component, temp);
    VPROJECT(temp, y_axis, u_y_component, u_z_component);
    VPROJECT(*v_axis, x_axis, v_x_component, temp);
    VPROJECT(temp, y_axis, v_y_component, v_z_component);
    mag_u_x = (VDOT(u_x_component, x_axis) > 0.0) ? (MAGNITUDE(u_x_component)) : (-1.0 * MAGNITUDE(u_x_component));
    mag_u_y = (VDOT(u_y_component, y_axis) > 0.0) ? (MAGNITUDE(u_y_component)) : (-1.0 * MAGNITUDE(u_y_component));
    mag_u_z = (VDOT(u_z_component, z_axis) > 0.0) ? (MAGNITUDE(u_z_component)) : (-1.0 * MAGNITUDE(u_z_component));
    mag_v_x = (VDOT(v_x_component, x_axis) > 0.0) ? (MAGNITUDE(v_x_component)) : (-1.0 * MAGNITUDE(v_x_component));
    mag_v_y = (VDOT(v_y_component, y_axis) > 0.0) ? (MAGNITUDE(v_y_component)) : (-1.0 * MAGNITUDE(v_y_component));
    mag_v_z = (VDOT(v_z_component, z_axis) > 0.0) ? (MAGNITUDE(v_z_component)) : (-1.0 * MAGNITUDE(v_z_component));

    /* Step 2 - for each 2D point, calculate the (x,y,z) coordinates as follows:
     * (http://math.stackexchange.com/questions/525829/how-to-find-the-3d-coordinate-of-a-2d-point-on-a-known-plane)
     */
    for (i = 0; i < n; i++) {
	vect_t temp_2d;
	VSET(temp_2d, points_2d[i][0]*mag_u_x + (points_2d)[i][1]*mag_v_x,
		(points_2d)[i][0]*mag_u_y + (points_2d)[i][1]*mag_v_y,
		(points_2d)[i][0]*mag_u_z + (points_2d)[i][1]*mag_v_z);
	VADD2((*points_3d)[i], (*origin_pnt), temp_2d);
    }

    return 0;
}
Example #26
0
static void
render_camera_prep_persp_dof(render_camera_t *camera)
{
    vect_t look, up, side, dof_look, dof_up, dof_side, dof_topl, dof_topr, dof_botl, temp, step_x, step_y, topl, topr, botl;
    tfloat angle, mag, sfov, cfov, sdof, cdof;
    uint32_t i, n;

    /* Generate unitized lookector */
    VSUB2(dof_look, camera->focus, camera->pos);
    VUNITIZE(dof_look);

    /* Generate standard up vector */
    dof_up[0] = 0;
    dof_up[1] = 0;
    dof_up[2] = 1;

    /* Make unitized up vector perpendicular to lookector */
    VMOVE(temp, dof_look);
    angle = VDOT(dof_up, temp);
    VSCALE(temp, temp, angle);
    VSUB2(dof_up, dof_up, temp);
    VUNITIZE(dof_up);

    /* Generate a temporary side vector */
    VCROSS(dof_side, dof_up, dof_look);

    /* Apply tilt to up vector - negate angle to make positive angles clockwise */
    sdof = sin(-camera->tilt * DEG2RAD);
    cdof = cos(-camera->tilt * DEG2RAD);
    VSCALE(dof_up, dof_up, cdof);
    VSCALE(dof_side, dof_side, sdof);
    VADD2(dof_up, dof_up, dof_side);

    /* Create final side vector */
    VCROSS(dof_side, dof_up, dof_look);

    /*
     * Generate a camera position, top left vector, and step vectors for each DOF sample
     */

    /* Obtain magnitude of reverse lookector */
    VSUB2(dof_look, camera->pos, camera->focus);
    mag = MAGNITUDE(dof_look);
    VUNITIZE(dof_look);

    /* Compute sine and cosine terms for field of view */
    sdof = sin(camera->dof*DEG2RAD);
    cdof = cos(camera->dof*DEG2RAD);


    /* Up, Look, and Side vectors are complete, generate Top Left reference vector */
    dof_topl[0] = sdof*dof_up[0] + sdof*dof_side[0] + cdof*dof_look[0];
    dof_topl[1] = sdof*dof_up[1] + sdof*dof_side[1] + cdof*dof_look[1];
    dof_topl[2] = sdof*dof_up[2] + sdof*dof_side[2] + cdof*dof_look[2];

    dof_topr[0] = sdof*dof_up[0] - sdof*dof_side[0] + cdof*dof_look[0];
    dof_topr[1] = sdof*dof_up[1] - sdof*dof_side[1] + cdof*dof_look[1];
    dof_topr[2] = sdof*dof_up[2] - sdof*dof_side[2] + cdof*dof_look[2];

    dof_botl[0] = -sdof*dof_up[0] + sdof*dof_side[0] + cdof*dof_look[0];
    dof_botl[1] = -sdof*dof_up[1] + sdof*dof_side[1] + cdof*dof_look[1];
    dof_botl[2] = -sdof*dof_up[2] + sdof*dof_side[2] + cdof*dof_look[2];

    VUNITIZE(dof_topl);
    VUNITIZE(dof_botl);
    VUNITIZE(dof_topr);

    VSUB2(step_x, dof_topr, dof_topl);
    VSUB2(step_y, dof_botl, dof_topl);

    for (i = 0; i < RENDER_CAMERA_DOF_SAMPLES; i++) {
	for (n = 0; n < RENDER_CAMERA_DOF_SAMPLES; n++) {
	    /* Generate virtual camera position for this depth of field sample */
	    VSCALE(temp, step_x, ((tfloat)i/(tfloat)(RENDER_CAMERA_DOF_SAMPLES-1)));
	    VADD2(camera->view_list[i*RENDER_CAMERA_DOF_SAMPLES+n].pos, dof_topl, temp);
	    VSCALE(temp, step_y, ((tfloat)n/(tfloat)(RENDER_CAMERA_DOF_SAMPLES-1)));
	    VADD2(camera->view_list[i*RENDER_CAMERA_DOF_SAMPLES+n].pos, camera->view_list[i*RENDER_CAMERA_DOF_SAMPLES+n].pos, temp);
	    VUNITIZE(camera->view_list[i*RENDER_CAMERA_DOF_SAMPLES+n].pos);
	    VSCALE(camera->view_list[i*RENDER_CAMERA_DOF_SAMPLES+n].pos, camera->view_list[i*RENDER_CAMERA_DOF_SAMPLES+n].pos, mag);
	    VADD2(camera->view_list[i*RENDER_CAMERA_DOF_SAMPLES+n].pos, camera->view_list[i*RENDER_CAMERA_DOF_SAMPLES+n].pos, camera->focus);

	    /* Generate unitized lookector */
	    VSUB2(look, camera->focus, camera->view_list[i*RENDER_CAMERA_DOF_SAMPLES+n].pos);
	    VUNITIZE(look);

	    /* Generate standard up vector */
	    up[0] = 0;
	    up[1] = 0;
	    up[2] = 1;

	    /* Make unitized up vector perpendicular to lookector */
	    VMOVE(temp, look);
	    angle = VDOT(up, temp);
	    VSCALE(temp, temp, angle);
	    VSUB2(up, up, temp);
	    VUNITIZE(up);

	    /* Generate a temporary side vector */
	    VCROSS(side, up, look);

	    /* Apply tilt to up vector - negate angle to make positive angles clockwise */
	    sfov = sin(-camera->tilt * DEG2RAD);
	    cfov = cos(-camera->tilt * DEG2RAD);
	    VSCALE(up, up, cfov);
	    VSCALE(side, side, sfov);
	    VADD2(up, up, side);

	    /* Create final side vector */
	    VCROSS(side, up, look);

	    /* Compute sine and cosine terms for field of view */
	    sfov = sin(camera->fov*DEG2RAD);
	    cfov = cos(camera->fov*DEG2RAD);


	    /* Up, Look, and Side vectors are complete, generate Top Left reference vector */
	    topl[0] = sfov*up[0] + camera->aspect*sfov*side[0] + cfov*look[0];
	    topl[1] = sfov*up[1] + camera->aspect*sfov*side[1] + cfov*look[1];
	    topl[2] = sfov*up[2] + camera->aspect*sfov*side[2] + cfov*look[2];

	    topr[0] = sfov*up[0] - camera->aspect*sfov*side[0] + cfov*look[0];
	    topr[1] = sfov*up[1] - camera->aspect*sfov*side[1] + cfov*look[1];
	    topr[2] = sfov*up[2] - camera->aspect*sfov*side[2] + cfov*look[2];

	    botl[0] = -sfov*up[0] + camera->aspect*sfov*side[0] + cfov*look[0];
	    botl[1] = -sfov*up[1] + camera->aspect*sfov*side[1] + cfov*look[1];
	    botl[2] = -sfov*up[2] + camera->aspect*sfov*side[2] + cfov*look[2];

	    VUNITIZE(topl);
	    VUNITIZE(botl);
	    VUNITIZE(topr);

	    /* Store the top left vector */
	    VMOVE(camera->view_list[i*RENDER_CAMERA_DOF_SAMPLES+n].top_l, topl);

	    /* Generate stepx and stepy vectors for sampling each pixel */
	    VSUB2(camera->view_list[i*RENDER_CAMERA_DOF_SAMPLES+n].step_x, topr, topl);
	    VSUB2(camera->view_list[i*RENDER_CAMERA_DOF_SAMPLES+n].step_y, botl, topl);

	    /* Divide stepx and stepy by the number of pixels */
	    VSCALE(camera->view_list[i*RENDER_CAMERA_DOF_SAMPLES+n].step_x, camera->view_list[i*RENDER_CAMERA_DOF_SAMPLES+n].step_x, 1.0 / camera->w);
	    VSCALE(camera->view_list[i*RENDER_CAMERA_DOF_SAMPLES+n].step_y, camera->view_list[i*RENDER_CAMERA_DOF_SAMPLES+n].step_y, 1.0 / camera->h);
	}
    }
}
Example #27
0
extern "C" void
rt_nmg_brep(ON_Brep **b, const struct rt_db_internal *ip, const struct bn_tol *tol)
{
    struct model *m;
    struct nmgregion *r;
    struct shell *s;
    struct faceuse *fu;
    struct loopuse *lu;
    struct edgeuse *eu;

    int edge_index;
    long* brepi;

    RT_CK_DB_INTERNAL(ip);
    m = (struct model *)ip->idb_ptr;
    NMG_CK_MODEL(m);

    brepi = static_cast<long*>(bu_malloc(m->maxindex * sizeof(long), "rt_nmg_brep: brepi[]"));
    for (int i = 0; i < m->maxindex; i++) brepi[i] = -INT_MAX;

    for (BU_LIST_FOR(r, nmgregion, &m->r_hd)) {
	for (BU_LIST_FOR(s, shell, &r->s_hd)) {
	    for (BU_LIST_FOR(fu, faceuse, &s->fu_hd)) {
		NMG_CK_FACEUSE(fu);
		if (fu->orientation != OT_SAME) continue;

		// Need to create ON_NurbsSurface based on plane of
		// face in order to have UV space in which to define
		// trimming loops.  Bounding points are NOT on the
		// face plane, so another approach must be used.
		//
		// General approach: For all loops in the faceuse,
		// collect all the vertices.  Find the center point of
		// all the vertices, and search for the point with the
		// greatest distance from that center point.  Once
		// found, cross the vector between the center point
		// and furthest point with the normal of the face and
		// scale the resulting vector to have the same length
		// as the vector to the furthest point.  Add the two
		// resulting vectors to find the first corner point.
		// Mirror the first corner point across the center to
		// find the second corner point.  Cross the two
		// vectors created by the first two corner points with
		// the face normal to get the vectors of the other two
		// corners, and scale the resulting vectors to the
		// same magnitude as the first two.  These four points
		// bound all vertices on the plane and form a suitable
		// staring point for a UV space, since all points on
		// all the edges are equal to or further than the
		// distance between the furthest vertex and the center
		// point.

		// ............. .............
		// .           .* .          .
		// .         .  .    .       .
		// .        .   .      .     .
		// .       .    .       *    .
		// .      .     .       .    .
		// .     .      .       .    .
		// .    .       .       .    .
		// .   *        *       .    .
		// .   .                .    .
		// .   .                .    .
		// .   .                .    .
		// .   *.               .    .
		// .     ...        ...*     .
		// .       .... ....         .
		// .           *             .
		// ...........................
		//


		const struct face_g_plane *fg = fu->f_p->g.plane_p;
		struct bu_ptbl vert_table;
		nmg_tabulate_face_g_verts(&vert_table, fg);
		point_t tmppt, center, max_pt;
		struct vertex **pt;

		VSET(tmppt, 0, 0, 0);
		VSET(max_pt, 0, 0, 0);

		int ptcnt = 0;
		for (BU_PTBL_FOR(pt, (struct vertex **), &vert_table)) {
		    tmppt[0] += (*pt)->vg_p->coord[0];
		    tmppt[1] += (*pt)->vg_p->coord[1];
		    tmppt[2] += (*pt)->vg_p->coord[2];
		    ptcnt++;
		    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;
		    }
		}
		VSET(center, tmppt[0]/ptcnt, tmppt[1]/ptcnt, tmppt[2]/ptcnt);
		fastf_t max_dist = 0.0;
		fastf_t curr_dist;
		for (BU_PTBL_FOR(pt, (struct vertex **), &vert_table)) {
		    tmppt[0] = (*pt)->vg_p->coord[0];
		    tmppt[1] = (*pt)->vg_p->coord[1];
		    tmppt[2] = (*pt)->vg_p->coord[2];
		    curr_dist = DIST_PT_PT(center, tmppt);
		    if (curr_dist > max_dist) {
			max_dist = curr_dist;
			VMOVE(max_pt, tmppt);
		    }
		}
		bu_ptbl_free(&vert_table);
		int ccw = 0;
		vect_t vtmp, uv1, uv2, uv3, uv4, vnormal;
		// If an outer loop is found in the nmg with a cw
		// orientation, use a flipped normal to form the NURBS
		// surface
		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]);
		}
		VSUB2(uv1, max_pt, center);
		VCROSS(vtmp, uv1, vnormal);
		VADD2(uv1, uv1, vtmp);
		VCROSS(uv2, uv1, vnormal);
		VREVERSE(uv3, uv1);
		VCROSS(uv4, uv3, vnormal);
		VADD2(uv1, uv1, center);
		VADD2(uv2, uv2, center);
		VADD2(uv3, uv3, center);
		VADD2(uv4, uv4, center);

		ON_3dPoint p1 = ON_3dPoint(uv1);
		ON_3dPoint p2 = ON_3dPoint(uv2);
		ON_3dPoint p3 = ON_3dPoint(uv3);
		ON_3dPoint p4 = ON_3dPoint(uv4);

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

		// Now that we have the surface, define the face
		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.
		vect_t u_axis, v_axis;
		VSUB2(u_axis, uv2, uv1);
		VSUB2(v_axis, uv4, uv1);
		fastf_t u_axis_dist = MAGNITUDE(u_axis);
		fastf_t v_axis_dist = MAGNITUDE(v_axis);

		// Now that the surface context is set up, add the loops.
		for (BU_LIST_FOR(lu, loopuse, &fu->lu_hd)) {
		    int edges=0;
		    if (BU_LIST_FIRST_MAGIC(&lu->down_hd) != NMG_EDGEUSE_MAGIC) continue; // loop is a single vertex
		    ON_BrepLoop::TYPE looptype;
		    // Check if this is an inner or outer loop
		    if (lu->orientation == OT_SAME) {
			looptype = ON_BrepLoop::outer;
		    } else {
			looptype = ON_BrepLoop::inner;
		    }
		    ON_BrepLoop& loop = (*b)->NewLoop(looptype, face);
		    for (BU_LIST_FOR(eu, edgeuse, &lu->down_hd)) {
			++edges;
			vect_t ev1, ev2;
			struct vertex_g *vg1, *vg2;
			vg1 = eu->vu_p->v_p->vg_p;
			NMG_CK_VERTEX_G(vg1);
			int vert1 = brepi[vg1->index];
			VMOVE(ev1, vg1->coord);
			vg2 = eu->eumate_p->vu_p->v_p->vg_p;
			NMG_CK_VERTEX_G(vg2);
			int vert2 = brepi[vg2->index];
			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 */
			    if (vg1->index > vg2->index) {
				int tmpvert = vert1;
				vert1 = vert2;
				vert2 = tmpvert;
			    }
			    // 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
			vect_t u_component, v_component;
			ON_3dPoint vg1pt(vg1->coord);
			int orientation = 0;
			edge_index = brepi[eu->e_p->index];
			if (vg1pt !=  (*b)->m_V[(*b)->m_E[edge_index].m_vi[0]].Point()) {
			    orientation = 1;
			}
			// Now, make 2d trimming curves
			vect_t vect1, vect2;
			VSUB2(vect1, ev1, uv1);
			VSUB2(vect2, ev2, uv1);
			ON_2dPoint from_uv, to_uv;
			double u0, u1, v0, v1;
			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_3dPoint S1, S2;
			ON_3dVector Su, Sv;
			surf->Ev1Der(from_uv.x, from_uv.y, S1, Su, Sv);
			surf->Ev1Der(to_uv.x, to_uv.y, S2, Su, Sv);
			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);
			edge_index = brepi[eu->e_p->index];
			ON_BrepTrim& trim = (*b)->NewTrim((*b)->m_E[edge_index], orientation, loop, c2i);
			trim.m_type = ON_BrepTrim::mated;
			trim.m_tolerance[0] = 0.0;
			trim.m_tolerance[1] = 0.0;
		    }
		}
	    }
	    (*b)->SetTrimIsoFlags();
	}
    }

    bu_free(brepi, "rt_nmg_brep: brepi[]");
}
Example #28
0
/*
 *			F _ H I D E L I N E
 */
int
f_hideline(ClientData clientData, Tcl_Interp *interp, int argc, char **argv)
{
    FILE 	*plotfp;
    char 	visible;
    int 	i, numobjs;
    char 	*objname[MAXOBJECTS], title[1];
    fastf_t 	len, u, step;
    float 	ratio;
    vect_t	last_move;
    struct rt_i	*rtip;
    struct resource resource;
    struct application a;
    vect_t temp;
    vect_t last, dir;
    register struct bn_vlist	*vp;

    CHECK_DBI_NULL;

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

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

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

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

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

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

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

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

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

    FOR_ALL_SOLIDS(sp) {

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

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

			    bu_vls_init(&tmp_vls);
			    bu_vls_printf(&tmp_vls, "\t\tDraw 0 -> %g, step %g\n", len, step);
			    Tcl_AppendResult(interp, bu_vls_addr(&tmp_vls), (char *)NULL);
			    bu_vls_free(&tmp_vls);
			}
			for (u = 0; u <= len; u += step) {
			    VJOIN1(aim_point, last, u, dir);
			    MAT4X3PNT(temp, view_state->vs_model2view, aim_point);
			    temp[Z] = 100;			/* parallel project */
			    MAT4X3PNT(a.a_ray.r_pt, view_state->vs_view2model, temp);
			    if (rt_shootray(&a)) {
				if (!visible) {
				    visible = TRUE;
				    MOVE(aim_point);
				}
			    } else {
				if (visible) {
				    visible = FALSE;
				    DRAW(aim_point);
				}
			    }
			}
			if (visible)
			    DRAW(aim_point);
			VMOVE(last, *pt); /* new last vertex */
		}
	    }
	}
    }
    fclose(plotfp);
    return TCL_OK;
}
/**
 * Given a pointer to an internal GED database object, mirror the
 * object's values about the given transformation matrix.
 */
int
rt_half_mirror(struct rt_db_internal *ip, register const plane_t plane)
{
    struct rt_half_internal *half;

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

    vect_t n1;
    vect_t n2;

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

    RT_CK_DB_INTERNAL(ip);

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

    MAT_IDN(mirmat);

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

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

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

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

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

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

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

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

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

	cosa = VDOT(h, mirror_dir);

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

    return 0;
}
Example #30
0
/**
 * R T _ P G _ T O _ B O T
 *
 * Convert in-memory form of a polysolid (pg) to a bag of triangles (BoT)
 * There is no record in the V5 database for a polysolid.
 *
 * Depends on the "max_npts" parameter having been set.
 *
 * Returns -
 * -1 FAIL
 * 0 OK
 */
int
rt_pg_to_bot(struct rt_db_internal *ip, const struct bn_tol *tol, struct resource *resp)
{
    struct rt_pg_internal *ip_pg;
    struct rt_bot_internal *ip_bot;
    size_t max_pts;
    size_t max_tri;
    size_t p;
    size_t i;

    RT_CK_DB_INTERNAL(ip);
    BN_CK_TOL(tol);
    RT_CK_RESOURCE(resp);

    if (ip->idb_type != ID_POLY) {
	bu_log("ERROR: rt_pt_to_bot() called with a non-polysolid!!!\n");
	return -1;
    }
    ip_pg = (struct rt_pg_internal *)ip->idb_ptr;

    RT_PG_CK_MAGIC(ip_pg);

    BU_ALLOC(ip_bot, struct rt_bot_internal);
    ip_bot->magic = RT_BOT_INTERNAL_MAGIC;
    ip_bot->mode = RT_BOT_SOLID;
    ip_bot->orientation = RT_BOT_CCW;
    ip_bot->bot_flags = 0;

    /* maximum possible vertices */
    max_pts = ip_pg->npoly * ip_pg->max_npts;
    BU_ASSERT_SIZE_T(max_pts, >, 0);

    /* maximum possible triangular faces */
    max_tri = ip_pg->npoly * 3;
    BU_ASSERT_SIZE_T(max_tri, >, 0);

    ip_bot->num_vertices = 0;
    ip_bot->num_faces = 0;
    ip_bot->thickness = (fastf_t *)NULL;
    ip_bot->face_mode = (struct bu_bitv *)NULL;

    ip_bot->vertices = (fastf_t *)bu_calloc(max_pts * 3, sizeof(fastf_t), "BOT vertices");
    ip_bot->faces = (int *)bu_calloc(max_tri * 3, sizeof(int), "BOT faces");

    for (p=0; p<ip_pg->npoly; p++) {
	vect_t work[3], tmp;
	struct tri_specific trip;
	fastf_t m1, m2, m3, m4;
	size_t v0=0, v2=0;
	int first;

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

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

	    VSUB2(trip.tri_BA, work[1], work[0]);
	    VSUB2(trip.tri_CA, work[2], work[0]);
	    VCROSS(trip.tri_wn, trip.tri_BA, trip.tri_CA);

	    /* Check to see if this plane is a line or pnt */
	    m1 = MAGNITUDE(trip.tri_BA);
	    m2 = MAGNITUDE(trip.tri_CA);
	    VSUB2(tmp, work[1], work[2]);
	    m3 = MAGNITUDE(tmp);
	    m4 = MAGNITUDE(trip.tri_wn);
	    if (m1 >= tol->dist && m2 >= tol->dist &&
		m3 >= tol->dist && m4 >= tol->dist) {

		/* add this triangle to the BOT */
		if (first) {
		    ip_bot->faces[ip_bot->num_faces * 3] = ip_bot->num_vertices;
		    VMOVE(&ip_bot->vertices[ip_bot->num_vertices * 3], work[0]);
		    v0 = ip_bot->num_vertices;
		    ip_bot->num_vertices++;

		    ip_bot->faces[ip_bot->num_faces * 3 + 1] = ip_bot->num_vertices;
		    VMOVE(&ip_bot->vertices[ip_bot->num_vertices * 3], work[1]);
		    ip_bot->num_vertices++;
		    first = 0;
		} else {
		    ip_bot->faces[ip_bot->num_faces * 3] = v0;
		    ip_bot->faces[ip_bot->num_faces * 3 + 1] = v2;
		}
		VMOVE(&ip_bot->vertices[ip_bot->num_vertices * 3], work[2]);
		ip_bot->faces[ip_bot->num_faces * 3 + 2] = ip_bot->num_vertices;
		v2 = ip_bot->num_vertices;
		ip_bot->num_vertices++;

		ip_bot->num_faces++;
	    }

	    /* Chop off a triangle, and continue */
	    VMOVE(work[1], work[2]);
	}
    }

    rt_bot_vertex_fuse(ip_bot, tol);
    rt_bot_face_fuse(ip_bot);

    rt_db_free_internal(ip);

    ip->idb_major_type = DB5_MAJORTYPE_BRLCAD;
    ip->idb_type = ID_BOT;
    ip->idb_meth = &rt_functab[ID_BOT];
    ip->idb_ptr = ip_bot;

    return 0;
}