Panda3D
 All Classes Functions Variables Enumerations
nurbsCurve.cxx
1 // Filename: nurbsCurve.cxx
2 // Created by: drose (27Feb98)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "nurbsCurve.h"
16 #include "config_parametrics.h"
17 
18 #include "indent.h"
19 #include "datagram.h"
20 #include "datagramIterator.h"
21 #include "bamWriter.h"
22 #include "bamReader.h"
23 #include "epvector.h"
24 
25 TypeHandle NurbsCurve::_type_handle;
26 
27 ////////////////////////////////////////////////////////////////////
28 // Function: NurbsCurve::Constructor
29 // Access: Published
30 // Description:
31 ////////////////////////////////////////////////////////////////////
32 NurbsCurve::
33 NurbsCurve() {
34  _order = 4;
35 }
36 
37 ////////////////////////////////////////////////////////////////////
38 // Function: NurbsCurve::Copy Constructor
39 // Access: Published
40 // Description: Constructs a NURBS curve equivalent to the indicated
41 // (possibly non-NURBS) curve.
42 ////////////////////////////////////////////////////////////////////
43 NurbsCurve::
44 NurbsCurve(const ParametricCurve &pc) {
45  _order = 4;
46 
47  if (!pc.convert_to_nurbs(this)) {
48  parametrics_cat->warning()
49  << "Cannot make a NURBS from the indicated curve.\n";
50  }
51 }
52 
53 ////////////////////////////////////////////////////////////////////
54 // Function: NurbsCurve::Constructor
55 // Access: Published
56 // Description: Constructs a NURBS curve according to the indicated
57 // NURBS parameters.
58 ////////////////////////////////////////////////////////////////////
59 NurbsCurve::
60 NurbsCurve(int order, int num_cvs,
61  const PN_stdfloat knots[], const LVecBase4 cvs[]) {
62  _order = order;
63 
64  int i;
65  _cvs.reserve(num_cvs);
66  for (i = 0; i < num_cvs; i++) {
67  append_cv(cvs[i]);
68  }
69 
70  int num_knots = num_cvs + order;
71  for (i = 0; i < num_knots; i++) {
72  set_knot(i, knots[i]);
73  }
74 
75  recompute();
76 }
77 
78 ////////////////////////////////////////////////////////////////////
79 // Function: NurbsCurve::Destructor
80 // Access: Published, Virtual
81 // Description:
82 ////////////////////////////////////////////////////////////////////
83 NurbsCurve::
84 ~NurbsCurve() {
85 }
86 
87 ////////////////////////////////////////////////////////////////////
88 // Function: NurbsCurve::make_copy
89 // Access: Public, Virtual
90 // Description: Returns a newly-allocated PandaNode that is a shallow
91 // copy of this one. It will be a different pointer,
92 // but its internal data may or may not be shared with
93 // that of the original PandaNode. No children will be
94 // copied.
95 ////////////////////////////////////////////////////////////////////
97 make_copy() const {
98  return new NurbsCurve(*this);
99 }
100 
101 ////////////////////////////////////////////////////////////////////
102 // Function: NurbsCurve::set_order
103 // Access: Published, Virtual
104 // Description: Changes the order of the curve. Must be a value from
105 // 1 to 4. Can only be done when there are no cv's.
106 ////////////////////////////////////////////////////////////////////
107 void NurbsCurve::
108 set_order(int order) {
109  nassertv(order >= 1 && order <= 4);
110  nassertv(_cvs.empty());
111 
112  _order = order;
113 }
114 
115 ////////////////////////////////////////////////////////////////////
116 // Function: NurbsCurve::get_order
117 // Access: Published, Virtual
118 // Description:
119 ////////////////////////////////////////////////////////////////////
120 int NurbsCurve::
121 get_order() const {
122  return _order;
123 }
124 
125 ////////////////////////////////////////////////////////////////////
126 // Function: NurbsCurve::get_num_cvs
127 // Access: Published, Virtual
128 // Description:
129 ////////////////////////////////////////////////////////////////////
130 int NurbsCurve::
131 get_num_cvs() const {
132  return _cvs.size();
133 }
134 
135 ////////////////////////////////////////////////////////////////////
136 // Function: NurbsCurve::get_num_knots
137 // Access: Published, Virtual
138 // Description: Returns the number of knots on the curve.
139 ////////////////////////////////////////////////////////////////////
140 int NurbsCurve::
141 get_num_knots() const {
142  return _cvs.size() + _order;
143 }
144 
145 
146 
147 ////////////////////////////////////////////////////////////////////
148 // Function: NurbsCurve::insert_cv
149 // Access: Published, Virtual
150 // Description: Inserts a new CV into the middle of the curve at the
151 // indicated parametric value. This doesn't change the
152 // shape or timing of the curve; however, it is
153 // irreversible: if the new CV is immediately removed,
154 // the curve will be changed. Returns true if
155 // successful, false otherwise.
156 ////////////////////////////////////////////////////////////////////
157 bool NurbsCurve::
158 insert_cv(PN_stdfloat t) {
159  if (_cvs.empty()) {
160  append_cv(0.0f, 0.0f, 0.0f);
161  return true;
162  }
163 
164  if (t <= 0) {
165  t = 0.0f;
166  }
167 
168  int k = find_cv(t);
169  if (k < 0) {
170  append_cv(_cvs.back()._p);
171  return true;
172  }
173 
174  // Now we are inserting a knot between k-1 and k. We'll adjust the
175  // CV's according to Bohm's rule.
176 
177  // First, get the new values of all the CV's that will change.
178  // These are the CV's in the range [k - (_order-1), k-1].
179 
180  LVecBase4 new_cvs[3];
181  int i;
182  for (i = 0; i < _order-1; i++) {
183  int nk = i + k - (_order-1);
184  PN_stdfloat ti = get_knot(nk);
185  PN_stdfloat d = get_knot(nk + _order-1) - ti;
186  if (d == 0.0f) {
187  new_cvs[i] = _cvs[nk-1]._p;
188  } else {
189  PN_stdfloat a = (t - ti) / d;
190  new_cvs[i] = (1.0f-a)*_cvs[nk-1]._p + a*_cvs[nk]._p;
191  }
192  }
193 
194  // Now insert the new CV
195  _cvs.insert(_cvs.begin() + k-1, CV());
196 
197  // Set all the new position values
198  for (i = 0; i < _order-1; i++) {
199  int nk = i + k - (_order-1);
200  _cvs[nk]._p = new_cvs[i];
201  }
202 
203  // And set the new knot value.
204  _cvs[k-1]._t = t;
205 
206  return true;
207 }
208 
209 ////////////////////////////////////////////////////////////////////
210 // Function: NurbsCurve::remove_cv
211 // Access: Published, Virtual
212 // Description: Removes the indicated CV from the curve. Returns
213 // true if the CV index was valid, false otherwise.
214 ////////////////////////////////////////////////////////////////////
215 bool NurbsCurve::
216 remove_cv(int n) {
217  if (n < 0 || n >= (int)_cvs.size()) {
218  return false;
219  }
220 
221  _cvs.erase(_cvs.begin() + n);
222  return true;
223 }
224 
225 ////////////////////////////////////////////////////////////////////
226 // Function: NurbsCurve::remove_all_cvs
227 // Access: Published, Virtual
228 // Description: Removes all CV's from the curve.
229 ////////////////////////////////////////////////////////////////////
230 void NurbsCurve::
232  _cvs.erase(_cvs.begin(), _cvs.end());
233 }
234 
235 
236 ////////////////////////////////////////////////////////////////////
237 // Function: NurbsCurve::set_cv
238 // Access: Published, Virtual
239 // Description: Repositions the indicated CV. Returns true if
240 // successful, false otherwise.
241 ////////////////////////////////////////////////////////////////////
242 bool NurbsCurve::
243 set_cv(int n, const LVecBase4 &v) {
244  nassertr(n >= 0 && n < get_num_cvs(), false);
245 
246  _cvs[n]._p = v;
247  return true;
248 }
249 
250 ////////////////////////////////////////////////////////////////////
251 // Function: NurbsCurve::get_cv
252 // Access: Published, Virtual
253 // Description: Returns the position in homogeneous space of the
254 // indicated CV.
255 ////////////////////////////////////////////////////////////////////
257 get_cv(int n) const {
258  nassertr(n >= 0 && n < get_num_cvs(), LVecBase4::zero());
259 
260  return _cvs[n]._p;
261 }
262 
263 
264 ////////////////////////////////////////////////////////////////////
265 // Function: NurbsCurve::set_knot
266 // Access: Published, Virtual
267 // Description: Sets the value of the indicated knot. There are
268 // get_num_cvs() + _order knot values, but the first
269 // _order - 1 and the last 1 knot values cannot be
270 // changed. It is also an error to set a knot value
271 // outside the range of its neighbors.
272 ////////////////////////////////////////////////////////////////////
273 bool NurbsCurve::
274 set_knot(int n, PN_stdfloat t) {
275  nassertr(n >= 0 && n < get_num_knots(), false);
276 
277  if (n < _order || n-1 >= (int)_cvs.size()) {
278  return false;
279  }
280  _cvs[n-1]._t = t;
281  return true;
282 }
283 
284 ////////////////////////////////////////////////////////////////////
285 // Function: NurbsCurve::get_knot
286 // Access: Published, Virtual
287 // Description: Retrieves the value of the indicated knot.
288 ////////////////////////////////////////////////////////////////////
289 PN_stdfloat NurbsCurve::
290 get_knot(int n) const {
291  if (n < _order || _cvs.empty()) {
292  return 0.0f;
293  } else if (n-1 >= (int)_cvs.size()) {
294  return _cvs.back()._t;
295  } else {
296  return _cvs[n-1]._t;
297  }
298 }
299 
300 
301 ////////////////////////////////////////////////////////////////////
302 // Function: NurbsCurve::recompute
303 // Access: Published, Virtual
304 // Description: Recalculates the curve basis according to the latest
305 // position of the CV's, knots, etc. Until this
306 // function is called, adjusting the NURBS parameters
307 // will have no visible effect on the curve. Returns
308 // true if the resulting curve is valid, false
309 // otherwise.
310 ////////////////////////////////////////////////////////////////////
311 bool NurbsCurve::
313  _segs.erase(_segs.begin(), _segs.end());
314 
315  PN_stdfloat knots[8];
316  LVecBase4 cvs[4];
317 
318  if ((int)_cvs.size() > _order-1) {
319  for (int cv = 0; cv < (int)_cvs.size()-(_order-1); cv++) {
320  if (get_knot(cv+_order-1) < get_knot(cv+_order)) {
321  // There are _order consecutive CV's that define each segment,
322  // beginning at cv. Collect the CV's and knot values that define
323  // this segment.
324  int c;
325  for (c = 0; c < _order; c++) {
326  cvs[c] = _cvs[c+cv]._p;
327  }
328  for (c = 0; c < _order+_order; c++) {
329  knots[c] = get_knot(c+cv);
330  }
331 
332  insert_curveseg(_segs.size(), new CubicCurveseg(_order, knots, cvs),
333  knots[_order] - knots[_order-1]);
334  }
335  }
336  }
337 
338  return !_segs.empty();
339 }
340 
341 ////////////////////////////////////////////////////////////////////
342 // Function: NurbsCurve::rebuild_curveseg
343 // Access: Public, Virtual
344 // Description: Rebuilds the current curve segment (as selected by
345 // the most recent call to find_curve()) according to
346 // the specified properties (see
347 // CubicCurveseg::compute_seg). Returns true if
348 // possible, false if something goes horribly wrong.
349 ////////////////////////////////////////////////////////////////////
350 bool NurbsCurve::
351 rebuild_curveseg(int rtype0, PN_stdfloat t0, const LVecBase4 &v0,
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) {
355  // Figure out which CV's contributed to this segment.
356  int seg = 0;
357 
358  nassertr((int)_cvs.size() > _order-1, false);
359 
360  int cv = 0;
361  for (cv = 0; cv < (int)_cvs.size()-(_order-1); cv++) {
362  if (get_knot(cv+_order-1) < get_knot(cv+_order)) {
363  if (seg == _last_ti) {
364  break;
365  }
366  seg++;
367  }
368  }
369 
370  // Now copy the cvs and knots in question.
371  LMatrix4 G;
372  PN_stdfloat knots[8];
373 
374  int c;
375 
376  // We only need to build the geometry matrix if at least one of the
377  // properties depends on the original value.
378  if ((rtype0 | rtype1 | rtype2 | rtype3) & RT_KEEP_ORIG) {
379  for (c = 0; c < 4; c++) {
380  const LVecBase4 &s = (c < _order) ? _cvs[c+cv]._p : LVecBase4::zero();
381 
382  G.set_col(c, s);
383  }
384  }
385 
386  // But we always need the knot vector to determine the basis matrix.
387  for (c = 0; c < _order+_order; c++) {
388  knots[c] = get_knot(c+cv);
389  }
390 
391  LMatrix4 B;
392  compute_nurbs_basis(_order, knots, B);
393 
394  LMatrix4 Bi;
395  Bi = invert(B);
396 
397  if (!CubicCurveseg::compute_seg(rtype0, t0, v0,
398  rtype1, t1, v1,
399  rtype2, t2, v2,
400  rtype3, t3, v3,
401  B, Bi, G)) {
402  return false;
403  }
404 
405  // Now extract the new CV's from the new G matrix, and restore them
406  // to the curve.
407  for (c = 0; c < _order; c++) {
408  _cvs[c+cv]._p = G.get_col(c);
409  }
410 
411  return true;
412 }
413 
414 ////////////////////////////////////////////////////////////////////
415 // Function: NurbsCurve::stitch
416 // Access: Published, Virtual
417 // Description: Regenerates this curve as one long curve: the first
418 // curve connected end-to-end with the second one.
419 // Either a or b may be the same as 'this'.
420 //
421 // Returns true if successful, false on failure or if
422 // the curve type does not support stitching.
423 ////////////////////////////////////////////////////////////////////
424 bool NurbsCurve::
426  // First, make a copy of both of our curves. This ensures they are
427  // of the correct type, and also protects us in case one of them is
428  // the same as 'this'.
429  PT(NurbsCurve) na = new NurbsCurve(*a);
430  PT(NurbsCurve) nb = new NurbsCurve(*b);
431 
432  if (na->get_num_cvs() == 0 || nb->get_num_cvs() == 0) {
433  return false;
434  }
435 
436  if (na->get_order() != nb->get_order()) {
437  parametrics_cat->error()
438  << "Cannot stitch NURBS curves of different orders!\n";
439  return false;
440  }
441 
442  // First, translate curve B to move its first CV to curve A's last
443  // CV.
444  LVecBase3 point_offset =
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);
449  }
450 
451  // Now define a vector of all of A's CV's except the last one.
452  _cvs = na->_cvs;
453  if (!_cvs.empty()) {
454  _cvs.pop_back();
455  }
456 
457  PN_stdfloat t = na->get_max_t();
458 
459  // Now add all the new CV's.
460  epvector<CV>::iterator ci;
461  for (ci = nb->_cvs.begin(); ci != nb->_cvs.end(); ++ci) {
462  CV new_cv = (*ci);
463  new_cv._t += t;
464  _cvs.push_back(new_cv);
465  }
466 
467  recompute();
468  return true;
469 }
470 
471 
472 ////////////////////////////////////////////////////////////////////
473 // Function: NurbsCurve::get_nurbs_interface
474 // Access: Public, Virtual
475 // Description: Returns a pointer to the object as a
476 // NurbsCurveInterface object if it happens to be a
477 // NURBS-style curve; otherwise, returns NULL.
478 ////////////////////////////////////////////////////////////////////
481  return this;
482 }
483 
484 ////////////////////////////////////////////////////////////////////
485 // Function: NurbsCurve::convert_to_nurbs
486 // Access: Public, Virtual
487 // Description: Stores in the indicated NurbsCurve a NURBS
488 // representation of an equivalent curve. Returns true
489 // if successful, false otherwise.
490 ////////////////////////////////////////////////////////////////////
491 bool NurbsCurve::
493  nc->set_curve_type(_curve_type);
494  return NurbsCurveInterface::convert_to_nurbs(nc);
495 }
496 
497 ////////////////////////////////////////////////////////////////////
498 // Function: NurbsCurve::write
499 // Access: Public, Virtual
500 // Description:
501 ////////////////////////////////////////////////////////////////////
502 void NurbsCurve::
503 write(ostream &out, int indent_level) const {
504  NurbsCurveInterface::write(out, indent_level);
505 }
506 
507 ////////////////////////////////////////////////////////////////////
508 // Function: NurbsCurve::append_cv_impl
509 // Access: Protected, Virtual
510 // Description: Adds a new CV to the end of the curve. Creates a new
511 // knot value by adding 1 to the last knot value.
512 // Returns the index of the new CV.
513 ////////////////////////////////////////////////////////////////////
514 int NurbsCurve::
515 append_cv_impl(const LVecBase4 &v) {
516  _cvs.push_back(CV(v, get_knot(_cvs.size())+1.0f));
517  return _cvs.size()-1;
518 }
519 
520 ////////////////////////////////////////////////////////////////////
521 // Function: NurbsCurve::format_egg
522 // Access: Protected, Virtual
523 // Description: Formats the curve as an egg structure to write to the
524 // indicated stream. Returns true on success, false on
525 // failure.
526 ////////////////////////////////////////////////////////////////////
527 bool NurbsCurve::
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);
531 }
532 
533 ////////////////////////////////////////////////////////////////////
534 // Function: NurbsCurve::find_cv
535 // Access: Protected
536 // Description: Finds the first knot whose value is >= t, or -1 if t
537 // is beyond the end of the curve.
538 ////////////////////////////////////////////////////////////////////
539 int NurbsCurve::
540 find_cv(PN_stdfloat t) {
541  int i;
542  for (i = _order-1; i < (int)_cvs.size(); i++) {
543  if (_cvs[i]._t >= t) {
544  return i+1;
545  }
546  }
547 
548  return -1;
549 }
550 
551 ////////////////////////////////////////////////////////////////////
552 // Function: NurbsCurve::register_with_read_factory
553 // Access: Public, Static
554 // Description: Initializes the factory for reading these things from
555 // Bam files.
556 ////////////////////////////////////////////////////////////////////
557 void NurbsCurve::
559  BamReader::get_factory()->register_factory(get_class_type(), make_NurbsCurve);
560 }
561 
562 ////////////////////////////////////////////////////////////////////
563 // Function: NurbsCurve::make_NurbsCurve
564 // Access: Protected
565 // Description: Factory method to generate an object of this type.
566 ////////////////////////////////////////////////////////////////////
567 TypedWritable *NurbsCurve::
568 make_NurbsCurve(const FactoryParams &params) {
569  NurbsCurve *me = new NurbsCurve;
570  DatagramIterator scan;
571  BamReader *manager;
572 
573  parse_params(params, scan, manager);
574  me->fillin(scan, manager);
575  return me;
576 }
577 
578 ////////////////////////////////////////////////////////////////////
579 // Function: NurbsCurve::write_datagram
580 // Access: Protected, Virtual
581 // Description: Function to write the important information in
582 // the particular object to a Datagram
583 ////////////////////////////////////////////////////////////////////
584 void NurbsCurve::
585 write_datagram(BamWriter *manager, Datagram &me) {
586  PiecewiseCurve::write_datagram(manager, me);
587 
588  me.add_int8(_order);
589 
590  me.add_uint32(_cvs.size());
591  size_t i;
592  for (i = 0; i < _cvs.size(); i++) {
593  const CV &cv = _cvs[i];
594  cv._p.write_datagram(me);
595  me.add_float64(cv._t);
596  }
597 }
598 
599 ////////////////////////////////////////////////////////////////////
600 // Function: NurbsCurve::fillin
601 // Access: Protected
602 // Description: Function that reads out of the datagram (or asks
603 // manager to read) all of the data that is needed to
604 // re-create this object and stores it in the appropiate
605 // place
606 ////////////////////////////////////////////////////////////////////
607 void NurbsCurve::
608 fillin(DatagramIterator &scan, BamReader *manager) {
609  PiecewiseCurve::fillin(scan, manager);
610 
611  _order = scan.get_int8();
612 
613  size_t num_cvs = scan.get_uint32();
614 
615  _cvs.reserve(num_cvs);
616  size_t i;
617  for (i = 0; i < num_cvs; i++) {
618  CV cv;
619  cv._p.read_datagram(scan);
620  cv._t = scan.get_float64();
621  _cvs.push_back(cv);
622  }
623 }
static void register_with_read_factory()
Initializes the factory for reading these things from Bam files.
Definition: nurbsCurve.cxx:558
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.
Definition: nurbsCurve.cxx:108
A basic node of the scene graph or data graph.
Definition: pandaNode.h:72
This is the base class for all three-component vectors and points.
Definition: lvecBase3.h:105
LVecBase4f get_col(int col) const
Retrieves the indicated column of the matrix as a 4-component vector.
Definition: lmatrix.h:1294
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...
Definition: nurbsCurve.cxx:351
void add_float64(PN_float64 value)
Adds a 64-bit floating-point number to the datagram.
Definition: datagram.I:228
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:122
A virtual base class for parametric curves.
virtual bool remove_cv(int n)
Removes the indicated CV from the curve.
Definition: nurbsCurve.cxx:216
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.
Definition: datagram.I:128
Base class for objects that can be written to and read from Bam files.
Definition: typedWritable.h:37
virtual PandaNode * make_copy() const
Returns a newly-allocated PandaNode that is a shallow copy of this one.
Definition: nurbsCurve.cxx:97
virtual NurbsCurveInterface * get_nurbs_interface()
Returns a pointer to the object as a NurbsCurveInterface object if it happens to be a NURBS-style cur...
Definition: nurbsCurve.cxx:480
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition: bamWriter.h:73
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...
Definition: nurbsCurve.cxx:425
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. ...
Definition: nurbsCurve.cxx:492
A CubicCurveseg is any curve that can be completely described by four 4-valued basis vectors...
Definition: cubicCurveseg.h:58
virtual bool set_knot(int n, PN_stdfloat t)
Sets the value of the indicated knot.
Definition: nurbsCurve.cxx:274
This is a 4-by-4 transform matrix.
Definition: lmatrix.h:451
virtual bool recompute()
Recalculates the curve basis according to the latest position of the CV&#39;s, knots, etc...
Definition: nurbsCurve.cxx:312
An instance of this class is passed to the Factory when requesting it to do its business and construc...
Definition: factoryParams.h:40
A Nonuniform Rational B-Spline.
Definition: nurbsCurve.h:48
virtual bool insert_cv(PN_stdfloat t)
Inserts a new CV into the middle of the curve at the indicated parametric value.
Definition: nurbsCurve.cxx:158
virtual bool set_cv(int n, const LVecBase4 &v)
Repositions the indicated CV.
Definition: nurbsCurve.cxx:243
void register_factory(TypeHandle handle, CreateFunc *func)
Registers a new kind of thing the Factory will be able to create.
Definition: factory.I:90
virtual PN_stdfloat get_knot(int n) const
Retrieves the value of the indicated knot.
Definition: nurbsCurve.cxx:290
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.
Definition: lmatrix.h:1204
This is the base class for all three-component vectors and points.
Definition: lvecBase4.h:111
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.
Definition: bamReader.I:213
virtual LVecBase4 get_cv(int n) const
Returns the position in homogeneous space of the indicated CV.
Definition: nurbsCurve.cxx:257
void add_uint32(PN_uint32 value)
Adds an unsigned 32-bit integer to the datagram.
Definition: datagram.I:192
A class to retrieve the individual data elements previously stored in a Datagram. ...
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:43
virtual void remove_all_cvs()
Removes all CV&#39;s from the curve.
Definition: nurbsCurve.cxx:231
virtual int get_num_knots() const
Returns the number of knots on the curve.
Definition: nurbsCurve.cxx:141
static const LVecBase4f & zero()
Returns a zero-length vector.
Definition: lvecBase4.h:492