15 #include "piecewiseCurve.h" 17 #include "config_parametrics.h" 18 #include "hermiteCurve.h" 21 #include "datagramIterator.h" 22 #include "bamWriter.h" 23 #include "bamReader.h" 70 CubicCurveseg(
int order,
const PN_stdfloat knots[],
const LVecBase4 cvs[]) {
93 PN_stdfloat t_sqrd = t*t;
94 evaluate_point(
LVecBase4(t*t_sqrd, t_sqrd, t, 1.0f), point);
106 evaluate_vector(
LVecBase4(3.0f*t*t, 2.0f*t, 1.0f, 0.0f), tangent);
118 PN_stdfloat t_sqrd=t*t;
119 evaluate_point(
LVecBase4(t*t_sqrd, t_sqrd, t, 1.0f), point);
120 evaluate_vector(
LVecBase4(3.0f*t_sqrd, t+t, 1.0f, 0.0f), tangent);
132 evaluate_vector(
LVecBase4(6.0f*t, 2.0f, 0.0f, 0.0f), tangent2);
147 PN_stdfloat tlength) {
149 Mh( 2.0f, -3.0f, 0.0f, 1.0f,
150 -2.0f, 3.0f, 0.0f, 0.0f,
151 1.0f, -2.0f, 1.0f, 0.0f,
152 1.0f, -1.0f, 0.0f, 0.0f);
155 cv0._out[0]*tlength, cv1._in[0]*tlength);
157 cv0._out[1]*tlength, cv1._in[1]*tlength);
159 cv0._out[2]*tlength, cv1._in[2]*tlength);
177 Mb(-1.0f, 3.0f, -3.0f, 1.0f,
178 3.0f, -6.0f, 3.0f, 0.0f,
179 -3.0f, 3.0f, 0.0f, 0.0f,
180 1.0f, 0.0f, 0.0f, 0.0f);
182 LVecBase4 Gx(seg._v[0][0], seg._v[1][0], seg._v[2][0], seg._v[3][0]);
183 LVecBase4 Gy(seg._v[0][1], seg._v[1][1], seg._v[2][1], seg._v[3][1]);
184 LVecBase4 Gz(seg._v[0][2], seg._v[1][2], seg._v[2][2], seg._v[3][2]);
193 nurbs_blending_function(
int order,
int i,
int j,
194 const PN_stdfloat knots[]) {
199 if (i==order-1 && knots[i] < knots[i+1]) {
200 r.set(0.0f, 0.0f, 0.0f, 1.0f);
202 r.set(0.0f, 0.0f, 0.0f, 0.0f);
206 LVecBase4 bi0 = nurbs_blending_function(order, i, j-1, knots);
207 LVecBase4 bi1 = nurbs_blending_function(order, i+1, j-1, knots);
209 PN_stdfloat d0 = knots[i+j-1] - knots[i];
210 PN_stdfloat d1 = knots[i+j] - knots[i+1];
215 r = bi0 / d0 - bi1 / d1;
220 }
else if (d1 != 0.0f) {
224 r.set(0.0f, 0.0f, 0.0f, 0.0f);
236 r += bi0 * (- knots[i] / d0) + bi1 * (knots[i+j] / d1);
238 r += bi0 * (- knots[i] / d0);
241 }
else if (d1 != 0.0f) {
242 r += bi1 * (knots[i+j] / d1);
250 compute_nurbs_basis(
int order,
251 const PN_stdfloat knots_in[],
256 PN_stdfloat knots[8];
257 PN_stdfloat mink = knots_in[order-1];
258 PN_stdfloat maxk = knots_in[order];
262 parametrics_cat->warning()
263 <<
"Trivial NURBS curve specified." << endl;
264 memset((
void *)&basis, 0,
sizeof(
LMatrix4));
268 for (i = 0; i<2*order; i++) {
269 knots[i] = (knots_in[i] - mink) / (maxk-mink);
274 for (i = 0; i<order; i++) {
275 b[i] = nurbs_blending_function(order, i, order, knots);
278 for (i = 0; i<order; i++) {
282 for (i=order; i<4; i++) {
299 assert(order>=1 && order<=4);
302 compute_nurbs_basis(order, knots, B);
307 for (
int i = 0; i < 4; i++) {
308 c[i] = (i<order) ? cvs[i] :
LVecBase4(0.0f, 0.0f, 0.0f, 0.0f);
311 Bx =
LVecBase4(c[0][0], c[1][0], c[2][0], c[3][0]) * B;
312 By =
LVecBase4(c[0][1], c[1][1], c[2][1], c[3][1]) * B;
313 Bz =
LVecBase4(c[0][2], c[1][2], c[2][2], c[3][2]) * B;
314 Bw =
LVecBase4(c[0][3], c[1][3], c[2][3], c[3][3]) * B;
330 Mbi(0.0f, 0.0f, 0.0f, 1.0f,
331 0.0f, 0.0f, 1.0f/3.0f, 1.0f,
332 0.0f, 1.0f/3.0f, 2.0f/3.0f, 1.0f,
333 1.0f, 1.0f, 1.0f, 1.0f);
341 seg._v[0].set(Gx[0]/Gw[0], Gy[0]/Gw[0], Gz[0]/Gw[0]);
342 seg._v[1].set(Gx[1]/Gw[1], Gy[1]/Gw[1], Gz[1]/Gw[1]);
343 seg._v[2].set(Gx[2]/Gw[2], Gy[2]/Gw[2], Gz[2]/Gw[2]);
344 seg._v[3].set(Gx[3]/Gw[3], Gy[3]/Gw[3], Gz[3]/Gw[3]);
346 seg._v[0].set(Gx[0], Gy[0], Gz[0]);
347 seg._v[1].set(Gx[1], Gy[1], Gz[1]);
348 seg._v[2].set(Gx[2], Gy[2], Gz[2]);
349 seg._v[3].set(Gx[3], Gy[3], Gz[3]);
358 return LVecBase4(M(0,0)*v[0] + M(0,1)*v[1] + M(0,2)*v[2] + M(0,3)*v[3],
359 M(1,0)*v[0] + M(1,1)*v[1] + M(1,2)*v[2] + M(1,3)*v[3],
360 M(2,0)*v[0] + M(2,1)*v[1] + M(2,2)*v[2] + M(2,3)*v[3],
361 M(3,0)*v[0] + M(3,1)*v[1] + M(3,2)*v[2] + M(3,3)*v[3]);
371 compute_seg_col(
int c,
372 int rtype, PN_stdfloat t,
const LVecBase4 &v,
378 bool keep_orig = ((rtype & RT_KEEP_ORIG) != 0);
380 if (parametrics_cat.is_debug()) {
381 parametrics_cat.debug()
382 <<
"Computing col " << c <<
" type " << (rtype & RT_BASE_TYPE)
383 <<
" at " << t <<
" keep_orig = " << keep_orig
384 <<
" v = " << v <<
"\n";
387 switch (rtype & RT_BASE_TYPE) {
390 PN_stdfloat t_sqrd,t_cubed;
399 if (parametrics_cat.is_debug()) {
400 parametrics_cat.debug()
401 <<
"orig point = " << ov <<
"\n";
415 LVecBase4 vec(3.0f*t_sqrd, t+t, 1.0f, 0.0f);
417 if (parametrics_cat.is_debug()) {
418 parametrics_cat.debug()
420 GB.write(parametrics_cat.debug(
false), 2);
421 parametrics_cat.debug(
false)
422 <<
"vector is " << vec <<
"\n" 423 <<
"orig tangent = " << ov <<
"\n";
436 if (parametrics_cat.is_debug()) {
437 parametrics_cat.debug()
438 <<
"orig CV = " << G.
get_col(c) <<
"\n";
447 cerr <<
"Invalid rebuild type in compute_seg\n";
507 int rtype1, PN_stdfloat t1,
const LVecBase4 &v1,
508 int rtype2, PN_stdfloat t2,
const LVecBase4 &v2,
509 int rtype3, PN_stdfloat t3,
const LVecBase4 &v3,
536 if ((rtype0 | rtype1 | rtype2 | rtype3) & RT_KEEP_ORIG) {
540 if (! (compute_seg_col(0, rtype0, t0, v0, B, Bi, G, GB, T, P) &&
541 compute_seg_col(1, rtype1, t1, v1, B, Bi, G, GB, T, P) &&
542 compute_seg_col(2, rtype2, t2, v2, B, Bi, G, GB, T, P) &&
543 compute_seg_col(3, rtype3, t3, v3, B, Bi, G, GB, T, P))) {
584 parse_params(params, scan, manager);
585 me->fillin(scan, manager);
597 ParametricCurve::write_datagram(manager, me);
616 ParametricCurve::fillin(scan, manager);
This is the base class for all three-component vectors and points.
bool get_bool()
Extracts a boolean value.
virtual bool get_point(PN_stdfloat t, LVecBase3 &point) const
Computes the surface point at a given parametric point t.
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
void hermite_basis(const HermiteCurveCV &cv0, const HermiteCurveCV &cv1, PN_stdfloat tlength=1.0f)
Defines the curve segment as a Hermite.
Base class for objects that can be written to and read from Bam files.
void bezier_basis(const BezierSeg &seg)
Defines the curve segment as a Bezier.
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
virtual bool get_2ndtangent(PN_stdfloat t, LVecBase3 &tangent2) const
Computes the surface 2nd-order tangent at a given parametric point t.
A CubicCurveseg is any curve that can be completely described by four 4-valued basis vectors...
void add_bool(bool value)
Adds a boolean value to the datagram.
This is a 4-by-4 transform matrix.
An instance of this class is passed to the Factory when requesting it to do its business and construc...
void read_datagram(DatagramIterator &source)
Reads the vector from the Datagram using get_stdfloat().
virtual bool get_bezier_seg(BezierSeg &seg) const
Fills the BezierSeg structure with a description of the curve segment as a Bezier, if possible, but does not change the _t member of the structure.
void register_factory(TypeHandle handle, CreateFunc *func)
Registers a new kind of thing the Factory will be able to create.
void set_col(int col, const LVecBase4f &v)
Replaces the indicated column of the matrix.
This is the base class for all three-component vectors and points.
static bool compute_seg(int rtype0, PN_stdfloat t0, const LVecBase4 &v0, int rtype1, PN_stdfloat t1, const LVecBase4 &v1, int rtype2, PN_stdfloat t2, const LVecBase4 &v2, int rtype3, PN_stdfloat t3, const LVecBase4 &v3, const LMatrix4 &B, const LMatrix4 &Bi, LMatrix4 &G)
Given a set of four properties of a curve segment (e.g.
void write_datagram(Datagram &destination) const
Writes the vector to the Datagram using add_stdfloat().
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
A single CV of a Hermite curve.
LVecBase4f get_col(int col) const
Retrieves the indicated column of the matrix as a 4-component vector.
static void register_with_read_factory()
Initializes the factory for reading these things from Bam files.
void nurbs_basis(int order, const PN_stdfloat knots[], const LVecBase4 cvs[])
Defines the curve segment as a NURBS.
void set_row(int row, const LVecBase4f &v)
Replaces the indicated row of the matrix.
A class to retrieve the individual data elements previously stored in a Datagram. ...
TypeHandle is the identifier used to differentiate C++ class types.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
virtual bool get_pt(PN_stdfloat t, LVecBase3 &point, LVecBase3 &tangent) const
Simultaneously computes the point and the tangent at the given parametric point.
virtual bool get_tangent(PN_stdfloat t, LVecBase3 &tangent) const
Computes the surface tangent at a given parametric point t.
static const LVecBase4f & zero()
Returns a zero-length vector.