Example #1
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;
}
Example #2
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");

}
Example #3
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;
}