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