21 template <
typename Real>
27 int numIndices,
int const*
indices);
58 static std::shared_ptr<Vertex> Create(
int v);
126 template <
typename Real>
134 if (numPositions <= 0 || !positions || numIndices < 3 || !indices)
142 int numTriangles = numIndices / 3;
144 for (
int t = 0;
t < numTriangles; ++
t)
156 auto edge = eelement.second;
157 if (!edge->T[1].lock())
159 for (
int i = 0; i < 2; ++i)
161 auto velement = vmap.find(edge->V[i]);
162 auto vertex = std::static_pointer_cast<
VCVertex>(velement->second);
170 for (
auto const& velement : vmap)
172 auto vertex = std::static_pointer_cast<
VCVertex>(velement.second);
175 if (vertex->isBoundary)
177 weight = std::numeric_limits<Real>::max();
185 mHeapRecords.insert(std::make_pair(velement.first, record));
189 template <
typename Real>
192 record.
vertex = 0x80000000;
205 Real
weight = std::numeric_limits<Real>::max();
207 if (weight == std::numeric_limits<Real>::max())
214 auto velement = vmap.find(v);
215 if (velement == vmap.end())
221 auto vertex = std::static_pointer_cast<
VCVertex>(velement->second);
222 std::vector<TriangleKey<true>> removed, inserted;
223 std::vector<int> linkVertices;
232 result =
Collapsed(removed, inserted, linkVertices);
245 for (
auto vlink : linkVertices)
247 velement = vmap.find(vlink);
248 if (velement == vmap.end())
254 vertex = std::static_pointer_cast<
VCVertex>(velement->second);
255 if (!vertex->isBoundary)
270 record.
removed = std::move(removed);
271 record.
inserted = std::move(inserted);
296 template <
typename Real>
inline 302 template <
typename Real>
305 std::vector<int>& linkVertices)
const 314 int const numVertices =
static_cast<int>(vertex->TAdjacent.size());
315 removed.resize(numVertices);
317 std::map<int, int> edgeMap;
318 for (
auto tri : vertex->TAdjacent)
320 for (
int i = 0; i < 3; ++i)
322 if (tri->V[i] == vertex->V)
324 edgeMap.insert(std::make_pair(tri->V[(i + 1) % 3], tri->V[(i + 2) % 3]));
330 if (edgeMap.size() != vertex->TAdjacent.size())
337 linkVertices.resize(numVertices);
338 auto iter = edgeMap.begin();
339 for (
int i = 0; i < numVertices; ++i)
341 linkVertices[i] = iter->first;
342 iter = edgeMap.find(iter->second);
343 if (iter == edgeMap.end())
349 if (iter->first != linkVertices[0])
360 basis[0] = vertex->normal;
362 std::vector<Vector2<Real>> projected(numVertices);
363 std::vector<int>
indices(numVertices);
364 for (
int i = 0; i < numVertices; ++i)
367 projected[i][0] =
Dot(basis[1], diff);
368 projected[i][1] =
Dot(basis[2], diff);
373 Polygon2<Real> polygon(projected.data(), numVertices, indices.data(),
true);
374 if (polygon.IsSimple())
379 if (triangles.size() == 0)
385 int const numTriangles =
static_cast<int>(triangles.size());
386 inserted.resize(numTriangles);
387 for (
int t = 0;
t < numTriangles; ++
t)
390 linkVertices[triangles[
t][0]],
391 linkVertices[triangles[
t][1]],
392 linkVertices[triangles[
t][2]]);
402 template <
typename Real>
404 std::vector<
TriangleKey<true>>
const& inserted, std::vector<int>
const& linkVertices)
413 bool isCollapsible =
true;
415 std::set<EdgeKey<false>> edges;
416 for (
auto const& tri : inserted)
418 for (
int k0 = 2, k1 = 0; k1 < 3; k0 = k1++)
421 if (edges.find(edge) == edges.end())
430 auto eelement = emap.find(edge);
431 if (eelement != emap.end())
433 if (eelement->second->T[1].lock())
436 isCollapsible =
false;
453 for (
auto tri : removed)
459 for (
auto const& tri : inserted)
468 size_t const numVertices = linkVertices.size();
469 for (
size_t i0 = numVertices - 1, i1 = 0; i1 < numVertices; i0 = i1++)
472 auto eelement = emap.find(ekey);
473 if (eelement == emap.end())
479 auto edge = eelement->second;
486 if (edge->T[0].lock() && !edge->T[1].lock())
488 for (
int k = 0; k < 2; ++k)
490 auto velement = vmap.find(edge->V[k]);
491 if (velement == vmap.end())
497 auto vertex = std::static_pointer_cast<
VCVertex>(velement->second);
506 template <
typename Real>
515 template <
typename Real>
518 return std::make_shared<VCVertex>(
v);
521 template <
typename Real>
526 normal = { (Real)0, (Real)0, (Real)0 };
529 Vector3<Real> E0 = positions[tri->V[1]] - positions[tri->V[0]];
530 Vector3<Real> E1 = positions[tri->V[2]] - positions[tri->V[0]];
std::vector< TriangleKey< true > > inserted
Record * Insert(KeyType const &key, ValueType const &value)
EMap const & GetEdges() const
int GetNumElements() const
GLuint GLuint GLfloat weight
std::set< std::shared_ptr< Triangle > > TAdjacent
bool DoCollapse(Record &record)
void Update(Record *record, ValueType const &value)
void Reset(int maxElements)
std::set< int > VAdjacent
int Collapsed(std::vector< TriangleKey< true >> const &removed, std::vector< TriangleKey< true >> const &inserted, std::vector< int > const &linkVertices)
GLsizei GLenum const void * indices
#define LogError(message)
static std::shared_ptr< Vertex > Create(int v)
DualQuaternion< Real > Dot(DualQuaternion< Real > const &d0, DualQuaternion< Real > const &d1)
bool Remove(KeyType &key, ValueType &value)
Real Normalize(GVector< Real > &v, bool robust=false)
DualQuaternion< Real > Cross(DualQuaternion< Real > const &d0, DualQuaternion< Real > const &d1)
virtual bool Remove(int v0, int v1, int v2) override
std::vector< std::array< int, 3 > > const & GetTriangles() const
Real ComputeWeight(Vector3< Real > const *positions)
DualQuaternion< Real > Length(DualQuaternion< Real > const &d, bool robust=false)
int TriangulateLink(std::shared_ptr< VCVertex > const &vertex, std::vector< TriangleKey< true >> &removed, std::vector< TriangleKey< true >> &inserted, std::vector< int > &linkVertices) const
ETManifoldMesh const & GetMesh() const
GLfloat GLfloat GLfloat v2
Real ComputeOrthogonalComplement(int numInputs, Vector2< Real > *v, bool robust=false)
bool GetMinimum(KeyType &key, ValueType &value) const
std::map< int, typename MinHeap< int, Real >::Record * > mHeapRecords
std::vector< TriangleKey< true > > removed
MinHeap< int, Real > mMinHeap
virtual std::shared_ptr< Triangle > Insert(int v0, int v1, int v2) override
VMap const & GetVertices() const
Vector3< Real > const * mPositions
VertexCollapseMesh(int numPositions, Vector3< Real > const *positions, int numIndices, int const *indices)