Skip to content

Marching Cubes CPU Implementation Produces Artifacts at Higher Resolutions #1934

Open
@AlexWolski

Description

@AlexWolski

🐛 Bugs / Unexpected behaviors

Running marching cubes on the CPU at higher resolutions (256, 512, 1024) seems to produce meshes with missing vertices and faces. The higher the resolution, the more holes that appear in the mesh. The GPU implementation doesn't exhibit this behavior.

128 Resolution CPU vs GPU:
128

256 Resolution CPU vs GPU:
256

512 Resolution CPU vs GPU:
512

Minimal Reproducible Example:

import torch
from pytorch3d.ops.marching_cubes import marching_cubes
from pytorch3d.io import save_obj


def get_grid_points(min_bound, max_bound, resolution, device=None):
	axis_values = torch.linspace(min_bound, max_bound, resolution, dtype=torch.float32, device=device)
	grid_axes = torch.meshgrid(axis_values, axis_values, axis_values, indexing='ij')
	grid_points = torch.stack(grid_axes, dim=-1)
	return grid_points.detach()


def sdf_ellipsoid(query_points, dimensions):
	dimensions = dimensions.unsqueeze(1)
	k0 = (query_points / dimensions).norm(dim=-1)
	k1 = (query_points / (dimensions*dimensions)).norm(dim=-1)
	distances = k0 * (k0 - 1.0) / k1
	return distances


def export_mesh(distances, filename):
	device_str = distances.device.type
	verts, faces = marching_cubes(distances, isolevel=0.0, return_local_coords=True)
	print(f'{device_str} Verts:\t{verts[0].size()[0]}', end='\t')
	print(f'{device_str} Faces:\t{faces[0].size()[0]}')
	save_obj(filename, verts[0], faces[0])


def marching_cubes_test(resolution):
	cuda_device = torch.device('cuda')

	grid_points = get_grid_points(-1, 1, resolution, cuda_device)
	flat_points = grid_points.reshape(1, -1, 3)
	ellipse_dimensions = torch.tensor([[0.1, 1, 1]], dtype=torch.float32, device=cuda_device)
	distances = sdf_ellipsoid(flat_points, ellipse_dimensions)
	distances = distances.reshape(1, resolution, resolution, resolution)

	print(f'Tensors Equal?\t{torch.equal(distances, distances.cpu().to(cuda_device))}')
	print(f'CUDA dtype:\t{distances.dtype}')
	print(f'CPU  dtype:\t{distances.cpu().dtype}')
	export_mesh(distances, f'cuda_mesh_{resolution}.obj')
	export_mesh(distances.cpu(), f'cpu_mesh_{resolution}.obj')


marching_cubes_test(256)

The output when testing with a resolution of 512 is:

Tensors Equal?	True
CUDA dtype:	torch.float32
CPU  dtype:	torch.float32
cuda Verts:	491944	cuda Faces:	983884
cpu Verts:	176121	cpu Faces:	968836

Environment

The python environment has pytorch 2.4.1 and pytorch3d 0.7.8.

My machine is running Linux with an RTX 3080 graphics card and AMD 3950X CPU.

Can anyone else reproduce this issue?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions