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