示例#1
0
struct face_g_snurb *
rt_nurb_scopy(const struct face_g_snurb *srf, struct resource *res)
{
    register struct face_g_snurb * n;
    int i;

    NMG_CK_SNURB(srf);

    n = (struct face_g_snurb *) rt_nurb_new_snurb(srf->order[0], srf->order[1],
						  srf->u.k_size, srf->v.k_size,
						  srf->s_size[0], srf->s_size[1],
						  srf->pt_type, res);

    for (i = 0; i < srf->u.k_size; i++)
	n->u.knots[i] =  srf->u.knots[i];

    for (i = 0; i < srf->v.k_size; i++)
	n->v.knots[i] =  srf->v.knots[i];

    for (i = 0; i < srf->s_size[0] * srf->s_size[1] *
	     RT_NURB_EXTRACT_COORDS(srf->pt_type); i++)
    {

	n->ctl_points[i] = srf->ctl_points[i];
    }

    return (struct face_g_snurb *) n;
}
示例#2
0
/*
 *			R T _ N U R B _ B E Z I E R
 *
 *  Given a single snurb, if it is in Bezier form,
 *  duplicate the snurb, and enqueue it on the bezier_hd list.
 *  If the original snurb is NOT in Bezier form,
 *  subdivide it a set of snurbs which are,
 *  each of which are enqueued on the bezier_hd list.
 *
 *  In either case, the original surface remains untouched.
 *
 *  Returns -
 *	0	Surface splitting was done.
 *	1	Original surface was Bezier, only a copy was done.
 */
int
rt_nurb_bezier(struct bu_list *bezier_hd, const struct face_g_snurb *orig_surf, struct resource *res)
{
    struct face_g_snurb	*s;
    int		dir;
    struct bu_list	todo;

    NMG_CK_SNURB(orig_surf);

    if ( (dir = rt_bez_check( orig_surf )) == -1)  {
	s = rt_nurb_scopy( orig_surf, res );
	BU_LIST_APPEND( bezier_hd, &s->l );
	return 1;	/* Was already Bezier, nothing done */
    }

    BU_LIST_INIT( &todo );
    rt_nurb_s_split( &todo, orig_surf, dir, res );

    while ( BU_LIST_WHILE( s, face_g_snurb, &todo ) )  {
	if ( (dir = rt_bez_check(s)) == -1)  {
	    /* This snurb is now a Bezier */
	    BU_LIST_DEQUEUE( &s->l );
	    BU_LIST_APPEND( bezier_hd, &s->l );
	} else {
	    /* Split, and keep going */
	    BU_LIST_DEQUEUE( &s->l );
	    rt_nurb_s_split( &todo, s, dir, res );
	    rt_nurb_free_snurb(s, res);
	}
    }
    return 0;		/* Bezier snurbs on bezier_hd list */
}
示例#3
0
extern "C" void
rt_nurb_brep(ON_Brep **b, const struct rt_db_internal *ip, const struct bn_tol *)
{
    int i, j, k;
    struct rt_nurb_internal *nip;

    RT_CK_DB_INTERNAL(ip);
    nip = (struct rt_nurb_internal *)ip->idb_ptr;
    RT_NURB_CK_MAGIC(nip);

    ON_TextLog log(stderr);

    for (i = 0; i < nip->nsrf; i++) {
	struct face_g_snurb *surface = nip->srfs[i];
	NMG_CK_SNURB(surface);

	ON_NurbsSurface *nurb = ON_NurbsSurface::New(3, true, surface->order[0], surface->order[1], surface->s_size[0], surface->s_size[1]);

	/* set 'u' knots */
	/* skip first and last (duplicates?) */
	for (j = 1; j < surface->u.k_size - 1; j++) {
	    nurb->SetKnot(0, j-1, surface->u.knots[j]);
	    /* bu_log("u knot %d is %f\n", j-1, surface->u.knots[j]); */
	}
	/* set 'v' knots */
	/* skip first and last (duplicates?) */
	for (j = 1; j < surface->v.k_size - 1; j++) {
	    nurb->SetKnot(1, j-1, surface->v.knots[j]);
	    /* bu_log("v knot %d is %f\n", j-1, surface->u.knots[j]); */
	}

	/* set control points */
	for (j = 0; j < surface->s_size[0]; j++) {
	    for (k = 0; k < surface->s_size[1]; k++) {
		ON_3dPoint point = &RT_NURB_GET_CONTROL_POINT(surface, j, k);
		nurb->SetCV(k, j, point);
	    }
	}

	/* nurb->Dump(log); */
	bu_log("NURBS surface %d %s valid\n", i, nurb->IsValid(&log) ? "is" : "is not");

	(*b)->m_S.Append(nurb);
	int sindex = (*b)->m_S.Count();
	(*b)->NewFace(sindex - 1);
	int findex = (*b)->m_F.Count();
	(*b)->NewOuterLoop(findex - 1);
    }

    bu_log("BREP object %s a single surface\n", (*b)->IsSurface() ? "is" : "is not");
    bu_log("BREP object %s valid\n", (*b)->IsValid(&log) ? "is" : "is not");
    bu_log("BREP object %s valid topology\n", (*b)->IsValidTopology(&log) ? "is" : "is not");
    bu_log("BREP object %s valid geometry\n", (*b)->IsValidGeometry(&log) ? "is" : "is not");
    bu_log("BREP object %s solid\n", (*b)->IsSolid() ? "is" : "is not");
    bu_log("BREP object %s manifold\n", (*b)->IsManifold() ? "is" : "is not");
}
示例#4
0
int
rt_bez_check(const struct face_g_snurb *srf)
{
    NMG_CK_SNURB(srf);

    if ( srf->u.k_size > (2.0 * srf->order[0]))
	return 0;
    if ( srf->v.k_size > (2.0 * srf->order[1]))
	return 1;

    return -1;
}
void
rt_nurb_free_snurb(struct face_g_snurb *srf, struct resource *res)
{
    NMG_CK_SNURB(srf);

    if (res) RT_CK_RESOURCE(res);

    /* assume that links to other surface and curves are already
     * deleted.
     */

    bu_free((char *)srf->u.knots, "rt_nurb_free_snurb: u kv knots");
    bu_free((char *)srf->v.knots, "rt_nurb_free_snurb: v kv knots");
    bu_free((char *)srf->ctl_points, "rt_nurb_free_snurb: mesh points");

    srf->l.magic = 0;
    bu_free((char *)srf, "rt_nurb_free_snurb: snurb struct");
}
/**
 * Clean up the storage use of an snurb, but don't release the
 * pointer.  Often used by routines that allocate an array of nurb
 * pointers, or use automatic variables to hold one.
 */
