Panda3D
eggNurbsCurve.cxx
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file eggNurbsCurve.cxx
10  * @author drose
11  * @date 2000-02-15
12  */
13 
14 #include "eggNurbsCurve.h"
15 
16 #include "indent.h"
17 
18 TypeHandle EggNurbsCurve::_type_handle;
19 
20 /**
21  * Makes a copy of this object.
22  */
24 make_copy() const {
25  return new EggNurbsCurve(*this);
26 }
27 
28 /**
29  * Prepares a new curve definition with the indicated order and number of
30  * knots. This also implies a particular number of vertices as well (the
31  * number of knots minus the order), but it is up to the user to add the
32  * correct number of vertices to the curve by repeatedly calling push_back().
33  */
34 void EggNurbsCurve::
35 setup(int order, int num_knots) {
36  _order = order;
37  _knots.clear();
38 
39  int i;
40  _knots.reserve(num_knots);
41  for (i = 0; i < num_knots; i++) {
42  _knots.push_back((double)i);
43  }
44 }
45 
46 /**
47  * Directly changes the number of knots. This will either add zero-valued
48  * knots onto the end, or truncate knot values from the end, depending on
49  * whether the list is being increased or decreased. If possible, it is
50  * preferable to use the setup() method instead of directly setting the number
51  * of knots, as this may result in an invalid curve.
52  */
53 void EggNurbsCurve::
54 set_num_knots(int num) {
55  if ((int)_knots.size() >= num) {
56  // Truncate knot values at the end.
57  _knots.erase(_knots.begin() + num, _knots.end());
58  } else {
59  // Append knot values to the end.
60  _knots.reserve(num);
61  for (int i = _knots.size(); i < num; i++) {
62  _knots.push_back(0.0);
63  }
64  }
65 }
66 
67 /**
68  * Returns true if the NURBS parameters are all internally consistent (e.g.
69  * it has the right number of vertices to match its number of knots and order
70  * in each dimension), or false otherwise.
71  */
72 bool EggNurbsCurve::
73 is_valid() const {
74  if (_order < 1 || _order > 4) {
75  // Invalid order.
76  return false;
77  }
78 
79  if (get_num_cvs() != (int)size()) {
80  // Wrong number of CV's.
81  return false;
82  }
83 
84  // Do all the knot values monotonically increase?
85  int i;
86  for (i = 1; i < get_num_knots(); i++) {
87  if (get_knot(i) < get_knot(i - 1)) {
88  return false;
89  }
90  }
91 
92  // Everything's looking good!
93  return true;
94 }
95 
96 /**
97  * Returns true if the curve appears to be closed. Since the Egg syntax does
98  * not provide a means for explicit indication of closure, this has to be
99  * guessed at by examining the curve itself.
100  */
101 bool EggNurbsCurve::
102 is_closed() const {
103  // Technically, the curve is closed if the CV's at the end are repeated from
104  // the beginning. We'll do a cheesy test for expediency's sake: the curve
105  // is closed if the first n knots are not repeated. I think this will catch
106  // all the normal curves we're likely to see.
107 
108  int i;
109  for (i = 1; i < get_order(); i++) {
110  if (get_knot(i) != get_knot(i-1)) {
111  return true;
112  }
113  }
114  return false;
115 }
116 
117 /**
118  * Writes the nurbsCurve to the indicated output stream in Egg format.
119  */
120 void EggNurbsCurve::
121 write(std::ostream &out, int indent_level) const {
122  write_header(out, indent_level, "<NurbsCurve>");
123 
124  if (get_curve_type() != CT_none) {
125  indent(out, indent_level + 2)
126  << "<Char*> type { " << get_curve_type() << " }\n";
127  }
128  if (get_subdiv() != 0) {
129  indent(out, indent_level + 2)
130  << "<Scalar> subdiv { " << get_subdiv() << " }\n";
131  }
132  indent(out, indent_level + 2)
133  << "<Order> { " << get_order() << " }\n";
134  indent(out, indent_level + 2)
135  << "<Knots> {\n";
136  write_long_list(out, indent_level+4, _knots.begin(), _knots.end(), "",
137  "", 72);
138  indent(out, indent_level + 2)
139  << "}\n";
140 
141  write_body(out, indent_level+2);
142  indent(out, indent_level) << "}\n";
143 }
void setup(int order, int num_knots)
Prepares a new curve definition with the indicated order and number of knots.
get_order
Returns the order of the curve.
Definition: eggNurbsCurve.h:55
void write_header(std::ostream &out, int indent_level, const char *egg_keyword) const
Writes the first line of the egg object, e.g.
CurveType get_curve_type() const
Returns the indicated type of the curve.
Definition: eggCurve.I:80
virtual EggNurbsCurve * make_copy() const override
Makes a copy of this object.
void set_num_knots(int num)
Directly changes the number of knots.
get_num_knots
Returns the number of knots.
Definition: eggNurbsCurve.h:51
int get_subdiv() const
Returns the requested number of subdivisions, or 0 if no particular subdivisions have been requested.
Definition: eggCurve.I:62
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
Definition: indent.cxx:20
void write_long_list(std::ostream &out, int indent_level, InputIterator ifirst, InputIterator ilast, std::string first_prefix="", std::string later_prefix="", int max_col=72)
Writes a list of things to the indicated output stream, with a space separating each item.
Definition: indent.I:22
A parametric NURBS curve.
Definition: eggNurbsCurve.h:26
virtual void write(std::ostream &out, int indent_level) const override
Writes the nurbsCurve to the indicated output stream in Egg format.
get_knot
Returns the nth knot value defined.
Definition: eggNurbsCurve.h:51
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
int get_num_cvs() const
Returns the total number of control vertices that *should* be defined for the curve.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool is_valid() const
Returns true if the NURBS parameters are all internally consistent (e.g.