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