Dual Marching Cubes¶
Dual marching cubes extracts the dual of the marching cubes mesh (Nielson [2004]). The chosen marching cubes variant triangulates each cell, every connected piece of that triangulation becomes one vertex, and every crossed grid edge yields a quad connecting the vertices of the four cells around it. A cell crossed by several surface sheets gets one vertex per sheet, which avoids dual contouring’s pinches, and the topology follows the variant’s tables. Method Comparisons compares the methods in detail.
import torch
import isoext
from isoext import viewer
from isoext.sdf import CuboidSDF, RotationOp, get_sdf_normal, project_to_surface
Basic Usage¶
vertices, faces = isoext.dual_marching_cubes(grid, level=0.0, method="vega")
grid: AUniformGridorSparseGridwith values setlevel: The iso-value to extract (default: 0.0)method: The marching cubes variant that triangulates the cells ("vega","lewiner","nagae", or"lorensen")intersection: Optional edge crossings fromget_intersection; attach normals to them for sharp features
grid = isoext.UniformGrid([64, 64, 64])
grid.set_values(grid.get_points().norm(dim=-1) - 0.8) # Sphere
vertices, faces = isoext.dual_marching_cubes(grid)
print(f"{vertices.shape[0]:,} vertices, {faces.shape[0]:,} triangles")
viewer.embed(vertices, faces, color="crimson")
11,954 vertices, 23,904 triangles
Patches¶
A patch is one connected piece of a cell’s triangulation. Most cells have one. A cell crossed by two sheets has two, and gets two vertices, so the sheets stay separate. The smallest field that shows this has two inside samples at opposite corners of the center cell: the mesh comes out as two pieces, each the dual of the octahedron marching cubes would extract, and the center cell contributes one vertex to each:
t = 1 / 3
blobs = isoext.UniformGrid([4, 4, 4])
p = blobs.get_points()
centers = torch.tensor([[-t, -t, -t], [t, t, t]], device="cuda")
blobs.set_values((p[..., None, :] - centers).norm(dim=-1).amin(-1) - 0.5)
vertices, faces = isoext.dual_marching_cubes(blobs)
print(f"{vertices.shape[0]} vertices, {faces.shape[0]} triangles")
viewer.embed(vertices, faces, color="crimson", flat_shading=True, height=340, grid=blobs)
16 vertices, 24 triangles
References¶
Gregory M. Nielson. Dual marching cubes. In IEEE Visualization 2004, 489–496. 2004. doi:10.1109/VISUAL.2004.28.