15 #include "nurbsCurve.h"
16 #include "config_parametrics.h"
20 #include "datagramIterator.h"
21 #include "bamWriter.h"
22 #include "bamReader.h"
48 parametrics_cat->warning()
49 <<
"Cannot make a NURBS from the indicated curve.\n";
60 NurbsCurve(
int order,
int num_cvs,
61 const PN_stdfloat knots[],
const LVecBase4 cvs[]) {
65 _cvs.reserve(num_cvs);
66 for (i = 0; i < num_cvs; i++) {
70 int num_knots = num_cvs + order;
71 for (i = 0; i < num_knots; i++) {
109 nassertv(order >= 1 && order <= 4);
110 nassertv(_cvs.empty());
131 get_num_cvs()
const {
142 return _cvs.size() + _order;
160 append_cv(0.0f, 0.0f, 0.0f);
170 append_cv(_cvs.back()._p);
182 for (i = 0; i < _order-1; i++) {
183 int nk = i + k - (_order-1);
185 PN_stdfloat d =
get_knot(nk + _order-1) - ti;
187 new_cvs[i] = _cvs[nk-1]._p;
189 PN_stdfloat a = (t - ti) / d;
190 new_cvs[i] = (1.0f-a)*_cvs[nk-1]._p + a*_cvs[nk]._p;
195 _cvs.insert(_cvs.begin() + k-1, CV());
198 for (i = 0; i < _order-1; i++) {
199 int nk = i + k - (_order-1);
200 _cvs[nk]._p = new_cvs[i];
217 if (n < 0 || n >= (
int)_cvs.size()) {
221 _cvs.erase(_cvs.begin() + n);
232 _cvs.erase(_cvs.begin(), _cvs.end());
244 nassertr(n >= 0 && n < get_num_cvs(),
false);
277 if (n < _order || n-1 >= (
int)_cvs.size()) {
291 if (n < _order || _cvs.empty()) {
293 }
else if (n-1 >= (
int)_cvs.size()) {
294 return _cvs.back()._t;
313 _segs.erase(_segs.begin(), _segs.end());
315 PN_stdfloat knots[8];
318 if ((
int)_cvs.size() > _order-1) {
319 for (
int cv = 0; cv < (int)_cvs.size()-(_order-1); cv++) {
325 for (c = 0; c < _order; c++) {
326 cvs[c] = _cvs[c+cv]._p;
328 for (c = 0; c < _order+_order; c++) {
333 knots[_order] - knots[_order-1]);
338 return !_segs.empty();
352 int rtype1, PN_stdfloat t1,
const LVecBase4 &v1,
353 int rtype2, PN_stdfloat t2,
const LVecBase4 &v2,
354 int rtype3, PN_stdfloat t3,
const LVecBase4 &v3) {
358 nassertr((
int)_cvs.size() > _order-1,
false);
361 for (cv = 0; cv < (int)_cvs.size()-(_order-1); cv++) {
363 if (seg == _last_ti) {
372 PN_stdfloat knots[8];
378 if ((rtype0 | rtype1 | rtype2 | rtype3) & RT_KEEP_ORIG) {
379 for (c = 0; c < 4; c++) {
387 for (c = 0; c < _order+_order; c++) {
392 compute_nurbs_basis(_order, knots, B);
407 for (c = 0; c < _order; c++) {
432 if (na->get_num_cvs() == 0 || nb->get_num_cvs() == 0) {
436 if (na->get_order() != nb->get_order()) {
437 parametrics_cat->error()
438 <<
"Cannot stitch NURBS curves of different orders!\n";
445 na->get_cv_point(na->get_num_cvs() - 1) - nb->get_cv_point(0);
446 int num_b_cvs = nb->get_num_cvs();
447 for (
int i = 0; i < num_b_cvs; i++) {
448 nb->set_cv_point(i, nb->get_cv_point(i) + point_offset);
457 PN_stdfloat t = na->get_max_t();
460 epvector<CV>::iterator ci;
461 for (ci = nb->_cvs.begin(); ci != nb->_cvs.end(); ++ci) {
464 _cvs.push_back(new_cv);
494 return NurbsCurveInterface::convert_to_nurbs(nc);
503 write(ostream &out,
int indent_level)
const {
504 NurbsCurveInterface::write(out, indent_level);
516 _cvs.push_back(CV(v,
get_knot(_cvs.size())+1.0f));
517 return _cvs.size()-1;
528 format_egg(ostream &out,
const string &name,
const string &curve_type,
529 int indent_level)
const {
530 return NurbsCurveInterface::format_egg(out, name, curve_type, indent_level);
540 find_cv(PN_stdfloat t) {
542 for (i = _order-1; i < (int)_cvs.size(); i++) {
543 if (_cvs[i]._t >= t) {
573 parse_params(params, scan, manager);
574 me->fillin(scan, manager);
586 PiecewiseCurve::write_datagram(manager, me);
592 for (i = 0; i < _cvs.size(); i++) {
593 const CV &cv = _cvs[i];
594 cv._p.write_datagram(me);
609 PiecewiseCurve::fillin(scan, manager);
615 _cvs.reserve(num_cvs);
617 for (i = 0; i < num_cvs; i++) {
619 cv._p.read_datagram(scan);
static void register_with_read_factory()
Initializes the factory for reading these things from Bam files.
PN_int8 get_int8()
Extracts a signed 8-bit integer.
virtual bool convert_to_nurbs(ParametricCurve *nc) const
Stores in the indicated NurbsCurve a NURBS representation of an equivalent curve. ...
virtual void set_order(int order)
Changes the order of the curve.
A basic node of the scene graph or data graph.
This is the base class for all three-component vectors and points.
LVecBase4f get_col(int col) const
Retrieves the indicated column of the matrix as a 4-component vector.
virtual bool rebuild_curveseg(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)
Rebuilds the current curve segment (as selected by the most recent call to find_curve()) according to...
void add_float64(PN_float64 value)
Adds a 64-bit floating-point number to the datagram.
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
A virtual base class for parametric curves.
virtual bool remove_cv(int n)
Removes the indicated CV from the curve.
bool insert_curveseg(int ti, ParametricCurve *seg, PN_stdfloat tlength)
Inserts a new curve segment at the indicated index.
void add_int8(PN_int8 value)
Adds a signed 8-bit integer to the datagram.
Base class for objects that can be written to and read from Bam files.
virtual PandaNode * make_copy() const
Returns a newly-allocated PandaNode that is a shallow copy of this one.
virtual NurbsCurveInterface * get_nurbs_interface()
Returns a pointer to the object as a NurbsCurveInterface object if it happens to be a NURBS-style cur...
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
virtual bool stitch(const ParametricCurve *a, const ParametricCurve *b)
Regenerates this curve as one long curve: the first curve connected end-to-end with the second one...
This abstract class defines the interface only for a Nurbs-style curve, with knots and coordinates in...
PN_uint32 get_uint32()
Extracts an unsigned 32-bit integer.
virtual bool convert_to_nurbs(ParametricCurve *nc) const
Stores in the indicated NurbsCurve a NURBS representation of an equivalent curve. ...
A CubicCurveseg is any curve that can be completely described by four 4-valued basis vectors...
virtual bool set_knot(int n, PN_stdfloat t)
Sets the value of the indicated knot.
This is a 4-by-4 transform matrix.
virtual bool recompute()
Recalculates the curve basis according to the latest position of the CV's, knots, etc...
An instance of this class is passed to the Factory when requesting it to do its business and construc...
A Nonuniform Rational B-Spline.
virtual bool insert_cv(PN_stdfloat t)
Inserts a new CV into the middle of the curve at the indicated parametric value.
virtual bool set_cv(int n, const LVecBase4 &v)
Repositions the indicated CV.
void register_factory(TypeHandle handle, CreateFunc *func)
Registers a new kind of thing the Factory will be able to create.
virtual PN_stdfloat get_knot(int n) const
Retrieves the value of the indicated knot.
void set_curve_type(int type)
Sets the flag indicating the use to which the curve is intended to be put.
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.
PN_float64 get_float64()
Extracts a 64-bit floating-point number.
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
virtual LVecBase4 get_cv(int n) const
Returns the position in homogeneous space of the indicated CV.
void add_uint32(PN_uint32 value)
Adds an unsigned 32-bit integer to the datagram.
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 void remove_all_cvs()
Removes all CV's from the curve.
virtual int get_num_knots() const
Returns the number of knots on the curve.
static const LVecBase4f & zero()
Returns a zero-length vector.