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; }
void make_face(fastf_t *a, fastf_t *b, fastf_t *c, fastf_t *d, int order) { register struct face_g_snurb *srf; int interior_pts = 0; int cur_kv; int i; int ki; register fastf_t *fp; srf = rt_nurb_new_snurb( order, order, 2*order+interior_pts, 2*order+interior_pts, /* # knots */ 2+interior_pts, 2+interior_pts, RT_NURB_MAKE_PT_TYPE(3, RT_NURB_PT_XYZ, RT_NURB_PT_NONRAT ), &rt_uniresource ); /* Build both knot vectors */ cur_kv = 0; /* current knot value */ ki = 0; /* current knot index */ for ( i=0; i<order; i++, ki++ ) { srf->u.knots[ki] = srf->v.knots[ki] = cur_kv; } cur_kv++; for ( i=0; i<interior_pts; i++, ki++ ) { srf->u.knots[ki] = srf->v.knots[ki] = cur_kv++; } for ( i=0; i<order; i++, ki++ ) { srf->u.knots[ki] = srf->v.knots[ki] = cur_kv; } rt_nurb_pr_kv( &srf->u ); /* * The control mesh is stored in row-major order. */ /* Head from point A to B */ #if 0 row = 0; for ( col=0; col < srf->s_curve[1]; col++ ) { fp = &srf->ctl_points[col*srf->s_curve[1]+row]; VSET( fp } #endif #define SSET(_col, _row, _val) { \ fp = &srf->ctl_points[((_col*srf->s_size[1])+_row)*3]; \ VMOVE( fp, _val ); } /* VADD2SCALE( mid, a, b, 0.5 ); */ SSET( 0, 0, a ); SSET( 0, 1, b ); SSET( 1, 0, d ); SSET( 1, 1, c ); si.srfs[si.nsrf++] = srf; }
void make_face(struct rt_nurb_internal *s, fastf_t *a, fastf_t *b, fastf_t *c, fastf_t *d, int order) { int i; int ki; int cur_kv; int interior_pts = 2; fastf_t *fp = NULL; struct face_g_snurb *srf = NULL; srf = rt_nurb_new_snurb(order, order, 2*order+interior_pts, 2*order+interior_pts, /* # knots */ 2+interior_pts, 2+interior_pts, RT_NURB_MAKE_PT_TYPE(3, RT_NURB_PT_XYZ, RT_NURB_PT_NONRAT), &rt_uniresource); /* Build both knot vectors */ /* current knot value */ cur_kv = 0; /* current knot index */ ki = 0; for (i=0; i<order; i++, ki++) { srf->u.knots[ki] = srf->v.knots[ki] = cur_kv; } cur_kv++; for (i=0; i<interior_pts; i++, ki++) { srf->u.knots[ki] = srf->v.knots[ki] = cur_kv++; } for (i=0; i<order; i++, ki++) { srf->u.knots[ki] = srf->v.knots[ki] = cur_kv; } rt_nurb_pr_kv(&srf->u); /* * The control mesh is stored in row-major order. */ SSET(fp, srf, 0, 0, a); SSET(fp, srf, 0, 1, b); SSET(fp, srf, 1, 0, d); SSET(fp, srf, 1, 1, c); s->srfs[s->nsrf++] = srf; }
struct face_g_snurb * rt_nurb_project_srf(const struct face_g_snurb *srf, fastf_t *plane1, fastf_t *plane2, struct resource *res) { register struct face_g_snurb *psrf; register fastf_t *mp1, *mp2; int n_pt_type; int rational; int i; if (RTG.NMG_debug & DEBUG_RT_ISECT) bu_log("rt_nurb_project_srf: projecting surface, planes = (%g %g %g %g) (%g %g %g %g)\n", V4ARGS(plane1), V4ARGS(plane2)); rational = RT_NURB_IS_PT_RATIONAL(srf->pt_type); n_pt_type = RT_NURB_MAKE_PT_TYPE(2, RT_NURB_PT_PROJ, 0); psrf = (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], n_pt_type, res); psrf->dir = RT_NURB_SPLIT_COL; for (i = 0; i < srf->u.k_size; i++) { psrf->u.knots[i] = srf->u.knots[i]; } for (i = 0; i < srf->v.k_size; i++) { psrf->v.knots[i] = srf->v.knots[i]; } mp1 = srf->ctl_points; mp2 = psrf->ctl_points; for (i = 0; i < srf->s_size[0] * srf->s_size[1]; i++) { if (rational) { mp2[0] = (mp1[0] / mp1[3] * plane1[0] + mp1[1] / mp1[3] * plane1[1] + mp1[2] / mp1[3] * plane1[2] - plane1[3]) * mp1[3]; mp2[1] = (mp1[0] / mp1[3] * plane2[0] + mp1[1] / mp1[3] * plane2[1] + mp1[2] / mp1[3] * plane2[2] - plane2[3]) * mp1[3]; } else { mp2[0] = mp1[0] * plane1[0] + mp1[1] * plane1[1] + mp1[2] * plane1[2] - plane1[3]; mp2[1] = mp1[0] * plane2[0] + mp1[1] * plane2[1] + mp1[2] * plane2[2] - plane2[3]; } if (RTG.NMG_debug & DEBUG_RT_ISECT) { if (rational) bu_log("\tmesh pt (%g %g %g %g), becomes (%g %g)\n", V4ARGS(mp1), mp2[0], mp2[1]); else bu_log("\tmesh pt (%g %g %g), becomes (%g %g)\n", V3ARGS(mp1), mp2[0], mp2[1]); } mp1 += RT_NURB_EXTRACT_COORDS(srf->pt_type); mp2 += RT_NURB_EXTRACT_COORDS(psrf->pt_type); } return (struct face_g_snurb *) psrf; }
int spline(int entityno, struct face_g_snurb **b_patch) { int k1; /* upper index of first sum */ int k2; /* upper index of second sum */ int m1; /* degree of 1st set of basis functions */ int m2; /* degree of 2nd set of basis functions */ int prop1; /* !0 if closed in first direction */ int prop2; /* !0 if closed in second direction */ int prop3; /* !0 if polynomial (else rational) */ int prop4; /* !0 if periodic in first direction */ int prop5; /* !0 if periodic in second direction */ int sol_num; /* IGES solid type number */ int n1, n2; int i, j, k; int count = 0; int point_size; fastf_t min_knot; double max_wt; double scan; /* Acquiring Data */ if (dir[entityno]->param <= pstart) { bu_log("Illegal parameter pointer for entity D%07d (%s)\n" , dir[entityno]->direct, dir[entityno]->name); return 0; } Readrec(dir[entityno]->param); Readint(&sol_num, ""); Readint(&k1, ""); Readint(&k2, ""); Readint(&m1, ""); Readint(&m2, ""); Readint(&prop1, ""); Readint(&prop2, ""); Readint(&prop3, ""); Readint(&prop4, ""); Readint(&prop5, ""); n1 = k1 - m1 + 1; n2 = k2 - m2 + 1; /* spl_new: Creates a spline surface data structure * u_order (e.g. cubic = order 4) * v_order * num_u (e.g. num control points + order) * num_v * num_rows num control points in V direction * num_cols num control points in U direction * point_size number of values in a point (e.g. 3 or 4) */ if (prop3 == 0) { point_size = 4; } else { point_size = 3; } (*b_patch) = rt_nurb_new_snurb( m1+1, m2+1, n1+2*m1+1, n2+2*m2+1, k2+1, k1+1, RT_NURB_MAKE_PT_TYPE(point_size, 2, (prop3 == 0 ? RT_NURB_PT_RATIONAL : RT_NURB_PT_NONRAT)), (struct resource *)NULL); /* U knot vector */ min_knot = 0.0; for (i = 0; i <= n1+2*m1; i++) { Readdbl(&scan, ""); (*b_patch)->u.knots[i] = scan; /* double to fastf_t */ if ((*b_patch)->u.knots[i] < min_knot) min_knot = (*b_patch)->u.knots[i]; } if (min_knot < 0.0) { for (i = 0; i <= n1+2*m1; i++) { (*b_patch)->u.knots[i] -= min_knot; } } min_knot = 0.0; /* V knot vector */ for (i = 0; i <= n2+2*m2; i++) { Readdbl(&scan, ""); (*b_patch)->v.knots[i] = scan; /* double to fastf_t */ if ((*b_patch)->v.knots[i] < min_knot) min_knot = (*b_patch)->v.knots[i]; } if (min_knot < 0.0) { for (i = 0; i <= n2+2*m2; i++) { (*b_patch)->v.knots[i] -= min_knot; } } /* weights */ max_wt = 0.0; count = 0; for (i = 0; i <= k2; i++) { for (j = 0; j <= k1; j++) { if (point_size == 4) { Readdbl(&scan, ""); (*b_patch)->ctl_points[count*4 + 3] = scan; /* double to fastf_t */ if ((*b_patch)->ctl_points[count*4 + 3] > max_wt) max_wt = (*b_patch)->ctl_points[count*4 + 3]; } else { Readdbl(&max_wt, ""); } count++; } } /* control points */ count = 0; for (i = 0; i <= k2; i++) { for (j = 0; j <= k1; j++) { Readcnv(&(*b_patch)->ctl_points[count*point_size], ""); Readcnv(&(*b_patch)->ctl_points[count*point_size + 1], ""); Readcnv(&(*b_patch)->ctl_points[count*point_size + 2], ""); count++; } } if (point_size == 4) { /* apply weights */ count = 0; for (i = 0; i <= k2; i++) { for (j = 0; j <= k1; j++) { for (k = 0; k < 3; k++) (*b_patch)->ctl_points[count*4 + k] *= (*b_patch)->ctl_points[count*4 + 3]; count++; } } } return 1; }
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; }
void build_spline(char *name, int npts, double radius) { struct face_g_snurb *bp; int i; int nv; int cur_kv; fastf_t *meshp; int col; vect_t point; /* * This spline will look like a cylinder. * In the mesh, the circular cross section will be presented * across the first row by filling in the 9 (NCOLS) columns. * * The U direction is across the first row, * and has NCOLS+order[U] positions, 12 in this instance. * The V direction is down the first column, * and has NROWS+order[V] positions. */ bp = rt_nurb_new_snurb(3, 4, /* u, v order */ N_CIRCLE_KNOTS, npts+6, /* u, v knot vector size */ npts+2, NCOLS, /* nrows, ncols */ RT_NURB_MAKE_PT_TYPE(4, 2, 1), &rt_uniresource); /* Build the U knots */ for (i=0; i<N_CIRCLE_KNOTS; i++) bp->u.knots[i] = circle_knots[i]; /* Build the V knots */ cur_kv = 0; /* current knot value */ nv = 0; /* current knot subscript */ for (i=0; i<4; i++) bp->v.knots[nv++] = cur_kv; cur_kv++; for (i=4; i<(npts+4-2); i++) bp->v.knots[nv++] = cur_kv++; for (i=0; i<4; i++) bp->v.knots[nv++] = cur_kv; /* * The control mesh is stored in row-major order, * which works out well for us, as a row is one * circular slice through the tube. So we just * have to write down the slices, one after another. * The first and last "slice" are the center points that * create the end caps. */ meshp = bp->ctl_points; /* Row 0 */ for (col=0; col<9; col++) { *meshp++ = sample[0][X]; *meshp++ = sample[0][Y]; *meshp++ = sample[0][Z]; *meshp++ = 1; } /* Rows 1..npts */ for (i=0; i<npts; i++) { /* row = i; */ VMOVE(point, sample[i]); for (col=0; col<9; col++) { fastf_t h; h = polyline[col*4+H]; *meshp++ = polyline[col*4+X]*radius + point[X]*h; *meshp++ = polyline[col*4+Y]*radius + point[Y]*h; *meshp++ = polyline[col*4+Z]*radius + point[Z]*h; *meshp++ = h; } } /* Row npts+1 */ for (col=0; col<9; col++) { *meshp++ = sample[npts-1][X]; *meshp++ = sample[npts-1][Y]; *meshp++ = sample[npts-1][Z]; *meshp++ = 1; } { struct face_g_snurb *surfp[2]; surfp[0] = bp; surfp[1] = NULL; mk_bspline(outfp, name, surfp); } rt_nurb_free_snurb(bp, &rt_uniresource); }