void rt_nurb_c_print(const struct edge_g_cnurb *crv) { register fastf_t * ptr; int i, j; NMG_CK_CNURB(crv); bu_log("curve = {\n"); bu_log("\tOrder = %d\n", crv->order); bu_log("\tKnot Vector = {\n\t\t"); for (i = 0; i < crv->k.k_size; i++) bu_log("%10.8f ", crv->k.knots[i]); bu_log("\n\t}\n"); bu_log("\t"); rt_nurb_print_pt_type(crv->pt_type); bu_log("\tmesh = {\n"); for (ptr = &crv->ctl_points[0], i= 0; i < crv->c_size; i++, ptr += RT_NURB_EXTRACT_COORDS(crv->pt_type)) { bu_log("\t\t"); for (j = 0; j < RT_NURB_EXTRACT_COORDS(crv->pt_type); j++) bu_log("%4.5f\t", ptr[j]); bu_log("\n"); } bu_log("\t}\n}\n"); }
struct edge_g_cnurb * rt_nurb_c_diff(const struct edge_g_cnurb *crv) { struct edge_g_cnurb *ncrv; fastf_t * opts, *npts; int i; NMG_CK_CNURB(crv); ncrv = (struct edge_g_cnurb *) rt_nurb_new_cnurb(crv->order - 1, crv->k.k_size - 2, crv->c_size - 1, crv->pt_type); opts = (fastf_t *) crv->ctl_points; npts = (fastf_t *) ncrv->ctl_points; rt_nurb_mesh_diff(crv->order, opts, npts, crv->k.knots, RT_NURB_EXTRACT_COORDS(crv->pt_type), RT_NURB_EXTRACT_COORDS(ncrv->pt_type), crv->c_size, crv->pt_type); for (i = 1; i < crv->k.k_size - 1; i++) ncrv->k.knots[ i - 1] = crv->k.knots[i]; return ncrv; }
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; }
/** * Release a cnurb and all the storage that it references. */ void rt_nurb_free_cnurb(struct edge_g_cnurb *crv) { NMG_CK_CNURB(crv); bu_free((char*)crv->k.knots, "rt_nurb_free_cnurb: knots"); bu_free((char*)crv->ctl_points, "rt_nurb_free_cnurb: control points"); crv->l.magic = 0; /* sanity */ bu_free((char*)crv, "rt_nurb_free_cnurb: cnurb struct"); }
/** * 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; }
/** * Clean up the storage use of a cnurb, 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_cnurb(struct edge_g_cnurb *crv) { NMG_CK_CNURB(crv); bu_free((char*)crv->k.knots, "rt_nurb_free_cnurb: knots"); bu_free((char*)crv->ctl_points, "rt_nurb_free_cnurb: control points"); /* Invalidate the structure */ crv->k.knots = (fastf_t *)NULL; crv->ctl_points = (fastf_t *)NULL; crv->c_size = 0; crv->order = -1; crv->l.magic = 0; }
struct edge_g_cnurb * rt_nurb_crv_copy(const struct edge_g_cnurb *crv) { register struct edge_g_cnurb * n; int i; NMG_CK_CNURB(crv); n = (struct edge_g_cnurb *) rt_nurb_new_cnurb(crv->order, crv->k.k_size, crv->c_size, crv->pt_type); for (i = 0; i < crv->k.k_size; i++) n->k.knots[i] = crv->k.knots[i]; for (i = 0; i < crv->c_size * RT_NURB_EXTRACT_COORDS(crv->pt_type); i++) n->ctl_points[i] = crv->ctl_points[i]; return (struct edge_g_cnurb *) n; }
/** * 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); }