in DirectXMesh/DirectXMeshOptimizeTVC.cpp [34:161]
HRESULT initialize(
_In_reads_(nFaces * 3) const index_t* indices, size_t nFaces,
_In_reads_(nFaces * 3) const uint32_t* adjacency,
const std::vector<std::pair<size_t, size_t>>& subsets)
{
if (!indices || !nFaces || !adjacency || subsets.empty())
return E_INVALIDARG;
// Convert adjacency to 'physical' adjacency
mPhysicalNeighbors.reset(new (std::nothrow) neighborInfo[nFaces]);
if (!mPhysicalNeighbors)
return E_OUTOFMEMORY;
#ifdef _DEBUG
memset(mPhysicalNeighbors.get(), 0xcd, sizeof(neighborInfo) * nFaces);
#endif
mFaceOffset = 0;
mFaceCount = 0;
mMaxSubset = 0;
mTotalFaces = nFaces;
for (const auto& it : subsets)
{
if ((uint64_t(it.first) + uint64_t(it.second)) >= UINT32_MAX)
return HRESULT_E_ARITHMETIC_OVERFLOW;
if (it.second > mMaxSubset)
{
mMaxSubset = it.second;
}
uint32_t faceOffset = uint32_t(it.first);
uint32_t faceMax = uint32_t(it.first + it.second);
for (uint32_t face = faceOffset; face < faceMax; ++face)
{
if (face >= nFaces)
return E_UNEXPECTED;
index_t i0 = indices[face * 3];
index_t i1 = indices[face * 3 + 1];
index_t i2 = indices[face * 3 + 2];
if (i0 == index_t(-1)
|| i1 == index_t(-1)
|| i2 == index_t(-1)
|| i0 == i1
|| i0 == i2
|| i1 == i2)
{
// unused and degenerate faces should not have neighbors
for (uint32_t point = 0; point < 3; ++point)
{
uint32_t k = adjacency[face * 3 + point];
if (k != UNUSED32)
{
if (k >= nFaces)
return E_UNEXPECTED;
if (adjacency[k * 3] == face)
mPhysicalNeighbors[k].neighbors[0] = UNUSED32;
if (adjacency[k * 3 + 1] == face)
mPhysicalNeighbors[k].neighbors[1] = UNUSED32;
if (adjacency[k * 3 + 2] == face)
mPhysicalNeighbors[k].neighbors[2] = UNUSED32;
}
mPhysicalNeighbors[face].neighbors[point] = UNUSED32;
}
}
else
{
for (uint32_t n = 0; n < 3; ++n)
{
uint32_t neighbor = adjacency[face * 3 + n];
if (neighbor != UNUSED32)
{
if ((neighbor < faceOffset) || (neighbor >= faceMax)
|| (neighbor == adjacency[face * 3 + ((n + 1) % 3)])
|| (neighbor == adjacency[face * 3 + ((n + 2) % 3)]))
{
// Break links for any neighbors outside of our attribute set, and remove duplicate neighbors
neighbor = UNUSED32;
}
else
{
uint32_t edgeBack = find_edge<uint32_t>(&adjacency[neighbor * 3], face);
if (edgeBack < 3)
{
index_t p1 = indices[face * 3 + n];
index_t p2 = indices[face * 3 + ((n + 1) % 3)];
index_t pn1 = indices[neighbor * 3 + edgeBack];
index_t pn2 = indices[neighbor * 3 + ((edgeBack + 1) % 3)];
// if wedge not identical on shared edge, drop link
if ((p1 != pn2) || (p2 != pn1))
{
neighbor = UNUSED32;
}
}
else
{
neighbor = UNUSED32;
}
}
}
mPhysicalNeighbors[face].neighbors[n] = neighbor;
}
}
}
}
if (!mMaxSubset)
return E_FAIL;
mListElements.reset(new (std::nothrow) listElement[mMaxSubset]);
if (!mListElements)
return E_OUTOFMEMORY;
return S_OK;
}