Skip to content

Commit

Permalink
simplify: Implement internal flag for topology debug information
Browse files Browse the repository at this point in the history
We have been relying on smuggling the kind/loop info computed during
classification via meshopt_simplifyDebug global pointers. This
information is valuable to visualize, and there's future improvements to
classification that would need to be debugged, so it's not ready to
remove but exposing this as globals results in issues as it expands the
exported API surface, making it different between release & debug builds.

Instead, this change adds a way to request this via an option bit, and
return it via indices[] - instead of per-vertex information, we return
this per-triangle-corner. It's not exactly identical, as there's some
redundancy, but per-corner metadata is nice in general and this is
generally sufficient to do the requisite visualization.

The newly added option bit is *not* part of the official API surface -
the format of the data may change at any point, and the entire feature
may get dropped at any point once it stops being useful.
  • Loading branch information
zeux committed Jul 12, 2024
1 parent f16ee88 commit 93c0013
Showing 1 changed file with 22 additions and 2 deletions.
24 changes: 22 additions & 2 deletions src/simplifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1546,8 +1546,13 @@ static float interpolate(float y, float x0, float y0, float x1, float y1, float

} // namespace meshopt

// Note: this is only exposed for debug visualization purposes; do *not* use
enum
{
meshopt_SimplifyInternalDebug = 1 << 30
};

#ifndef NDEBUG
// Note: this is only exposed for debug visualization purposes; do *not* use these in debug builds
MESHOPTIMIZER_API unsigned char* meshopt_simplifyDebugKind = NULL;
MESHOPTIMIZER_API unsigned int* meshopt_simplifyDebugLoop = NULL;
MESHOPTIMIZER_API unsigned int* meshopt_simplifyDebugLoopBack = NULL;
Expand All @@ -1561,7 +1566,7 @@ size_t meshopt_simplifyEdge(unsigned int* destination, const unsigned int* indic
assert(vertex_positions_stride >= 12 && vertex_positions_stride <= 256);
assert(vertex_positions_stride % sizeof(float) == 0);
assert(target_index_count <= index_count);
assert((options & ~(meshopt_SimplifyLockBorder | meshopt_SimplifySparse | meshopt_SimplifyErrorAbsolute)) == 0);
assert((options & ~(meshopt_SimplifyLockBorder | meshopt_SimplifySparse | meshopt_SimplifyErrorAbsolute | meshopt_SimplifyInternalDebug)) == 0);
assert(vertex_attributes_stride >= attribute_count * sizeof(float) && vertex_attributes_stride <= 256);
assert(vertex_attributes_stride % sizeof(float) == 0);
assert(attribute_count <= kMaxAttributes);
Expand Down Expand Up @@ -1705,6 +1710,21 @@ size_t meshopt_simplifyEdge(unsigned int* destination, const unsigned int* indic
printf("result: %d triangles, error: %e; total %d passes\n", int(result_count / 3), sqrtf(result_error), int(pass_count));
#endif

// if debug visualization data is requested, fill it instead of index data; for simplicity, this doesn't work with sparsity
if ((options & meshopt_SimplifyInternalDebug) && !sparse_remap)
{
assert(Kind_Count <= 8 && vertex_count < (1 << 28)); // 3 bit kind, 1 bit loop

for (size_t i = 0; i < result_count; i += 3)
{
unsigned int a = result[i + 0], b = result[i + 1], c = result[i + 2];

result[i + 0] |= (vertex_kind[a] << 28) | (unsigned(loop[a] == b || loopback[b] == a) << 31);
result[i + 1] |= (vertex_kind[b] << 28) | (unsigned(loop[b] == c || loopback[c] == b) << 31);
result[i + 2] |= (vertex_kind[c] << 28) | (unsigned(loop[c] == a || loopback[a] == c) << 31);
}
}

#ifndef NDEBUG
if (meshopt_simplifyDebugKind)
memcpy(meshopt_simplifyDebugKind, vertex_kind, vertex_count);
Expand Down

0 comments on commit 93c0013

Please sign in to comment.