Exemple #1
0
/**
 * R E C _ C U R V E
 *
 * Return the "curvature" of the cylinder.  If an endplate,
 * pick a principle direction orthogonal to the normal, and
 * indicate no curvature.  Otherwise, compute curvature.
 * Normal must have been computed before calling this routine.
 */
void
rt_rec_curve(struct curvature *cvp, struct hit *hitp, struct soltab *stp)
{
    struct rec_specific *rec =
	(struct rec_specific *)stp->st_specific;
    vect_t uu;
    fastf_t ax, bx, q;

    switch (hitp->hit_surfno) {
	case REC_NORM_BODY:
	    /* This could almost certainly be simpler if we used
	     * inverse A rather than inverse A squared, right Ed?
	     */
	    VMOVE(cvp->crv_pdir, rec->rec_Hunit);
	    VSUB2(uu, hitp->hit_point, rec->rec_V);
	    cvp->crv_c1 = 0;
	    ax = VDOT(uu, rec->rec_A) * rec->rec_iAsq;
	    bx = VDOT(uu, rec->rec_B) * rec->rec_iBsq;
	    q = sqrt(ax * ax * rec->rec_iAsq + bx * bx * rec->rec_iBsq);
	    cvp->crv_c2 = - rec->rec_iAsq * rec->rec_iBsq / (q*q*q);
	    break;
	case REC_NORM_TOP:
	case REC_NORM_BOT:
	    bn_vec_ortho(cvp->crv_pdir, hitp->hit_normal);
	    cvp->crv_c1 = cvp->crv_c2 = 0;
	    break;
	default:
	    bu_log("rt_rec_curve: bad surfno %d\n", hitp->hit_surfno);
	    break;
    }
}
Exemple #2
0
/**
 * Return the "curvature" of the ARB face.
 * Pick a principle direction orthogonal to normal, and
 * indicate no curvature.
 */
void
rt_arbn_curve(struct curvature *cvp, struct hit *hitp, struct soltab *stp)
{
    struct rt_arbn_internal *arbn = (struct rt_arbn_internal *)stp->st_specific;

    RT_ARBN_CK_MAGIC(arbn);

    bn_vec_ortho(cvp->crv_pdir, hitp->hit_normal);
    cvp->crv_c1 = cvp->crv_c2 = 0;
}
Exemple #3
0
/**
 * R T _ P G _ C U R V E
 */
void
rt_pg_curve(struct curvature *cvp, struct hit *hitp, struct soltab *stp)
{
    if (!cvp || !hitp)
	return;
    RT_CK_HIT(hitp);
    if (stp) RT_CK_SOLTAB(stp);

    bn_vec_ortho(cvp->crv_pdir, hitp->hit_normal);
    cvp->crv_c1 = cvp->crv_c2 = 0;
}
Exemple #4
0
/**
 * Return the curvature of the revolve.
 */
void
rt_revolve_curve(struct curvature *cvp, struct hit *hitp, struct soltab *stp)
{
    if (!cvp || !hitp)
	return;
    RT_CK_HIT(hitp);
    if (stp) RT_CK_SOLTAB(stp);

    cvp->crv_c1 = cvp->crv_c2 = 0;

    /* any tangent direction */
    bn_vec_ortho(cvp->crv_pdir, hitp->hit_normal);
}
/**
 *@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);

}
Exemple #6
0
/**
 * Return the curvature of the xxx.
 */
void
rt_xxx_curve(struct curvature *cvp, struct hit *hitp, struct soltab *stp)
{
    struct xxx_specific *xxx;

    if (!stp) return;
    xxx = (struct xxx_specific *)stp->st_specific;
    if (!xxx) return;
    RT_CK_SOLTAB(stp);

    cvp->crv_c1 = cvp->crv_c2 = 0;

    /* any tangent direction */
    bn_vec_ortho(cvp->crv_pdir, hitp->hit_normal);
}
HIDDEN int
rt_pattern_circ_spiral(fastf_t **rays, size_t *ray_cnt, const point_t center_pt, const vect_t dir,
       	const double radius, const int rays_per_ring, const int nring, const double delta)
{
    int ring;
    double fraction = 1.0;
    double theta;
    double radial_scale;
    vect_t avec, bvec;
    int ray_index = 0;

    bn_vec_ortho(avec, dir);
    VCROSS(bvec, dir, avec);
    VUNITIZE(bvec);

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

    *(rays) = (fastf_t *)bu_calloc(sizeof(fastf_t) * 6, (rays_per_ring * nring) + 1, "rays");

    for (ring = 0; ring < nring; ring++) {
	register int i;

	theta = 0;
	fraction = ((double)(ring+1)) / nring;
	theta = delta * fraction;       /* spiral skew */
	radial_scale = radius * fraction;
	for (i=0; i < rays_per_ring; i++) {
	    register double ct, st;
	    point_t pt;
	    /* pt = V + cos(theta) * A + sin(theta) * B */
	    ct = cos(theta) * radial_scale;
	    st = sin(theta) * radial_scale;
	    VJOIN2(pt, center_pt, ct, avec, st, bvec);
	    (*rays)[6*ray_index] = pt[0];
	    (*rays)[6*ray_index+1] = pt[1];
	    (*rays)[6*ray_index+2] = pt[2];
	    (*rays)[6*ray_index+3] = dir[0];
	    (*rays)[6*ray_index+4] = dir[1];
	    (*rays)[6*ray_index+5] = dir[2];
	    theta += delta;
	    ray_index++;
	}
    }
    *(ray_cnt) = ray_index;
    return ray_index;
}
Exemple #8
0
/*
 *			M A I N
 */
