Isotropic Remeshing
2 min read•1 page
Isotropic Remeshing (Botsch & Kobbelt) iteratively transforms irregular, stretched triangles into nearly equilateral triangles of uniform target edge length $L$.
Split & Collapse Criteria:
1. Split Long Edges: Any edge with length $> \frac43 L$ is bisected at its midpoint. 2. Collapse Short Edges: Any edge with length $< \frac45 L$ is collapsed to an endpoint. 3. Target Uniformity: Prevents needle triangles and extreme area variations.
python
1def isotropic_remesh_pass(mesh, target_length):2 high_threshold = (4.0 / 3.0) * target_length3 low_threshold = (4.0 / 5.0) * target_length45 # 1. Split edges longer than high_threshold6 for edge in mesh.edges():7 if edge.length() > high_threshold:8 mesh.split_edge(edge)910 # 2. Collapse edges shorter than low_threshold11 for edge in mesh.edges():12 if edge.length() < low_threshold:13 mesh.collapse_edge(edge)
Target Length (L)
2.503 min read•1 page
Valence Optimization flips non-delaunay or irregular diagonal edges so that every interior vertex approaches the ideal valence of 6 (the optimal hexagonal packing topology).
Valence Flip Criterion:
1. Target Valence 6: Regular triangulations have 6 equilateral neighbors per vertex. 2. Cost Metric: Minimizes sum of squared valence errors (valence - 6)^2 before and after an edge swap. 3. Geometric Invariant: Flips are rejected if the resulting flipped triangles invert or fold.
python
1def flip_edges_for_valence(mesh):2 """Flip edges if doing so brings vertex valences closer to target 6."""3 target_valence = 645 for edge in mesh.interior_edges():6 v1, v2 = edge.vertices7 v3, v4 = edge.opposite_vertices()89 # Calculate current squared deviation from valence 610 current_cost = (11 (v1.valence - target_valence)**2 +12 (v2.valence - target_valence)**2 +13 (v3.valence - target_valence)**2 +14 (v4.valence - target_valence)**215 )1617 # After flipping: v1 and v2 lose 1 edge; v3 and v4 gain 1 edge18 flipped_cost = (19 (v1.valence - 1 - target_valence)**2 +20 (v2.valence - 1 - target_valence)**2 +21 (v3.valence + 1 - target_valence)**2 +22 (v4.valence + 1 - target_valence)**223 )2425 if flipped_cost < current_cost:26 mesh.flip_edge(edge)
Flip Diagonal Edge