VETManifoldMesh.h 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  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/ETManifoldMesh.h>
  9. // The VETManifoldMesh class represents an edge-triangle manifold mesh
  10. // but additionally stores vertex adjacency information.
  11. namespace WwiseGTE
  12. {
  13. class VETManifoldMesh : public ETManifoldMesh
  14. {
  15. public:
  16. // Vertex data types.
  17. class Vertex;
  18. typedef std::shared_ptr<Vertex>(*VCreator)(int);
  19. typedef std::map<int, std::shared_ptr<Vertex>> VMap;
  20. // Vertex object.
  21. class Vertex
  22. {
  23. public:
  24. virtual ~Vertex() = default;
  25. Vertex(int vIndex)
  26. :
  27. V(vIndex)
  28. {
  29. }
  30. // The index into the vertex pool of the mesh.
  31. int V;
  32. // Adjacent objects.
  33. std::set<int> VAdjacent;
  34. std::set<std::shared_ptr<Edge>> EAdjacent;
  35. std::set<std::shared_ptr<Triangle>> TAdjacent;
  36. };
  37. // Construction and destruction.
  38. virtual ~VETManifoldMesh() = default;
  39. VETManifoldMesh(VCreator vCreator = nullptr, ECreator eCreator = nullptr, TCreator tCreator = nullptr)
  40. :
  41. ETManifoldMesh(eCreator, tCreator),
  42. mVCreator(vCreator ? vCreator : CreateVertex)
  43. {
  44. }
  45. // Support for a deep copy of the mesh. The mVMap, mEMap, and mTMap
  46. // objects have dynamically allocated memory for vertices, edges, and
  47. // triangles. A shallow copy of the pointers to this memory is
  48. // problematic. Allowing sharing, say, via std::shared_ptr, is an
  49. // option but not really the intent of copying the mesh graph.
  50. VETManifoldMesh(VETManifoldMesh const& mesh)
  51. {
  52. *this = mesh;
  53. }
  54. VETManifoldMesh& operator=(VETManifoldMesh const& mesh)
  55. {
  56. Clear();
  57. mVCreator = mesh.mVCreator;
  58. ETManifoldMesh::operator=(mesh);
  59. return *this;
  60. }
  61. // Member access.
  62. inline VMap const& GetVertices() const
  63. {
  64. return mVMap;
  65. }
  66. // If <v0,v1,v2> is not in the mesh, a Triangle object is created and
  67. // returned; otherwise, <v0,v1,v2> is in the mesh and nullptr is
  68. // returned. If the insertion leads to a nonmanifold mesh, the call
  69. // fails with a nullptr returned.
  70. virtual std::shared_ptr<Triangle> Insert(int v0, int v1, int v2) override
  71. {
  72. std::shared_ptr<Triangle> tri = ETManifoldMesh::Insert(v0, v1, v2);
  73. if (!tri)
  74. {
  75. return nullptr;
  76. }
  77. for (int i = 0; i < 3; ++i)
  78. {
  79. int vIndex = tri->V[i];
  80. auto vItem = mVMap.find(vIndex);
  81. std::shared_ptr<Vertex> vertex;
  82. if (vItem == mVMap.end())
  83. {
  84. vertex = mVCreator(vIndex);
  85. mVMap[vIndex] = vertex;
  86. }
  87. else
  88. {
  89. vertex = vItem->second;
  90. }
  91. vertex->TAdjacent.insert(tri);
  92. for (int j = 0; j < 3; ++j)
  93. {
  94. auto edge = tri->E[j].lock();
  95. LogAssert(edge != nullptr, "Malformed mesh.");
  96. if (edge->V[0] == vIndex)
  97. {
  98. vertex->VAdjacent.insert(edge->V[1]);
  99. vertex->EAdjacent.insert(edge);
  100. }
  101. else if (edge->V[1] == vIndex)
  102. {
  103. vertex->VAdjacent.insert(edge->V[0]);
  104. vertex->EAdjacent.insert(edge);
  105. }
  106. }
  107. }
  108. return tri;
  109. }
  110. // If <v0,v1,v2> is in the mesh, it is removed and 'true' is returned;
  111. // otherwise, <v0,v1,v2> is not in the mesh and 'false' is returned.
  112. virtual bool Remove(int v0, int v1, int v2) override
  113. {
  114. auto tItem = mTMap.find(TriangleKey<true>(v0, v1, v2));
  115. if (tItem == mTMap.end())
  116. {
  117. return false;
  118. }
  119. std::shared_ptr<Triangle> tri = tItem->second;
  120. for (int i = 0; i < 3; ++i)
  121. {
  122. int vIndex = tri->V[i];
  123. auto vItem = mVMap.find(vIndex);
  124. LogAssert(vItem != mVMap.end(), "Malformed mesh.");
  125. std::shared_ptr<Vertex> vertex = vItem->second;
  126. for (int j = 0; j < 3; ++j)
  127. {
  128. auto edge = tri->E[j].lock();
  129. LogAssert(edge != nullptr, "Malformed mesh.");
  130. if (edge->T[0].lock() && !edge->T[1].lock())
  131. {
  132. if (edge->V[0] == vIndex)
  133. {
  134. vertex->VAdjacent.erase(edge->V[1]);
  135. vertex->EAdjacent.erase(edge);
  136. }
  137. else if (edge->V[1] == vIndex)
  138. {
  139. vertex->VAdjacent.erase(edge->V[0]);
  140. vertex->EAdjacent.erase(edge);
  141. }
  142. }
  143. }
  144. vertex->TAdjacent.erase(tri);
  145. if (vertex->TAdjacent.size() == 0)
  146. {
  147. LogAssert(vertex->VAdjacent.size() == 0 && vertex->EAdjacent.size() == 0,
  148. "Malformed mesh: Inconsistent vertex adjacency information.");
  149. mVMap.erase(vItem);
  150. }
  151. }
  152. return ETManifoldMesh::Remove(v0, v1, v2);
  153. }
  154. // Destroy the vertices, edges, and triangles to obtain an empty mesh.
  155. virtual void Clear() override
  156. {
  157. mVMap.clear();
  158. ETManifoldMesh::Clear();
  159. }
  160. protected:
  161. // The vertex data and default vertex creation.
  162. static std::shared_ptr<Vertex> CreateVertex(int vIndex)
  163. {
  164. return std::make_shared<Vertex>(vIndex);
  165. }
  166. VCreator mVCreator;
  167. VMap mVMap;
  168. };
  169. }