UniqueVerticesTriangles.h 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  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 <algorithm>
  9. #include <map>
  10. #include <vector>
  11. // The VertexType must have an operator< member because it is used as the
  12. // key in a std::map<VertexType,int>. For example, if VertexType is
  13. // Vector3<float>, the comparison operator already exist. Another example is
  14. // that you have a vertex type used for vertex coloring, say,
  15. // struct VertexType
  16. // {
  17. // Vector3<float> position;
  18. // Vector4<float> color;
  19. // bool operator< (VertexType const& v) const
  20. // {
  21. // return position < v.position;
  22. // }
  23. // }
  24. // The comparision will guarantee unique vertex positions, although if you
  25. // have two VertexType objects with the same position but different colors,
  26. // there is no guarantee which color will occur in the final result.
  27. namespace WwiseGTE
  28. {
  29. template <typename VertexType>
  30. class UniqueVerticesTriangles
  31. {
  32. public:
  33. // Triangle soup. The input vertex array consists of triples of
  34. // vertices, each triple representing a triangle. The array
  35. // 'inVertices' must have a multiple of 3 elements. An array
  36. // 'outVertices' of unique vertices and an array 'outIndices' of
  37. // 'inVertices.size()/3' unique index triples are computed. The
  38. // indices are relative to the array of unique vertices and each
  39. // index triple represents a triangle.
  40. UniqueVerticesTriangles(
  41. std::vector<VertexType> const& inVertices,
  42. std::vector<VertexType>& outVertices,
  43. std::vector<int>& outIndices)
  44. {
  45. ConstructUniqueVertices(inVertices, outVertices);
  46. // The input index array is implicitly
  47. // {<0,1,2>,<3,4,5>,...,<n-3,n-2,n-1>}
  48. // where n is the number of vertices. The output index array is
  49. // the same as the mapping array.
  50. outIndices.resize(inVertices.size());
  51. std::copy(mInToOutMapping.begin(), mInToOutMapping.end(),
  52. outIndices.begin());
  53. }
  54. // Indexed triangles. The input vertex array consists of all vertices
  55. // referenced by the input index array. The array 'inIndices' must
  56. // have a multiple of 3 elements. An array 'outVertices' of unique
  57. // vertices and an array 'outIndices' of 'indices.size()/3' unique
  58. // index triples are computed. The indices are relative to the array
  59. // of unique vertices and each index triple represents a triangle.
  60. UniqueVerticesTriangles(
  61. std::vector<VertexType> const& inVertices,
  62. std::vector<int> const& inIndices,
  63. std::vector<VertexType>& outVertices,
  64. std::vector<int>& outIndices)
  65. {
  66. ConstructUniqueVertices(inVertices, outVertices);
  67. // The input index array needs it indices mapped to the unique
  68. // vertex indices.
  69. outIndices.resize(inIndices.size());
  70. for (size_t i = 0; i < inIndices.size(); ++i)
  71. {
  72. outIndices[i] = mInToOutMapping[inIndices[i]];
  73. }
  74. }
  75. // The input vertices have indices 0 <= i < VInNum. The output
  76. // vertices have indices 0 <= j < VOutNum. The construction leads to
  77. // a mapping of input indices i to output indices j. Duplicate
  78. // vertices have different input indices but the same output index.
  79. // The following function gives you access to the mapping. If the
  80. // input index is invalid (i < 0 or i >= VINum), the return value
  81. // is -1.
  82. inline int GetOutputIndexFor(int index) const
  83. {
  84. return mInToOutMapping[index];
  85. }
  86. private:
  87. void ConstructUniqueVertices(std::vector<VertexType> const& inVertices,
  88. std::vector<VertexType>& outVertices)
  89. {
  90. // Construct the unique vertices.
  91. mNumInVertices = (int)inVertices.size();
  92. mInToOutMapping.resize(mNumInVertices);
  93. std::map<VertexType, int> table;
  94. mNumOutVertices = 0;
  95. for (int i = 0; i < mNumInVertices; ++i)
  96. {
  97. auto const iter = table.find(inVertices[i]);
  98. if (iter != table.end())
  99. {
  100. // Vertex i is a duplicate of one inserted earlier into
  101. // the table. Map vertex i to the first-found copy.
  102. mInToOutMapping[i] = iter->second;
  103. }
  104. else
  105. {
  106. // Vertex i is the first occurrence of such a point.
  107. table.insert(std::make_pair(inVertices[i], mNumOutVertices));
  108. mInToOutMapping[i] = mNumOutVertices;
  109. ++mNumOutVertices;
  110. }
  111. }
  112. // Pack the unique vertices into an array in the correct order.
  113. outVertices.resize(mNumOutVertices);
  114. for (auto const& element : table)
  115. {
  116. outVertices[element.second] = element.first;
  117. }
  118. }
  119. int mNumInVertices, mNumOutVertices;
  120. std::vector<int> mInToOutMapping;
  121. };
  122. }