void
rt_nurb_clean_snurb(struct face_g_snurb *srf, struct resource *res)
{
    NMG_CK_SNURB(srf);

    if (res) RT_CK_RESOURCE(res);

    bu_free((char *)srf->u.knots, "rt_nurb_clean_snurb() u.knots");
    bu_free((char *)srf->v.knots, "rt_nurb_free_snurb() v.knots");
    bu_free((char *)srf->ctl_points, "rt_nurb_free_snurb() ctl_points");

    /* Invalidate the structure */
    srf->u.knots = (fastf_t *)NULL;
    srf->v.knots = (fastf_t *)NULL;
    srf->ctl_points = (fastf_t *)NULL;
    srf->order[0] = srf->order[1] = -1;
    srf->l.magic = 0;
}
void
rt_nurb_pr_mesh(const struct face_g_snurb *m)
{
    int i, j, k;
    fastf_t * m_ptr = m->ctl_points;
    int evp = RT_NURB_EXTRACT_COORDS(m->pt_type);

    NMG_CK_SNURB(m);

    bu_log("\t[%d] [%d]\n", m->s_size[0], m->s_size[1]);

    for (i = 0; i < m->s_size[0]; i++) {
	for (j =0; j < m->s_size[1]; j++) {
	    bu_log("\t");

	    for (k = 0; k < evp; k++)
		bu_log("%f    ", m_ptr[k]);

	    bu_log("\n");
	    m_ptr += RT_NURB_EXTRACT_COORDS(m->pt_type);
	}
	bu_log("\n");
    }
}
示例#8
0
文件: nurb_ray.c 项目: kanzure/brlcad
struct rt_nurb_uv_hit *
rt_nurb_intersect(const struct face_g_snurb *srf, fastf_t *plane1, fastf_t *plane2, double uv_tol, struct resource *res, struct bu_list *plist)
{
    struct rt_nurb_uv_hit * h;
    struct face_g_snurb * psrf,
	* osrf;
    int dir,
	sub;

    point_t vmin,
	vmax;
    fastf_t u[2],
	v[2];
    struct bu_list rni_plist;

    NMG_CK_SNURB(srf);

    h = (struct rt_nurb_uv_hit *) 0;
    if (plist == NULL) {
	plist = &rni_plist;
	BU_LIST_INIT(plist);
    }

    /* project the surface to a 2 dimensional problem */
    /* NOTE that this gives a single snurb back, NOT a list */
    psrf = rt_nurb_project_srf(srf, plane2, plane1, res);
    psrf->dir = 1;
    BU_LIST_APPEND(plist, &psrf->l);

    if (RT_G_DEBUG & DEBUG_SPLINE)
	rt_nurb_s_print("srf", psrf);

    /* This list starts out with only a single snurb, but more may be
     * added on as work progresses.
     */
    while (BU_LIST_WHILE(psrf, face_g_snurb, plist)) {
	int flat;

	BU_LIST_DEQUEUE(&psrf->l);
	NMG_CK_SNURB(psrf);
	sub = 0;
	flat = 0;
	dir = psrf->dir;

	while (!flat) {
	    fastf_t smin = 0.0, smax = 0.0;

	    sub++;
	    dir = (dir == 0)?1:0;	/* change direction */

	    if (RT_G_DEBUG & DEBUG_SPLINE)
		rt_nurb_s_print("psrf", psrf);

	    rt_nurb_pbound(psrf, vmin, vmax);

	    /* Check for origin to be included in the bounding box */
	    if (!(vmin[0] <= 0.0 && vmin[1] <= 0.0 &&
		  vmax[0] >= 0.0 && vmax[1] >= 0.0)) {
		if (RT_G_DEBUG & DEBUG_SPLINE)
		    bu_log("this srf doesn't include the origin\n");
		flat = 1;
		rt_nurb_free_snurb(psrf, res);
		continue;
	    }

	    rt_nurb_clip_srf(psrf, dir, &smin, &smax);

	    if ((smax - smin) > .8) {
		struct rt_nurb_uv_hit *hp;

		/* Split surf, requeue both sub-surfs at head */
		/* New surfs will have same dir as arg, here */
		if (RT_G_DEBUG & DEBUG_SPLINE)
		    bu_log("splitting this surface\n");
		rt_nurb_s_split(plist, psrf, dir, res);
		rt_nurb_free_snurb(psrf, res);

		hp = rt_nurb_intersect(srf, plane1, plane2, uv_tol, res, plist);
		return hp;
	    }
	    if (smin > 1.0 || smax < 0.0) {
		if (RT_G_DEBUG & DEBUG_SPLINE)
		    bu_log("eliminating this surface (smin=%g, smax=%g)\n", smin, smax);
		flat = 1;
		rt_nurb_free_snurb(psrf, res);
		continue;
	    }
	    if (dir == RT_NURB_SPLIT_ROW) {
		smin = (1.0 - smin) * psrf->u.knots[0] +
		    smin * psrf->u.knots[
			psrf->u.k_size -1];
		smax = (1.0 - smax) * psrf->u.knots[0] +
		    smax * psrf->u.knots[
			psrf->u.k_size -1];
	    } else {
		smin = (1.0 - smin) * psrf->v.knots[0] +
		    smin * psrf->v.knots[
			psrf->v.k_size -1];
		smax = (1.0 - smax) * psrf->v.knots[0] +
		    smax * psrf->v.knots[
			psrf->v.k_size -1];
	    }

	    osrf = psrf;
	    psrf = (struct face_g_snurb *) rt_nurb_region_from_srf(
		osrf, dir, smin, smax, res);

	    psrf->dir = dir;
	    rt_nurb_free_snurb(osrf, res);

	    if (RT_G_DEBUG & DEBUG_SPLINE) {
		bu_log("After call to rt_nurb_region_from_srf() (smin=%g, smax=%g)\n", smin, smax);
		rt_nurb_s_print("psrf", psrf);
	    }

	    u[0] = psrf->u.knots[0];
	    u[1] = psrf->u.knots[psrf->u.k_size -1];

	    v[0] = psrf->v.knots[0];
	    v[1] = psrf->v.knots[psrf->v.k_size -1];

	    if ((u[1] - u[0]) < uv_tol && (v[1] - v[0]) < uv_tol) {
		struct rt_nurb_uv_hit * hit;

		if (RT_G_DEBUG & DEBUG_SPLINE) {
		    fastf_t p1[4], p2[4];
		    int coords;
		    vect_t diff;

		    coords = RT_NURB_EXTRACT_COORDS(srf->pt_type);
		    rt_nurb_s_eval(srf, u[0], v[0], p1);
		    rt_nurb_s_eval(srf, u[1], v[1], p2);

		    if (RT_NURB_IS_PT_RATIONAL(srf->pt_type)) {
			fastf_t inv_w;

			inv_w = 1.0 / p1[coords-1];
			VSCALE(p1, p1, inv_w);

			inv_w = 1.0 / p2[coords-1];
			VSCALE(p2, p2, inv_w);
		    }

		    VSUB2(diff, p1, p2);
		    bu_log("Precision of hit point = %g (%f %f %f) <-> (%f %f %f)\n",
			   MAGNITUDE(diff), V3ARGS(p1), V3ARGS(p2));
		}

		hit = (struct rt_nurb_uv_hit *) bu_malloc(
		    sizeof(struct rt_nurb_uv_hit),  "hit");

		hit->next = (struct rt_nurb_uv_hit *)0;
		hit->sub = sub;
		hit->u = (u[0] + u[1])/2.0;
		hit->v = (v[0] + v[1])/2.0;

		if (h == (struct rt_nurb_uv_hit *)0)
		    h = hit;
		else {
		    hit->next = h;
		    h = hit;
		}
		flat = 1;
		rt_nurb_free_snurb(psrf, res);
	    }
	    if ((u[1] - u[0]) > (v[1] - v[0]))
		dir = 1;
	    else dir = 0;
	}
    }

    return (struct rt_nurb_uv_hit *)h;
}
struct face_g_snurb *
rt_nurb_s_diff(const struct face_g_snurb *srf, int dir)
{
    struct face_g_snurb *nsrf;
    int i;

    NMG_CK_SNURB(srf);

    if (dir == RT_NURB_SPLIT_ROW) {
	nsrf = (struct face_g_snurb *)
	    rt_nurb_new_snurb(srf->order[0] - 1, srf->order[1],
			      srf->u.k_size - 2, srf->v.k_size,
			      srf->s_size[0], srf->s_size[1] - 1,
			      srf->pt_type, (struct resource *)NULL);

	for (i = 0; i < srf->s_size[0]; i++) {
	    fastf_t * old_points, *new_points;

	    old_points = srf->ctl_points +
		i * RT_NURB_EXTRACT_COORDS(srf->pt_type)
		*srf->s_size[1];

	    new_points = nsrf->ctl_points +
		i * RT_NURB_EXTRACT_COORDS(nsrf->pt_type)
		*nsrf->s_size[1];

	    rt_nurb_mesh_diff(srf->order[0],
			      old_points, new_points, srf->u.knots,
			      RT_NURB_EXTRACT_COORDS(srf->pt_type),
			      RT_NURB_EXTRACT_COORDS(nsrf->pt_type),
			      srf->s_size[1], srf->pt_type);
	}

	for (i = 1; i < srf->u.k_size - 1; i++)
	    nsrf->u.knots[i - 1] = srf->u.knots[i];

	for (i = 0; i < srf->v.k_size; i++)
	    nsrf->v.knots[i] = srf->v.knots[i];
    } else {
	nsrf = (struct face_g_snurb *) rt_nurb_new_snurb(
	    srf->order[0], srf->order[1] - 1,
	    srf->u.k_size, srf->v.k_size - 2,
	    srf->s_size[0] - 1, srf->s_size[1],
	    srf->pt_type, (struct resource *)NULL);

	for (i = 0; i < srf->s_size[1]; i++) {
	    fastf_t * old_points, *new_points;

	    old_points = srf->ctl_points +
		i * RT_NURB_EXTRACT_COORDS(srf->pt_type);

	    new_points = nsrf->ctl_points +
		i * RT_NURB_EXTRACT_COORDS(nsrf->pt_type);

	    rt_nurb_mesh_diff(srf->order[1],
			      old_points, new_points, srf->v.knots,
			      RT_NURB_EXTRACT_COORDS(srf->pt_type) *
			      srf->s_size[1],
			      RT_NURB_EXTRACT_COORDS(nsrf->pt_type) *
			      nsrf->s_size[1],
			      srf->s_size[0], srf->pt_type);
	}

	for (i = 0; i < srf->u.k_size; i++)
	    nsrf->u.knots[i] = srf->u.knots[i];

	for (i = 1; i < srf->v.k_size - 1; i++)
	    nsrf->v.knots[i-1] = srf->v.knots[i];
    }
    return nsrf;
}
示例#10
0
/**
 * Algorithm
 *
 * Given a parametric direction (u or v) look at the direction knot
 * vector and insert a multiple knot of parametric direction surface
 * order.  If internal knot values exist than pick the one closest to
 * the middle and add additional knots to split at that value,
 * otherwise add multiple knots at the mid point of the knot
 * vector. Use the new knot vector to pass to the oslo refinement
 * process and split the surface.  Separate the surface and return the
 * two resulting surface.
 *
 * The original surface is undisturbed by this operation.
 */
