Mesh Simplification Options in meshoptimizer: Complete Guide to Flags Like meshopt_SimplifyLockBorder
meshoptimizer provides bit-mask flags such as meshopt_SimplifyLockBorder, meshopt_SimplifySparse, and meshopt_SimplifyRegularize in src/meshoptimizer.h to control border preservation, error metrics, and triangle regularity during mesh reduction.
The meshoptimizer library exposes fine-grained mesh simplification options through bitwise flags that modify the behavior of the decimation algorithm. These flags, defined in the public header [src/meshoptimizer.h](https://github.com/zeux/meshoptimizer/blob/master/src/meshoptimizer.h), allow you to preserve topological boundaries, adjust error calculations, and control vertex locking when generating level-of-detail (LOD) meshes. Understanding these options is essential for producing optimized geometry that maintains visual fidelity in critical areas.
Core Simplification Flags
The primary simplification options are defined as unsigned integer constants starting at line 469 in src/meshoptimizer.h. Pass these to meshopt_simplify or meshopt_simplifyWithAttributes by combining them with the bitwise OR operator (|).
Preserve Border Geometry with meshopt_SimplifyLockBorder
meshopt_SimplifyLockBorder prevents vertices on the topological border—edges belonging to only one triangle—from being moved or removed during simplification. This is essential when simplifying chunks of a larger mesh that must connect seamlessly at the boundaries. According to the source code, this flag is declared at src/meshoptimizer.h#L469.
Optimize for Sparse Indices with meshopt_SimplifySparse
meshopt_SimplifySparse adjusts the error metric to be relative to the extents of the sparse subset rather than the full mesh bounds. Use this flag when processing meshes with sparse index buffers to improve simplification accuracy and performance. See the definition at src/meshoptimizer.h#L470.
Control Error Thresholds with meshopt_SimplifyErrorAbsolute
By default, meshoptimizer interprets the target_error value relative to mesh extents. meshopt_SimplifyErrorAbsolute switches the error limit to absolute units, giving you precise control over deformation magnitude regardless of mesh size. This flag is located at src/meshoptimizer.h#L471.
Remove Disconnected Geometry with meshopt_SimplifyPrune
meshopt_SimplifyPrune enables the incremental removal of disconnected components during simplification, even when such removal violates local topological constraints. This helps clean up stray geometry that might otherwise persist through decimation. Find this at src/meshoptimizer.h#L472.
Improve Triangle Quality with Regularization
meshopt_SimplifyRegularize encourages the generation of uniform triangle shapes and sizes, trading slight geometric or attribute quality for rasterization efficiency. For a lighter touch, meshopt_SimplifyRegularizeLight applies similar regularization with reduced impact on overall mesh quality. These are defined at src/meshoptimizer.h#L473 and src/meshoptimizer.h#L475 respectively.
Handle Attribute Discontinuities with meshopt_SimplifyPermissive
meshopt_SimplifyPermissive is an experimental flag that permits edge collapses across attribute discontinuities, provided the vertices are not marked with meshopt_SimplifyVertex_Protect. This enables more aggressive simplification when you can tolerate attribute seams, such as UV boundaries or hard normals. The flag appears at src/meshoptimizer.h#L474.
Vertex-Level Control Flags
When supplying a vertex_lock array to meshopt_simplifyWithAttributes, you can mark individual vertices with specialized flags defined in src/meshoptimizer.h at lines 490-492.
Lock Specific Vertices with meshopt_SimplifyVertex_Lock
meshopt_SimplifyVertex_Lock guarantees that specific vertices remain completely stationary throughout the simplification process, preventing any collapses involving those positions. This is defined at src/meshoptimizer.h#L490.
Protect Attribute Seams with meshopt_SimplifyVertex_Protect
meshopt_SimplifyVertex_Protect marks vertices where attribute discontinuities must be preserved, preventing collapses across these boundaries when combined with meshopt_SimplifyPermissive. See src/meshoptimizer.h#L491.
Prioritize Vertex Preservation
meshopt_SimplifyVertex_Priority increases the preservation priority of specific vertices during simplification, making the algorithm less likely to remove them even when they are technically collapsible. This is declared at src/meshoptimizer.h#L492.
Implementing Simplification Options in Code
The simplification API accepts an options bitmask parameter. Combine flags using the bitwise OR operator (|).
The function signature from src/meshoptimizer.h is:
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);
To preserve borders and regularize triangles:
unsigned int opts = meshopt_SimplifyLockBorder | meshopt_SimplifyRegularize;
float result_error;
size_t new_index_count = meshopt_simplify(
dst_indices, src_indices, index_count,
positions, vertex_count, sizeof(float) * 3,
target_index_count, 0.01f, opts, &result_error);
When using meshopt_simplifyWithAttributes with vertex locks to protect UV seams:
unsigned char* vertex_lock = (unsigned char*)malloc(vertex_count);
memset(vertex_lock, 0, vertex_count);
// Mark seam vertices for protection
for (size_t i = 0; i < seam_vertex_count; ++i) {
vertex_lock[seam_indices[i]] = meshopt_SimplifyVertex_Protect;
}
unsigned int opts = meshopt_SimplifyPermissive;
float result_error;
size_t new_count = meshopt_simplifyWithAttributes(
dst_indices, src_indices, index_count,
positions, vertex_count, sizeof(float) * 3,
attributes, attribute_stride, attribute_weights, attribute_count,
vertex_lock, target_count, 0.02f, opts, &result_error);
For aggressive simplification on sparse meshes with absolute error control:
unsigned int opts = meshopt_SimplifySparse | meshopt_SimplifyErrorAbsolute;
size_t new_count = meshopt_simplify(
dst_indices, src_indices, index_count,
positions, vertex_count, sizeof(float) * 3,
target_count, 0.005f, opts, NULL);
Summary
- meshoptimizer exposes mesh simplification options as bit-mask flags in
src/meshoptimizer.h, includingmeshopt_SimplifyLockBorderfor border preservation andmeshopt_SimplifyRegularizefor triangle quality optimization. - The
optionsparameter inmeshopt_simplifyaccepts combined flags using bitwise OR to control error metrics, topology pruning, and attribute handling. - Vertex-level flags like
meshopt_SimplifyVertex_Lockandmeshopt_SimplifyVertex_Protectprovide fine-grained control when used withmeshopt_simplifyWithAttributes. - Implementation details are found in
src/simplifier.cpp, with practical usage examples indemo/clusterlod.hand the interactivedemo/simplify.html.
Frequently Asked Questions
What is the difference between meshopt_SimplifyRegularize and meshopt_SimplifyRegularizeLight?
meshopt_SimplifyRegularize aggressively enforces uniform triangle shapes, potentially sacrificing some geometric fidelity for better rasterization performance. meshopt_SimplifyRegularizeLight applies similar regularization but with a reduced impact on quality, offering a middle ground between geometric accuracy and mesh regularity.
Can I combine meshopt_SimplifyLockBorder with other simplification options?
Yes, you can combine meshopt_SimplifyLockBorder with any other flags using the bitwise OR operator. For example, meshopt_SimplifyLockBorder | meshopt_SimplifySparse | meshopt_SimplifyRegularize preserves borders while optimizing for sparse indices and improving triangle regularity.
When should I use meshopt_SimplifyErrorAbsolute instead of relative error?
Use meshopt_SimplifyErrorAbsolute when you need to specify error thresholds in absolute world units rather than as a percentage of mesh extents. This is particularly important when processing multiple meshes of vastly different scales where a relative error value would produce inconsistent visual quality.
How do vertex lock flags interact with the meshopt_SimplifyLockBorder option?
meshopt_SimplifyLockBorder operates automatically on topological border vertices detected by the algorithm, while meshopt_SimplifyVertex_Lock and related flags in the vertex_lock array allow you to manually constrain specific vertices regardless of their topological position. These systems work independently; border locks apply globally based on mesh topology, whereas vertex locks target specific indices you mark in the array passed to meshopt_simplifyWithAttributes.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →