Skip to content

Commit 2b72495

Browse files
committed
Accelerate deformable edge collisions
Evaluate each unordered edge pair once and use a block-shared tile stack to redistribute distance tests from divergent BVH traversals. Preserve directed contact rows, filtering, and world grouping. Add dense single-world and replicated multi-world benchmarks that saturate the GPU and cover the full deformable detection pass.
1 parent e5b731c commit 2b72495

5 files changed

Lines changed: 250 additions & 116 deletions

File tree

asv/benchmarks/simulation/bench_cloth.py

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
# SPDX-FileCopyrightText: Copyright (c) 2025 The Newton Developers
22
# SPDX-License-Identifier: Apache-2.0
33

4+
import numpy as np
45
import warp as wp
5-
from asv_runner.benchmarks.mark import skip_benchmark_if
6+
from asv_runner.benchmarks.mark import SkipNotImplemented, skip_benchmark_if
67

78
wp.config.log_level = wp.LOG_WARNING
89

@@ -15,10 +16,93 @@
1516
from benchmark_config import pr_gate_repeat
1617

1718
import newton.examples
19+
from newton._src.geometry.tri_mesh_collision import TriMeshCollisionDetector
1820
from newton.examples.cloth.example_cloth_franka import Example as ExampleClothManipulation
1921
from newton.examples.cloth.example_cloth_twist import Example as ExampleClothTwist
2022
from newton.viewer import ViewerNull
2123

24+
DEFORMABLE_COLLISION_CASES = ((256, 1), (16, 1024))
25+
26+
27+
def _make_collision_grid(resolution, height):
28+
x, y = np.meshgrid(np.arange(resolution) * 0.01, np.arange(resolution) * 0.01)
29+
vertices = np.column_stack((x.ravel(), y.ravel(), np.full(x.size, height))).astype(np.float32)
30+
triangles = []
31+
for row in range(resolution - 1):
32+
for column in range(resolution - 1):
33+
lower = row * resolution + column
34+
triangles.extend(
35+
((lower, lower + 1, lower + resolution), (lower + 1, lower + resolution + 1, lower + resolution))
36+
)
37+
return vertices, np.asarray(triangles, dtype=np.int32)
38+
39+
40+
def _make_collision_world(resolution):
41+
vertices_a, triangles_a = _make_collision_grid(resolution, 0.0)
42+
vertices_b, triangles_b = _make_collision_grid(resolution, 0.006)
43+
triangles_b += len(vertices_a)
44+
world = newton.ModelBuilder(gravity=wp.vec3(0.0))
45+
world.add_cloth_mesh(
46+
pos=wp.vec3(0.0),
47+
rot=wp.quat_identity(),
48+
scale=1.0,
49+
vel=wp.vec3(0.0),
50+
vertices=np.concatenate((vertices_a, vertices_b)),
51+
indices=np.concatenate((triangles_a, triangles_b)).reshape(-1),
52+
density=1.0,
53+
tri_ke=1.0,
54+
tri_ka=1.0,
55+
tri_kd=0.0,
56+
edge_ke=0.0,
57+
edge_kd=0.0,
58+
)
59+
return world
60+
61+
62+
class DeformableSelfCollision:
63+
"""Benchmark dense self-collision in one large and many RL-style worlds."""
64+
65+
params = (DEFORMABLE_COLLISION_CASES,)
66+
param_names = ["case"]
67+
repeat = pr_gate_repeat(5)
68+
number = 1
69+
70+
def setup(self, case):
71+
device = wp.get_device()
72+
if not device.is_cuda:
73+
raise SkipNotImplemented
74+
75+
resolution, world_count = case
76+
builder = newton.ModelBuilder()
77+
builder.replicate(_make_collision_world(resolution), world_count)
78+
self.model = builder.finalize(device=device)
79+
self.detector = TriMeshCollisionDetector(
80+
self.model,
81+
init_collision_info=True,
82+
topological_contact_filter_threshold=0,
83+
vertex_collision_buffer_pre_alloc=32,
84+
edge_collision_buffer_pre_alloc=64,
85+
)
86+
self.radius = 0.012
87+
self.launch_count = 20
88+
89+
for _ in range(5):
90+
self._detect()
91+
with wp.ScopedCapture(device=device) as capture:
92+
self._detect()
93+
self.graph = capture.graph
94+
95+
def _detect(self):
96+
self.detector.refit(self.model.particle_q)
97+
self.detector.vertex_triangle_collision_detection(self.radius)
98+
self.detector.edge_edge_collision_detection(self.radius)
99+
100+
@skip_benchmark_if(wp.get_cuda_device_count() == 0)
101+
def time_detect(self, case):
102+
for _ in range(self.launch_count):
103+
wp.capture_launch(self.graph)
104+
wp.synchronize_device()
105+
22106

23107
class FastExampleClothManipulation:
24108
timeout = 300
@@ -65,6 +149,7 @@ def time_simulate(self):
65149
from newton.utils import run_benchmark
66150

67151
benchmark_list = {
152+
"DeformableSelfCollision": DeformableSelfCollision,
68153
"FastExampleClothManipulation": FastExampleClothManipulation,
69154
"FastExampleClothTwist": FastExampleClothTwist,
70155
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Accelerate CUDA deformable self-collision detection in large and replicated scenes by balancing edge-pair distance evaluations across thread blocks; no migration is required.

0 commit comments

Comments
 (0)