void
rt_nurb_s_split(struct bu_list *split_hd, const struct face_g_snurb *srf, int dir, struct resource *res)
{
    struct knot_vector new_kv;
    fastf_t value;
    struct oslo_mat * oslo;
    int i;
    int k_index = 0;
    struct face_g_snurb * srf1, * srf2;

    NMG_CK_SNURB(srf);

    if (dir == RT_NURB_SPLIT_ROW) {
        value = srf->u.knots[(srf->u.k_size -1)/2];

        for (i = 0; i < srf->u.k_size; i++)
            if (ZERO(value - srf->u.knots[i])) {
                k_index = i;
                break;
            }
        if (k_index == 0) {
            value = (value +
                     srf->u.knots[ srf->u.k_size -1])
                    /2.0;
            k_index = srf->order[0];
        }

        rt_nurb_kvmult(&new_kv, &srf->u, srf->order[0], value, res);

        oslo = (struct oslo_mat *)
               rt_nurb_calc_oslo(srf->order[RT_NURB_SPLIT_ROW], &srf->u, &new_kv, res);

        GET_SNURB(srf1);
        srf1->order[0]  = srf->order[0];
        srf1->order[1]  = srf->order[1];
        srf1->dir = RT_NURB_SPLIT_ROW;
        rt_nurb_kvextract(&srf1->u, &new_kv, 0, k_index + srf1->order[0], res);
        rt_nurb_kvcopy(&srf1->v, &srf->v, res);

        srf1->pt_type = srf->pt_type;
        srf1->s_size[0] = srf1->v.k_size -
                          srf1->order[1];
        srf1->s_size[1] = srf1->u.k_size -
                          srf1->order[0];

        srf1->ctl_points = (fastf_t *)
                           bu_malloc(sizeof(fastf_t) * srf1->s_size[0] *
                                     srf1->s_size[1] *
                                     RT_NURB_EXTRACT_COORDS(srf1->pt_type),
                                     "rt_nurb_s_split: srf1 row mesh control points");

        GET_SNURB(srf2);
        srf2->order[0]  = srf->order[0];
        srf2->order[1]  = srf->order[1];
        srf2->dir = RT_NURB_SPLIT_ROW;
        rt_nurb_kvextract(&srf2->u, &new_kv, k_index, new_kv.k_size, res);
        rt_nurb_kvcopy(&srf2->v, &srf->v, res);

        srf2->pt_type = srf->pt_type;
        srf2->s_size[0] = srf2->v.k_size -
                          srf2->order[1];
        srf2->s_size[1] = srf2->u.k_size -
                          srf2->order[0];

        srf2->ctl_points = (fastf_t *)
                           bu_malloc(sizeof(fastf_t) * srf2->s_size[0] *
                                     srf2->s_size[1] *
                                     RT_NURB_EXTRACT_COORDS(srf2->pt_type),
                                     "rt_nurb_s_split: srf2 row mesh control points");

        for (i = 0; i < srf->s_size[0]; i++) {
            fastf_t * old_mesh_ptr;
            fastf_t * new_mesh_ptr;

            old_mesh_ptr = &srf->ctl_points[
                               i * srf->s_size[1] *
                               RT_NURB_EXTRACT_COORDS(srf->pt_type)];
            new_mesh_ptr = &srf1->ctl_points[
                               i * srf1->s_size[1] *
                               RT_NURB_EXTRACT_COORDS(srf1->pt_type)];
            rt_nurb_map_oslo(oslo, old_mesh_ptr, new_mesh_ptr,
                             RT_NURB_EXTRACT_COORDS(srf->pt_type),
                             RT_NURB_EXTRACT_COORDS(srf1->pt_type),
                             0, k_index, srf1->pt_type);
            new_mesh_ptr = &srf2->ctl_points[
                               i * srf2->s_size[1] *
                               RT_NURB_EXTRACT_COORDS(srf2->pt_type)];
            rt_nurb_map_oslo(oslo, old_mesh_ptr, new_mesh_ptr,
                             RT_NURB_EXTRACT_COORDS(srf->pt_type),
                             RT_NURB_EXTRACT_COORDS(srf2->pt_type),
                             k_index, new_kv.k_size - srf2->order[0],
                             srf2->pt_type);
        }
    } else {
        value = srf->v.knots[(srf->v.k_size -1)/2];

        for (i = 0; i < srf->v.k_size; i++)
            if (ZERO(value - srf->v.knots[i])) {
                k_index = i;
                break;
            }
        if (k_index == 0) {
            value = (value +
                     srf->v.knots[ srf->v.k_size -1])
                    /2.0;
            k_index = srf->order[1];
        }

        rt_nurb_kvmult(&new_kv, &srf->v, srf->order[RT_NURB_SPLIT_COL], value, res);

        oslo = (struct oslo_mat *)
               rt_nurb_calc_oslo(srf->order[RT_NURB_SPLIT_COL], &srf->v, &new_kv, res);

        GET_SNURB(srf1);
        srf1->order[0]  = srf->order[0];
        srf1->order[1]  = srf->order[1];
        srf1->dir = RT_NURB_SPLIT_COL;
        rt_nurb_kvextract(&srf1->v, &new_kv, 0, k_index + srf1->order[RT_NURB_SPLIT_COL], res);
        rt_nurb_kvcopy(&srf1->u, &srf->u, res);

        srf1->pt_type = srf->pt_type;
        srf1->s_size[0] = srf1->v.k_size -
                          srf1->order[1];
        srf1->s_size[1] = srf1->u.k_size -
                          srf1->order[0];

        srf1->ctl_points = (fastf_t *)
                           bu_malloc(sizeof(fastf_t) * srf1->s_size[0] *
                                     srf1->s_size[1] *
                                     RT_NURB_EXTRACT_COORDS(srf1->pt_type),
                                     "rt_nurb_s_split: srf1 col mesh control points");

        GET_SNURB(srf2);
        srf2->order[0]  = srf->order[0];
        srf2->order[1]  = srf->order[1];
        srf2->dir = RT_NURB_SPLIT_COL;
        rt_nurb_kvextract(&srf2->v, &new_kv, k_index, new_kv.k_size, res);
        rt_nurb_kvcopy(&srf2->u, &srf->u, res);

        srf2->pt_type = srf->pt_type;
        srf2->s_size[0] = srf2->v.k_size -
                          srf2->order[1];
        srf2->s_size[1] = srf2->u.k_size -
                          srf2->order[0];

        srf2->ctl_points = (fastf_t *)
                           bu_malloc(sizeof(fastf_t) * srf2->s_size[0] *
                                     srf2->s_size[1] *
                                     RT_NURB_EXTRACT_COORDS(srf2->pt_type),
                                     "rt_nurb_s_split: srf2 col mesh control points");

        for (i = 0; i < srf->s_size[1]; i++) {
            fastf_t * old_mesh_ptr;
            fastf_t * new_mesh_ptr;

            old_mesh_ptr = &srf->ctl_points[
                               i * RT_NURB_EXTRACT_COORDS(srf->pt_type)];
            new_mesh_ptr = &srf1->ctl_points[
                               i * RT_NURB_EXTRACT_COORDS(srf1->pt_type)];
            rt_nurb_map_oslo(oslo, old_mesh_ptr, new_mesh_ptr,
                             srf->s_size[1] *
                             RT_NURB_EXTRACT_COORDS(srf->pt_type),
                             srf1->s_size[1] *
                             RT_NURB_EXTRACT_COORDS(srf1->pt_type),
                             0, k_index, srf1->pt_type);
            new_mesh_ptr = &srf2->ctl_points[
                               i * RT_NURB_EXTRACT_COORDS(srf2->pt_type)];
            rt_nurb_map_oslo(oslo, old_mesh_ptr, new_mesh_ptr,
                             srf->s_size[1] *
                             RT_NURB_EXTRACT_COORDS(srf->pt_type),
                             srf2->s_size[1] *
                             RT_NURB_EXTRACT_COORDS(srf2->pt_type),
                             k_index, new_kv.k_size - srf2->order[1],
                             srf2->pt_type);
        }
    }

    /* Arrangement will be:  head, srf1, srf2 */
    BU_LIST_APPEND(split_hd, &srf2->l);
    BU_LIST_APPEND(split_hd, &srf1->l);

    rt_nurb_free_oslo(oslo, res);
    bu_free((char *)new_kv.knots, "rt_nurb_s_split: new kv knots");

}
示例#11
0
/**
 * Algorithm
 *
 * Given a parametric direction (u or v) look at the direction knot
 * vector and insert a multiple knot of parametric direction surface
 * order. This is somewhat different than rt_nurb_split in that the
 * surface is give a parametric value at which to split the surface.
 * rt_nurb_kvmult does the right thing in inserting a multiple knot
 * with the correct amount. Separate the surface and return the two
 * resulting surface.
 */
