Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Marching Cubes CPU Implementation Produces Artifacts at Higher Resolutions #1934

Open
AlexWolski opened this issue Jan 4, 2025 · 0 comments

Comments

@AlexWolski
Copy link

AlexWolski commented Jan 4, 2025

🐛 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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant