Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions DirectXMesh/DirectXMesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -426,48 +426,48 @@ namespace DirectX
};

DIRECTX_MESH_API HRESULT __cdecl OptimizeFaces(
_In_reads_(nFaces * 3) const uint16_t* indices, _In_ size_t nFaces,
_In_reads_(nFaces * 3) const uint16_t* indices, _In_ size_t nFaces, _In_ size_t nVerts,
_In_reads_(nFaces * 3) const uint32_t* adjacency,
_Out_writes_(nFaces) uint32_t* faceRemap,
_In_ uint32_t vertexCache = OPTFACES_V_DEFAULT,
_In_ uint32_t restart = OPTFACES_R_DEFAULT);
DIRECTX_MESH_API HRESULT __cdecl OptimizeFaces(
_In_reads_(nFaces * 3) const uint32_t* indices, _In_ size_t nFaces,
_In_reads_(nFaces * 3) const uint32_t* indices, _In_ size_t nFaces, _In_ size_t nVerts,
_In_reads_(nFaces * 3) const uint32_t* adjacency,
_Out_writes_(nFaces) uint32_t* faceRemap,
_In_ uint32_t vertexCache = OPTFACES_V_DEFAULT,
_In_ uint32_t restart = OPTFACES_R_DEFAULT);
DIRECTX_MESH_API HRESULT __cdecl OptimizeFacesLRU(
_In_reads_(nFaces * 3) const uint16_t* indices, _In_ size_t nFaces,
_In_reads_(nFaces * 3) const uint16_t* indices, _In_ size_t nFaces, _In_ size_t nVerts,
_Out_writes_(nFaces) uint32_t* faceRemap,
_In_ uint32_t lruCacheSize = OPTFACES_LRU_DEFAULT);
DIRECTX_MESH_API HRESULT __cdecl OptimizeFacesLRU(
_In_reads_(nFaces * 3) const uint32_t* indices, _In_ size_t nFaces,
_In_reads_(nFaces * 3) const uint32_t* indices, _In_ size_t nFaces, _In_ size_t nVerts,
_Out_writes_(nFaces) uint32_t* faceRemap,
_In_ uint32_t lruCacheSize = OPTFACES_LRU_DEFAULT);
// Reorders faces to increase hit rate of vertex caches

DIRECTX_MESH_API HRESULT __cdecl OptimizeFacesEx(
_In_reads_(nFaces * 3) const uint16_t* indices, _In_ size_t nFaces,
_In_reads_(nFaces * 3) const uint16_t* indices, _In_ size_t nFaces, _In_ size_t nVerts,
_In_reads_(nFaces * 3) const uint32_t* adjacency,
_In_reads_(nFaces) const uint32_t* attributes,
_Out_writes_(nFaces) uint32_t* faceRemap,
_In_ uint32_t vertexCache = OPTFACES_V_DEFAULT,
_In_ uint32_t restart = OPTFACES_R_DEFAULT);
DIRECTX_MESH_API HRESULT __cdecl OptimizeFacesEx(
_In_reads_(nFaces * 3) const uint32_t* indices, _In_ size_t nFaces,
_In_reads_(nFaces * 3) const uint32_t* indices, _In_ size_t nFaces, _In_ size_t nVerts,
_In_reads_(nFaces * 3) const uint32_t* adjacency,
_In_reads_(nFaces) const uint32_t* attributes,
_Out_writes_(nFaces) uint32_t* faceRemap,
_In_ uint32_t vertexCache = OPTFACES_V_DEFAULT,
_In_ uint32_t restart = OPTFACES_R_DEFAULT);
DIRECTX_MESH_API HRESULT __cdecl OptimizeFacesLRUEx(
_In_reads_(nFaces * 3) const uint16_t* indices, _In_ size_t nFaces,
_In_reads_(nFaces * 3) const uint16_t* indices, _In_ size_t nFaces, _In_ size_t nVerts,
_In_reads_(nFaces) const uint32_t* attributes,
_Out_writes_(nFaces) uint32_t* faceRemap,
_In_ uint32_t lruCacheSize = OPTFACES_LRU_DEFAULT);
DIRECTX_MESH_API HRESULT __cdecl OptimizeFacesLRUEx(
_In_reads_(nFaces * 3) const uint32_t* indices, _In_ size_t nFaces,
_In_reads_(nFaces * 3) const uint32_t* indices, _In_ size_t nFaces, _In_ size_t nVerts,
_In_reads_(nFaces) const uint32_t* attributes,
_Out_writes_(nFaces) uint32_t* faceRemap,
_In_ uint32_t lruCacheSize = OPTFACES_LRU_DEFAULT);
Expand Down
25 changes: 16 additions & 9 deletions DirectXMesh/DirectXMeshOptimizeLRU.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ namespace

