/** * 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; }
/** * Create a place holder for a new nurb curve. */ struct edge_g_cnurb * rt_nurb_new_cnurb(int order, int n_knots, int n_pts, int pt_type) { register struct edge_g_cnurb * crv; GET_CNURB(crv); crv->order = order; crv->k.k_size = n_knots; crv->k.knots = (fastf_t *) bu_malloc(n_knots * sizeof(fastf_t), "rt_nurb_new_cnurb: knot values"); crv->c_size = n_pts; crv->pt_type = pt_type; crv->ctl_points = (fastf_t *) bu_malloc(sizeof(fastf_t) * RT_NURB_EXTRACT_COORDS(pt_type) * n_pts, "rt_nurb_new_cnurb: mesh point values"); return crv; }
/** * 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); }