Mesh: GPU-Accelerated Remesh#1822
Conversation
# Conflicts: # physicsnemo/mesh/mesh.py
Greptile SummaryThis PR replaces the PyACVD-based remeshing backend with a Warp-accelerated implementation that runs on both CPU and CUDA (up to 300\u00d7 faster), exposing the feature through
Important Files Changed
Reviews (1): Last reviewed commit: "Enable Warp remeshing on CPU" | Re-trigger Greptile |
| mesh = wp.mesh_get(mesh_id) | ||
| p0 = mesh.points[mesh.indices[3 * query.face + 0]] | ||
| p1 = mesh.points[mesh.indices[3 * query.face + 1]] | ||
| p2 = mesh.points[mesh.indices[3 * query.face + 2]] | ||
| centroids[centroid_index] = ( | ||
| query.u * p0 + query.v * p1 + (float(1.0) - query.u - query.v) * p2 | ||
| ) |
There was a problem hiding this comment.
Incorrect barycentric interpolation — centroids projected to wrong surface point
The manual barycentric formula swaps the vertex weights relative to Warp's convention. Warp's mesh_eval_position (and the underlying closest_point_to_triangle in intersect.h) uses the standard Möller-Trumbore parameterisation: closest = (1-u-v)*p0 + u*p1 + v*p2. The kernel instead computes u*p0 + v*p1 + (1-u-v)*p2, which places the centroid at a different point inside the same triangle — not the closest point on the surface. Warp examples universally use wp.mesh_eval_position(mesh_id, query.face, query.u, query.v) for exactly this reason.
The projected point is still geometrically on the surface (the coordinates are a valid convex combination), so the tests pass on symmetric geometry such as a sphere, but centroids on anisotropic or high-curvature surfaces will drift, producing worse mesh quality than intended. The simplest fix is to replace the manual computation with the built-in call: centroids[centroid_index] = wp.mesh_eval_position(mesh_id, query.face, query.u, query.v).
peterdsharpe
left a comment
There was a problem hiding this comment.
Submitting an initial partial review! This PR seems to have good bones, but a lot of new API surface here violates repo rules by not including jaxtyping on tensor inputs. Many functions are also missing complete (i.e., conforming to repo-wide style rules, with explanations for parameters) docstrings. Would you mind adding these, to aid in the review? Thanks!
|
@peterdsharpe Regarding the use of bultins.int: This is intentional. tensorclass generates methods like @tensorclass
class Example:
value: torch.Tensor
# Bare `int | None` resolves to the generated `Example.int` method on Python 3.14.
def method(self, count: builtins.int | None = None):
pass |
|
For future reference based on our conversations: I dug into this a bit more and the behavior is specific to Python 3.14, where annotations are evaluated lazily.
Here’s a minimal repro: import builtins
from typing import get_type_hints
import torch
from tensordict import tensorclass
@tensorclass
class Bare:
value: torch.Tensor
def method(self, count: int | None = None):
pass
@tensorclass
class Qualified:
value: torch.Tensor
def method(self, count: builtins.int | None = None):
pass
try:
print(get_type_hints(Bare.method))
except TypeError as error:
print("Bare annotation failed:", error)
print("Qualified annotation:", get_type_hints(Qualified.method))On Python 3.14, this prints: So I think keeping |
There was a problem hiding this comment.
This looks good — nice work. I checked out the branch and ran the test suites locally (109 passed, CPU + CUDA).
Key comments to fix below:
- The 2^24
torch.multinomiallimit: remeshing currently crashes above ~16.7M input vertices (repro and a drop-in fix in the inline comment). - The tuning knobs (
search_radius_scale,hash_grid_resolution, etc.) might be best left out of theMesh.remeshsignature and kept on the tensor functional — if you agree? Once these ship in a release we are committed to them. - Validation logic should be deduplicated between
mesh.remeshing.remeshand the functional's_validate_inputs. bunny.ptshould get regenerated so the checked-in asset matches the new remesher.
Everything else below is a suggestion / nit / optional.
|
Following up on the 2^24 That would:
One mode note: |
|
Thanks for the suggestion! I benchmarked both Poisson modes against the current initializer. The current approach generates exactly Weighted elimination does produce an exact There's also a compatibility issue with this CVT formulation. Since Lloyd assignment integrates over the weighted input vertices, triangle-interior Poisson seeds can start out without owning any input vertex. With The replacement sampler has been tested with 100 million candidate entries, and the full Warp remeshing pipeline has been validated on a 41.9M-vertex mesh, so I think the current initializer is the safer choice for this PR. That said, dart throwing is still worth revisiting later once preprocessing is shared and there's an exact-K fallback. |
|
/ok to test c141e8f |
|
/ok to test c141e8f |
|
/ok to test 972c432 |
PhysicsNeMo Pull Request
Description
This PR adds mesh remeshing to PhysicsNeMo using Warp.
The public API is available through
physicsnemo.mesh.remeshing.remeshandMesh.remesh. It supports CPU and CUDA meshes, preserves the input device, and provides controls for target vertex count, clustering, projection, topology reconstruction, and cleanup.The implementation includes:
torch.compilesupport throughFunctionSpec.CUDA remeshing can be up to 300× faster than PyACVD on CPU.
Checklist
Dependencies
No new dependencies are required. The implementation uses the existing Warp dependency, and PyACVD is not required.
Review Process
All PRs are reviewed by the PhysicsNeMo team before merging.
Depending on which files are changed, GitHub may automatically assign a maintainer for review.
We are also testing AI-based code review tools (e.g., Greptile), which may add automated comments with a confidence score.
This score reflects the AI’s assessment of merge readiness and is not a qualitative judgment of your work, nor is
it an indication that the PR will be accepted / rejected.
AI-generated feedback should be reviewed critically for usefulness.
You are not required to respond to every AI comment, but they are intended to help both authors and reviewers.
Please react to Greptile comments with 👍 or 👎 to provide feedback on their accuracy.