19NurbsSurfaceEvaluator::
20NurbsSurfaceEvaluator() {
23 _u_knots_dirty =
true;
24 _v_knots_dirty =
true;
25 _u_basis_dirty =
true;
26 _v_basis_dirty =
true;
32NurbsSurfaceEvaluator::
33~NurbsSurfaceEvaluator() {
42reset(
int num_u_vertices,
int num_v_vertices) {
43 int num_vertices = num_u_vertices * num_v_vertices;
45 _vertices.reserve(num_vertices);
46 _num_u_vertices = num_u_vertices;
47 _num_v_vertices = num_v_vertices;
49 for (
int i = 0; i < num_vertices; i++) {
52 _u_knots_dirty =
true;
53 _v_knots_dirty =
true;
54 _u_basis_dirty =
true;
55 _v_basis_dirty =
true;
66 nassertr(ui >= 0 && ui < _num_u_vertices &&
67 vi >= 0 && vi < _num_v_vertices, empty_node_path);
69 return vert(ui, vi).get_space(rel_to);
80 const PN_stdfloat values[],
int num_values) {
81 nassertv(ui >= 0 && ui < _num_u_vertices &&
82 vi >= 0 && vi < _num_v_vertices);
85 for (
int n = 0; n < num_values; n++) {
100 nassertv(i >= 0 && i < (
int)_u_knots.size());
109 if (_u_knots_dirty) {
112 nassertr(i >= 0 && i < (
int)_u_knots.size(), 0.0f);
122 if (_u_knots_dirty) {
126 if (_num_u_vertices > _u_order - 1) {
127 double min_value = _u_knots[_u_order - 1];
128 double max_value = _u_knots[_num_u_vertices];
129 double range = (max_value - min_value);
131 for (Knots::iterator ki = _u_knots.begin(); ki != _u_knots.end(); ++ki) {
132 (*ki) = ((*ki) - min_value) / range;
134 _u_basis_dirty =
true;
145 if (_v_knots_dirty) {
148 nassertv(i >= 0 && i < (
int)_v_knots.size());
157 if (_v_knots_dirty) {
160 nassertr(i >= 0 && i < (
int)_v_knots.size(), 0.0f);
170 if (_v_knots_dirty) {
174 if (_num_v_vertices > _v_order - 1) {
175 double min_value = _v_knots[_v_order - 1];
176 double max_value = _v_knots[_num_v_vertices];
177 double range = (max_value - min_value);
179 for (Knots::iterator ki = _v_knots.begin(); ki != _v_knots.end(); ++ki) {
180 (*ki) = ((*ki) - min_value) / range;
182 _v_basis_dirty =
true;
192evaluate(
const NodePath &rel_to)
const {
193 if (_u_basis_dirty) {
196 if (_v_basis_dirty) {
202 get_vertices(vecs, rel_to);
207 &vecs[0], &_vertices[0],
208 _num_u_vertices, _num_v_vertices);
214void NurbsSurfaceEvaluator::
215output(std::ostream &out)
const {
228void NurbsSurfaceEvaluator::
229get_vertices(NurbsSurfaceEvaluator::Vert4Array &verts,
const NodePath &rel_to)
const {
230 int num_vertices = (int)_vertices.size();
231 verts.reserve(verts.size() + num_vertices);
233 for (vi = 0; vi < num_vertices; vi++) {
234 NodePath space = _vertices[vi].get_space(rel_to);
235 const LVecBase4 &vertex = _vertices[vi].get_vertex();
237 verts.push_back(vertex);
240 const LMatrix4 &mat = transform->get_mat();
241 verts.push_back(vertex * mat);
254void NurbsSurfaceEvaluator::
256 int num_vertices = (int)_vertices.size();
257 verts.reserve(verts.size() + num_vertices);
259 for (vi = 0; vi < num_vertices; vi++) {
260 const NodePath &space = _vertices[vi].get_space(rel_to);
261 LVecBase4 vertex = _vertices[vi].get_vertex();
264 const LMatrix4 &mat = transform->get_mat();
265 vertex = vertex * mat;
267 LPoint3 v3(vertex[0] / vertex[3], vertex[1] / vertex[3], vertex[2] / vertex[3]);
275void NurbsSurfaceEvaluator::
279 _u_knots.reserve(num_knots);
281 PN_stdfloat value = 0.0f;
284 while (i < _u_order) {
285 _u_knots.push_back(value);
288 while (i < num_knots - _u_order) {
290 _u_knots.push_back(value);
294 while (i < num_knots) {
295 _u_knots.push_back(value);
299 _u_knots_dirty =
false;
305void NurbsSurfaceEvaluator::
309 _v_knots.reserve(num_knots);
311 PN_stdfloat value = 0.0f;
314 while (i < _v_order) {
315 _v_knots.push_back(value);
318 while (i < num_knots - _v_order) {
320 _v_knots.push_back(value);
324 while (i < num_knots) {
325 _v_knots.push_back(value);
329 _v_knots_dirty =
false;
335void NurbsSurfaceEvaluator::
337 if (_u_knots_dirty) {
341 _u_basis.
clear(_u_order);
342 if (_num_u_vertices > _u_order - 1) {
343 int min_knot = _u_order;
344 int max_knot = _num_u_vertices;
346 for (
int i = min_knot; i <= max_knot; i++) {
347 nassertv(i - 1 >= 0 && i < (
int)_u_knots.size());
348 if (_u_knots[i - 1] < _u_knots[i]) {
355 _u_basis_dirty =
false;
361void NurbsSurfaceEvaluator::
363 if (_v_knots_dirty) {
367 _v_basis.
clear(_v_order);
368 if (_num_v_vertices > _v_order - 1) {
369 int min_knot = _v_order;
370 int max_knot = _num_v_vertices;
372 for (
int i = min_knot; i <= max_knot; i++) {
373 nassertv(i - 1 >= 0 && i < (
int)_v_knots.size());
374 if (_v_knots[i - 1] < _v_knots[i]) {
381 _v_basis_dirty =
false;
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
bool is_empty() const
Returns true if the NodePath contains no nodes.
const TransformState * get_transform(Thread *current_thread=Thread::get_current_thread()) const
Returns the complete transform object set on this node.
void append_segment(int vertex_index, const PN_stdfloat knots[])
Computes a NURBS basis for one segment of the curve and appends it to the set of basis matrices.
void clear(int order)
Removes all the segments from the curve.
This class is an abstraction for evaluating NURBS surfaces.
void set_extended_vertices(int ui, int vi, int d, const PN_stdfloat values[], int num_values)
Simultaneously sets several extended values in the slots d through (d + num_values - 1) from the num_...
void reset(int num_u_vertices, int num_v_vertices)
Resets all the vertices and knots to their default values, and sets the surface up with the indicated...
set_u_knot
Sets the value of the nth knot.
get_v_knot
Returns the value of the nth knot.
set_v_knot
Sets the value of the nth knot.
get_num_v_knots
Returns the number of knot values in the surface in the V direction.
void normalize_u_knots()
Normalizes the knot sequence so that the parametric range of the surface in the U direction is 0 .
get_num_u_knots
Returns the number of knot values in the surface in the U direction.
NodePath get_vertex_space(int ui, int vi, const NodePath &rel_to) const
Returns the coordinate space of the nth control vertex of the surface, expressed as a NodePath.
void normalize_v_knots()
Normalizes the knot sequence so that the parametric range of the surface in the U direction is 0 .
get_u_knot
Returns the value of the nth knot.
The result of a NurbsSurfaceEvaluator.
This represents a single control vertex in a NurbsEvaluator.
void set_extended_vertex(int d, PN_stdfloat value)
Sets an n-dimensional vertex value.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.