38 CubicCurveseg(
const LMatrix4 &basis) {
39 Bx = basis.get_col(0);
40 By = basis.get_col(1);
41 Bz = basis.get_col(2);
42 Bw = basis.get_col(3);
61 CubicCurveseg(
int order,
const PN_stdfloat knots[],
const LVecBase4 cvs[]) {
78 get_point(PN_stdfloat t, LVecBase3 &point)
const {
79 PN_stdfloat t_sqrd = t*t;
80 evaluate_point(LVecBase4(t*t_sqrd, t_sqrd, t, 1.0f), point);
88 get_tangent(PN_stdfloat t, LVecBase3 &tangent)
const {
89 evaluate_vector(LVecBase4(3.0f*t*t, 2.0f*t, 1.0f, 0.0f), tangent);
98 get_pt(PN_stdfloat t, LVecBase3 &point, LVecBase3 &tangent)
const {
99 PN_stdfloat t_sqrd=t*t;
100 evaluate_point(LVecBase4(t*t_sqrd, t_sqrd, t, 1.0f), point);
101 evaluate_vector(LVecBase4(3.0f*t_sqrd, t+t, 1.0f, 0.0f), tangent);
110 evaluate_vector(LVecBase4(6.0f*t, 2.0f, 0.0f, 0.0f), tangent2);
123 PN_stdfloat tlength) {
125 Mh( 2.0f, -3.0f, 0.0f, 1.0f,
126 -2.0f, 3.0f, 0.0f, 0.0f,
127 1.0f, -2.0f, 1.0f, 0.0f,
128 1.0f, -1.0f, 0.0f, 0.0f);
130 LVecBase4 Gx(cv0._p[0], cv1._p[0],
131 cv0._out[0]*tlength, cv1._in[0]*tlength);
132 LVecBase4 Gy(cv0._p[1], cv1._p[1],
133 cv0._out[1]*tlength, cv1._in[1]*tlength);
134 LVecBase4 Gz(cv0._p[2], cv1._p[2],
135 cv0._out[2]*tlength, cv1._in[2]*tlength);
151 Mb(-1.0f, 3.0f, -3.0f, 1.0f,
152 3.0f, -6.0f, 3.0f, 0.0f,
153 -3.0f, 3.0f, 0.0f, 0.0f,
154 1.0f, 0.0f, 0.0f, 0.0f);
156 LVecBase4 Gx(seg._v[0][0], seg._v[1][0], seg._v[2][0], seg._v[3][0]);
157 LVecBase4 Gy(seg._v[0][1], seg._v[1][1], seg._v[2][1], seg._v[3][1]);
158 LVecBase4 Gz(seg._v[0][2], seg._v[1][2], seg._v[2][2], seg._v[3][2]);
167 nurbs_blending_function(
int order,
int i,
int j,
168 const PN_stdfloat knots[]) {
173 if (i==order-1 && knots[i] < knots[i+1]) {
174 r.set(0.0f, 0.0f, 0.0f, 1.0f);
176 r.set(0.0f, 0.0f, 0.0f, 0.0f);
180 LVecBase4 bi0 = nurbs_blending_function(order, i, j-1, knots);
181 LVecBase4 bi1 = nurbs_blending_function(order, i+1, j-1, knots);
183 PN_stdfloat d0 = knots[i+j-1] - knots[i];
184 PN_stdfloat d1 = knots[i+j] - knots[i+1];
189 r = bi0 / d0 - bi1 / d1;
194 }
else if (d1 != 0.0f) {
198 r.set(0.0f, 0.0f, 0.0f, 0.0f);
210 r += bi0 * (- knots[i] / d0) + bi1 * (knots[i+j] / d1);
212 r += bi0 * (- knots[i] / d0);
215 }
else if (d1 != 0.0f) {
216 r += bi1 * (knots[i+j] / d1);
224 compute_nurbs_basis(
int order,
225 const PN_stdfloat knots_in[],
230 PN_stdfloat knots[8];
231 PN_stdfloat mink = knots_in[order-1];
232 PN_stdfloat maxk = knots_in[order];
236 parametrics_cat->warning()
237 <<
"Trivial NURBS curve specified." << std::endl;
238 memset((
void *)&basis, 0,
sizeof(LMatrix4));
242 for (i = 0; i<2*order; i++) {
243 knots[i] = (knots_in[i] - mink) / (maxk-mink);
248 for (i = 0; i<order; i++) {
249 b[i] = nurbs_blending_function(order, i, order, knots);
252 for (i = 0; i<order; i++) {
253 basis.set_row(i, b[i]);
256 for (i=order; i<4; i++) {
257 basis.set_row(i, LVecBase4::zero());
269 nurbs_basis(
int order,
const PN_stdfloat knots[],
const LVecBase4 cvs[]) {
270 assert(order>=1 && order<=4);
273 compute_nurbs_basis(order, knots, B);
277 for (
int i = 0; i < 4; i++) {
278 c[i] = (i<order) ? cvs[i] : LVecBase4(0.0f, 0.0f, 0.0f, 0.0f);
281 Bx = LVecBase4(c[0][0], c[1][0], c[2][0], c[3][0]) * B;
282 By = LVecBase4(c[0][1], c[1][1], c[2][1], c[3][1]) * B;
283 Bz = LVecBase4(c[0][2], c[1][2], c[2][2], c[3][2]) * B;
284 Bw = LVecBase4(c[0][3], c[1][3], c[2][3], c[3][3]) * B;
297 Mbi(0.0f, 0.0f, 0.0f, 1.0f,
298 0.0f, 0.0f, 1.0f/3.0f, 1.0f,
299 0.0f, 1.0f/3.0f, 2.0f/3.0f, 1.0f,
300 1.0f, 1.0f, 1.0f, 1.0f);
302 LVecBase4 Gx = Bx * Mbi;
303 LVecBase4 Gy = By * Mbi;
304 LVecBase4 Gz = Bz * Mbi;
307 LVecBase4 Gw = Bw * Mbi;
308 seg._v[0].set(Gx[0]/Gw[0], Gy[0]/Gw[0], Gz[0]/Gw[0]);
309 seg._v[1].set(Gx[1]/Gw[1], Gy[1]/Gw[1], Gz[1]/Gw[1]);
310 seg._v[2].set(Gx[2]/Gw[2], Gy[2]/Gw[2], Gz[2]/Gw[2]);
311 seg._v[3].set(Gx[3]/Gw[3], Gy[3]/Gw[3], Gz[3]/Gw[3]);
313 seg._v[0].set(Gx[0], Gy[0], Gz[0]);
314 seg._v[1].set(Gx[1], Gy[1], Gz[1]);
315 seg._v[2].set(Gx[2], Gy[2], Gz[2]);
316 seg._v[3].set(Gx[3], Gy[3], Gz[3]);
324 col_mult(
const LMatrix4 &M,
const LVecBase4 &v) {
325 return LVecBase4(M(0,0)*v[0] + M(0,1)*v[1] + M(0,2)*v[2] + M(0,3)*v[3],
326 M(1,0)*v[0] + M(1,1)*v[1] + M(1,2)*v[2] + M(1,3)*v[3],
327 M(2,0)*v[0] + M(2,1)*v[1] + M(2,2)*v[2] + M(2,3)*v[3],
328 M(3,0)*v[0] + M(3,1)*v[1] + M(3,2)*v[2] + M(3,3)*v[3]);
336 compute_seg_col(
int c,
337 int rtype, PN_stdfloat t,
const LVecBase4 &v,
342 LMatrix4 &T, LMatrix4 &P) {
343 bool keep_orig = ((rtype & RT_KEEP_ORIG) != 0);
345 if (parametrics_cat.is_debug()) {
346 parametrics_cat.debug()
347 <<
"Computing col " << c <<
" type " << (rtype & RT_BASE_TYPE)
348 <<
" at " << t <<
" keep_orig = " << keep_orig
349 <<
" v = " << v <<
"\n";
352 switch (rtype & RT_BASE_TYPE) {
355 PN_stdfloat t_sqrd,t_cubed;
360 T.set_col(c, LVecBase4(t_cubed, t_sqrd, t, 1.0f));
362 LVecBase4 vec(t_cubed, t_sqrd, t, 1.0f);
363 LVecBase4 ov = col_mult(GB, vec);
364 if (parametrics_cat.is_debug()) {
365 parametrics_cat.debug()
366 <<
"orig point = " << ov <<
"\n";
378 T.set_col(c, LVecBase4(3.0f*t_sqrd, t+t, 1.0f, 0.0f));
380 LVecBase4 vec(3.0f*t_sqrd, t+t, 1.0f, 0.0f);
381 LVecBase4 ov = col_mult(GB, vec);
382 if (parametrics_cat.is_debug()) {
383 parametrics_cat.debug()
385 GB.write(parametrics_cat.debug(
false), 2);
386 parametrics_cat.debug(
false)
387 <<
"vector is " << vec <<
"\n"
388 <<
"orig tangent = " << ov <<
"\n";
399 T.set_col(c, Bi.get_col(c));
401 if (parametrics_cat.is_debug()) {
402 parametrics_cat.debug()
403 <<
"orig CV = " << G.get_col(c) <<
"\n";
405 P.set_col(c, G.get_col(c));
412 std::cerr <<
"Invalid rebuild type in compute_seg\n";
459 compute_seg(
int rtype0, PN_stdfloat t0,
const LVecBase4 &v0,
460 int rtype1, PN_stdfloat t1,
const LVecBase4 &v1,
461 int rtype2, PN_stdfloat t2,
const LVecBase4 &v2,
462 int rtype3, PN_stdfloat t3,
const LVecBase4 &v3,
488 if ((rtype0 | rtype1 | rtype2 | rtype3) & RT_KEEP_ORIG) {
492 if (! (compute_seg_col(0, rtype0, t0, v0, B, Bi, G, GB, T, P) &&
493 compute_seg_col(1, rtype1, t1, v1, B, Bi, G, GB, T, P) &&
494 compute_seg_col(2, rtype2, t2, v2, B, Bi, G, GB, T, P) &&
495 compute_seg_col(3, rtype3, t3, v3, B, Bi, G, GB, T, P))) {
532 me->fillin(scan, manager);
542 ParametricCurve::write_datagram(manager, me);
544 Bx.write_datagram(me);
545 By.write_datagram(me);
546 Bz.write_datagram(me);
547 Bw.write_datagram(me);
558 ParametricCurve::fillin(scan, manager);
560 Bx.read_datagram(scan);
561 By.read_datagram(scan);
562 Bz.read_datagram(scan);
563 Bw.read_datagram(scan);