VETNonmanifoldMesh.h 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. // David Eberly, Geometric Tools, Redmond WA 98052
  2. // Copyright (c) 1998-2020
  3. // Distributed under the Boost Software License, Version 1.0.
  4. // https://www.boost.org/LICENSE_1_0.txt
  5. // https://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
  6. // Version: 4.0.2019.08.13
  7. #pragma once
  8. #include <Mathematics/SharedPtrCompare.h>
  9. #include <Mathematics/ETNonmanifoldMesh.h>
  10. // The VETNonmanifoldMesh class represents an edge-triangle nonmanifold mesh
  11. // but additionally stores vertex adjacency information.
  12. namespace WwiseGTE
  13. {
  14. class VETNonmanifoldMesh : public ETNonmanifoldMesh
  15. {
  16. public:
  17. // Vertex data types.
  18. class Vertex;
  19. typedef std::shared_ptr<Vertex>(*VCreator)(int);
  20. typedef std::map<int, std::shared_ptr<Vertex>> VMap;
  21. // Vertex object.
  22. class Vertex
  23. {
  24. public:
  25. virtual ~Vertex() = default;
  26. Vertex(int vIndex)
  27. :
  28. V(vIndex)
  29. {
  30. }
  31. // The index into the vertex pool of the mesh.
  32. int V;
  33. bool operator<(Vertex const& other) const
  34. {
  35. return V < other.V;
  36. }
  37. // Adjacent objects.
  38. std::set<int> VAdjacent;
  39. std::set<std::shared_ptr<Edge>, SharedPtrLT<Edge>> EAdjacent;
  40. std::set<std::shared_ptr<Triangle>, SharedPtrLT<Triangle>> TAdjacent;
  41. };
  42. // Construction and destruction.
  43. virtual ~VETNonmanifoldMesh() = default;
  44. VETNonmanifoldMesh(VCreator vCreator = nullptr, ECreator eCreator = nullptr, TCreator tCreator = nullptr)
  45. :
  46. ETNonmanifoldMesh(eCreator, tCreator),
  47. mVCreator(vCreator ? vCreator : CreateVertex)
  48. {
  49. }
  50. // Support for a deep copy of the mesh. The mVMap, mEMap, and mTMap
  51. // objects have dynamically allocated memory for vertices, edges, and
  52. // triangles. A shallow copy of the pointers to this memory is
  53. // problematic. Allowing sharing, say, via std::shared_ptr, is an
  54. // option but not really the intent of copying the mesh graph.
  55. VETNonmanifoldMesh(VETNonmanifoldMesh const& mesh)
  56. {
  57. *this = mesh;
  58. }
  59. VETNonmanifoldMesh& operator=(VETNonmanifoldMesh const& mesh)
  60. {
  61. Clear();
  62. mVCreator = mesh.mVCreator;
  63. ETNonmanifoldMesh::operator=(mesh);
  64. return *this;
  65. }
  66. // Member access.
  67. inline VMap const& GetVertices() const
  68. {
  69. return mVMap;
  70. }
  71. // If <v0,v1,v2> is not in the mesh, a Triangle object is created and
  72. // returned; otherwise, <v0,v1,v2> is in the mesh and nullptr is
  73. // returned.
  74. virtual std::shared_ptr<Triangle> Insert(int v0, int v1, int v2) override
  75. {
  76. std::shared_ptr<Triangle> tri = ETNonmanifoldMesh::Insert(v0, v1, v2);
  77. if (!tri)
  78. {
  79. return nullptr;
  80. }
  81. for (int i = 0; i < 3; ++i)
  82. {
  83. int vIndex = tri->V[i];
  84. auto vItem = mVMap.find(vIndex);
  85. std::shared_ptr<Vertex> vertex;
  86. if (vItem == mVMap.end())
  87. {
  88. vertex = mVCreator(vIndex);
  89. mVMap[vIndex] = vertex;
  90. }
  91. else
  92. {
  93. vertex = vItem->second;
  94. }
  95. vertex->TAdjacent.insert(tri);
  96. for (int j = 0; j < 3; ++j)
  97. {
  98. auto edge = tri->E[j].lock();
  99. LogAssert(edge != nullptr, "Unexpected condition.");
  100. if (edge->V[0] == vIndex)
  101. {
  102. vertex->VAdjacent.insert(edge->V[1]);
  103. vertex->EAdjacent.insert(edge);
  104. }
  105. else if (edge->V[1] == vIndex)
  106. {
  107. vertex->VAdjacent.insert(edge->V[0]);
  108. vertex->EAdjacent.insert(edge);
  109. }
  110. }
  111. }
  112. return tri;
  113. }
  114. // If <v0,v1,v2> is in the mesh, it is removed and 'true' is returned;
  115. // otherwise, <v0,v1,v2> is not in the mesh and 'false' is returned.
  116. virtual bool Remove(int v0, int v1, int v2) override
  117. {
  118. auto tItem = mTMap.find(TriangleKey<true>(v0, v1, v2));
  119. if (tItem == mTMap.end())
  120. {
  121. return false;
  122. }
  123. std::shared_ptr<Triangle> tri = tItem->second;
  124. for (int i = 0; i < 3; ++i)
  125. {
  126. int vIndex = tri->V[i];
  127. auto vItem = mVMap.find(vIndex);
  128. LogAssert(vItem != mVMap.end(), "Unexpected condition.");
  129. std::shared_ptr<Vertex> vertex = vItem->second;
  130. for (int j = 0; j < 3; ++j)
  131. {
  132. auto edge = tri->E[j].lock();
  133. LogAssert(edge != nullptr, "Unexpected condition.");
  134. // If the edge will be removed by
  135. // ETNonmanifoldMesh::Remove, remove the vertex
  136. // references to it.
  137. if (edge->T.size() == 1)
  138. {
  139. for (auto const& adjw : edge->T)
  140. {
  141. auto adj = adjw.lock();
  142. LogAssert(adj != nullptr, "Unexpected condition.");
  143. if (edge->V[0] == vIndex)
  144. {
  145. vertex->VAdjacent.erase(edge->V[1]);
  146. vertex->EAdjacent.erase(edge);
  147. }
  148. else if (edge->V[1] == vIndex)
  149. {
  150. vertex->VAdjacent.erase(edge->V[0]);
  151. vertex->EAdjacent.erase(edge);
  152. }
  153. }
  154. }
  155. }
  156. vertex->TAdjacent.erase(tri);
  157. // If the vertex is no longer shared by any triangle,
  158. // remove it.
  159. if (vertex->TAdjacent.size() == 0)
  160. {
  161. LogAssert(vertex->VAdjacent.size() != 0 || vertex->EAdjacent.size() != 0,
  162. "Malformed mesh.");
  163. mVMap.erase(vItem);
  164. }
  165. }
  166. return ETNonmanifoldMesh::Remove(v0, v1, v2);
  167. }
  168. // Destroy the vertices, edges, and triangles to obtain an empty mesh.
  169. virtual void Clear() override
  170. {
  171. mVMap.clear();
  172. ETNonmanifoldMesh::Clear();
  173. }
  174. protected:
  175. // The vertex data and default vertex creation.
  176. static std::shared_ptr<Vertex> CreateVertex(int vIndex)
  177. {
  178. return std::make_shared<Vertex>(vIndex);
  179. }
  180. VCreator mVCreator;
  181. VMap mVMap;
  182. };
  183. }