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 }
A base class for any of a number of kinds of geometry primitives: polygons, point lights,...
Definition: eggPrimitive.h:47
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
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PrimitiveRef::size_type pref_size() const
Returns the number of elements between pref_begin() and pref_end().
Definition: eggVertex.cxx:815
This is our own Panda specialization on the default STL map.
Definition: pmap.h:49
EggVertex * add_vertex(EggVertex *vertex, int index=-1)
Adds the indicated vertex to the pool.
EggVertexPool * get_pool() const
Returns the vertex pool this vertex belongs in.
Definition: eggVertex.I:19
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool test_ref_count_integrity() const
Does some easy checks to make sure that the reference count isn't completely bogus.
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
This is our own Panda specialization on the default STL vector.
Definition: pvector.h:42
The main glue of the egg hierarchy, this corresponds to the <Group>, <Instance>, and <Joint> type nod...
Definition: eggGroup.h:34
Any one-, two-, three-, or four-component vertex, possibly with attributes such as a normal.
Definition: eggVertex.h:39
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
double get_vertex_membership(const EggVertex *vert) const
Returns the amount of membership of the indicated vertex in this group.
Definition: eggGroup.cxx:677
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
void replace(iterator position, EggVertex *vertex)
Replaces the vertex at the indicated position with the indicated vertex.
Definition: eggPrimitive.I:335
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
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A collection of vertices.
Definition: eggVertexPool.h:41
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