Example #1
0
/**
 * R T _ P G _ P L O T
 *
 * Calculate the bounding RPP for a poly
 */
int
rt_pg_bbox(struct rt_db_internal *ip, point_t *min, point_t *max, const struct bn_tol *UNUSED(tol))
{
    struct rt_pg_internal *pgp;
    size_t i;
    size_t p;

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

    VSETALL((*min), INFINITY);
    VSETALL((*max), -INFINITY);

    for (p = 0; p < pgp->npoly; p++) {
	vect_t work[3];

	VMOVE(work[0], &pgp->poly[p].verts[0*3]);
	VMINMAX((*min), (*max), work[0]);
	VMOVE(work[1], &pgp->poly[p].verts[1*3]);
	VMINMAX((*min), (*max), work[1]);

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

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

    return 0;		/* OK */
}
Example #2
0
    } RT_VISIT_ALL_SOLTABS_END

	  /*
	   * Another pass, no restarting.  Assign "piecestate" indices
	   * for those solids which contain pieces.
	   */
	  RT_VISIT_ALL_SOLTABS_START( stp, rtip )  {
	if ( stp->st_npieces > 1 )  {
	    /* all pieces must be within model bounding box for pieces
	     * to work correctly.
	     */
	    VMINMAX( rtip->mdl_min, rtip->mdl_max, stp->st_min );
	    VMINMAX( rtip->mdl_min, rtip->mdl_max, stp->st_max );
	    stp->st_piecestate_num = rtip->rti_nsolids_with_pieces++;
	}
	if (RT_G_DEBUG&DEBUG_SOLIDS)
	    rt_pr_soltab( stp );
    } RT_VISIT_ALL_SOLTABS_END
Example #3
0
File: hyp.c Project: kanzure/brlcad
/**
 * Create a bounding RPP for an hyp
 */
int
rt_hyp_bbox(struct rt_db_internal *ip, point_t *min, point_t *max, const struct bn_tol *UNUSED(tol)) {
    struct rt_hyp_internal *xip;
    vect_t hyp_Au, hyp_B, hyp_An, hyp_Bn, hyp_H;
    vect_t pt1, pt2, pt3, pt4, pt5, pt6, pt7, pt8;
    RT_CK_DB_INTERNAL(ip);
    xip = (struct rt_hyp_internal *)ip->idb_ptr;
    RT_HYP_CK_MAGIC(xip);

    VMOVE(hyp_H, xip->hyp_Hi);
    VUNITIZE(hyp_H);
    VMOVE(hyp_Au, xip->hyp_A);
    VUNITIZE(hyp_Au);
    VCROSS(hyp_B, hyp_Au, hyp_H);

    VSETALL((*min), INFINITY);
    VSETALL((*max), -INFINITY);

    VSCALE(hyp_B, hyp_B, xip->hyp_b);
    VREVERSE(hyp_An, xip->hyp_A);
    VREVERSE(hyp_Bn, hyp_B);

    VADD3(pt1, xip->hyp_Vi, xip->hyp_A, hyp_B);
    VADD3(pt2, xip->hyp_Vi, xip->hyp_A, hyp_Bn);
    VADD3(pt3, xip->hyp_Vi, hyp_An, hyp_B);
    VADD3(pt4, xip->hyp_Vi, hyp_An, hyp_Bn);
    VADD4(pt5, xip->hyp_Vi, xip->hyp_A, hyp_B, xip->hyp_Hi);
    VADD4(pt6, xip->hyp_Vi, xip->hyp_A, hyp_Bn, xip->hyp_Hi);
    VADD4(pt7, xip->hyp_Vi, hyp_An, hyp_B, xip->hyp_Hi);
    VADD4(pt8, xip->hyp_Vi, hyp_An, hyp_Bn, xip->hyp_Hi);

    /* Find the RPP of the rotated axis-aligned hyp bbox - that is,
     * the bounding box the given hyp would have if its height
     * vector were in the positive Z direction. This does not give
     * us an optimal bbox except in the case where the hyp is
     * actually axis aligned to start with, but it's usually
     * at least a bit better than the bounding sphere RPP. */
    VMINMAX((*min), (*max), pt1);
    VMINMAX((*min), (*max), pt2);
    VMINMAX((*min), (*max), pt3);
    VMINMAX((*min), (*max), pt4);
    VMINMAX((*min), (*max), pt5);
    VMINMAX((*min), (*max), pt6);
    VMINMAX((*min), (*max), pt7);
    VMINMAX((*min), (*max), pt8);

    return 0;
}
Example #4
0
/**
 * Calculates the bounding Right Parallel Piped (RPP) of the NURB
 * surface, and returns the minimum and maximum points of the surface.
 */
