Skip to content

Commit

Permalink
Merge pull request #779 from zeux/simp-vlock
Browse files Browse the repository at this point in the history
simplify: Improve vertex_lock handling in presence of seams
  • Loading branch information
zeux authored Oct 3, 2024
2 parents 97408c6 + 7e0fad1 commit 1c8e968
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 6 deletions.
73 changes: 73 additions & 0 deletions demo/tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1221,6 +1221,78 @@ static void simplifyLockFlags()
assert(memcmp(ib, expected, sizeof(expected)) == 0);
}

static void simplifyLockFlagsSeam()
{
float vb[] = {
0, 0, 0,
0, 1, 0,
0, 1, 0,
0, 2, 0,
1, 0, 0,
1, 1, 0,
1, 1, 0,
1, 2, 0,
2, 0, 0,
2, 1, 0,
2, 1, 0,
2, 2, 0, // clang-format :-/
};

unsigned char lock0[12] = {
1, 0, 0, 1,
0, 0, 0, 0,
1, 0, 0, 1, // clang-format :-/
};

unsigned char lock1[12] = {
1, 0, 0, 1,
1, 0, 0, 1,
1, 0, 0, 1, // clang-format :-/
};

unsigned char lock2[12] = {
1, 0, 1, 1,
1, 0, 1, 1,
1, 0, 1, 1, // clang-format :-/
};

unsigned char lock3[12] = {
1, 1, 0, 1,
1, 1, 0, 1,
1, 1, 0, 1, // clang-format :-/
};

// 0 1-2 3
// 4 5-6 7
// 8 9-10 11

unsigned int ib[] = {
0, 1, 4,
4, 1, 5,
4, 5, 8,
8, 5, 9,
2, 3, 6,
6, 3, 7,
6, 7, 10,
10, 7, 11, // clang-format :-/
};

unsigned int res[24];
// with no locks, we should be able to collapse the entire mesh (vertices 1-2 and 9-10 are locked but others can move towards them)
assert(meshopt_simplifyWithAttributes(res, ib, 24, vb, 12, 12, NULL, 0, NULL, 0, NULL, 0, 1.f, 0) == 0);

// with corners locked, we should get two quads
assert(meshopt_simplifyWithAttributes(res, ib, 24, vb, 12, 12, NULL, 0, NULL, 0, lock0, 0, 1.f, 0) == 12);

// with both sides locked, we can only collapse the seam spine
assert(meshopt_simplifyWithAttributes(res, ib, 24, vb, 12, 12, NULL, 0, NULL, 0, lock1, 0, 1.f, 0) == 18);

// with seam spine locked, we can collapse nothing; note that we intentionally test two different lock configurations
// they each lock only one side of the seam spine, which should be equivalent
assert(meshopt_simplifyWithAttributes(res, ib, 24, vb, 12, 12, NULL, 0, NULL, 0, lock2, 0, 1.f, 0) == 24);
assert(meshopt_simplifyWithAttributes(res, ib, 24, vb, 12, 12, NULL, 0, NULL, 0, lock3, 0, 1.f, 0) == 24);
}

static void simplifySparse()
{
float vb[] = {
Expand Down Expand Up @@ -1774,6 +1846,7 @@ void runTests()
simplifyAttr(/* skip_g= */ false);
simplifyAttr(/* skip_g= */ true);
simplifyLockFlags();
simplifyLockFlagsSeam();
simplifySparse();
simplifyErrorAbsolute();
simplifySeam();
Expand Down
19 changes: 13 additions & 6 deletions src/simplifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -369,12 +369,7 @@ static void classifyVertices(unsigned char* result, unsigned int* loop, unsigned
{
if (remap[i] == i)
{
if (vertex_lock && vertex_lock[sparse_remap ? sparse_remap[i] : i])
{
// vertex is explicitly locked
result[i] = Kind_Locked;
}
else if (wedge[i] == i)
if (wedge[i] == i)
{
// no attribute seam, need to check if it's manifold
unsigned int openi = openinc[i], openo = openout[i];
Expand Down Expand Up @@ -438,6 +433,18 @@ static void classifyVertices(unsigned char* result, unsigned int* loop, unsigned
}
}

if (vertex_lock)
{
// vertex_lock may lock any wedge, not just the primary vertex, so we need to lock the primary vertex and relock any wedges
for (size_t i = 0; i < vertex_count; ++i)
if (vertex_lock[sparse_remap ? sparse_remap[i] : i])
result[remap[i]] = Kind_Locked;

for (size_t i = 0; i < vertex_count; ++i)
if (result[remap[i]] == Kind_Locked)
result[i] = Kind_Locked;
}

if (options & meshopt_SimplifyLockBorder)
for (size_t i = 0; i < vertex_count; ++i)
if (result[i] == Kind_Border)
Expand Down

0 comments on commit 1c8e968

Please sign in to comment.