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 */
23 EggNurbsCurve *EggNurbsCurve::
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 }
EggCurve::get_subdiv
int get_subdiv() const
Returns the requested number of subdivisions, or 0 if no particular subdivisions have been requested.
Definition: eggCurve.I:62
EggCurve::get_curve_type
CurveType get_curve_type() const
Returns the indicated type of the curve.
Definition: eggCurve.I:80
EggNamedObject::write_header
void write_header(std::ostream &out, int indent_level, const char *egg_keyword) const
Writes the first line of the egg object, e.g.
Definition: eggNamedObject.cxx:39
EggNurbsCurve
A parametric NURBS curve.
Definition: eggNurbsCurve.h:26
EggNurbsCurve::setup
void setup(int order, int num_knots)
Prepares a new curve definition with the indicated order and number of knots.
Definition: eggNurbsCurve.cxx:35
EggNurbsCurve::is_closed
is_closed
Returns true if the curve appears to be closed.
Definition: eggNurbsCurve.h:57
EggNurbsCurve::write
virtual void write(std::ostream &out, int indent_level) const override
Writes the nurbsCurve to the indicated output stream in Egg format.
Definition: eggNurbsCurve.cxx:121
EggNurbsCurve::get_order
get_order
Returns the order of the curve.
Definition: eggNurbsCurve.h:55
EggNurbsCurve::get_num_knots
get_num_knots
Returns the number of knots.
Definition: eggNurbsCurve.h:51
EggNurbsCurve::get_num_cvs
int get_num_cvs() const
Returns the total number of control vertices that *should* be defined for the curve.
Definition: eggNurbsCurve.I:101
EggNurbsCurve::is_valid
bool is_valid() const
Returns true if the NURBS parameters are all internally consistent (e.g.
Definition: eggNurbsCurve.cxx:73
EggNurbsCurve::set_num_knots
void set_num_knots(int num)
Directly changes the number of knots.
Definition: eggNurbsCurve.cxx:54
EggNurbsCurve::make_copy
virtual EggNurbsCurve * make_copy() const override
Makes a copy of this object.
Definition: eggNurbsCurve.cxx:24
EggNurbsCurve::get_knot
get_knot
Returns the nth knot value defined.
Definition: eggNurbsCurve.h:51
TypeHandle
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
eggNurbsCurve.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
indent
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
Definition: indent.cxx:20
indent.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
write_long_list
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