struct face_g_snurb *
rt_nurb_s_xsplit(struct face_g_snurb *srf, fastf_t param, int dir)
{
    struct knot_vector new_kv;
    struct oslo_mat * oslo;
    int i;
    int k_index;
    struct face_g_snurb * srf1, * srf2;

    NMG_CK_SNURB(srf);

    if (dir == RT_NURB_SPLIT_ROW) {
	rt_nurb_kvmult(&new_kv, &srf->u, srf->order[0], param, (struct resource *)NULL);

	k_index = srf->order[0];

	oslo = (struct oslo_mat *)
	    rt_nurb_calc_oslo(srf->order[RT_NURB_SPLIT_ROW], &srf->u, &new_kv, (struct resource *)NULL);

	GET_SNURB(srf1);
	srf1->order[0]  = srf->order[0];
	srf1->order[1]  = srf->order[1];
	srf1->dir = RT_NURB_SPLIT_ROW;
	rt_nurb_kvextract(&srf1->u, &new_kv, 0, k_index + srf1->order[0], (struct resource *)NULL);
	rt_nurb_kvcopy(&srf1->v, &srf->v, (struct resource *)NULL);

	srf1->pt_type = srf->pt_type;
	srf1->s_size[0] = srf1->v.k_size -
	    srf1->order[1];
	srf1->s_size[1] = srf1->u.k_size -
	    srf1->order[0];

	srf1->ctl_points = (fastf_t *)
	    bu_malloc(sizeof(fastf_t) * srf1->s_size[0] *
		      srf1->s_size[1] *
		      RT_NURB_EXTRACT_COORDS(srf1->pt_type),
		      "rt_nurb_s_xsplit: srf1 row mesh control points");

	GET_SNURB(srf2);
	srf2->order[0]  = srf->order[0];
	srf2->order[1]  = srf->order[1];
	srf2->dir = RT_NURB_SPLIT_ROW;
	rt_nurb_kvextract(&srf2->u, &new_kv, k_index, new_kv.k_size, (struct resource *)NULL);
	rt_nurb_kvcopy(&srf2->v, &srf->v, (struct resource *)NULL);

	srf2->pt_type = srf->pt_type;
	srf2->s_size[0] = srf2->v.k_size -
	    srf2->order[1];
	srf2->s_size[1] = srf2->u.k_size -
	    srf2->order[0];

	srf2->ctl_points = (fastf_t *)
	    bu_malloc(sizeof(fastf_t) * srf2->s_size[0] *
		      srf2->s_size[1] *
		      RT_NURB_EXTRACT_COORDS(srf2->pt_type),
		      "rt_nurb_s_xsplit: srf2 row mesh control points");

	for (i = 0; i < srf->s_size[0]; i++) {
	    fastf_t * old_mesh_ptr;
	    fastf_t * new_mesh_ptr;

	    old_mesh_ptr = &srf->ctl_points[
		i * srf->s_size[1] *
		RT_NURB_EXTRACT_COORDS(srf->pt_type)];
	    new_mesh_ptr = &srf1->ctl_points[
		i * srf1->s_size[1] *
		RT_NURB_EXTRACT_COORDS(srf1->pt_type)];
	    rt_nurb_map_oslo(oslo, old_mesh_ptr, new_mesh_ptr,
			     RT_NURB_EXTRACT_COORDS(srf->pt_type),
			     RT_NURB_EXTRACT_COORDS(srf1->pt_type),
			     0, k_index, srf1->pt_type);
	    new_mesh_ptr = &srf2->ctl_points[
		i * srf2->s_size[1] *
		RT_NURB_EXTRACT_COORDS(srf2->pt_type)];
	    rt_nurb_map_oslo(oslo, old_mesh_ptr, new_mesh_ptr,
			     RT_NURB_EXTRACT_COORDS(srf->pt_type),
			     RT_NURB_EXTRACT_COORDS(srf2->pt_type),
			     k_index, new_kv.k_size - srf2->order[0],
			     srf2->pt_type);
	}
    } else {
	rt_nurb_kvmult(&new_kv, &srf->v, srf->order[RT_NURB_SPLIT_COL], param, (struct resource *)NULL);

	k_index = srf->order[1];

	oslo = (struct oslo_mat *)
	    rt_nurb_calc_oslo(srf->order[RT_NURB_SPLIT_COL], &srf->v, &new_kv, (struct resource *)NULL);

	GET_SNURB(srf1);
	srf1->order[0]  = srf->order[0];
	srf1->order[1]  = srf->order[1];
	srf1->dir = RT_NURB_SPLIT_COL;
	rt_nurb_kvextract(&srf1->v, &new_kv, 0, k_index + srf1->order[RT_NURB_SPLIT_COL], (struct resource *)NULL);
	rt_nurb_kvcopy(&srf1->u, &srf->u, (struct resource *)NULL);

	srf1->pt_type = srf->pt_type;
	srf1->s_size[0] = srf1->v.k_size -
	    srf1->order[1];
	srf1->s_size[1] = srf1->u.k_size -
	    srf1->order[0];

	srf1->ctl_points = (fastf_t *)
	    bu_malloc(sizeof(fastf_t) * srf1->s_size[0] *
		      srf1->s_size[1] *
		      RT_NURB_EXTRACT_COORDS(srf1->pt_type),
		      "rt_nurb_split: srf1 row mesh control points");

	GET_SNURB(srf2);
	srf2->order[0]  = srf->order[0];
	srf2->order[1]  = srf->order[1];
	srf2->dir = RT_NURB_SPLIT_COL;
	rt_nurb_kvextract(&srf2->v, &new_kv, k_index, new_kv.k_size, (struct resource *)NULL);
	rt_nurb_kvcopy(&srf2->u, &srf->u, (struct resource *)NULL);

	srf2->pt_type = srf->pt_type;
	srf2->s_size[0] = srf2->v.k_size -
	    srf2->order[1];
	srf2->s_size[1] = srf2->u.k_size -
	    srf2->order[0];

	srf2->ctl_points = (fastf_t *)
	    bu_malloc(sizeof(fastf_t) * srf2->s_size[0] *
		      srf2->s_size[1] *
		      RT_NURB_EXTRACT_COORDS(srf2->pt_type),
		      "rt_nurb_s_xsplit: srf2 row mesh control points");

	for (i = 0; i < srf->s_size[1]; i++) {
	    fastf_t * old_mesh_ptr;
	    fastf_t * new_mesh_ptr;

	    old_mesh_ptr = &srf->ctl_points[
		i * RT_NURB_EXTRACT_COORDS(srf->pt_type)];
	    new_mesh_ptr = &srf1->ctl_points[
		i * RT_NURB_EXTRACT_COORDS(srf1->pt_type)];
	    rt_nurb_map_oslo(oslo, old_mesh_ptr, new_mesh_ptr,
			     srf->s_size[1] *
			     RT_NURB_EXTRACT_COORDS(srf->pt_type),
			     srf1->s_size[1] *
			     RT_NURB_EXTRACT_COORDS(srf1->pt_type),
			     0, k_index, srf1->pt_type);
	    new_mesh_ptr = &srf2->ctl_points[
		i * RT_NURB_EXTRACT_COORDS(srf2->pt_type)];
	    rt_nurb_map_oslo(oslo, old_mesh_ptr, new_mesh_ptr,
			     srf->s_size[1] *
			     RT_NURB_EXTRACT_COORDS(srf->pt_type),
			     srf2->s_size[1] *
			     RT_NURB_EXTRACT_COORDS(srf2->pt_type),
			     k_index, new_kv.k_size - srf2->order[1],
			     srf2->pt_type);
	}
    }

    BU_LIST_APPEND(&srf1->l, &srf2->l);

    bu_free((char *) new_kv.knots, "rt_nurb_s_xsplit: new_kv.knots");

    rt_nurb_free_oslo(oslo, (struct resource *)NULL);

    return srf1;
}
示例#12
0
/**
 * Returns a refined surface.  The original surface is unmodified.
 */