template <typename IndexType>
HRESULT OptimizeFacesImpl(
_In_reads_(indexCount) const IndexType* indexList, uint32_t indexCount,
_In_reads_(indexCount) const IndexType* indexList, uint32_t indexCount, size_t nVerts,
_Out_writes_(indexCount / 3) uint32_t* faceRemap, uint32_t lruCacheSize, uint32_t offset)
{
std::unique_ptr<OptimizeVertexData<IndexType>[]> vertexDataList(new (std::nothrow) OptimizeVertexData<IndexType>[indexCount]);
Expand Down Expand Up @@ -245,6 +245,9 @@ namespace
continue;
}

if (indexList[idx] >= nVerts)
return E_UNEXPECTED;

if (!i || first || sortFunc(indexSorted[i - 1], idx))
{
// it's not a duplicate
Expand Down Expand Up @@ -510,10 +513,11 @@ _Use_decl_annotations_
HRESULT DirectX::OptimizeFacesLRU(
const uint16_t* indices,
size_t nFaces,
size_t nVerts,
uint32_t* faceRemap,
uint32_t lruCacheSize)
{
if (!indices || !nFaces || !faceRemap)
if (!indices || !nFaces || !nVerts || !faceRemap)
return E_INVALIDARG;

if (!lruCacheSize || lruCacheSize > kMaxVertexCacheSize)
Expand All @@ -528,17 +532,18 @@ HRESULT DirectX::OptimizeFacesLRU(
std::call_once(s_initOnce, ComputeVertexScores);
#endif

return OptimizeFacesImpl<uint16_t>(indices, static_cast<uint32_t>(nFaces * 3), faceRemap, lruCacheSize, 0);
return OptimizeFacesImpl<uint16_t>(indices, static_cast<uint32_t>(nFaces * 3), nVerts, faceRemap, lruCacheSize, 0);
}

_Use_decl_annotations_
HRESULT DirectX::OptimizeFacesLRU(
const uint32_t* indices,
size_t nFaces,
size_t nVerts,
uint32_t* faceRemap,
uint32_t lruCacheSize)
{
if (!indices || !nFaces || !faceRemap)
if (!indices || !nFaces || !nVerts || !faceRemap)
return E_INVALIDARG;

if (!lruCacheSize || lruCacheSize > kMaxVertexCacheSize)
Expand All @@ -553,7 +558,7 @@ HRESULT DirectX::OptimizeFacesLRU(
std::call_once(s_initOnce, ComputeVertexScores);
#endif

return OptimizeFacesImpl<uint32_t>(indices, static_cast<uint32_t>(nFaces * 3), faceRemap, lruCacheSize, 0);
return OptimizeFacesImpl<uint32_t>(indices, static_cast<uint32_t>(nFaces * 3), nVerts, faceRemap, lruCacheSize, 0);
}


Expand All @@ -562,11 +567,12 @@ _Use_decl_annotations_
HRESULT DirectX::OptimizeFacesLRUEx(
const uint16_t* indices,
size_t nFaces,
size_t nVerts,
const uint32_t* attributes,
uint32_t* faceRemap,
uint32_t lruCacheSize)
{
if (!indices || !nFaces || !attributes || !faceRemap)
if (!indices || !nFaces || !nVerts || !attributes || !faceRemap)
return E_INVALIDARG;

if (!lruCacheSize || lruCacheSize > kMaxVertexCacheSize)
Expand Down Expand Up @@ -602,7 +608,7 @@ HRESULT DirectX::OptimizeFacesLRUEx(
return E_UNEXPECTED;

HRESULT hr = OptimizeFacesImpl<uint16_t>(
&indices[it.first * 3], static_cast<uint32_t>(it.second * 3),
&indices[it.first * 3], static_cast<uint32_t>(it.second * 3), nVerts,
&faceRemap[it.first], lruCacheSize, uint32_t(it.first));
if (FAILED(hr))
return hr;
Expand All @@ -615,11 +621,12 @@ _Use_decl_annotations_
HRESULT DirectX::OptimizeFacesLRUEx(
const uint32_t* indices,
size_t nFaces,
size_t nVerts,
const uint32_t* attributes,
uint32_t* faceRemap,
uint32_t lruCacheSize)
{
if (!indices || !nFaces || !attributes || !faceRemap)
if (!indices || !nFaces || !nVerts || !attributes || !faceRemap)
return E_INVALIDARG;

if (!lruCacheSize || lruCacheSize > kMaxVertexCacheSize)
Expand Down Expand Up @@ -655,7 +662,7 @@ HRESULT DirectX::OptimizeFacesLRUEx(
return E_UNEXPECTED;

HRESULT hr = OptimizeFacesImpl<uint32_t>(
&indices[it.first * 3], static_cast<uint32_t>(it.second * 3),
&indices[it.first * 3], static_cast<uint32_t>(it.second * 3), nVerts,
&faceRemap[it.first], lruCacheSize, uint32_t(it.first));
if (FAILED(hr))
return hr;
Expand Down
59 changes: 38 additions & 21 deletions DirectXMesh/DirectXMeshOptimizeTVC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ namespace
{}

HRESULT initialize(
_In_reads_(nFaces * 3) const index_t* indices, size_t nFaces,
_In_reads_(nFaces * 3) const index_t* indices,
size_t nFaces,
size_t nVerts,
_In_reads_(nFaces * 3) const uint32_t* adjacency,
const std::vector<std::pair<size_t, size_t>>& subsets)
{
Expand Down Expand Up @@ -74,7 +76,13 @@ namespace
index_t i1 = indices[face * 3 + 1];
index_t i2 = indices[face * 3 + 2];

if (i0 == index_t(-1)
if ((i0 != index_t(-1) && i0 >= nVerts)
|| (i1 != index_t(-1) && i1 >= nVerts)
|| (i2 != index_t(-1) && i2 >= nVerts))
{
return E_UNEXPECTED;
}
else if (i0 == index_t(-1)
|| i1 == index_t(-1)
|| i2 == index_t(-1)
|| i0 == i1
Expand Down Expand Up @@ -163,7 +171,7 @@ namespace
}

HRESULT setSubset(
_In_reads_(nFaces * 3) const index_t* indices, size_t nFaces,
_In_reads_(nFaces * 3) const index_t* indices, size_t nFaces, size_t nVerts,
size_t faceOffset, size_t faceCount) noexcept
{
if (!indices || !mListElements)
Expand Down Expand Up @@ -202,6 +210,11 @@ namespace
continue;
}

if (i0 >= nVerts
|| i1 >= nVerts
|| i2 >= nVerts)
return E_UNEXPECTED;

uint32_t unprocessed = 0;

for (uint32_t n = 0; n < 3; ++n)
Expand Down Expand Up @@ -508,7 +521,7 @@ namespace
//---------------------------------------------------------------------------------
template<class index_t>
HRESULT StripReorderImpl(
_In_reads_(nFaces * 3) const index_t* indices, _In_ size_t nFaces,
_In_reads_(nFaces * 3) const index_t* indices, _In_ size_t nFaces, _In_ size_t nVerts,
_In_reads_(nFaces * 3) const uint32_t* adjacency,
_In_reads_opt_(nFaces) const uint32_t* attributes,
_Out_writes_(nFaces) uint32_t* faceRemap)
Expand All @@ -518,7 +531,7 @@ namespace
return E_UNEXPECTED;

mesh_status<index_t> status;
HRESULT hr = status.initialize(indices, nFaces, adjacency, subsets);
HRESULT hr = status.initialize(indices, nFaces, nVerts, adjacency, subsets);
if (FAILED(hr))
return hr;

Expand All @@ -530,7 +543,7 @@ namespace

for (const auto& it : subsets)
{
hr = status.setSubset(indices, nFaces, it.first, it.second);
hr = status.setSubset(indices, nFaces, nVerts, it.first, it.second);
if (FAILED(hr))
return hr;

Expand Down Expand Up @@ -585,7 +598,7 @@ namespace
//---------------------------------------------------------------------------------
template<class index_t>
HRESULT VertexCacheStripReorderImpl(
_In_reads_(nFaces * 3) const index_t* indices, _In_ size_t nFaces,
_In_reads_(nFaces * 3) const index_t* indices, _In_ size_t nFaces, _In_ size_t nVerts,
_In_reads_(nFaces * 3) const uint32_t* adjacency,
_In_reads_opt_(nFaces) const uint32_t* attributes,
_Out_writes_(nFaces) uint32_t* faceRemap,
Expand All @@ -596,7 +609,7 @@ namespace
return E_UNEXPECTED;

mesh_status<index_t> status;
HRESULT hr = status.initialize(indices, nFaces, adjacency, subsets);
HRESULT hr = status.initialize(indices, nFaces, nVerts, adjacency, subsets);
if (FAILED(hr))
return hr;

Expand All @@ -616,7 +629,7 @@ namespace

for (const auto& it : subsets)
{
hr = status.setSubset(indices, nFaces, it.first, it.second);
hr = status.setSubset(indices, nFaces, nVerts, it.first, it.second);
if (FAILED(hr))
return hr;

Expand Down Expand Up @@ -771,55 +784,57 @@ _Use_decl_annotations_
HRESULT DirectX::OptimizeFaces(
const uint16_t* indices,
size_t nFaces,
size_t nVerts,
const uint32_t* adjacency,
uint32_t* faceRemap,
uint32_t vertexCache,
uint32_t restart)
{
if (!indices || !nFaces || !adjacency || !faceRemap)
if (!indices || !nFaces || !nVerts || !adjacency || !faceRemap)
return E_INVALIDARG;

if ((uint64_t(nFaces) * 3) >= UINT32_MAX)
return HRESULT_E_ARITHMETIC_OVERFLOW;

if (vertexCache == OPTFACES_V_STRIPORDER)
{
return StripReorderImpl<uint16_t>(indices, nFaces, adjacency, nullptr, faceRemap);
return StripReorderImpl<uint16_t>(indices, nFaces, nVerts, adjacency, nullptr, faceRemap);
}
else
{
if (restart > vertexCache)
return E_INVALIDARG;

return VertexCacheStripReorderImpl<uint16_t>(indices, nFaces, adjacency, nullptr, faceRemap, vertexCache, restart);
return VertexCacheStripReorderImpl<uint16_t>(indices, nFaces, nVerts, adjacency, nullptr, faceRemap, vertexCache, restart);
}
}

_Use_decl_annotations_
HRESULT DirectX::OptimizeFaces(
const uint32_t* indices,
size_t nFaces,
size_t nVerts,
const uint32_t* adjacency,
uint32_t* faceRemap,
uint32_t vertexCache,
uint32_t restart)
{
if (!indices || !nFaces || !adjacency || !faceRemap)
if (!indices || !nFaces || !nVerts || !adjacency || !faceRemap)
return E_INVALIDARG;

if ((uint64_t(nFaces) * 3) >= UINT32_MAX)
return HRESULT_E_ARITHMETIC_OVERFLOW;

if (vertexCache == OPTFACES_V_STRIPORDER)
{
return StripReorderImpl<uint32_t>(indices, nFaces, adjacency, nullptr, faceRemap);
return StripReorderImpl<uint32_t>(indices, nFaces, nVerts, adjacency, nullptr, faceRemap);
}
else
{
if (restart > vertexCache)
return E_INVALIDARG;

return VertexCacheStripReorderImpl<uint32_t>(indices, nFaces, adjacency, nullptr, faceRemap, vertexCache, restart);
return VertexCacheStripReorderImpl<uint32_t>(indices, nFaces, nVerts, adjacency, nullptr, faceRemap, vertexCache, restart);
}
}

Expand All @@ -829,56 +844,58 @@ _Use_decl_annotations_
HRESULT DirectX::OptimizeFacesEx(
const uint16_t* indices,
size_t nFaces,
size_t nVerts,
const uint32_t* adjacency,
const uint32_t* attributes,
uint32_t* faceRemap,
uint32_t vertexCache,
uint32_t restart)
{
if (!indices || !nFaces || !adjacency || !attributes || !faceRemap)
if (!indices || !nFaces || !nVerts || !adjacency || !attributes || !faceRemap)
return E_INVALIDARG;

if ((uint64_t(nFaces) * 3) >= UINT32_MAX)
return HRESULT_E_ARITHMETIC_OVERFLOW;

if (vertexCache == OPTFACES_V_STRIPORDER)
{
return StripReorderImpl<uint16_t>(indices, nFaces, adjacency, attributes, faceRemap);
return StripReorderImpl<uint16_t>(indices, nFaces, nVerts, adjacency, attributes, faceRemap);
}
else
{
if (restart > vertexCache)
return E_INVALIDARG;

return VertexCacheStripReorderImpl<uint16_t>(indices, nFaces, adjacency, attributes, faceRemap, vertexCache, restart);
return VertexCacheStripReorderImpl<uint16_t>(indices, nFaces, nVerts, adjacency, attributes, faceRemap, vertexCache, restart);
}
}

_Use_decl_annotations_
HRESULT DirectX::OptimizeFacesEx(
const uint32_t* indices,
size_t nFaces,
size_t nVerts,
const uint32_t* adjacency,
const uint32_t* attributes,
uint32_t* faceRemap,
uint32_t vertexCache,
uint32_t restart)
{
if (!indices || !nFaces || !adjacency || !attributes || !faceRemap)
if (!indices || !nFaces || !nVerts || !adjacency || !attributes || !faceRemap)
return E_INVALIDARG;

if ((uint64_t(nFaces) * 3) >= UINT32_MAX)
return HRESULT_E_ARITHMETIC_OVERFLOW;

if (vertexCache == OPTFACES_V_STRIPORDER)
{
return StripReorderImpl<uint32_t>(indices, nFaces, adjacency, attributes, faceRemap);
return StripReorderImpl<uint32_t>(indices, nFaces, nVerts, adjacency, attributes, faceRemap);
}
else
{
if (restart > vertexCache)
return E_INVALIDARG;

return VertexCacheStripReorderImpl<uint32_t>(indices, nFaces, adjacency, attributes, faceRemap, vertexCache, restart);
return VertexCacheStripReorderImpl<uint32_t>(indices, nFaces, nVerts, adjacency, attributes, faceRemap, vertexCache, restart);
}
}
Loading
Loading