int
rt_nurb_s_bound(struct face_g_snurb *srf, fastf_t *bmin, fastf_t *bmax)
{
    register fastf_t *p_ptr;	/* Mesh pointer */
    register int coords;		/* Elements per vector */
    int i;
    int rat;

    VSETALL(bmin, INFINITY);
    VSETALL(bmax, -INFINITY);

    if (srf == (struct face_g_snurb *)0) {
	bu_log("nurb_s_bound:  NULL surface\n");
	return -1;		/* BAD */
    }

    p_ptr = srf->ctl_points;
    coords = RT_NURB_EXTRACT_COORDS(srf->pt_type);
    rat =    RT_NURB_IS_PT_RATIONAL(srf->pt_type);

    for (i = (srf->s_size[RT_NURB_SPLIT_ROW] *
	      srf->s_size[RT_NURB_SPLIT_COL]); i > 0; i--) {
	if (!rat) {
	    VMINMAX(bmin, bmax, p_ptr);
	} else if (rat) {
	    point_t tmp_pt;
	    if (ZERO(p_ptr[H])) {
		HPRINT("mesh point", p_ptr);
		bu_log("nurb_s_bound:  H too small\n");
	    } else {
		HDIVIDE(tmp_pt, p_ptr);
		VMINMAX(bmin, bmax, tmp_pt);
	    }
	}
	p_ptr += coords;
    }
    return 0;	/* OK */
}
Example #5
0
int PolylineBBox(
    const ON_Polyline& pline,
    ON_BoundingBox* bbox
    )
{
    ON_3dPoint min = pline[0], max = pline[0];
    for (int i = 1; i < pline.Count(); i++) {
	VMINMAX(min, max, pline[i]);
    }

    bbox->m_min = min;
    bbox->m_max = max;
    return 0;
}
Example #6
0
/**
 * Calculate a bounding RPP for an ARBN
 */
int
rt_arbn_bbox(struct rt_db_internal *ip, point_t *min, point_t *max, const struct bn_tol *UNUSED(tol)) {
    size_t i, j, k;
    struct rt_arbn_internal *aip;
    RT_CK_DB_INTERNAL(ip);
    aip = (struct rt_arbn_internal *)ip->idb_ptr;
    RT_ARBN_CK_MAGIC(aip);

    VSETALL((*min), INFINITY);
    VSETALL((*max), -INFINITY);

    /* Discover all vertices, use to calculate RPP */
    for (i = 0; i < aip->neqn-2; i++) {
	for (j = i+1; j < aip->neqn-1; j++) {
	    double dot;

	    /* If normals are parallel, no intersection */
	    dot = VDOT(aip->eqn[i], aip->eqn[j]);
	    if (((dot) <= -SMALL_FASTF) ? (NEAR_EQUAL((dot), -1.0,  RT_DOT_TOL)) : (NEAR_EQUAL((dot), 1.0, RT_DOT_TOL))) continue;

	    /* Have an edge line, isect with higher numbered planes */
	    for (k = j + 1; k < aip->neqn; k++) {
		size_t m;
		size_t next_k;
		point_t pt;

		next_k = 0;

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

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

		VMINMAX((*min), (*max), pt);
	    }
	}
    }

    return 0;
}
Example #7
0
/**
 * Returns -
 *  0 OK
 * !0 failure
 */
int
rt_arbn_prep(struct soltab *stp, struct rt_db_internal *ip, struct rt_i *rtip)
{
    struct rt_arbn_internal *aip;
    vect_t work;
    fastf_t f;
    size_t i;
    size_t j;
    size_t k;
    int *used = (int *)0;	/* plane eqn use count */
    const struct bn_tol *tol = &rtip->rti_tol;

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

    used = (int *)bu_malloc(aip->neqn*sizeof(int), "arbn used[]");

    /*
     * ARBN must be convex.  Test for concavity.
     * Byproduct is an enumeration of all the vertices,
     * which are used to make the bounding RPP.  No need
     * to call the bbox routine, as the work must be duplicated
     * here to count faces.
     */

    /* Zero face use counts
     * and make sure normal vectors are unit vectors
     */
    for (i = 0; i < aip->neqn; i++) {
	double normalLen = MAGNITUDE(aip->eqn[i]);
	double scale;
	if (ZERO(normalLen)) {
	    bu_log("arbn has zero length normal vector\n");
	    return 1;
	}
	scale = 1.0 / normalLen;
	HSCALE(aip->eqn[i], aip->eqn[i], scale);
	used[i] = 0;
    }
    for (i = 0; i < aip->neqn-2; i++) {
	for (j=i+1; j<aip->neqn-1; j++) {
	    double dot;

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

	    /* Have an edge line, isect with higher numbered planes */
	    for (k=j+1; k<aip->neqn; k++) {
		size_t m;
		size_t next_k;
		point_t pt;

		next_k = 0;

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

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

		VMINMAX(stp->st_min, stp->st_max, pt);

		/* Increment "face used" counts */
		used[i]++;
		used[j]++;
		used[k]++;
	    }
	}
    }

    /* If any planes were not used, then arbn is not convex */
    for (i = 0; i < aip->neqn; i++) {
	if (used[i] != 0) continue;	/* face was used */
	bu_log("arbn(%s) face %zu unused, solid is not convex\n",
	       stp->st_name, i);
	bu_free((char *)used, "arbn used[]");
	return -1;		/* BAD */
    }
    bu_free((char *)used, "arbn used[]");

    stp->st_specific = (void *)aip;
    ip->idb_ptr = ((void *)0);	/* indicate we stole it */

    VADD2SCALE(stp->st_center, stp->st_min, stp->st_max, 0.5);
    VSUB2SCALE(work, stp->st_max, stp->st_min, 0.5);

    f = work[X];
    if (work[Y] > f) f = work[Y];
    if (work[Z] > f) f = work[Z];
    stp->st_aradius = f;
    stp->st_bradius = MAGNITUDE(work);
    return 0;			/* OK */
}