15 #include "eggVertexPool.h" 16 #include "eggPrimitive.h" 17 #include "eggUtilities.h" 32 EggVertexPool(
const string &name) :
EggNode(name) {
47 for (i = copy.
begin(); i != copy.
end(); ++i) {
63 nassertv(_index_vertices.size() == _unique_vertices.size());
65 IndexVertices::iterator ivi;
66 for (ivi = _index_vertices.begin(); ivi != _index_vertices.end(); ++ivi) {
67 int index = (*ivi).first;
71 nassertv(vertex->_pool ==
this);
78 _index_vertices.clear();
79 _unique_vertices.clear();
91 IndexVertices::const_iterator ivi;
92 for (ivi = _index_vertices.begin(); ivi != _index_vertices.end(); ++ivi) {
111 IndexVertices::const_iterator ivi;
112 for (ivi = _index_vertices.begin(); ivi != _index_vertices.end(); ++ivi) {
131 IndexVertices::const_iterator ivi = _index_vertices.find(index);
133 if (ivi == _index_vertices.end()) {
156 nassertr(index >= 0, NULL);
158 IndexVertices::const_iterator ivi = _index_vertices.find(index);
160 if (ivi == _index_vertices.end()) {
162 forward->_forward_reference =
true;
165 return (*ivi).second;
178 return _highest_index;
192 _highest_index = highest_index;
203 int num_dimensions = 0;
205 IndexVertices::const_iterator ivi;
206 for (ivi = _index_vertices.begin(); ivi != _index_vertices.end(); ++ivi) {
211 return num_dimensions;
222 IndexVertices::const_iterator ivi;
223 for (ivi = _index_vertices.begin(); ivi != _index_vertices.end(); ++ivi) {
225 if (vertex->has_normal()) {
241 IndexVertices::const_iterator ivi;
242 for (ivi = _index_vertices.begin(); ivi != _index_vertices.end(); ++ivi) {
244 if (vertex->has_color()) {
261 IndexVertices::const_iterator ivi;
262 for (ivi = _index_vertices.begin(); ivi != _index_vertices.end(); ++ivi) {
264 if (vertex->has_color() &&
266 !vertex->_drgbas.empty())) {
288 has_overall_color =
true;
289 overall_color.set(1.0f, 1.0f, 1.0f, 1.0f);
293 IndexVertices::const_iterator ivi;
294 ivi = _index_vertices.begin();
299 while (ivi != _index_vertices.end()) {
300 vertex = (*ivi).second;
302 has_overall_color =
false;
308 has_overall_color =
true;
319 IndexVertices::const_iterator ivi;
320 for (ivi = _index_vertices.begin(); ivi != _index_vertices.end(); ++ivi) {
338 IndexVertices::const_iterator ivi;
339 for (ivi = _index_vertices.begin(); ivi != _index_vertices.end(); ++ivi) {
362 vector_string &tbn_names)
const {
363 pset<string> uv_names_set, uvw_names_set, tbn_names_set;
364 IndexVertices::const_iterator ivi;
365 for (ivi = _index_vertices.begin(); ivi != _index_vertices.end(); ++ivi) {
370 uv_names_set.insert(uv_obj->get_name());
371 if (uv_obj->
has_w()) {
372 uvw_names_set.insert(uv_obj->get_name());
374 if (uv_obj->has_tangent() && uv_obj->has_binormal()) {
375 tbn_names_set.insert(uv_obj->get_name());
381 for (si = uv_names_set.begin(); si != uv_names_set.end(); ++si) {
382 uv_names.push_back(*si);
384 for (si = uvw_names_set.begin(); si != uvw_names_set.end(); ++si) {
385 uvw_names.push_back(*si);
387 for (si = tbn_names_set.begin(); si != tbn_names_set.end(); ++si) {
388 tbn_names.push_back(*si);
401 IndexVertices::const_iterator ivi;
402 for (ivi = _index_vertices.begin(); ivi != _index_vertices.end(); ++ivi) {
407 aux_names_set.insert(aux_obj->get_name());
412 for (si = aux_names_set.begin(); si != aux_names_set.end(); ++si) {
413 aux_names.push_back(*si);
425 nassertr(_index_vertices.size() == _unique_vertices.size(),
427 return iterator(_index_vertices.begin());
438 return iterator(_index_vertices.end());
448 return _index_vertices.empty();
458 nassertr(_index_vertices.size() == _unique_vertices.size(), 0);
459 return _index_vertices.size();
489 nassertr(vertex->_pool == NULL, NULL);
495 nassertr(index >= 0, NULL);
498 IndexVertices::const_iterator ivi = _index_vertices.find(index);
500 if (ivi != _index_vertices.end()) {
504 (*orig_vertex) = (*vertex);
505 orig_vertex->_forward_reference =
false;
506 _highest_index = max(_highest_index, index);
511 nassertr(
false, NULL);
514 _unique_vertices.insert(vertex);
515 _index_vertices[index] = vertex;
518 _highest_index = max(_highest_index, index);
521 vertex->_pool =
this;
522 vertex->_index = index;
538 UniqueVertices::iterator uvi;
539 uvi = _unique_vertices.find((
EggVertex *)©);
541 if (uvi != _unique_vertices.end()) {
560 UniqueVertices::iterator uvi;
561 uvi = _unique_vertices.find((
EggVertex *)©);
563 if (uvi != _unique_vertices.end()) {
582 nassertv(vertex->_pool ==
this);
585 nassertv(
get_vertex(vertex->_index) == vertex);
588 _index_vertices.erase(vertex->_index);
590 if (_highest_index == vertex->_index) {
592 if (_index_vertices.empty()) {
595 IndexVertices::reverse_iterator ivi = _index_vertices.rbegin();
596 while (ivi != _index_vertices.rend() &&
597 (*ivi).second->is_forward_reference()) {
600 if (ivi != _index_vertices.rend()) {
601 _highest_index = (*ivi).first;
612 UniqueVertices::iterator uvi;
613 uvi = _unique_vertices.find(vertex);
616 nassertv(uvi != _unique_vertices.end());
618 while ((*uvi) != vertex) {
621 nassertv(uvi != _unique_vertices.end());
624 _unique_vertices.erase(uvi);
626 vertex->_pool = NULL;
646 IndexVertices::const_iterator ivi;
647 for (ivi = _index_vertices.begin(); ivi != _index_vertices.end(); ++ivi) {
652 vertex->_pool = NULL;
658 UniqueVertices::iterator uvi;
659 uvi = new_unique_vertices.find(vertex);
660 if (uvi != new_unique_vertices.end()) {
667 EggVertex::PrimitiveRef::iterator pi;
668 for (pi = pref.begin(); pi != pref.end(); ++pi) {
670 EggPrimitive::iterator pvi = prim->
find(vertex);
671 nassertr(pvi != prim->end(), 0);
672 prim->
replace(pvi, orig_vertex);
674 vertex->test_pref_integrity();
675 orig_vertex->test_pref_integrity();
678 vertex->_pool = NULL;
684 vertex->_index = new_index_vertices.size();
685 new_index_vertices.insert(IndexVertices::value_type(vertex->_index, vertex));
686 new_unique_vertices.insert(vertex);
692 _unique_vertices.swap(new_unique_vertices);
693 _index_vertices.swap(new_index_vertices);
694 _highest_index = (int)_index_vertices.size() - 1;
696 nassertr(_index_vertices.size() == _unique_vertices.size(), num_removed);
709 IndexVertices::iterator ivi;
710 for (ivi = _index_vertices.begin(); ivi != _index_vertices.end(); ++ivi) {
742 if (translation ==
LVector3d(0.0, 0.0, 0.0)) {
747 for (i =
begin(); i !=
end(); ++i) {
763 verts.reserve(
size());
764 copy(
begin(),
end(), back_inserter(verts));
766 Verts::const_iterator vi;
767 for (vi = verts.begin(); vi != verts.end(); ++vi) {
772 if (num_global_coord != 0) {
774 if (num_local_coord != 0) {
789 for (i =
begin(); i !=
end(); ++i) {
828 SortedVertices sorted_vertices;
829 sorted_vertices.reserve(
size());
831 for (i =
begin(); i !=
end(); ++i) {
832 sorted_vertices.push_back(*i);
840 for (vi = 0; vi < (int)sorted_vertices.size(); ++vi) {
843 new_index_vertices[vi] = vertex;
847 _index_vertices.swap(new_index_vertices);
857 write(ostream &out,
int indent_level)
const {
861 for (i =
begin(); i !=
end(); ++i) {
862 (*i)->write(out, indent_level+2);
865 indent(out, indent_level)
897 r_transform_vertices(
const LMatrix4d &mat) {
bool empty() const
Returns true if the pool is empty.
A base class for any of a number of kinds of geometry primitives: polygons, point lights...
The set of UV's that may or may not be assigned to a vertex.
bool has_uvs() const
Returns true if any vertex in the pool has a uv defined, false if none of them do.
This is an iterator adaptor that converts any iterator that returns a pair (e.g.
PrimitiveRef::size_type pref_size() const
Returns the number of elements between pref_begin() and pref_end().
void set_highest_index(int highest_index)
Artificially changes the "highest index number", so that a newly created vertex will begin at this nu...
int get_num_dimensions() const
Returns the number of dimensions the vertex uses.
int get_num_dimensions() const
Returns the maximum number of dimensions used by any vertex in the pool.
This is a 4-by-4 transform matrix.
EggVertex * add_vertex(EggVertex *vertex, int index=-1)
Adds the indicated vertex to the pool.
bool has_aux() const
Returns true if the vertex has any auxiliary data, false otherwise.
EggVertex * get_vertex(int index) const
Returns the vertex in the pool with the indicated index number, or NULL if no vertices have that inde...
EggVertex * get_forward_vertex(int index)
Returns the vertex in the pool with the indicated index number.
void check_overall_color(bool &has_overall_color, LColor &overall_color) const
Scans the vertex pool for different colors on different vertices.
const_aux_iterator aux_end() const
Returns an iterator that allows walking through the complete set of auxiliary data on the vertex...
void clear_grefs()
Removes all group references from the vertex, so that it is not assigned to any group.
LColor get_color() const
Returns the color set on this particular attribute.
size_type size() const
Returns the number of vertices in the pool.
bool has_normals() const
Returns true if any vertex in the pool has a normal defined, false if none of them do...
iterator end() const
Returns an iterator that can be used to traverse through all the vertices in the pool.
void set_row(int row, const LVecBase4d &v)
Replaces the indicated row of the matrix.
This is our own Panda specialization on the default STL vector.
iterator begin() const
Returns an iterator that can be used to traverse through all the vertices in the pool.
bool has_aux() const
Returns true if any vertex in the pool has auxiliary data defined, false if none of them do...
int get_index() const
Returns the index number of the vertex within its pool.
int get_highest_index() const
Returns the highest index number used by any vertex in the pool (except forward references).
bool has_w() const
Returns true if the texture coordinate has a third, w component, false if it is just a normal 2-d tex...
void get_uv_names(vector_string &uv_names, vector_string &uvw_names, vector_string &tbn_names) const
Returns the list of UV names that are defined by any vertices in the pool, as well as the subset of U...
bool is_local_coord() const
Returns true if this node's vertices are not in the global coordinate space.
bool has_defined_vertices() const
Returns true if any vertices in the pool are fully defined vertices, false if all vertices are forwar...
bool has_colors() const
Returns true if any vertex in the pool has a color defined, false if none of them do...
void transform(const LMatrix4d &mat)
Applies the indicated transformation matrix to the vertex.
Any one-, two-, three-, or four-component vertex, possibly with attributes such as a normal...
bool almost_equal(const LVecBase4f &other, float threshold) const
Returns true if two vectors are memberwise equal within a specified tolerance.
int remove_unused_vertices()
Removes all vertices from the pool that are not referenced by at least one primitive.
iterator find(EggVertex *vertex)
Returns the iterator pointing to the indicated vertex, or end() if the vertex is not part of the prim...
LVecBase3d get_row3(int row) const
Retrieves the row column of the matrix as a 3-component vector, ignoring the last column...
void add_unused_vertices_to_prim(EggPrimitive *prim)
Adds all of the unused vertices in this vertex pool to the indicated primitive, in ascending order...
bool has_uv() const
Returns true if the vertex has an unnamed UV coordinate pair, false otherwise.
void write_header(ostream &out, int indent_level, const char *egg_keyword) const
Writes the first line of the egg object, e.g.
The set of named auxiliary data that may or may not be assigned to a vertex.
const_aux_iterator aux_begin() const
Returns an iterator that allows walking through the complete set of auxiliary data on the vertex...
This is the base class for all three-component vectors and points.
EggVertex * find_matching_vertex(const EggVertex ©)
If the EggVertexPool already has a vertex matching the indicated vertex, returns it; otherwise...
This is a three-component vector distance (as opposed to a three-component point, which represents a ...
bool is_forward_reference() const
Returns true if the vertex is a forward reference to some vertex that hasn't been defined yet...
const_uv_iterator uv_begin() const
Returns an iterator that allows walking through the complete set of named UV's on the vertex...
A base class for things that may be directly added into the egg hierarchy.
void sort_by_external_index()
Re-orders (and re-numbers) the vertices in this vertex pool so that they appear in increasing order b...
void write(ostream &out, int indent_level) const
Writes the vertex pool to the indicated output stream in Egg format.
int get_external_index() const
Returns the number set by set_external_index().
void replace(iterator position, EggVertex *vertex)
Replaces the vertex at the indicated position with the indicated vertex.
int get_num_global_coord() const
Returns the number of primitives that own this vertex whose vertices are interpreted in the global co...
TypeHandle is the identifier used to differentiate C++ class types.
int get_num_local_coord() const
Returns the number of primitives that own this vertex whose vertices are interpreted to be in a local...
void get_aux_names(vector_string &aux_names) const
Returns the list of auxiliary data names that are defined by any vertices in the pool.
EggVertex * create_unique_vertex(const EggVertex ©)
Creates a new vertex in the pool that is a copy of the indicated one and returns it.
A collection of vertices.
EggVertex * add_vertex(EggVertex *vertex)
Adds the indicated vertex to the end of the primitive's list of vertices, and returns it...
void transform(const LMatrix4d &mat)
Applies the indicated transformation matrix to all the vertices.
const_uv_iterator uv_end() const
Returns an iterator that allows walking through the complete set of named UV's on the vertex...
bool has_forward_vertices() const
Returns true if any vertices in the pool are undefined forward-reference vertices, false if all vertices are defined.
bool has_nonwhite_colors() const
Returns true if any vertex in the pool has a color defined other than white, false if no vertices hav...
void remove_vertex(EggVertex *vertex)
Removes the vertex from the pool.