Merge pull request #721 from zeux/simp-attrk

simplify: Only allocate and compute quadrics for used attributes
This commit is contained in:
Arseny Kapoulkine
2024-07-13 06:24:01 -07:00
committed by GitHub
6 changed files with 34 additions and 15 deletions
+1 -2
View File
@@ -1303,8 +1303,7 @@ void processDev(const char* path)
if (!loadMesh(mesh, path))
return;
simplify(mesh);
simplifyClusters(mesh);
simplifyAttr(mesh);
}
int main(int argc, char** argv)
+4 -3
View File
@@ -1136,7 +1136,7 @@ static void simplifyLockBorder()
assert(memcmp(ib, expected, sizeof(expected)) == 0);
}
static void simplifyAttr()
static void simplifyAttr(bool skip_g)
{
float vb[8 * 3][6];
@@ -1173,7 +1173,7 @@ static void simplifyAttr()
}
}
float attr_weights[3] = {0.01f, 0.01f, 0.01f};
float attr_weights[3] = {0.01f, skip_g ? 0.f : 0.01f, 0.01f};
unsigned int expected[3][6] = {
{0, 2, 9, 9, 2, 11},
@@ -1551,7 +1551,8 @@ void runTests()
simplifyScale();
simplifyDegenerate();
simplifyLockBorder();
simplifyAttr();
simplifyAttr(/* skip_g= */ false);
simplifyAttr(/* skip_g= */ true);
simplifyLockFlags();
simplifySparse();
simplifyErrorAbsolute();
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -362,7 +362,7 @@ MESHOPTIMIZER_API size_t meshopt_simplify(unsigned int* destination, const unsig
*
* vertex_attributes should have attribute_count floats for each vertex
* attribute_weights should have attribute_count floats in total; the weights determine relative priority of attributes between each other and wrt position. The recommended weight range is [1e-3..1e-1], assuming attribute data is in [0..1] range.
* attribute_count must be <= 16
* attribute_count must be <= 32
* vertex_lock can be NULL; when it's not NULL, it should have a value for each vertex; 1 denotes vertices that can't be moved
* TODO target_error/result_error currently use combined distance+attribute error; this may change in the future
*/
+18 -5
View File
@@ -503,7 +503,7 @@ static float rescalePositions(Vector3* result, const float* vertex_positions_dat
return extent;
}
static void rescaleAttributes(float* result, const float* vertex_attributes_data, size_t vertex_count, size_t vertex_attributes_stride, const float* attribute_weights, size_t attribute_count, const unsigned int* sparse_remap)
static void rescaleAttributes(float* result, const float* vertex_attributes_data, size_t vertex_count, size_t vertex_attributes_stride, const float* attribute_weights, size_t attribute_count, const unsigned int* attribute_remap, const unsigned int* sparse_remap)
{
size_t vertex_attributes_stride_float = vertex_attributes_stride / sizeof(float);
@@ -513,14 +513,15 @@ static void rescaleAttributes(float* result, const float* vertex_attributes_data
for (size_t k = 0; k < attribute_count; ++k)
{
float a = vertex_attributes_data[ri * vertex_attributes_stride_float + k];
unsigned int rk = attribute_remap[k];
float a = vertex_attributes_data[ri * vertex_attributes_stride_float + rk];
result[i * attribute_count + k] = a * attribute_weights[k];
result[i * attribute_count + k] = a * attribute_weights[rk];
}
}
}
static const size_t kMaxAttributes = 16;
static const size_t kMaxAttributes = 32;
struct Quadric
{
@@ -1560,10 +1561,13 @@ 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(target_error >= 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);
for (size_t i = 0; i < attribute_count; ++i)
assert(attribute_weights[i] >= 0);
meshopt_Allocator allocator;
@@ -1615,8 +1619,17 @@ size_t meshopt_simplifyEdge(unsigned int* destination, const unsigned int* indic
if (attribute_count)
{
unsigned int attribute_remap[kMaxAttributes];
// remap attributes to only include ones with weight > 0 to minimize memory/compute overhead for quadrics
size_t attributes_used = 0;
for (size_t i = 0; i < attribute_count; ++i)
if (attribute_weights[i] > 0)
attribute_remap[attributes_used++] = unsigned(i);
attribute_count = attributes_used;
vertex_attributes = allocator.allocate<float>(vertex_count * attribute_count);
rescaleAttributes(vertex_attributes, vertex_attributes_data, vertex_count, vertex_attributes_stride, attribute_weights, attribute_count, sparse_remap);
rescaleAttributes(vertex_attributes, vertex_attributes_data, vertex_count, vertex_attributes_stride, attribute_weights, attribute_count, attribute_remap, sparse_remap);
}
Quadric* vertex_quadrics = allocator.allocate<Quadric>(vertex_count);