Panda3D
eggUtilities.I
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 eggUtilities.I
10  * @author drose
11  * @date 1999-02-10
12  */
13 
14 #include "eggGroup.h"
15 #include "eggPrimitive.h"
16 #include "eggVertexPool.h"
17 
18 #include <algorithm>
19 
20 /**
21  * Splits a vertex into two or more vertices, each an exact copy of the
22  * original and in the same vertex pool.
23  *
24  * The splitting is based on some arbitrary property of the primitives that
25  * own the vertex. In the extreme, each primitive may get a different copy of
26  * the vertex, although it is also possible for some primitives to still share
27  * vertices.
28  *
29  * This decision is made based on the function object 'sequence'. This object
30  * must define the following function:
31  *
32  * int operator () (const EggPrimitive *prim) const;
33  *
34  * This function returns a sequence number, which determines which primitives
35  * will share which vertices. The sequence number 0 refers to the original
36  * vertex pointer; other sequence numbers indicate new vertices. Other than
37  * that, the sequence number is totally arbitrary. Primitives for which the
38  * sequence number is the same will end up sharing the same copy of the
39  * vertex.
40  */
41 template<class FunctionObject>
42 void
43 split_vertex(EggVertex *vert, const FunctionObject &sequence) {
44  // Did we start in a happy world?
45  vert->test_pref_integrity();
46  vert->test_gref_integrity();
47 
48  EggVertexPool *pool = vert->get_pool();
49 
50  // Define a map of ints to vert pointers, to indicate which sequence numbers
51  // we have already created vertices for.
52  typedef pmap<int, EggVertex *> Sequences;
53  Sequences _sequences;
54 
55  // Get a copy of the list of primitives that reference this vertex. We must
56  // have a copy because we will be modifying the list as we traverse it.
57  typedef pvector<EggPrimitive *> Prims;
58  Prims prims;
59  prims.reserve(vert->pref_size());
60  std::copy(vert->pref_begin(), vert->pref_end(), std::back_inserter(prims));
61 
62  // Now walk through the list of primitives that reference this vertex.
63  Prims::const_iterator pri;
64  for (pri = prims.begin(); pri != prims.end(); ++pri) {
65  EggPrimitive *prim = *pri;
67 
68  int seq = sequence(prim);
69 
70  if (seq != 0) {
71  // Here's a new sequence number! Have we already defined it?
72  EggVertex *new_vert = nullptr;
73 
74  Sequences::const_iterator si = _sequences.find(seq);
75 
76  if (si != _sequences.end()) {
77  // Yes, we've seen this sequence number before. Use the same vertex.
78  new_vert = (*si).second;
79 
80  } else {
81  // No, this is the first time we've encountered this sequence. Split
82  // the vertex.
83  new_vert = new EggVertex(*vert);
84  pool->add_vertex(new_vert);
85  _sequences[seq] = new_vert;
86 
87  // The new vertex gets all the same group memberships as the old one.
88  EggVertex::GroupRef::const_iterator gri;
89  for (gri = vert->gref_begin(); gri != vert->gref_end(); ++gri) {
90  EggGroup *group = *gri;
91  group->ref_vertex(new_vert, group->get_vertex_membership(vert));
92  }
93  }
94 
95  // Now replace the vertex in the primitive.
96  EggPrimitive::iterator pi;
97  for (pi = prim->begin(); pi != prim->end(); ++pi) {
98  if (*pi == vert) {
99  prim->replace(pi, new_vert);
100  }
101  }
102  }
103  }
104 
105 #ifndef NDEBUG
106  // Now verify everything is still happy.
107  vert->test_pref_integrity();
108  vert->test_gref_integrity();
109 
110  Sequences::const_iterator si;
111  for (si = _sequences.begin();
112  si != _sequences.end();
113  ++si) {
114  EggVertex *new_vert = (*si).second;
115  new_vert->test_gref_integrity();
116  new_vert->test_pref_integrity();
117  }
118 #endif // NDEBUG
119 
120 }
EggVertex::pref_begin
PrimitiveRef::const_iterator pref_begin() const
Returns an iterator that can, in conjunction with pref_end(), be used to traverse the entire set of p...
Definition: eggVertex.cxx:793
eggVertexPool.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
eggPrimitive.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
pvector
This is our own Panda specialization on the default STL vector.
Definition: pvector.h:42
EggVertex::pref_end
PrimitiveRef::const_iterator pref_end() const
Returns an iterator that can, in conjunction with pref_begin(), be used to traverse the entire set of...
Definition: eggVertex.cxx:805
pmap
This is our own Panda specialization on the default STL map.
Definition: pmap.h:49
EggPrimitive
A base class for any of a number of kinds of geometry primitives: polygons, point lights,...
Definition: eggPrimitive.h:47
EggVertex::gref_end
GroupRef::const_iterator gref_end() const
Returns an iterator that can, in conjunction with gref_begin(), be used to traverse the entire set of...
Definition: eggVertex.cxx:714
EggVertexPool::add_vertex
EggVertex * add_vertex(EggVertex *vertex, int index=-1)
Adds the indicated vertex to the pool.
Definition: eggVertexPool.cxx:421
EggVertex
Any one-, two-, three-, or four-component vertex, possibly with attributes such as a normal.
Definition: eggVertex.h:39
ReferenceCount::test_ref_count_integrity
bool test_ref_count_integrity() const
Does some easy checks to make sure that the reference count isn't completely bogus.
Definition: referenceCount.I:197
EggVertex::pref_size
PrimitiveRef::size_type pref_size() const
Returns the number of elements between pref_begin() and pref_end().
Definition: eggVertex.cxx:815
EggGroup::get_vertex_membership
double get_vertex_membership(const EggVertex *vert) const
Returns the amount of membership of the indicated vertex in this group.
Definition: eggGroup.cxx:677
EggPrimitive::replace
void replace(iterator position, EggVertex *vertex)
Replaces the vertex at the indicated position with the indicated vertex.
Definition: eggPrimitive.I:335
split_vertex
void split_vertex(EggVertex *vert, const FunctionObject &sequence)
Splits a vertex into two or more vertices, each an exact copy of the original and in the same vertex ...
Definition: eggUtilities.I:43
EggVertex::get_pool
EggVertexPool * get_pool() const
Returns the vertex pool this vertex belongs in.
Definition: eggVertex.I:19
EggGroup::ref_vertex
void ref_vertex(EggVertex *vert, double membership=1.0)
Adds the vertex to the set of those referenced by the group, at the indicated membership level.
Definition: eggGroup.cxx:608
EggVertexPool
A collection of vertices.
Definition: eggVertexPool.h:41
EggVertex::gref_begin
GroupRef::const_iterator gref_begin() const
Returns an iterator that can, in conjunction with gref_end(), be used to traverse the entire set of g...
Definition: eggVertex.cxx:702
EggGroup
The main glue of the egg hierarchy, this corresponds to the <Group>, <Instance>, and <Joint> type nod...
Definition: eggGroup.h:34
eggGroup.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.