int
main(int argc, char **argv)
{
    struct application	ap;

    static struct rt_i *rtip;
    char *title_file;
    char idbuf[RT_BUFSIZE] = {0};		/* First ID record info */
    char *ptr;
    int attr_count=0, i;
    char **attrs = (char **)NULL;

    if ( argc < 3 )  {
	bu_exit(1, usage);
    }

    RT_APPLICATION_INIT(&ap);

    argc--;
    argv++;
    while ( argv[0][0] == '-' ) switch ( argv[0][1] )  {
	case 'R':
	    bundle_radius = atof( argv[1] );
	    argc -= 2;
	    argv += 2;
	    break;
	case 'n':
	    num_rings = atoi( argv[1] );
	    argc -= 2;
	    argv += 2;
	    break;
	case 'c':
	    rays_per_ring = atoi( argv[1] );
	    argc -= 2;
	    argv += 2;
	    break;
	case 'v':
	    /* count the number of attribute names provided */
	    ptr = argv[1];
	    while ( *ptr ) {
		while ( *ptr && isspace( *ptr ) )
		    ptr++;
		if ( *ptr )
		    attr_count++;
		while ( *ptr && !isspace( *ptr ) )
		    ptr++;
	    }

	    if ( attr_count == 0 ) {
		bu_log( "missing list of attribute names!\n" );
		bu_exit( 1, usage );
	    }

	    /* allocate enough for a null terminated list */
	    attrs = (char **)bu_calloc( attr_count + 1, sizeof( char *), "attrs" );

	    /* use strtok to actually grab the names */
	    i = 0;
	    ptr = strtok( argv[1], "\t " );
	    while ( ptr && i < attr_count ) {
		attrs[i] = bu_strdup( ptr );
		ptr = strtok( (char *)NULL, "\t " );
		i++;
	    }
	    argc -= 2;
	    argv += 2;
	    break;
	case 't':
	    rt_bot_tri_per_piece = atoi( argv[1] );
	    argc -= 2;
	    argv += 2;
	    break;
	case 'b':
	    rt_bot_minpieces = atoi( argv[1] );
	    argc -= 2;
	    argv += 2;
	    break;
	case 'o':
	    sscanf( argv[1], "%d", &set_onehit );
	    argc -= 2;
	    argv += 2;
	    break;
	case 'r':
	{
	    float ray_len;

	    sscanf( argv[1], "%f", &ray_len );
	    set_ray_length = ray_len;
	}
	argc -= 2;
	argv += 2;
	break;
	case 'U':
	    sscanf( argv[1], "%d", &use_air );
	    argc -= 2;
	    argv += 2;
	    break;
	case 'u':
	    sscanf( argv[1], "%x", (unsigned int *)&bu_debug );
	    fprintf(stderr, "librt bu_debug=x%x\n", bu_debug);
	    argc -= 2;
	    argv += 2;
	    break;
	case 'x':
	    sscanf( argv[1], "%x", (unsigned int *)&rt_g.debug );
	    fprintf(stderr, "librt rt_g.debug=x%x\n", rt_g.debug);
	    argc -= 2;
	    argv += 2;
	    break;
	case 'X':
	    sscanf( argv[1], "%x", (unsigned int *)&rdebug );
	    fprintf(stderr, "rdebug=x%x\n", rdebug);
	    argc -= 2;
	    argv += 2;
	    break;
	case 'N':
	    sscanf( argv[1], "%x", (unsigned int *)&rt_g.NMG_debug);
	    fprintf(stderr, "librt rt_g.NMG_debug=x%x\n", rt_g.NMG_debug);
	    argc -= 2;
	    argv += 2;
	    break;
	case 'd':
	    if ( argc < 4 )  goto err;
	    ap.a_ray.r_dir[X] = atof( argv[1] );
	    ap.a_ray.r_dir[Y] = atof( argv[2] );
	    ap.a_ray.r_dir[Z] = atof( argv[3] );
	    set_dir = 1;
	    argc -= 4;
	    argv += 4;
	    continue;

	case 'p':
	    if ( argc < 4 )  goto err;
	    ap.a_ray.r_pt[X] = atof( argv[1] );
	    ap.a_ray.r_pt[Y] = atof( argv[2] );
	    ap.a_ray.r_pt[Z] = atof( argv[3] );
	    set_pt = 1;
	    argc -= 4;
	    argv += 4;
	    continue;

	case 'a':
	    if ( argc < 4 )  goto err;
	    at_vect[X] = atof( argv[1] );
	    at_vect[Y] = atof( argv[2] );
	    at_vect[Z] = atof( argv[3] );
	    set_at = 1;
	    argc -= 4;
	    argv += 4;
	    continue;

	case 'O':
	{
	    if ( !strcmp( argv[1], "resolve" ) || !strcmp( argv[1], "0") )
		overlap_claimant_handling = 0;
	    else if ( !strcmp( argv[1], "rebuild_fastgen" ) || !strcmp( argv[1], "1") )
		overlap_claimant_handling = 1;
	    else if ( !strcmp( argv[1], "rebuild_all" ) || !strcmp( argv[1], "2") )
		overlap_claimant_handling = 2;
	    else if ( !strcmp( argv[1], "retain" ) || !strcmp( argv[1], "3") )
		overlap_claimant_handling = 3;
	    else
	    {
		bu_log( "Illegal argument (%s) to '-O' option.  Must be:\n", argv[1] );
		bu_log( "\t'resolve' or '0'\n");
		bu_log( "\t'rebuild_fastgen' or '1'\n");
		bu_log( "\t'rebuild_all' or '2'\n");
		bu_log( "\t'retain' or '3'\n");
		bu_exit(1, NULL);
	    }
	    argc -= 2;
	    argv += 2;
	}
	continue;

	default:
    err:
	    bu_exit(1, usage);
    }
    if ( argc < 2 )  {
	(void)fputs(usage, stderr);
	bu_exit(1, "rtshot: MGED database not specified\n");
    }

    if ( set_dir + set_pt + set_at != 2 )  goto err;

    if ( num_rings != 0 || rays_per_ring != 0 || bundle_radius != 0.0 ) {
	if ( num_rings <= 0 || rays_per_ring <= 0 || bundle_radius <= 0.0 ) {
	    fprintf( stderr, "Must have all of \"-R\", \"-n\", and \"-c\" set\n" );
	    goto err;
	}
    }

    /* Load database */
    title_file = argv[0];
    argv++;
    argc--;
    if ( (rtip=rt_dirbuild(title_file, idbuf, sizeof(idbuf))) == RTI_NULL ) {
	bu_exit(2, "rtshot:  rt_dirbuild failure\n");
    }

    if ( overlap_claimant_handling )
	rtip->rti_save_overlaps = 1;

    ap.a_rt_i = rtip;
    fprintf(stderr, "db title:  %s\n", idbuf);
    rtip->useair = use_air;

    /* Walk trees */
    if ( rt_gettrees_and_attrs( rtip, (const char **)attrs, argc, (const char **)argv, 1 ) ) {
	bu_exit(1, "rt_gettrees FAILED\n");
    }
    ap.attrs = attrs;

    rt_prep(rtip);

    if ( R_DEBUG&RDEBUG_RAYPLOT )  {
	if ( (plotfp = fopen("rtshot.plot", "w")) == NULL )  {
	    perror("rtshot.plot");
	    bu_exit(1, NULL);
	}
	pdv_3space( plotfp, rtip->rti_pmin, rtip->rti_pmax );
    }

    /* Compute r_dir and r_pt from the inputs */
    if ( set_at )  {
	if ( set_dir ) {
	    vect_t	diag;
	    fastf_t	viewsize;
	    VSUB2( diag, rtip->mdl_max, rtip->mdl_min );
	    viewsize = MAGNITUDE( diag );
	    VJOIN1( ap.a_ray.r_pt, at_vect,
		    -viewsize/2.0, ap.a_ray.r_dir );
	} else {
	    /* set_pt */
	    VSUB2( ap.a_ray.r_dir, at_vect, ap.a_ray.r_pt );
	}
    }
    VUNITIZE( ap.a_ray.r_dir );

    if ( rays_per_ring ) {
	bu_log( "Central Ray:\n" );
    }
    VPRINT( "Pnt", ap.a_ray.r_pt );
    VPRINT( "Dir", ap.a_ray.r_dir );

    if ( set_onehit )
	ap.a_onehit = set_onehit;
    else
	ap.a_onehit = 0;

    if ( set_ray_length > 0.0 )
	ap.a_ray_length = set_ray_length;
    else
	ap.a_ray_length = 0.0;

    /* Shoot Ray */
    ap.a_purpose = "main ray";
    ap.a_hit = hit;
    ap.a_miss = miss;

    if ( rays_per_ring ) {
	vect_t avec, bvec;
	struct xray *rp;

	/* create orthogonal rays for basis of bundle */
	bn_vec_ortho( avec, ap.a_ray.r_dir );
	VCROSS( bvec, ap.a_ray.r_dir, avec );
	VUNITIZE( bvec );

	rp = (struct xray *)bu_calloc( sizeof( struct xray ),
				       (rays_per_ring * num_rings) + 1,
				       "ray bundle" );
	rp[0] = ap.a_ray;	/* struct copy */
	rp[0].magic = RT_RAY_MAGIC;
	rt_raybundle_maker( rp, bundle_radius, avec, bvec, rays_per_ring, num_rings );
	(void)rt_shootray_bundle( &ap, rp, (rays_per_ring * num_rings) + 1 );
    } else {
	(void)rt_shootray( &ap );
    }

    return(0);
}
Exemple #9
0
/**
 * Return the curvature of the hyp.
 */
