23 # if defined(__GNUC__) && (__GNUC__ >= 3)
26 # include <hash_map.h>
38 #include "../system/TimeUtils.h"
46 void GeomCleaner::SortIndexedVertexArray(
const float *iVertices,
48 const unsigned *iIndices,
54 list<IndexedVertex> indexedVertices;
56 for (i = 0; i < iVSize; i += 3) {
57 indexedVertices.emplace_back(
Vec3f(iVertices[i], iVertices[i + 1], iVertices[i + 2]), i / 3);
61 indexedVertices.sort();
64 unsigned *mapIndices =
new unsigned[iVSize / 3];
65 *oVertices =
new float[iVSize];
66 list<IndexedVertex>::iterator iv;
67 unsigned newIndex = 0;
69 for (iv = indexedVertices.begin(); iv != indexedVertices.end(); iv++) {
71 (*oVertices)[vIndex] = iv->x();
72 (*oVertices)[vIndex + 1] = iv->y();
73 (*oVertices)[vIndex + 2] = iv->z();
75 mapIndices[iv->index()] = newIndex;
81 *oIndices =
new unsigned[iISize];
82 for (i = 0; i < iISize; i++) {
83 (*oIndices)[i] = 3 * mapIndices[iIndices[i] / 3];
89 void GeomCleaner::CompressIndexedVertexArray(
const float *iVertices,
91 const unsigned *iIndices,
98 vector<Vec3f> vertices;
100 for (i = 0; i < iVSize; i += 3) {
101 vertices.emplace_back(iVertices[i], iVertices[i + 1], iVertices[i + 2]);
104 unsigned *mapVertex =
new unsigned[iVSize];
105 vector<Vec3f>::iterator
v = vertices.begin();
107 vector<Vec3f> compressedVertices;
110 compressedVertices.push_back(vertices.front());
115 for (;
v != vertices.end();
v++) {
117 if (current == previous) {
118 mapVertex[i] = compressedVertices.size() - 1;
121 compressedVertices.push_back(current);
122 mapVertex[i] = compressedVertices.size() - 1;
129 *oVSize = 3 * compressedVertices.size();
130 *oVertices =
new float[*oVSize];
132 for (
v = compressedVertices.begin();
v != compressedVertices.end();
v++) {
133 (*oVertices)[i] = (*v)[0];
134 (*oVertices)[i + 1] = (*v)[1];
135 (*oVertices)[i + 2] = (*v)[2];
140 *oIndices =
new unsigned[iISize];
141 for (i = 0; i < iISize; i++) {
142 (*oIndices)[i] = 3 * mapVertex[iIndices[i] / 3];
148 void GeomCleaner::SortAndCompressIndexedVertexArray(
const float *iVertices,
150 const unsigned *iIndices,
158 unsigned *tmpIndices;
163 GeomCleaner::SortIndexedVertexArray(
164 iVertices, iVSize, iIndices, iISize, &tmpVertices, &tmpIndices);
166 printf(
"Sorting: %lf sec.\n", chrono.
stop());
171 GeomCleaner::CompressIndexedVertexArray(
172 tmpVertices, iVSize, tmpIndices, iISize, oVertices, oVSize, oIndices);
175 printf(
"Merging: %lf sec.\n", duration);
179 delete[] tmpVertices;
185 #define _MUL 950706376UL
186 #define _MOD 2147483647UL
189 size_t res = ((
unsigned long)(p[0] *
_MUL)) %
_MOD;
190 res = ((res + (
unsigned long)(p[1]) *
_MUL)) %
_MOD;
191 return ((res + (
unsigned long)(p[2]) *
_MUL)) %
_MOD;
197 void GeomCleaner::CleanIndexedVertexArray(
const float *iVertices,
199 const unsigned *iIndices,
205 using cleanHashTable = map<Vec3f, unsigned>;
206 vector<Vec3f> vertices;
208 for (i = 0; i < iVSize; i += 3) {
209 vertices.emplace_back(iVertices[i], iVertices[i + 1], iVertices[i + 2]);
213 vector<unsigned> newIndices;
214 vector<Vec3f> newVertices;
217 unsigned currentIndex = 0;
218 vector<Vec3f>::const_iterator
v = vertices.begin();
219 vector<Vec3f>::const_iterator end = vertices.end();
220 cleanHashTable::const_iterator found;
221 for (;
v != end;
v++) {
223 if (found != ht.end()) {
225 newIndices.push_back((*found).second);
228 newVertices.push_back(*
v);
229 newIndices.push_back(currentIndex);
230 ht[*
v] = currentIndex;
236 *oVSize = 3 * newVertices.size();
237 *oVertices =
new float[*oVSize];
239 end = newVertices.end();
240 for (
v = newVertices.begin();
v != end;
v++) {
241 (*oVertices)[currentIndex++] = (*v)[0];
242 (*oVertices)[currentIndex++] = (*v)[1];
243 (*oVertices)[currentIndex++] = (*v)[2];
247 *oIndices =
new unsigned[iISize];
248 for (i = 0; i < iISize; i++) {
249 (*oIndices)[i] = 3 * newIndices[iIndices[i] / 3];
Class to define a cleaner of geometry providing a set of useful tools.
ATTR_WARN_UNUSED_RESULT const BMVert * v
size_t operator()(const Vec3r &p) const