Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

panda/src/egg/eggUtilities.I

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

Generated on Fri May 2 00:38:02 2003 for Panda by doxygen1.3