struct edge_g_cnurb * rt_nurb_c_refine(const struct edge_g_cnurb *crv, struct knot_vector *kv) { struct oslo_mat * oslo; struct edge_g_cnurb * new_crv; int i, coords; NMG_CK_CNURB(crv); coords = RT_NURB_EXTRACT_COORDS(crv->pt_type); new_crv = (struct edge_g_cnurb *) rt_nurb_new_cnurb( crv->order, kv->k_size, kv->k_size - crv->order, crv->pt_type); oslo = (struct oslo_mat *) rt_nurb_calc_oslo( crv->order, &crv->k, kv, (struct resource *)NULL); rt_nurb_map_oslo(oslo, crv->ctl_points, new_crv->ctl_points, coords, coords, 0, kv->k_size - new_crv->order, new_crv->pt_type); new_crv->k.k_size = kv->k_size; for (i = 0; i < kv->k_size; i++) new_crv->k.knots[i] = kv->knots[i]; rt_nurb_free_oslo(oslo, (struct resource *)NULL); return new_crv; }
/** * rt_nurb_c_xsplit() * * Split a NURB curve by inserting a multiple knot and return the * result of the two curves. * * Algorithm: * * Insert a multiple knot of the curve order. A parameter is give for * the knot value for which the curve will be split. */ struct edge_g_cnurb * rt_nurb_c_xsplit(struct edge_g_cnurb *crv, fastf_t param) { struct knot_vector new_kv; struct oslo_mat * oslo; int k_index; struct edge_g_cnurb * crv1, * crv2; int coords; NMG_CK_CNURB(crv); coords = RT_NURB_EXTRACT_COORDS(crv->pt_type), k_index = crv->order; rt_nurb_kvmult(&new_kv, &crv->k, crv->order, param, (struct resource *)NULL); oslo = (struct oslo_mat *) rt_nurb_calc_oslo(crv->order, &crv->k, &new_kv, (struct resource *)NULL); GET_CNURB(crv1); crv1->order = crv->order; rt_nurb_kvextract(&crv1->k, &new_kv, 0, k_index + crv->order, (struct resource *)NULL); crv1->pt_type = crv->pt_type; crv1->c_size = crv1->k.k_size - crv1->order; crv1->ctl_points = (fastf_t *) bu_malloc(sizeof(fastf_t) * crv1->c_size * RT_NURB_EXTRACT_COORDS(crv1->pt_type), "rt_nurb_c_xsplit: crv1 control points"); GET_CNURB(crv2); crv2->order = crv->order; rt_nurb_kvextract(&crv2->k, &new_kv, k_index, new_kv.k_size, (struct resource *)NULL); crv2->pt_type = crv->pt_type; crv2->c_size = crv2->k.k_size - crv2->order; crv2->ctl_points = (fastf_t *) bu_malloc(sizeof(fastf_t) * crv2->c_size * RT_NURB_EXTRACT_COORDS(crv2->pt_type), "rt_nurb_c_xsplit: crv2 row mesh control points"); rt_nurb_map_oslo(oslo, crv->ctl_points, crv1->ctl_points, coords, coords, 0, k_index, crv->pt_type); rt_nurb_map_oslo(oslo, crv->ctl_points, crv2->ctl_points, coords, coords, k_index, new_kv.k_size - crv2->order, crv2->pt_type); rt_nurb_free_oslo(oslo, (struct resource *)NULL); bu_free((char *) new_kv.knots, "rt_nurb_c_xsplit: new_kv.knots"); BU_LIST_APPEND(&crv1->l, &crv2->l); return crv1; }
/** * 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"); }
/** * Split a NURB curve by inserting a multiple knot and return the * result of the two curves. * * Algorithm * * Insert a multiple knot of the curve 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 curve. Separate the * curve and return the two resulting curves. * * The original curve is undisturbed by this operation. */ void rt_nurb_c_split(struct bu_list *split_hd, const struct edge_g_cnurb *crv) { struct knot_vector new_kv; fastf_t value; struct oslo_mat * oslo; int i; int k_index = 0; struct edge_g_cnurb * crv1, * crv2; int coords; NMG_CK_CNURB(crv); coords = RT_NURB_EXTRACT_COORDS(crv->pt_type), value = crv->k.knots[(crv->k.k_size -1)/2]; for (i = 0; i < crv->k.k_size; i++) if (ZERO(value - crv->k.knots[i])) { k_index = i; break; } if (k_index == 0) { value = (value + crv->k.knots[ crv->k.k_size -1]) /2.0; k_index = crv->order; } rt_nurb_kvmult(&new_kv, &crv->k, crv->order, value, (struct resource *)NULL); oslo = (struct oslo_mat *) rt_nurb_calc_oslo(crv->order, &crv->k, &new_kv, (struct resource *)NULL); GET_CNURB(crv1); crv1->order = crv->order; rt_nurb_kvextract(&crv1->k, &new_kv, 0, k_index + crv->order, (struct resource *)NULL); crv1->pt_type = crv->pt_type; crv1->c_size = crv1->k.k_size - crv1->order; crv1->ctl_points = (fastf_t *) bu_malloc(sizeof(fastf_t) * crv1->c_size * RT_NURB_EXTRACT_COORDS(crv1->pt_type), "rt_nurb_c_split: crv1 control points"); GET_CNURB(crv2); crv2->order = crv->order; rt_nurb_kvextract(&crv2->k, &new_kv, k_index, new_kv.k_size, (struct resource *)NULL); crv2->pt_type = crv->pt_type; crv2->c_size = crv2->k.k_size - crv2->order; crv2->ctl_points = (fastf_t *) bu_malloc(sizeof(fastf_t) * crv2->c_size * RT_NURB_EXTRACT_COORDS(crv2->pt_type), "rt_nurb_s_split: crv2 mesh control points"); rt_nurb_map_oslo(oslo, crv->ctl_points, crv1->ctl_points, coords, coords, 0, k_index, crv->pt_type); rt_nurb_map_oslo(oslo, crv->ctl_points, crv2->ctl_points, coords, coords, k_index, new_kv.k_size - crv2->order, crv2->pt_type); rt_nurb_free_oslo(oslo, (struct resource *)NULL); bu_free((char *) new_kv.knots, "rt_nurb_c_split; new_kv.knots"); /* Arrangement will be: head, crv1, crv2 */ BU_LIST_APPEND(split_hd, &crv2->l); BU_LIST_APPEND(split_hd, &crv1->l); }
/** * 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; }
/** * 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; }