Panda3D

eggVertex.cxx

00001 // Filename: eggVertex.cxx
00002 // Created by:  drose (16Jan99)
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 "eggVertex.h"
00016 #include "eggVertexPool.h"
00017 #include "eggParameters.h"
00018 #include "eggGroup.h"
00019 #include "eggMiscFuncs.h"
00020 #include "eggPrimitive.h"
00021 
00022 #include "indent.h"
00023 #include "luse.h"
00024 #include "lmatrix.h"
00025 #include "pandabase.h"
00026 
00027 #include <math.h>
00028 #include <algorithm>
00029 
00030 TypeHandle EggVertex::_type_handle;
00031 
00032 
00033 ////////////////////////////////////////////////////////////////////
00034 //     Function: EggVertex::Constructor
00035 //       Access: Published
00036 //  Description:
00037 ////////////////////////////////////////////////////////////////////
00038 EggVertex::
00039 EggVertex() {
00040   _pool = NULL;
00041   _forward_reference = false;
00042   _index = -1;
00043   _external_index = -1;
00044   set_pos(LPoint3d(0.0, 0.0, 0.0));
00045   test_pref_integrity();
00046   test_gref_integrity();
00047 }
00048 
00049 ////////////////////////////////////////////////////////////////////
00050 //     Function: EggVertex::Copy constructor
00051 //       Access: Published
00052 //  Description: Copies all properties of the vertex except its vertex
00053 //               pool, index number, and group membership.
00054 ////////////////////////////////////////////////////////////////////
00055 EggVertex::
00056 EggVertex(const EggVertex &copy)
00057   : EggObject(copy), EggAttributes(copy),
00058     _dxyzs(copy._dxyzs),
00059     _external_index(copy._external_index),
00060     _pos(copy._pos),
00061     _num_dimensions(copy._num_dimensions),
00062     _uv_map(copy._uv_map)
00063 {
00064   _pool = NULL;
00065   _forward_reference = false;
00066   _index = -1;
00067   test_pref_integrity();
00068   test_gref_integrity();
00069 }
00070 
00071 
00072 ////////////////////////////////////////////////////////////////////
00073 //     Function: EggVertex::Copy assignment operator
00074 //       Access: Published
00075 //  Description: Copies all properties of the vertex except its vertex
00076 //               pool, index number, and group membership.
00077 ////////////////////////////////////////////////////////////////////
00078 EggVertex &EggVertex::
00079 operator = (const EggVertex &copy) {
00080   EggObject::operator = (copy);
00081   EggAttributes::operator = (copy);
00082   _dxyzs = copy._dxyzs;
00083   _external_index = copy._external_index;
00084   _pos = copy._pos;
00085   _num_dimensions = copy._num_dimensions;
00086   _uv_map = copy._uv_map;
00087 
00088   test_pref_integrity();
00089   test_gref_integrity();
00090 
00091   return *this;
00092 }
00093 
00094 ////////////////////////////////////////////////////////////////////
00095 //     Function: EggVertex::Destructor
00096 //       Access: Published, Virtual
00097 //  Description:
00098 ////////////////////////////////////////////////////////////////////
00099 EggVertex::
00100 ~EggVertex() {
00101   // We should never destruct a vertex while it still thinks it
00102   // belongs to a VertexPool.  If we do, we've probably lost a
00103   // reference count somewhere.
00104   nassertv(_pool == NULL);
00105 
00106   // Also, a vertex shouldn't be destructed while it's being
00107   // referenced by a group or a primitive, for the same reason.
00108   nassertv(_gref.empty());
00109   nassertv(_pref.empty());
00110 }
00111 
00112 ////////////////////////////////////////////////////////////////////
00113 //     Function: EggVertex::has_uv
00114 //       Access: Published
00115 //  Description: Returns true if the vertex has the named UV
00116 //               coordinate pair, and the named UV coordinate pair is
00117 //               2-d, false otherwise.
00118 ////////////////////////////////////////////////////////////////////
00119 bool EggVertex::
00120 has_uv(const string &name) const {
00121   UVMap::const_iterator ui = _uv_map.find(EggVertexUV::filter_name(name));
00122   if (ui != _uv_map.end()) {
00123     EggVertexUV *uv_obj = (*ui).second;
00124     return !uv_obj->has_w();
00125   }
00126   return false;
00127 }
00128 
00129 ////////////////////////////////////////////////////////////////////
00130 //     Function: EggVertex::has_uvw
00131 //       Access: Published
00132 //  Description: Returns true if the vertex has the named UV
00133 //               coordinate triple, and the named UV coordinate triple is
00134 //               3-d, false otherwise.
00135 ////////////////////////////////////////////////////////////////////
00136 bool EggVertex::
00137 has_uvw(const string &name) const {
00138   UVMap::const_iterator ui = _uv_map.find(EggVertexUV::filter_name(name));
00139   if (ui != _uv_map.end()) {
00140     EggVertexUV *uv_obj = (*ui).second;
00141     return uv_obj->has_w();
00142   }
00143   return false;
00144 }
00145 
00146 ////////////////////////////////////////////////////////////////////
00147 //     Function: EggVertex::get_uv
00148 //       Access: Published
00149 //  Description: Returns the named UV coordinate pair on the vertex.
00150 //               vertex.  It is an error to call this if has_uv(name)
00151 //               returned false.
00152 ////////////////////////////////////////////////////////////////////
00153 TexCoordd EggVertex::
00154 get_uv(const string &name) const {
00155   UVMap::const_iterator ui = _uv_map.find(EggVertexUV::filter_name(name));
00156   nassertr(ui != _uv_map.end(), TexCoordd::zero());
00157   return (*ui).second->get_uv();
00158 }
00159 
00160 ////////////////////////////////////////////////////////////////////
00161 //     Function: EggVertex::get_uvw
00162 //       Access: Published
00163 //  Description: Returns the named UV coordinate triple on the vertex.
00164 //               vertex.  It is an error to call this if has_uvw(name)
00165 //               returned false.
00166 ////////////////////////////////////////////////////////////////////
00167 const TexCoord3d &EggVertex::
00168 get_uvw(const string &name) const {
00169   UVMap::const_iterator ui = _uv_map.find(EggVertexUV::filter_name(name));
00170   nassertr(ui != _uv_map.end(), TexCoord3d::zero());
00171   return (*ui).second->get_uvw();
00172 }
00173 
00174 ////////////////////////////////////////////////////////////////////
00175 //     Function: EggVertex::set_uv
00176 //       Access: Published
00177 //  Description: Sets the indicated UV coordinate pair on the vertex.
00178 //               This replaces any UV coordinate pair with the same
00179 //               name already on the vertex, but preserves UV morphs.
00180 ////////////////////////////////////////////////////////////////////
00181 void EggVertex::
00182 set_uv(const string &name, const TexCoordd &uv) {
00183   string fname = EggVertexUV::filter_name(name);
00184   PT(EggVertexUV) &uv_obj = _uv_map[fname];
00185 
00186   if (uv_obj.is_null()) {
00187     uv_obj = new EggVertexUV(fname, uv);
00188   } else {
00189     uv_obj = new EggVertexUV(*uv_obj);
00190     uv_obj->set_uv(uv);
00191   }
00192 
00193   nassertv(get_uv(fname) == uv);
00194 }
00195 
00196 ////////////////////////////////////////////////////////////////////
00197 //     Function: EggVertex::set_uvw
00198 //       Access: Published
00199 //  Description: Sets the indicated UV coordinate triple on the vertex.
00200 //               This replaces any UV coordinate pair or triple with
00201 //               the same name already on the vertex, but preserves UV
00202 //               morphs.
00203 ////////////////////////////////////////////////////////////////////
00204 void EggVertex::
00205 set_uvw(const string &name, const TexCoord3d &uvw) {
00206   string fname = EggVertexUV::filter_name(name);
00207   PT(EggVertexUV) &uv_obj = _uv_map[fname];
00208 
00209   if (uv_obj.is_null()) {
00210     uv_obj = new EggVertexUV(fname, uvw);
00211   } else {
00212     uv_obj = new EggVertexUV(*uv_obj);
00213     uv_obj->set_uvw(uvw);
00214   }
00215 
00216   nassertv(get_uvw(fname) == uvw);
00217 }
00218 
00219 ////////////////////////////////////////////////////////////////////
00220 //     Function: EggVertex::get_uv_obj
00221 //       Access: Published
00222 //  Description: Returns the named EggVertexUV object, which defines
00223 //               both the UV coordinate pair for this name and the UV
00224 //               morphs.  This object might be shared between multiple
00225 //               vertices.  You should not attempt to modify this
00226 //               object; instead, call modify_uv_object to return a
00227 //               modifiable pointer.
00228 ////////////////////////////////////////////////////////////////////
00229 const EggVertexUV *EggVertex::
00230 get_uv_obj(const string &name) const {
00231   UVMap::const_iterator ui = _uv_map.find(EggVertexUV::filter_name(name));
00232   if (ui != _uv_map.end()) {
00233     return (*ui).second;
00234   }
00235   return NULL;
00236 }
00237 
00238 ////////////////////////////////////////////////////////////////////
00239 //     Function: EggVertex::modify_uv_obj
00240 //       Access: Published
00241 //  Description: Returns a modifiable pointer to the named EggVertexUV
00242 //               object, which defines both the UV coordinate pair for
00243 //               this name and the UV morphs.  Returns NULL if there
00244 //               is no such named UV object.
00245 ////////////////////////////////////////////////////////////////////
00246 EggVertexUV *EggVertex::
00247 modify_uv_obj(const string &name) {
00248   UVMap::iterator ui = _uv_map.find(EggVertexUV::filter_name(name));
00249   if (ui != _uv_map.end()) {
00250     if ((*ui).second->get_ref_count() != 1) {
00251       // Copy on write.
00252       (*ui).second = new EggVertexUV(*(*ui).second);
00253     }
00254     return (*ui).second;
00255   }
00256 
00257   return NULL;
00258 }
00259 
00260 ////////////////////////////////////////////////////////////////////
00261 //     Function: EggVertex::set_uv_obj
00262 //       Access: Published
00263 //  Description: Sets the indicated EggVertexUV on the vertex.
00264 //               This replaces any UV coordinate pair with the same
00265 //               name already on the vertex, including UV morphs.
00266 ////////////////////////////////////////////////////////////////////
00267 void EggVertex::
00268 set_uv_obj(EggVertexUV *uv) {
00269   _uv_map[uv->get_name()] = uv;
00270 }
00271 
00272 ////////////////////////////////////////////////////////////////////
00273 //     Function: EggVertex::clear_uv
00274 //       Access: Published
00275 //  Description: Removes the named UV coordinate pair from the vertex,
00276 //               along with any UV morphs.
00277 ///////////////////////////////////////////////////////////////////
00278 void EggVertex::
00279 clear_uv(const string &name) {
00280   _uv_map.erase(EggVertexUV::filter_name(name));
00281 }
00282 
00283 
00284 ///////////////////////////////////////////////////////////////////
00285 //       Class : GroupRefEntry
00286 // Description : A temporary class used in EggVertex::write(), below,
00287 //               to hold the groups that reference each vertex prior
00288 //               to outputting them as a formatted list.
00289 ////////////////////////////////////////////////////////////////////
00290 class GroupRefEntry {
00291 public:
00292   GroupRefEntry(EggGroup *group, double membership)
00293     : _group(group), _membership(membership) { }
00294 
00295   bool operator < (const GroupRefEntry &other) const {
00296     return _group->get_name() < other._group->get_name();
00297   }
00298   void output(ostream &out) const {
00299     out << _group->get_name() << ":" << _membership;
00300   }
00301 
00302   EggGroup *_group;
00303   double _membership;
00304 };
00305 
00306 INLINE ostream &operator << (ostream &out, const GroupRefEntry &gre) {
00307   gre.output(out);
00308   return out;
00309 }
00310 
00311 ////////////////////////////////////////////////////////////////////
00312 //     Function: EggVertex::write
00313 //       Access: Published
00314 //  Description: Writes the vertex to the indicated output stream in
00315 //               Egg format.
00316 ////////////////////////////////////////////////////////////////////
00317 void EggVertex::
00318 write(ostream &out, int indent_level) const {
00319   test_pref_integrity();
00320   test_gref_integrity();
00321 
00322   indent(out, indent_level)
00323     << "<Vertex> " << _index << " {\n";
00324 
00325   // Now output the position.  This might have any number of
00326   // dimensions up to 4.
00327   indent(out, indent_level+1);
00328   for (int i = 0; i < _num_dimensions; i++) {
00329     out << " " << _pos[i];
00330   }
00331   out << "\n";
00332 
00333   UVMap::const_iterator ui;
00334   for (ui = _uv_map.begin(); ui != _uv_map.end(); ++ui) {
00335     (*ui).second->write(out, indent_level + 2);
00336   }
00337 
00338   EggAttributes::write(out, indent_level+2);
00339 
00340   _dxyzs.write(out, indent_level + 2, "<Dxyz>", 3);
00341 
00342   // If the vertex is referenced by one or more groups, write that as
00343   // a helpful comment.
00344   if (!_gref.empty()) {
00345     // We need to build a list of group entries.
00346     pset<GroupRefEntry> gre;
00347 
00348     GroupRef::const_iterator gi;
00349     for (gi = _gref.begin(); gi != _gref.end(); ++gi) {
00350       gre.insert(GroupRefEntry(*gi, (*gi)->get_vertex_membership(this)));
00351     }
00352 
00353     // Now output the list.
00354     write_long_list(out, indent_level + 2, gre.begin(), gre.end(), "// ",
00355                     "", 72);
00356   }
00357 
00358   indent(out, indent_level)
00359     << "}\n";
00360 }
00361 
00362 
00363 ////////////////////////////////////////////////////////////////////
00364 //     Function: EggVertex::compare_to
00365 //       Access: Published
00366 //  Description: An ordering operator to compare two vertices for
00367 //               sorting order.  This imposes an arbitrary ordering
00368 //               useful to identify unique vertices.
00369 //
00370 //               Group membership is not considered in this
00371 //               comparison.  This is somewhat problematic, but cannot
00372 //               easily be helped, because considering group
00373 //               membership would make it difficult to add and remove
00374 //               groups from vertices.  It also makes it impossible to
00375 //               meaningfully compare with a concrete EggVertex object
00376 //               (which cannot have group memberships).
00377 //
00378 //               However, this is not altogether bad, because two
00379 //               vertices that are identical in all other properties
00380 //               should generally also be identical in group
00381 //               memberships, else the vertices will tend to fly apart
00382 //               when the joints animate.
00383 ////////////////////////////////////////////////////////////////////
00384 int EggVertex::
00385 compare_to(const EggVertex &other) const {
00386   if (_external_index != other._external_index) {
00387     return (int)_external_index - (int)other._external_index;
00388   }
00389   if (_num_dimensions != other._num_dimensions) {
00390     return (int)_num_dimensions - (int)other._num_dimensions;
00391   }
00392 
00393   int compare =
00394     _pos.compare_to(other._pos, egg_parameters->_pos_threshold);
00395   if (compare != 0) {
00396     return compare;
00397   }
00398   compare = _dxyzs.compare_to(other._dxyzs, egg_parameters->_pos_threshold);
00399   if (compare != 0) {
00400     return compare;
00401   }
00402 
00403   // Merge-compare the uv maps.
00404   UVMap::const_iterator ai, bi;
00405   ai = _uv_map.begin();
00406   bi = other._uv_map.begin();
00407   while (ai != _uv_map.end() && bi != other._uv_map.end()) {
00408     if ((*ai).first < (*bi).first) {
00409       return -1;
00410 
00411     } else if ((*bi).first < (*ai).first) {
00412       return 1;
00413 
00414     } else {
00415       int compare = (*ai).second->compare_to(*(*bi).second);
00416       if (compare != 0) {
00417         return compare;
00418       }
00419     }
00420     ++ai;
00421     ++bi;
00422   }
00423   if (bi != other._uv_map.end()) {
00424     return -1;
00425   }
00426   if (ai != _uv_map.end()) {
00427     return 1;
00428   }
00429 
00430   return EggAttributes::compare_to(other);
00431 }
00432 
00433 ////////////////////////////////////////////////////////////////////
00434 //     Function: EggVertex::get_num_local_coord
00435 //       Access: Published
00436 //  Description: Returns the number of primitives that own this vertex
00437 //               whose vertices are interpreted to be in a local
00438 //               coordinate system.
00439 ////////////////////////////////////////////////////////////////////
00440 int EggVertex::
00441 get_num_local_coord() const {
00442   test_pref_integrity();
00443 
00444   PrimitiveRef::const_iterator pri;
00445 
00446   int count = 0;
00447   for (pri = pref_begin(); pri != pref_end(); ++pri) {
00448     EggPrimitive *prim = *pri;
00449     count += (prim->is_local_coord() ? 1 : 0);
00450   }
00451   return count;
00452 }
00453 
00454 ////////////////////////////////////////////////////////////////////
00455 //     Function: EggVertex::get_num_global_coord
00456 //       Access: Published
00457 //  Description: Returns the number of primitives that own this vertex
00458 //               whose vertices are interpreted in the global
00459 //               coordinate system.
00460 ////////////////////////////////////////////////////////////////////
00461 int EggVertex::
00462 get_num_global_coord() const {
00463   test_pref_integrity();
00464 
00465   PrimitiveRef::const_iterator pri;
00466 
00467   int count = 0;
00468   for (pri = pref_begin(); pri != pref_end(); ++pri) {
00469     EggPrimitive *prim = *pri;
00470     count += (prim->is_local_coord() ? 0 : 1);
00471   }
00472   return count;
00473 }
00474 
00475 
00476 ////////////////////////////////////////////////////////////////////
00477 //     Function: EggVertex::transform
00478 //       Access: Published, Virtual
00479 //  Description: Applies the indicated transformation matrix to the
00480 //               vertex.
00481 ////////////////////////////////////////////////////////////////////
00482 void EggVertex::
00483 transform(const LMatrix4d &mat) {
00484   _pos = _pos * mat;
00485 
00486   EggMorphVertexList::iterator mi;
00487   for (mi = _dxyzs.begin(); mi != _dxyzs.end(); ++mi) {
00488     // We can safely cast the morph object to a non-const, because
00489     // we're not changing its name, which is the only thing the set
00490     // cares about preserving.
00491     EggMorphVertex &morph = (EggMorphVertex &)(*mi);
00492 
00493     morph.set_offset((*mi).get_offset() * mat);
00494   }
00495 
00496   UVMap::iterator ui;
00497   for (ui = _uv_map.begin(); ui != _uv_map.end(); ++ui) {
00498     (*ui).second->transform(mat);
00499   }
00500 
00501   EggAttributes::transform(mat);
00502 }
00503 
00504 
00505 ////////////////////////////////////////////////////////////////////
00506 //     Function: EggVertex::gref_begin
00507 //       Access: Public
00508 //  Description: Returns an iterator that can, in conjunction with
00509 //               gref_end(), be used to traverse the entire set of
00510 //               groups that reference this vertex.  Each iterator
00511 //               returns a pointer to a group.
00512 //
00513 //               This interface is not safe to use outside of
00514 //               PANDAEGG.DLL.
00515 ////////////////////////////////////////////////////////////////////
00516 EggVertex::GroupRef::const_iterator EggVertex::
00517 gref_begin() const {
00518   return _gref.begin();
00519 }
00520 
00521 ////////////////////////////////////////////////////////////////////
00522 //     Function: EggVertex::gref_end
00523 //       Access: Public
00524 //  Description: Returns an iterator that can, in conjunction with
00525 //               gref_begin(), be used to traverse the entire set of
00526 //               groups that reference this vertex.  Each iterator
00527 //               returns a pointer to a group.
00528 //
00529 //               This interface is not safe to use outside of
00530 //               PANDAEGG.DLL.
00531 ////////////////////////////////////////////////////////////////////
00532 EggVertex::GroupRef::const_iterator EggVertex::
00533 gref_end() const {
00534   return _gref.end();
00535 }
00536 
00537 ////////////////////////////////////////////////////////////////////
00538 //     Function: EggVertex::gref_size
00539 //       Access: Public
00540 //  Description: Returns the number of elements between gref_begin()
00541 //               and gref_end().
00542 //
00543 //               This interface is not safe to use outside of
00544 //               PANDAEGG.DLL.
00545 ////////////////////////////////////////////////////////////////////
00546 EggVertex::GroupRef::size_type EggVertex::
00547 gref_size() const {
00548   return _gref.size();
00549 }
00550 
00551 ////////////////////////////////////////////////////////////////////
00552 //     Function: EggVertex::has_gref
00553 //       Access: Published
00554 //  Description: Returns true if the indicated group references this
00555 //               vertex, false otherwise.
00556 ////////////////////////////////////////////////////////////////////
00557 bool EggVertex::
00558 has_gref(const EggGroup *group) const {
00559   return _gref.count((EggGroup *)group) != 0;
00560 }
00561 
00562 ////////////////////////////////////////////////////////////////////
00563 //     Function: EggVertex::copy_grefs_from
00564 //       Access: Published
00565 //  Description: Copies all the group references from the other vertex
00566 //               onto this one.  This assigns the current vertex to
00567 //               exactly the same groups, with exactly the same
00568 //               memberships, as the given one.
00569 //
00570 //               Warning: only an EggVertex allocated from the free
00571 //               store may have groups assigned to it.  Do not attempt
00572 //               to call this on a temporary concrete EggVertex
00573 //               object; a core dump will certainly result.
00574 ////////////////////////////////////////////////////////////////////
00575 void EggVertex::
00576 copy_grefs_from(const EggVertex &other) {
00577   if (&other == this) {
00578     return;
00579   }
00580   test_gref_integrity();
00581   other.test_gref_integrity();
00582 
00583   clear_grefs();
00584   test_gref_integrity();
00585 
00586   GroupRef::const_iterator gri;
00587 
00588   for (gri = other.gref_begin(); gri != other.gref_end(); ++gri) {
00589     EggGroup *group = *gri;
00590     nassertv(group != NULL);
00591 
00592     group->ref_vertex(this, group->get_vertex_membership(&other));
00593   }
00594 }
00595 
00596 ////////////////////////////////////////////////////////////////////
00597 //     Function: EggVertex::clear_grefs
00598 //       Access: Published
00599 //  Description: Removes all group references from the vertex, so that
00600 //               it is not assigned to any group.
00601 ////////////////////////////////////////////////////////////////////
00602 void EggVertex::
00603 clear_grefs() {
00604   GroupRef gref_copy = _gref;
00605   GroupRef::const_iterator gri;
00606   for (gri = gref_copy.begin(); gri != gref_copy.end(); ++gri) {
00607     EggGroup *group = *gri;
00608     nassertv(group != NULL);
00609     group->unref_vertex(this);
00610   }
00611 
00612   // Now we should have no more refs.
00613   nassertv(_gref.empty());
00614 }
00615 
00616 ////////////////////////////////////////////////////////////////////
00617 //     Function: EggVertex::pref_begin
00618 //       Access: Public
00619 //  Description: Returns an iterator that can, in conjunction with
00620 //               pref_end(), be used to traverse the entire set of
00621 //               primitives that reference this vertex.  Each iterator
00622 //               returns a pointer to a primitive.
00623 //
00624 //               This interface is not safe to use outside of
00625 //               PANDAEGG.DLL.
00626 ////////////////////////////////////////////////////////////////////
00627 EggVertex::PrimitiveRef::const_iterator EggVertex::
00628 pref_begin() const {
00629   return _pref.begin();
00630 }
00631 
00632 ////////////////////////////////////////////////////////////////////
00633 //     Function: EggVertex::pref_end
00634 //       Access: Public
00635 //  Description: Returns an iterator that can, in conjunction with
00636 //               pref_begin(), be used to traverse the entire set of
00637 //               primitives that reference this vertex.  Each iterator
00638 //               returns a pointer to a primitive.
00639 //
00640 //               This interface is not safe to use outside of
00641 //               PANDAEGG.DLL.
00642 ////////////////////////////////////////////////////////////////////
00643 EggVertex::PrimitiveRef::const_iterator EggVertex::
00644 pref_end() const {
00645   return _pref.end();
00646 }
00647 
00648 ////////////////////////////////////////////////////////////////////
00649 //     Function: EggVertex::pref_size
00650 //       Access: Public
00651 //  Description: Returns the number of elements between pref_begin()
00652 //               and pref_end().
00653 //
00654 //               This interface is not safe to use outside of
00655 //               PANDAEGG.DLL.
00656 ////////////////////////////////////////////////////////////////////
00657 EggVertex::GroupRef::size_type EggVertex::
00658 pref_size() const {
00659   return _pref.size();
00660 }
00661 
00662 ////////////////////////////////////////////////////////////////////
00663 //     Function: EggVertex::has_pref
00664 //       Access: Published
00665 //  Description: Returns the number of times the vertex appears in the
00666 //               indicated primitive, or 0 if it does not appear.
00667 ////////////////////////////////////////////////////////////////////
00668 int EggVertex::
00669 has_pref(const EggPrimitive *prim) const {
00670   return _pref.count((EggPrimitive *)prim);
00671 }
00672 
00673 #ifndef NDEBUG
00674 
00675 ////////////////////////////////////////////////////////////////////
00676 //     Function: EggVertex::test_gref_integrity
00677 //       Access: Published
00678 //  Description: Verifies that the gref list is correct and that all
00679 //               the groups included actually exist and do reference
00680 //               the vertex.
00681 ////////////////////////////////////////////////////////////////////
00682 void EggVertex::
00683 test_gref_integrity() const {
00684   test_ref_count_integrity();
00685 
00686   GroupRef::const_iterator gri;
00687 
00688   for (gri = gref_begin(); gri != gref_end(); ++gri) {
00689     EggGroup *group = *gri;
00690     nassertv(group != NULL);
00691     group->test_ref_count_integrity();
00692 
00693     double membership = group->get_vertex_membership(this);
00694     nassertv(membership != 0.0);
00695   }
00696 }
00697 
00698 ////////////////////////////////////////////////////////////////////
00699 //     Function: EggVertex::test_pref_integrity
00700 //       Access: Published
00701 //  Description: Verifies that the pref list is correct and that all
00702 //               the primitives included actually exist and do
00703 //               reference the vertex.
00704 ////////////////////////////////////////////////////////////////////
00705 void EggVertex::
00706 test_pref_integrity() const {
00707   test_ref_count_integrity();
00708 
00709   PrimitiveRef::const_iterator pri;
00710 
00711   for (pri = pref_begin(); pri != pref_end(); ++pri) {
00712     EggPrimitive *prim = *pri;
00713     nassertv(prim != NULL);
00714     prim->test_ref_count_integrity();
00715 
00716     EggPrimitive::iterator vi;
00717     vi = find(prim->begin(), prim->end(), this);
00718     nassertv(vi != prim->end());
00719   }
00720 }
00721 
00722 #endif  // NDEBUG
00723 
00724 ////////////////////////////////////////////////////////////////////
00725 //     Function: EggVertex::output
00726 //       Access: Published
00727 //  Description:
00728 ////////////////////////////////////////////////////////////////////
00729 void EggVertex::
00730 output(ostream &out) const {
00731   if (get_pool() == NULL) {
00732     out << "(null):" << get_index();
00733   } else {
00734     out << get_pool()->get_name() << ":" << get_index();
00735   }
00736 }
 All Classes Functions Variables Enumerations