Panda3D
 All Classes Functions Variables Enumerations
eggUtilities.I
00001 // Filename: eggUtilities.I
00002 // Created by:  drose (10Feb99)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "eggGroup.h"
00016 #include "eggPrimitive.h"
00017 #include "eggVertexPool.h"
00018 
00019 #include <algorithm>
00020 
00021 ////////////////////////////////////////////////////////////////////
00022 //     Function: split_vertex
00023 //  Description: Splits a vertex into two or more vertices, each an
00024 //               exact copy of the original and in the same vertex
00025 //               pool.
00026 //
00027 //               The splitting is based on some arbitrary property of
00028 //               the primitives that own the vertex.  In the extreme,
00029 //               each primitive may get a different copy of the
00030 //               vertex, although it is also possible for some
00031 //               primitives to still share vertices.
00032 //
00033 //               This decision is made based on the function object
00034 //               'sequence'.  This object must define the following
00035 //               function:
00036 //
00037 //               int operator () (const EggPrimitive *prim) const;
00038 //
00039 //               This function returns a sequence number, which
00040 //               determines which primitives will share which
00041 //               vertices.  The sequence number 0 refers to the
00042 //               original vertex pointer; other sequence numbers
00043 //               indicate new vertices.  Other than that, the sequence
00044 //               number is totally arbitrary.  Primitives for which
00045 //               the sequence number is the same will end up sharing
00046 //               the same copy of the vertex.
00047 ////////////////////////////////////////////////////////////////////
00048 template<class FunctionObject>
00049 void
00050 split_vertex(EggVertex *vert, const FunctionObject &sequence) {
00051   // Did we start in a happy world?
00052   vert->test_pref_integrity();
00053   vert->test_gref_integrity();
00054 
00055   EggVertexPool *pool = vert->get_pool();
00056 
00057   // Define a map of ints to vert pointers, to indicate which sequence
00058   // numbers we have already created vertices for.
00059   typedef pmap<int, EggVertex *> Sequences;
00060   Sequences _sequences;
00061 
00062   // Get a copy of the list of primitives that reference this vertex.
00063   // We must have a copy because we will be modifying the list as we
00064   // traverse it.
00065   typedef pvector<EggPrimitive *> Prims;
00066   Prims prims;
00067   prims.reserve(vert->pref_size());
00068   copy(vert->pref_begin(), vert->pref_end(), back_inserter(prims));
00069 
00070   // Now walk through the list of primitives that reference this
00071   // vertex.
00072   Prims::const_iterator pri;
00073   for (pri = prims.begin(); pri != prims.end(); ++pri) {
00074     EggPrimitive *prim = *pri;
00075     prim->test_ref_count_integrity();
00076 
00077     int seq = sequence(prim);
00078 
00079     if (seq != 0) {
00080       // Here's a new sequence number!  Have we already defined it?
00081       EggVertex *new_vert = NULL;
00082 
00083       Sequences::const_iterator si = _sequences.find(seq);
00084 
00085       if (si != _sequences.end()) {
00086         // Yes, we've seen this sequence number before.  Use the same
00087         // vertex.
00088         new_vert = (*si).second;
00089 
00090       } else {
00091         // No, this is the first time we've encountered this sequence.
00092         // Split the vertex.
00093         new_vert = new EggVertex(*vert);
00094         pool->add_vertex(new_vert);
00095         _sequences[seq] = new_vert;
00096 
00097         // The new vertex gets all the same group memberships as the
00098         // old one.
00099         EggVertex::GroupRef::const_iterator gri;
00100         for (gri = vert->gref_begin(); gri != vert->gref_end(); ++gri) {
00101           EggGroup *group = *gri;
00102           group->ref_vertex(new_vert, group->get_vertex_membership(vert));
00103         }
00104       }
00105 
00106       // Now replace the vertex in the primitive.
00107       EggPrimitive::iterator pi;
00108       for (pi = prim->begin(); pi != prim->end(); ++pi) {
00109         if (*pi == vert) {
00110           prim->replace(pi, new_vert);
00111         }
00112       }
00113     }
00114   }
00115 
00116 #ifndef NDEBUG
00117   // Now verify everything is still happy.
00118   vert->test_pref_integrity();
00119   vert->test_gref_integrity();
00120 
00121   Sequences::const_iterator si;
00122   for (si = _sequences.begin();
00123        si != _sequences.end();
00124        ++si) {
00125     EggVertex *new_vert = (*si).second;
00126     new_vert->test_gref_integrity();
00127     new_vert->test_pref_integrity();
00128   }
00129 #endif  // NDEBUG
00130 
00131 }
 All Classes Functions Variables Enumerations