void
rt_hyp_curve(struct curvature *cvp, struct hit *hitp, struct soltab *stp)
{
    struct hyp_specific *hyp =
	(struct hyp_specific *)stp->st_specific;
    vect_t vert, horiz;
    point_t hp;
    fastf_t c, h, k1, k2, denom;
    fastf_t x, y, ratio;

    switch (hitp->hit_surfno) {
	case HYP_NORM_BODY:
	    /* calculate principle curvature directions */
	    VMOVE(hp, hitp->hit_vpriv);

	    VMOVE(vert, hitp->hit_normal);
	    vert[Z] += 10;
	    VCROSS(horiz, vert, hitp->hit_normal);
	    VUNITIZE(horiz);
	    VCROSS(vert, hitp->hit_normal, horiz);
	    VUNITIZE(vert);

	    /* vertical curvature */
	    c = hyp->hyp_c;
	    h = sqrt(hp[X]*hp[X] + hp[Y]*hp[Y]);

	    denom = 1 + (c*c*c*c)*(hp[Z]*hp[Z])/(h*h);
	    denom = sqrt(denom*denom*denom);

	    /* k1 is in the vert direction on the hyberbola */
	    k1 = fabs(c*c/h - (c*c*c*c)*(hp[Z]*hp[Z])/(h*h*h)) / denom;

	    /* horizontal curvature */
	    if (fabs(hp[Y]) >= fabs(hp[X])) {
		ratio = hyp->hyp_rx / hyp->hyp_ry;	/* (b/a)^2 */
		x = hp[X];
		y = hp[Y];
	    } else {
		/* flip x and y to avoid div by zero */
		ratio = hyp->hyp_ry / hyp->hyp_rx;
		x = hp[Y];
		y = hp[X];
	    }

	    denom = fabs(y*y*y + (ratio*ratio)*(x*x)*y);
	    denom = sqrt(denom*denom*denom);

	    /* k2 is in the horiz direction on the ellipse */
	    k2 = -fabs(ratio*y + (ratio*ratio)*(x*x)/y) / denom;

	    if (k1 < fabs(k2)) {
		VMOVE(cvp->crv_pdir, vert);
		cvp->crv_c1 = k1;
		cvp->crv_c2 = k2;
	    } else {
		VMOVE(cvp->crv_pdir, horiz);
		cvp->crv_c1 = k2;
		cvp->crv_c2 = k1;
	    }
	    break;
	case HYP_NORM_TOP:
	case HYP_NORM_BOTTOM:
	    cvp->crv_c1 = cvp->crv_c2 = 0;
	    bn_vec_ortho(cvp->crv_pdir, hitp->hit_normal);
	    break;
    }
}