diff --git a/src/meshoptimizer.h b/src/meshoptimizer.h index 05bacc72..18142390 100644 --- a/src/meshoptimizer.h +++ b/src/meshoptimizer.h @@ -347,15 +347,6 @@ enum */ MESHOPTIMIZER_API size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, unsigned int options, float* result_error); -/** - * Mesh simplifier which locks a given list of vertices - * Works like meshopt_simplify, but accept a list of vertices not allowed to collapse. Other vertices are still allowed to collapse onto locked vertices. - * - * locked_vertices points to an array of vertex indices, denoting which vertices are to be locked. Can be NULL if locked_vertex_count is 0. - * locked_vertex_count number of elements in the locked_vertices array. - */ -MESHOPTIMIZER_API size_t meshopt_simplifyWithLocks(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, const unsigned int* locked_vertices, size_t locked_vertex_count, size_t target_index_count, float target_error, unsigned int options, float* result_error); - /** * Experimental: Mesh simplifier with attribute metric * The algorithm ehnahces meshopt_simplify by incorporating attribute values into the error metric used to prioritize simplification order; see meshopt_simplify documentation for details. @@ -363,9 +354,10 @@ MESHOPTIMIZER_API size_t meshopt_simplifyWithLocks(unsigned int* destination, co * * 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. + * vertex_lock should have vertex_count chars, 1 for each vertex; they determine which vertices are locked (1) or free to be simplified (0). * TODO target_error/result_error currently use combined distance+attribute error; this may change in the future */ -MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, const float* vertex_attributes, size_t vertex_attributes_stride, const float* attribute_weights, size_t attribute_count, const unsigned int* locked_vertices, size_t locked_vertex_count, size_t target_index_count, float target_error, unsigned int options, float* result_error); +MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, const float* vertex_attributes, size_t vertex_attributes_stride, const float* attribute_weights, size_t attribute_count, const unsigned char* vertex_lock, size_t target_index_count, float target_error, unsigned int options, float* result_error); /** * Experimental: Mesh simplifier (sloppy) diff --git a/src/simplifier.cpp b/src/simplifier.cpp index 04b7ee36..737657d9 100644 --- a/src/simplifier.cpp +++ b/src/simplifier.cpp @@ -252,7 +252,7 @@ static bool hasEdge(const EdgeAdjacency& adjacency, unsigned int a, unsigned int return false; } -static void classifyVertices(unsigned char* result, unsigned int* loop, unsigned int* loopback, size_t vertex_count, const EdgeAdjacency& adjacency, const unsigned int* remap, const unsigned int* wedge, const unsigned int* locked_vertices, size_t locked_vertex_count, unsigned int options) +static void classifyVertices(unsigned char* result, unsigned int* loop, unsigned int* loopback, size_t vertex_count, const EdgeAdjacency& adjacency, const unsigned int* remap, const unsigned int* wedge, const unsigned char* vertex_lock, unsigned int options) { memset(loop, -1, vertex_count * sizeof(unsigned int)); memset(loopback, -1, vertex_count * sizeof(unsigned int)); @@ -298,7 +298,12 @@ static void classifyVertices(unsigned char* result, unsigned int* loop, unsigned { if (remap[i] == i) { - if (wedge[i] == i) + if (vertex_lock && vertex_lock[i]) + { + // vertex is explicitly locked + result[i] = Kind_Locked; + } + else if (wedge[i] == i) { // no attribute seam, need to check if it's manifold unsigned int openi = openinc[i], openo = openout[i]; @@ -362,9 +367,6 @@ static void classifyVertices(unsigned char* result, unsigned int* loop, unsigned } } - for (size_t i = 0; i < locked_vertex_count; i++) - result[remap[locked_vertices[i]]] = Kind_Locked; - if (options & meshopt_SimplifyLockBorder) for (size_t i = 0; i < vertex_count; ++i) if (result[i] == Kind_Border) @@ -1426,7 +1428,7 @@ MESHOPTIMIZER_API unsigned int* meshopt_simplifyDebugLoop = 0; MESHOPTIMIZER_API unsigned int* meshopt_simplifyDebugLoopBack = 0; #endif -size_t meshopt_simplifyEdge(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, const float* vertex_attributes_data, size_t vertex_attributes_stride, const float* attribute_weights, size_t attribute_count, const unsigned int* locked_vertices, size_t locked_vertex_count, size_t target_index_count, float target_error, unsigned int options, float* out_result_error) +size_t meshopt_simplifyEdge(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, const float* vertex_attributes_data, size_t vertex_attributes_stride, const float* attribute_weights, size_t attribute_count, const unsigned char* vertex_lock, size_t target_index_count, float target_error, unsigned int options, float* out_result_error) { using namespace meshopt; @@ -1457,7 +1459,7 @@ size_t meshopt_simplifyEdge(unsigned int* destination, const unsigned int* indic unsigned char* vertex_kind = allocator.allocate(vertex_count); unsigned int* loop = allocator.allocate(vertex_count); unsigned int* loopback = allocator.allocate(vertex_count); - classifyVertices(vertex_kind, loop, loopback, vertex_count, adjacency, remap, wedge, locked_vertices, locked_vertex_count, options); + classifyVertices(vertex_kind, loop, loopback, vertex_count, adjacency, remap, wedge, vertex_lock, options); #if TRACE size_t unique_positions = 0; @@ -1592,17 +1594,12 @@ size_t meshopt_simplifyEdge(unsigned int* destination, const unsigned int* indic size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, unsigned int options, float* out_result_error) { - return meshopt_simplifyEdge(destination, indices, index_count, vertex_positions_data, vertex_count, vertex_positions_stride, NULL, 0, NULL, 0, NULL, 0, target_index_count, target_error, options, out_result_error); + return meshopt_simplifyEdge(destination, indices, index_count, vertex_positions_data, vertex_count, vertex_positions_stride, NULL, 0, NULL, 0, NULL, target_index_count, target_error, options, out_result_error); } -size_t meshopt_simplifyWithLocks(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, const unsigned int* locked_vertices, size_t locked_vertex_count, size_t target_index_count, float target_error, unsigned int options, float* out_result_error) +size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, const float* vertex_attributes_data, size_t vertex_attributes_stride, const float* attribute_weights, size_t attribute_count, const unsigned char* vertex_lock, size_t target_index_count, float target_error, unsigned int options, float* out_result_error) { - return meshopt_simplifyEdge(destination, indices, index_count, vertex_positions_data, vertex_count, vertex_positions_stride, NULL, 0, NULL, 0, locked_vertices, locked_vertex_count, target_index_count, target_error, options, out_result_error); -} - -size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, const float* vertex_attributes_data, size_t vertex_attributes_stride, const float* attribute_weights, size_t attribute_count, const unsigned int* locked_vertices, size_t locked_vertex_count, size_t target_index_count, float target_error, unsigned int options, float* out_result_error) -{ - return meshopt_simplifyEdge(destination, indices, index_count, vertex_positions_data, vertex_count, vertex_positions_stride, vertex_attributes_data, vertex_attributes_stride, attribute_weights, attribute_count, locked_vertices, locked_vertex_count, target_index_count, target_error, options, out_result_error); + return meshopt_simplifyEdge(destination, indices, index_count, vertex_positions_data, vertex_count, vertex_positions_stride, vertex_attributes_data, vertex_attributes_stride, attribute_weights, attribute_count, vertex_lock, target_index_count, target_error, options, out_result_error); } size_t meshopt_simplifySloppy(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float* out_result_error) @@ -1655,16 +1652,14 @@ size_t meshopt_simplifySloppy(unsigned int* destination, const unsigned int* ind // we clamp the prediction of the grid size to make sure that the search converges int grid_size = next_grid_size; - grid_size = (grid_size <= min_grid) ? min_grid + 1 : (grid_size >= max_grid) ? max_grid - 1 - : grid_size; + grid_size = (grid_size <= min_grid) ? min_grid + 1 : (grid_size >= max_grid) ? max_grid - 1 : grid_size; computeVertexIds(vertex_ids, vertex_positions, vertex_count, grid_size); size_t triangles = countTriangles(vertex_ids, indices, index_count); #if TRACE printf("pass %d (%s): grid size %d, triangles %d, %s\n", - pass, (pass == 0) ? "guess" : (pass <= kInterpolationPasses) ? "lerp" - : "binary", + pass, (pass == 0) ? "guess" : (pass <= kInterpolationPasses) ? "lerp" : "binary", grid_size, int(triangles), (triangles <= target_index_count / 3) ? "under" : "over"); #endif @@ -1786,8 +1781,7 @@ size_t meshopt_simplifyPoints(unsigned int* destination, const float* vertex_pos // we clamp the prediction of the grid size to make sure that the search converges int grid_size = next_grid_size; - grid_size = (grid_size <= min_grid) ? min_grid + 1 : (grid_size >= max_grid) ? max_grid - 1 - : grid_size; + grid_size = (grid_size <= min_grid) ? min_grid + 1 : (grid_size >= max_grid) ? max_grid - 1 : grid_size; computeVertexIds(vertex_ids, vertex_positions, vertex_count, grid_size); size_t vertices = countVertexCells(table, table_size, vertex_ids, vertex_count);