struct face_g_snurb *
rt_nurb_s_refine(const struct face_g_snurb *srf, int dir, struct knot_vector *kv, struct resource *res)
    /* Old surface to be refined */
    /* Direction to refine */
    /* Row = 0, Col = 1 */
    /* New knot vector */

{
    register struct face_g_snurb * nurb_srf;
    struct oslo_mat *oslo;	/* oslo refinement matrix */
    int i;

    NMG_CK_SNURB(srf);

    if (dir == RT_NURB_SPLIT_ROW) {
	/* Row (u) direction */
	GET_SNURB(nurb_srf);
	nurb_srf->order[0] = srf->order[0];
	nurb_srf->order[1] = srf->order[1];

	rt_nurb_kvcopy(&nurb_srf->u, kv, res);
	rt_nurb_kvcopy(&nurb_srf->v, &srf->v, res);

	nurb_srf->s_size[0] = srf->s_size[0];
	nurb_srf->s_size[1] = kv->k_size - srf->order[0];
	nurb_srf->pt_type = srf->pt_type;
	nurb_srf->ctl_points = (fastf_t *)
	    bu_malloc(sizeof (fastf_t) *
		      nurb_srf->s_size[0] *
		      nurb_srf->s_size[1] *
		      RT_NURB_EXTRACT_COORDS(nurb_srf->pt_type),
		      "rt_nurb_s_refine: row mesh control points");

	oslo = (struct oslo_mat *)
	    rt_nurb_calc_oslo (srf -> order[RT_NURB_SPLIT_ROW], &srf->u, kv, res);

	for (i = 0; i < nurb_srf->s_size[0]; i++) {
	    fastf_t * old_mesh_ptr;
	    fastf_t * new_mesh_ptr;

	    old_mesh_ptr = &srf->ctl_points[
		i * srf->s_size[1] *
		RT_NURB_EXTRACT_COORDS(srf->pt_type)];
	    new_mesh_ptr = &nurb_srf->ctl_points[
		i * nurb_srf->s_size[1] *
		RT_NURB_EXTRACT_COORDS(nurb_srf->pt_type)];
	    rt_nurb_map_oslo(oslo, old_mesh_ptr, new_mesh_ptr,
			     RT_NURB_EXTRACT_COORDS(srf->pt_type),
			     RT_NURB_EXTRACT_COORDS(nurb_srf->pt_type),
			     0, kv->k_size - nurb_srf->order[0],
			     nurb_srf->pt_type);
	}

	rt_nurb_free_oslo(oslo, res);

    } else {
	/* Col (v) direction */
	GET_SNURB(nurb_srf);
	nurb_srf->order[0] = srf->order[0];
	nurb_srf->order[1] = srf->order[1];

	rt_nurb_kvcopy(&nurb_srf->u, &srf->u, res);
	rt_nurb_kvcopy(&nurb_srf->v, kv, res);

	nurb_srf->s_size[0] = kv->k_size - srf->order[1];
	nurb_srf->s_size[1] = srf->s_size[1];

	nurb_srf->pt_type = srf->pt_type;
	nurb_srf->ctl_points = (fastf_t *)
	    bu_malloc(sizeof (fastf_t) *
		      nurb_srf->s_size[0] *
		      nurb_srf->s_size[1] *
		      RT_NURB_EXTRACT_COORDS(nurb_srf->pt_type),
		      "rt_nurb_s_refine: row mesh control points");

	oslo = (struct oslo_mat *)
	    rt_nurb_calc_oslo (srf->order[RT_NURB_SPLIT_COL], &srf->v, kv, res);

	for (i = 0; i < nurb_srf->s_size[1]; i++) {
	    fastf_t * old_mesh_ptr;
	    fastf_t * new_mesh_ptr;

	    old_mesh_ptr = &srf->ctl_points[
		i * RT_NURB_EXTRACT_COORDS(srf->pt_type)];
	    new_mesh_ptr = &nurb_srf->ctl_points[
		i * RT_NURB_EXTRACT_COORDS(nurb_srf->pt_type)];
	    rt_nurb_map_oslo(oslo, old_mesh_ptr, new_mesh_ptr,
			     srf->s_size[1] *
			     RT_NURB_EXTRACT_COORDS(srf->pt_type),
			     nurb_srf->s_size[1] *
			     RT_NURB_EXTRACT_COORDS(nurb_srf->pt_type),
			     0, kv->k_size - nurb_srf->order[1],
			     nurb_srf->pt_type);
	}
	rt_nurb_free_oslo(oslo, res);
    }
    return nurb_srf;
}