Panda3D
|
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 ©) 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 ©) { 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 }