warp-lang 1.3.3__py3-none-macosx_10_13_universal2.whl → 1.4.1__py3-none-macosx_10_13_universal2.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of warp-lang might be problematic. Click here for more details.
- warp/__init__.py +6 -0
- warp/autograd.py +59 -6
- warp/bin/libwarp.dylib +0 -0
- warp/build_dll.py +8 -10
- warp/builtins.py +103 -3
- warp/codegen.py +447 -53
- warp/config.py +1 -1
- warp/context.py +682 -405
- warp/dlpack.py +2 -0
- warp/examples/benchmarks/benchmark_cloth.py +10 -0
- warp/examples/core/example_render_opengl.py +12 -10
- warp/examples/fem/example_adaptive_grid.py +251 -0
- warp/examples/fem/example_apic_fluid.py +1 -1
- warp/examples/fem/example_diffusion_3d.py +2 -2
- warp/examples/fem/example_magnetostatics.py +1 -1
- warp/examples/fem/example_streamlines.py +1 -0
- warp/examples/fem/utils.py +25 -5
- warp/examples/sim/example_cloth.py +50 -6
- warp/fem/__init__.py +2 -0
- warp/fem/adaptivity.py +493 -0
- warp/fem/field/field.py +2 -1
- warp/fem/field/nodal_field.py +18 -26
- warp/fem/field/test.py +4 -4
- warp/fem/field/trial.py +4 -4
- warp/fem/geometry/__init__.py +1 -0
- warp/fem/geometry/adaptive_nanogrid.py +843 -0
- warp/fem/geometry/nanogrid.py +55 -28
- warp/fem/space/__init__.py +1 -1
- warp/fem/space/nanogrid_function_space.py +69 -35
- warp/fem/utils.py +118 -107
- warp/jax_experimental.py +28 -15
- warp/native/array.h +0 -1
- warp/native/builtin.h +103 -6
- warp/native/bvh.cu +4 -2
- warp/native/cuda_util.cpp +14 -0
- warp/native/cuda_util.h +2 -0
- warp/native/error.cpp +4 -2
- warp/native/exports.h +99 -0
- warp/native/mat.h +97 -0
- warp/native/mesh.cpp +36 -0
- warp/native/mesh.cu +52 -1
- warp/native/mesh.h +1 -0
- warp/native/quat.h +43 -0
- warp/native/range.h +11 -2
- warp/native/spatial.h +6 -0
- warp/native/vec.h +74 -0
- warp/native/warp.cpp +2 -1
- warp/native/warp.cu +10 -3
- warp/native/warp.h +8 -1
- warp/paddle.py +382 -0
- warp/sim/__init__.py +1 -0
- warp/sim/collide.py +519 -0
- warp/sim/integrator_euler.py +18 -5
- warp/sim/integrator_featherstone.py +5 -5
- warp/sim/integrator_vbd.py +1026 -0
- warp/sim/integrator_xpbd.py +2 -6
- warp/sim/model.py +50 -25
- warp/sparse.py +9 -7
- warp/stubs.py +459 -0
- warp/tape.py +2 -0
- warp/tests/aux_test_dependent.py +1 -0
- warp/tests/aux_test_name_clash1.py +32 -0
- warp/tests/aux_test_name_clash2.py +32 -0
- warp/tests/aux_test_square.py +1 -0
- warp/tests/test_array.py +188 -0
- warp/tests/test_async.py +3 -3
- warp/tests/test_atomic.py +6 -0
- warp/tests/test_closest_point_edge_edge.py +93 -1
- warp/tests/test_codegen.py +93 -15
- warp/tests/test_codegen_instancing.py +1457 -0
- warp/tests/test_collision.py +486 -0
- warp/tests/test_compile_consts.py +3 -28
- warp/tests/test_dlpack.py +170 -0
- warp/tests/test_examples.py +22 -8
- warp/tests/test_fast_math.py +10 -4
- warp/tests/test_fem.py +81 -1
- warp/tests/test_func.py +46 -0
- warp/tests/test_implicit_init.py +49 -0
- warp/tests/test_jax.py +58 -0
- warp/tests/test_mat.py +84 -0
- warp/tests/test_mesh_query_point.py +188 -0
- warp/tests/test_model.py +13 -0
- warp/tests/test_module_hashing.py +40 -0
- warp/tests/test_multigpu.py +3 -3
- warp/tests/test_overwrite.py +8 -0
- warp/tests/test_paddle.py +852 -0
- warp/tests/test_print.py +89 -0
- warp/tests/test_quat.py +111 -0
- warp/tests/test_reload.py +31 -1
- warp/tests/test_scalar_ops.py +2 -0
- warp/tests/test_static.py +568 -0
- warp/tests/test_streams.py +64 -3
- warp/tests/test_struct.py +4 -4
- warp/tests/test_torch.py +24 -0
- warp/tests/test_triangle_closest_point.py +137 -0
- warp/tests/test_types.py +1 -1
- warp/tests/test_vbd.py +386 -0
- warp/tests/test_vec.py +143 -0
- warp/tests/test_vec_scalar_ops.py +139 -0
- warp/tests/unittest_suites.py +12 -0
- warp/tests/unittest_utils.py +9 -5
- warp/thirdparty/dlpack.py +3 -1
- warp/types.py +167 -36
- warp/utils.py +37 -14
- {warp_lang-1.3.3.dist-info → warp_lang-1.4.1.dist-info}/METADATA +10 -8
- {warp_lang-1.3.3.dist-info → warp_lang-1.4.1.dist-info}/RECORD +109 -97
- warp/tests/test_point_triangle_closest_point.py +0 -143
- {warp_lang-1.3.3.dist-info → warp_lang-1.4.1.dist-info}/LICENSE.md +0 -0
- {warp_lang-1.3.3.dist-info → warp_lang-1.4.1.dist-info}/WHEEL +0 -0
- {warp_lang-1.3.3.dist-info → warp_lang-1.4.1.dist-info}/top_level.txt +0 -0
warp/tests/test_torch.py
CHANGED
|
@@ -382,6 +382,27 @@ def test_array_ctype_from_torch(test, device):
|
|
|
382
382
|
wrap_vec_tensor_with_warp_grad(wp.transform)
|
|
383
383
|
|
|
384
384
|
|
|
385
|
+
def test_cuda_array_interface(test, device):
|
|
386
|
+
# We should be able to construct Torch tensors from Warp arrays via __cuda_array_interface__ on GPU.
|
|
387
|
+
# Note that Torch does not support __array_interface__ on CPU.
|
|
388
|
+
|
|
389
|
+
torch_device = wp.device_to_torch(device)
|
|
390
|
+
n = 10
|
|
391
|
+
|
|
392
|
+
# test the types supported by both Warp and Torch
|
|
393
|
+
scalar_types = [wp.float16, wp.float32, wp.float64, wp.int8, wp.int16, wp.int32, wp.int64, wp.uint8]
|
|
394
|
+
|
|
395
|
+
for dtype in scalar_types:
|
|
396
|
+
# test round trip
|
|
397
|
+
a1 = wp.zeros(n, dtype=dtype, device=device)
|
|
398
|
+
t = torch.tensor(a1, device=torch_device)
|
|
399
|
+
a2 = wp.array(t, device=device)
|
|
400
|
+
|
|
401
|
+
assert a1.dtype == a2.dtype
|
|
402
|
+
assert a1.shape == a2.shape
|
|
403
|
+
assert a1.strides == a2.strides
|
|
404
|
+
|
|
405
|
+
|
|
385
406
|
def test_to_torch(test, device):
|
|
386
407
|
import torch
|
|
387
408
|
|
|
@@ -918,6 +939,9 @@ try:
|
|
|
918
939
|
test_warp_graph_torch_stream,
|
|
919
940
|
devices=torch_compatible_cuda_devices,
|
|
920
941
|
)
|
|
942
|
+
add_function_test(
|
|
943
|
+
TestTorch, "test_cuda_array_interface", test_cuda_array_interface, devices=torch_compatible_cuda_devices
|
|
944
|
+
)
|
|
921
945
|
|
|
922
946
|
# multi-GPU tests
|
|
923
947
|
if len(torch_compatible_cuda_devices) > 1:
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# Copyright (c) 2024 NVIDIA CORPORATION. All rights reserved.
|
|
2
|
+
# NVIDIA CORPORATION and its licensors retain all intellectual property
|
|
3
|
+
# and proprietary rights in and to this software, related documentation
|
|
4
|
+
# and any modifications thereto. Any use, reproduction, disclosure or
|
|
5
|
+
# distribution of this software and related documentation without an express
|
|
6
|
+
# license agreement from NVIDIA CORPORATION is strictly prohibited.
|
|
7
|
+
|
|
8
|
+
import unittest
|
|
9
|
+
|
|
10
|
+
from warp.sim.collide import triangle_closest_point_barycentric
|
|
11
|
+
from warp.tests.unittest_utils import *
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# a-b is the edge where the closest point is located at
|
|
15
|
+
@wp.func
|
|
16
|
+
def check_edge_feasible_region(p: wp.vec3, a: wp.vec3, b: wp.vec3, c: wp.vec3, eps: float):
|
|
17
|
+
ap = p - a
|
|
18
|
+
bp = p - b
|
|
19
|
+
ab = b - a
|
|
20
|
+
|
|
21
|
+
if wp.dot(ap, ab) < -eps:
|
|
22
|
+
return False
|
|
23
|
+
|
|
24
|
+
if wp.dot(bp, ab) > eps:
|
|
25
|
+
return False
|
|
26
|
+
|
|
27
|
+
ab_sqr_norm = wp.dot(ab, ab)
|
|
28
|
+
if ab_sqr_norm < eps:
|
|
29
|
+
return False
|
|
30
|
+
|
|
31
|
+
t = wp.dot(ab, c - a) / ab_sqr_norm
|
|
32
|
+
|
|
33
|
+
perpendicular_foot = a + t * ab
|
|
34
|
+
|
|
35
|
+
if wp.dot(c - perpendicular_foot, p - perpendicular_foot) > eps:
|
|
36
|
+
return False
|
|
37
|
+
|
|
38
|
+
return True
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
# closest point is a
|
|
42
|
+
@wp.func
|
|
43
|
+
def check_vertex_feasible_region(p: wp.vec3, a: wp.vec3, b: wp.vec3, c: wp.vec3, eps: float):
|
|
44
|
+
ap = p - a
|
|
45
|
+
ba = a - b
|
|
46
|
+
ca = a - c
|
|
47
|
+
|
|
48
|
+
if wp.dot(ap, ba) < -eps:
|
|
49
|
+
return False
|
|
50
|
+
|
|
51
|
+
if wp.dot(p, ca) < -eps:
|
|
52
|
+
return False
|
|
53
|
+
|
|
54
|
+
return True
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
@wp.kernel
|
|
58
|
+
def test_triangle_closest_point_kernel(tri: wp.array(dtype=wp.vec3), passed: wp.array(dtype=wp.bool)):
|
|
59
|
+
state = wp.uint32(wp.rand_init(wp.int32(123), wp.int32(0)))
|
|
60
|
+
eps = 1e-5
|
|
61
|
+
|
|
62
|
+
a = tri[0]
|
|
63
|
+
b = tri[1]
|
|
64
|
+
c = tri[2]
|
|
65
|
+
|
|
66
|
+
for _i in range(1000):
|
|
67
|
+
l = wp.float32(0.0)
|
|
68
|
+
while l < eps:
|
|
69
|
+
p = wp.vec3(wp.randn(state), wp.randn(state), wp.randn(state))
|
|
70
|
+
l = wp.length(p)
|
|
71
|
+
|
|
72
|
+
# project to a sphere with r=2
|
|
73
|
+
p = 2.0 * p / l
|
|
74
|
+
|
|
75
|
+
bary = triangle_closest_point_barycentric(tri[0], tri[1], tri[2], p)
|
|
76
|
+
|
|
77
|
+
for dim in range(3):
|
|
78
|
+
v1_index = (dim + 1) % 3
|
|
79
|
+
v2_index = (dim + 2) % 3
|
|
80
|
+
v1 = tri[v1_index]
|
|
81
|
+
v2 = tri[v2_index]
|
|
82
|
+
v3 = tri[dim]
|
|
83
|
+
|
|
84
|
+
# on edge
|
|
85
|
+
if bary[dim] == 0.0 and bary[v1_index] != 0.0 and bary[v2_index] != 0.0:
|
|
86
|
+
if not check_edge_feasible_region(p, v1, v2, v3, eps):
|
|
87
|
+
passed[0] = False
|
|
88
|
+
return
|
|
89
|
+
|
|
90
|
+
# p-closest_p must be perpendicular to v1-v2
|
|
91
|
+
closest_p = a * bary[0] + b * bary[1] + c * bary[2]
|
|
92
|
+
e = v1 - v2
|
|
93
|
+
err = wp.dot(e, closest_p - p)
|
|
94
|
+
if wp.abs(err) > eps:
|
|
95
|
+
passed[0] = False
|
|
96
|
+
return
|
|
97
|
+
|
|
98
|
+
if bary[v1_index] == 0.0 and bary[v2_index] == 0.0:
|
|
99
|
+
if not check_vertex_feasible_region(p, v3, v1, v2, eps):
|
|
100
|
+
passed[0] = False
|
|
101
|
+
return
|
|
102
|
+
|
|
103
|
+
if bary[dim] != 0.0 and bary[v1_index] != 0.0 and bary[v2_index] != 0.0:
|
|
104
|
+
closest_p = a * bary[0] + b * bary[1] + c * bary[2]
|
|
105
|
+
e1 = v1 - v2
|
|
106
|
+
e2 = v1 - v3
|
|
107
|
+
if wp.abs(wp.dot(e1, closest_p - p)) > eps or wp.abs(wp.dot(e2, closest_p - p)) > eps:
|
|
108
|
+
passed[0] = False
|
|
109
|
+
return
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def test_triangle_closest_point(test, device):
|
|
113
|
+
passed = wp.array([True], dtype=wp.bool, device=device)
|
|
114
|
+
|
|
115
|
+
a = wp.vec3(1.0, 0.0, 0.0)
|
|
116
|
+
b = wp.vec3(0.0, 0.0, 0.0)
|
|
117
|
+
c = wp.vec3(0.0, 1.0, 0.0)
|
|
118
|
+
|
|
119
|
+
tri = wp.array([a, b, c], dtype=wp.vec3, device=device)
|
|
120
|
+
wp.launch(test_triangle_closest_point_kernel, dim=1, inputs=[tri, passed], device=device)
|
|
121
|
+
passed = passed.numpy()
|
|
122
|
+
|
|
123
|
+
test.assertTrue(passed.all())
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
devices = get_test_devices()
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
class TestTriangleClosestPoint(unittest.TestCase):
|
|
130
|
+
pass
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
add_function_test(TestTriangleClosestPoint, "test_triangle_closest_point", test_triangle_closest_point, devices=devices)
|
|
134
|
+
|
|
135
|
+
if __name__ == "__main__":
|
|
136
|
+
wp.clear_kernel_cache()
|
|
137
|
+
unittest.main(verbosity=2)
|
warp/tests/test_types.py
CHANGED
|
@@ -215,7 +215,7 @@ class TestTypes(unittest.TestCase):
|
|
|
215
215
|
self.assertEqual(const, wp.vec3i(1, 2, 3))
|
|
216
216
|
|
|
217
217
|
def test_constant_error_invalid_type(self):
|
|
218
|
-
with self.assertRaisesRegex(
|
|
218
|
+
with self.assertRaisesRegex(TypeError, r"Invalid constant type: <class 'tuple'>$"):
|
|
219
219
|
wp.constant((1, 2, 3))
|
|
220
220
|
|
|
221
221
|
def test_vector_assign(self):
|
warp/tests/test_vbd.py
ADDED
|
@@ -0,0 +1,386 @@
|
|
|
1
|
+
# Copyright (c) 2024 NVIDIA CORPORATION. All rights reserved.
|
|
2
|
+
# NVIDIA CORPORATION and its licensors retain all intellectual property
|
|
3
|
+
# and proprietary rights in and to this software, related documentation
|
|
4
|
+
# and any modifications thereto. Any use, reproduction, disclosure or
|
|
5
|
+
# distribution of this software and related documentation without an express
|
|
6
|
+
# license agreement from NVIDIA CORPORATION is strictly prohibited.
|
|
7
|
+
|
|
8
|
+
import unittest
|
|
9
|
+
|
|
10
|
+
import warp as wp
|
|
11
|
+
import warp.optim
|
|
12
|
+
import warp.sim
|
|
13
|
+
from warp.sim.model import (
|
|
14
|
+
PARTICLE_FLAG_ACTIVE,
|
|
15
|
+
)
|
|
16
|
+
from warp.tests.unittest_utils import *
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class VBDClothSim:
|
|
20
|
+
def __init__(self, device):
|
|
21
|
+
# fmt: off
|
|
22
|
+
self.pts = [
|
|
23
|
+
(-50.0000000, 0.0000000, -50.0000000),
|
|
24
|
+
(-38.8888893, 11.1111107, -50.0000000),
|
|
25
|
+
(-27.7777786, 22.2222214, -50.0000000),
|
|
26
|
+
(-16.6666679, 33.3333321, -50.0000000),
|
|
27
|
+
(-5.5555558, 44.4444427, -50.0000000),
|
|
28
|
+
(5.5555558, 55.5555573, -50.0000000),
|
|
29
|
+
(16.6666679, 66.6666641, -50.0000000),
|
|
30
|
+
(27.7777786, 77.7777786, -50.0000000),
|
|
31
|
+
(38.8888893, 88.8888855, -50.0000000),
|
|
32
|
+
(50.0000000, 100.0000000, -50.0000000),
|
|
33
|
+
(-50.0000000, 0.0000000, -38.8888893),
|
|
34
|
+
(-38.8888893, 11.1111107, -38.8888893),
|
|
35
|
+
(-27.7777786, 22.2222214, -38.8888893),
|
|
36
|
+
(-16.6666679, 33.3333321, -38.8888893),
|
|
37
|
+
(-5.5555558, 44.4444427, -38.8888893),
|
|
38
|
+
(5.5555558, 55.5555573, -38.8888893),
|
|
39
|
+
(16.6666679, 66.6666641, -38.8888893),
|
|
40
|
+
(27.7777786, 77.7777786, -38.8888893),
|
|
41
|
+
(38.8888893, 88.8888855, -38.8888893),
|
|
42
|
+
(50.0000000, 100.0000000, -38.8888893),
|
|
43
|
+
(-50.0000000, 0.0000000, -27.7777786),
|
|
44
|
+
(-38.8888893, 11.1111107, -27.7777786),
|
|
45
|
+
(-27.7777786, 22.2222214, -27.7777786),
|
|
46
|
+
(-16.6666679, 33.3333321, -27.7777786),
|
|
47
|
+
(-5.5555558, 44.4444427, -27.7777786),
|
|
48
|
+
(5.5555558, 55.5555573, -27.7777786),
|
|
49
|
+
(16.6666679, 66.6666641, -27.7777786),
|
|
50
|
+
(27.7777786, 77.7777786, -27.7777786),
|
|
51
|
+
(38.8888893, 88.8888855, -27.7777786),
|
|
52
|
+
(50.0000000, 100.0000000, -27.7777786),
|
|
53
|
+
(-50.0000000, 0.0000000, -16.6666679),
|
|
54
|
+
(-38.8888893, 11.1111107, -16.6666679),
|
|
55
|
+
(-27.7777786, 22.2222214, -16.6666679),
|
|
56
|
+
(-16.6666679, 33.3333321, -16.6666679),
|
|
57
|
+
(-5.5555558, 44.4444427, -16.6666679),
|
|
58
|
+
(5.5555558, 55.5555573, -16.6666679),
|
|
59
|
+
(16.6666679, 66.6666641, -16.6666679),
|
|
60
|
+
(27.7777786, 77.7777786, -16.6666679),
|
|
61
|
+
(38.8888893, 88.8888855, -16.6666679),
|
|
62
|
+
(50.0000000, 100.0000000, -16.6666679),
|
|
63
|
+
(-50.0000000, 0.0000000, -5.5555558),
|
|
64
|
+
(-38.8888893, 11.1111107, -5.5555558),
|
|
65
|
+
(-27.7777786, 22.2222214, -5.5555558),
|
|
66
|
+
(-16.6666679, 33.3333321, -5.5555558),
|
|
67
|
+
(-5.5555558, 44.4444427, -5.5555558),
|
|
68
|
+
(5.5555558, 55.5555573, -5.5555558),
|
|
69
|
+
(16.6666679, 66.6666641, -5.5555558),
|
|
70
|
+
(27.7777786, 77.7777786, -5.5555558),
|
|
71
|
+
(38.8888893, 88.8888855, -5.5555558),
|
|
72
|
+
(50.0000000, 100.0000000, -5.5555558),
|
|
73
|
+
(-50.0000000, 0.0000000, 5.5555558),
|
|
74
|
+
(-38.8888893, 11.1111107, 5.5555558),
|
|
75
|
+
(-27.7777786, 22.2222214, 5.5555558),
|
|
76
|
+
(-16.6666679, 33.3333321, 5.5555558),
|
|
77
|
+
(-5.5555558, 44.4444427, 5.5555558),
|
|
78
|
+
(5.5555558, 55.5555573, 5.5555558),
|
|
79
|
+
(16.6666679, 66.6666641, 5.5555558),
|
|
80
|
+
(27.7777786, 77.7777786, 5.5555558),
|
|
81
|
+
(38.8888893, 88.8888855, 5.5555558),
|
|
82
|
+
(50.0000000, 100.0000000, 5.5555558),
|
|
83
|
+
(-50.0000000, 0.0000000, 16.6666679),
|
|
84
|
+
(-38.8888893, 11.1111107, 16.6666679),
|
|
85
|
+
(-27.7777786, 22.2222214, 16.6666679),
|
|
86
|
+
(-16.6666679, 33.3333321, 16.6666679),
|
|
87
|
+
(-5.5555558, 44.4444427, 16.6666679),
|
|
88
|
+
(5.5555558, 55.5555573, 16.6666679),
|
|
89
|
+
(16.6666679, 66.6666641, 16.6666679),
|
|
90
|
+
(27.7777786, 77.7777786, 16.6666679),
|
|
91
|
+
(38.8888893, 88.8888855, 16.6666679),
|
|
92
|
+
(50.0000000, 100.0000000, 16.6666679),
|
|
93
|
+
(-50.0000000, 0.0000000, 27.7777786),
|
|
94
|
+
(-38.8888893, 11.1111107, 27.7777786),
|
|
95
|
+
(-27.7777786, 22.2222214, 27.7777786),
|
|
96
|
+
(-16.6666679, 33.3333321, 27.7777786),
|
|
97
|
+
(-5.5555558, 44.4444427, 27.7777786),
|
|
98
|
+
(5.5555558, 55.5555573, 27.7777786),
|
|
99
|
+
(16.6666679, 66.6666641, 27.7777786),
|
|
100
|
+
(27.7777786, 77.7777786, 27.7777786),
|
|
101
|
+
(38.8888893, 88.8888855, 27.7777786),
|
|
102
|
+
(50.0000000, 100.0000000, 27.7777786),
|
|
103
|
+
(-50.0000000, 0.0000000, 38.8888893),
|
|
104
|
+
(-38.8888893, 11.1111107, 38.8888893),
|
|
105
|
+
(-27.7777786, 22.2222214, 38.8888893),
|
|
106
|
+
(-16.6666679, 33.3333321, 38.8888893),
|
|
107
|
+
(-5.5555558, 44.4444427, 38.8888893),
|
|
108
|
+
(5.5555558, 55.5555573, 38.8888893),
|
|
109
|
+
(16.6666679, 66.6666641, 38.8888893),
|
|
110
|
+
(27.7777786, 77.7777786, 38.8888893),
|
|
111
|
+
(38.8888893, 88.8888855, 38.8888893),
|
|
112
|
+
(50.0000000, 100.0000000, 38.8888893),
|
|
113
|
+
(-50.0000000, 0.0000000, 50.0000000),
|
|
114
|
+
(-38.8888893, 11.1111107, 50.0000000),
|
|
115
|
+
(-27.7777786, 22.2222214, 50.0000000),
|
|
116
|
+
(-16.6666679, 33.3333321, 50.0000000),
|
|
117
|
+
(-5.5555558, 44.4444427, 50.0000000),
|
|
118
|
+
(5.5555558, 55.5555573, 50.0000000),
|
|
119
|
+
(16.6666679, 66.6666641, 50.0000000),
|
|
120
|
+
(27.7777786, 77.7777786, 50.0000000),
|
|
121
|
+
(38.8888893, 88.8888855, 50.0000000),
|
|
122
|
+
(50.0000000, 100.0000000, 50.0000000),
|
|
123
|
+
]
|
|
124
|
+
|
|
125
|
+
self.faces = [
|
|
126
|
+
1, 12, 2,
|
|
127
|
+
1, 11, 12,
|
|
128
|
+
2, 12, 3,
|
|
129
|
+
12, 13, 3,
|
|
130
|
+
3, 14, 4,
|
|
131
|
+
3, 13, 14,
|
|
132
|
+
4, 14, 5,
|
|
133
|
+
14, 15, 5,
|
|
134
|
+
5, 16, 6,
|
|
135
|
+
5, 15, 16,
|
|
136
|
+
6, 16, 7,
|
|
137
|
+
16, 17, 7,
|
|
138
|
+
7, 18, 8,
|
|
139
|
+
7, 17, 18,
|
|
140
|
+
8, 18, 9,
|
|
141
|
+
18, 19, 9,
|
|
142
|
+
9, 20, 10,
|
|
143
|
+
9, 19, 20,
|
|
144
|
+
11, 21, 12,
|
|
145
|
+
21, 22, 12,
|
|
146
|
+
12, 23, 13,
|
|
147
|
+
12, 22, 23,
|
|
148
|
+
13, 23, 14,
|
|
149
|
+
23, 24, 14,
|
|
150
|
+
14, 25, 15,
|
|
151
|
+
14, 24, 25,
|
|
152
|
+
15, 25, 16,
|
|
153
|
+
25, 26, 16,
|
|
154
|
+
16, 27, 17,
|
|
155
|
+
16, 26, 27,
|
|
156
|
+
17, 27, 18,
|
|
157
|
+
27, 28, 18,
|
|
158
|
+
18, 29, 19,
|
|
159
|
+
18, 28, 29,
|
|
160
|
+
19, 29, 20,
|
|
161
|
+
29, 30, 20,
|
|
162
|
+
21, 32, 22,
|
|
163
|
+
21, 31, 32,
|
|
164
|
+
22, 32, 23,
|
|
165
|
+
32, 33, 23,
|
|
166
|
+
23, 34, 24,
|
|
167
|
+
23, 33, 34,
|
|
168
|
+
24, 34, 25,
|
|
169
|
+
34, 35, 25,
|
|
170
|
+
25, 36, 26,
|
|
171
|
+
25, 35, 36,
|
|
172
|
+
26, 36, 27,
|
|
173
|
+
36, 37, 27,
|
|
174
|
+
27, 38, 28,
|
|
175
|
+
27, 37, 38,
|
|
176
|
+
28, 38, 29,
|
|
177
|
+
38, 39, 29,
|
|
178
|
+
29, 40, 30,
|
|
179
|
+
29, 39, 40,
|
|
180
|
+
31, 41, 32,
|
|
181
|
+
41, 42, 32,
|
|
182
|
+
32, 43, 33,
|
|
183
|
+
32, 42, 43,
|
|
184
|
+
33, 43, 34,
|
|
185
|
+
43, 44, 34,
|
|
186
|
+
34, 45, 35,
|
|
187
|
+
34, 44, 45,
|
|
188
|
+
35, 45, 36,
|
|
189
|
+
45, 46, 36,
|
|
190
|
+
36, 47, 37,
|
|
191
|
+
36, 46, 47,
|
|
192
|
+
37, 47, 38,
|
|
193
|
+
47, 48, 38,
|
|
194
|
+
38, 49, 39,
|
|
195
|
+
38, 48, 49,
|
|
196
|
+
39, 49, 40,
|
|
197
|
+
49, 50, 40,
|
|
198
|
+
41, 52, 42,
|
|
199
|
+
41, 51, 52,
|
|
200
|
+
42, 52, 43,
|
|
201
|
+
52, 53, 43,
|
|
202
|
+
43, 54, 44,
|
|
203
|
+
43, 53, 54,
|
|
204
|
+
44, 54, 45,
|
|
205
|
+
54, 55, 45,
|
|
206
|
+
45, 56, 46,
|
|
207
|
+
45, 55, 56,
|
|
208
|
+
46, 56, 47,
|
|
209
|
+
56, 57, 47,
|
|
210
|
+
47, 58, 48,
|
|
211
|
+
47, 57, 58,
|
|
212
|
+
48, 58, 49,
|
|
213
|
+
58, 59, 49,
|
|
214
|
+
49, 60, 50,
|
|
215
|
+
49, 59, 60,
|
|
216
|
+
51, 61, 52,
|
|
217
|
+
61, 62, 52,
|
|
218
|
+
52, 63, 53,
|
|
219
|
+
52, 62, 63,
|
|
220
|
+
53, 63, 54,
|
|
221
|
+
63, 64, 54,
|
|
222
|
+
54, 65, 55,
|
|
223
|
+
54, 64, 65,
|
|
224
|
+
55, 65, 56,
|
|
225
|
+
65, 66, 56,
|
|
226
|
+
56, 67, 57,
|
|
227
|
+
56, 66, 67,
|
|
228
|
+
57, 67, 58,
|
|
229
|
+
67, 68, 58,
|
|
230
|
+
58, 69, 59,
|
|
231
|
+
58, 68, 69,
|
|
232
|
+
59, 69, 60,
|
|
233
|
+
69, 70, 60,
|
|
234
|
+
61, 72, 62,
|
|
235
|
+
61, 71, 72,
|
|
236
|
+
62, 72, 63,
|
|
237
|
+
72, 73, 63,
|
|
238
|
+
63, 74, 64,
|
|
239
|
+
63, 73, 74,
|
|
240
|
+
64, 74, 65,
|
|
241
|
+
74, 75, 65,
|
|
242
|
+
65, 76, 66,
|
|
243
|
+
65, 75, 76,
|
|
244
|
+
66, 76, 67,
|
|
245
|
+
76, 77, 67,
|
|
246
|
+
67, 78, 68,
|
|
247
|
+
67, 77, 78,
|
|
248
|
+
68, 78, 69,
|
|
249
|
+
78, 79, 69,
|
|
250
|
+
69, 80, 70,
|
|
251
|
+
69, 79, 80,
|
|
252
|
+
71, 81, 72,
|
|
253
|
+
81, 82, 72,
|
|
254
|
+
72, 83, 73,
|
|
255
|
+
72, 82, 83,
|
|
256
|
+
73, 83, 74,
|
|
257
|
+
83, 84, 74,
|
|
258
|
+
74, 85, 75,
|
|
259
|
+
74, 84, 85,
|
|
260
|
+
75, 85, 76,
|
|
261
|
+
85, 86, 76,
|
|
262
|
+
76, 87, 77,
|
|
263
|
+
76, 86, 87,
|
|
264
|
+
77, 87, 78,
|
|
265
|
+
87, 88, 78,
|
|
266
|
+
78, 89, 79,
|
|
267
|
+
78, 88, 89,
|
|
268
|
+
79, 89, 80,
|
|
269
|
+
89, 90, 80,
|
|
270
|
+
81, 92, 82,
|
|
271
|
+
81, 91, 92,
|
|
272
|
+
82, 92, 83,
|
|
273
|
+
92, 93, 83,
|
|
274
|
+
83, 94, 84,
|
|
275
|
+
83, 93, 94,
|
|
276
|
+
84, 94, 85,
|
|
277
|
+
94, 95, 85,
|
|
278
|
+
85, 96, 86,
|
|
279
|
+
85, 95, 96,
|
|
280
|
+
86, 96, 87,
|
|
281
|
+
96, 97, 87,
|
|
282
|
+
87, 98, 88,
|
|
283
|
+
87, 97, 98,
|
|
284
|
+
88, 98, 89,
|
|
285
|
+
98, 99, 89,
|
|
286
|
+
89, 100, 90,
|
|
287
|
+
89, 99, 100
|
|
288
|
+
]
|
|
289
|
+
|
|
290
|
+
self.coloring = [
|
|
291
|
+
[9, 12, 17, 24, 31, 38, 43, 46, 50, 62, 65, 68, 80, 84, 89, 92],
|
|
292
|
+
[6, 20, 25, 32, 37, 44, 51, 56, 59, 63, 70, 75, 82, 88, 90, 94, 96],
|
|
293
|
+
[2, 8, 10, 14, 26, 29, 33, 40, 48, 52, 55, 67, 73, 79, 86, 91, 98],
|
|
294
|
+
[4, 11, 16, 23, 28, 30, 35, 42, 49, 54, 57, 71, 74, 76, 78, 93, 97],
|
|
295
|
+
[3, 15, 18, 22, 34, 36, 39, 41, 53, 58, 60, 66, 72, 85, 99, 0, 87],
|
|
296
|
+
[7, 21, 27, 45, 47, 61, 64, 69, 77, 81, 83, 95, 1, 5, 13, 19],
|
|
297
|
+
]
|
|
298
|
+
# fmt: on
|
|
299
|
+
|
|
300
|
+
self.dt = 1 / 60
|
|
301
|
+
self.num_test_frames = 100
|
|
302
|
+
self.num_substeps = 10
|
|
303
|
+
self.iterations = 10
|
|
304
|
+
|
|
305
|
+
stiffness = 1e5
|
|
306
|
+
kd = 1.0e-7
|
|
307
|
+
|
|
308
|
+
self.input_scale_factor = 1.0
|
|
309
|
+
self.renderer_scale_factor = 0.01
|
|
310
|
+
vertices = [wp.vec3(v) * self.input_scale_factor for v in self.pts]
|
|
311
|
+
fs_flatten = [fv - 1 for fv in self.faces]
|
|
312
|
+
|
|
313
|
+
builder = wp.sim.ModelBuilder()
|
|
314
|
+
builder.add_cloth_mesh(
|
|
315
|
+
pos=wp.vec3(0.0, 200.0, 0.0),
|
|
316
|
+
rot=wp.quat_from_axis_angle(wp.vec3(1.0, 0.0, 0.0), 0.0),
|
|
317
|
+
scale=1.0,
|
|
318
|
+
vertices=vertices,
|
|
319
|
+
indices=fs_flatten,
|
|
320
|
+
vel=wp.vec3(0.0, 0.0, 0.0),
|
|
321
|
+
density=0.02,
|
|
322
|
+
tri_ke=stiffness,
|
|
323
|
+
tri_ka=stiffness,
|
|
324
|
+
tri_kd=kd,
|
|
325
|
+
)
|
|
326
|
+
|
|
327
|
+
self.model = builder.finalize(device=device)
|
|
328
|
+
self.model.ground = True
|
|
329
|
+
self.model.gravity = wp.vec3(0, -1000.0, 0)
|
|
330
|
+
|
|
331
|
+
self.model.soft_contact_ke = 1.0e4
|
|
332
|
+
self.model.soft_contact_kd = 1.0e2
|
|
333
|
+
|
|
334
|
+
coloring_wp = []
|
|
335
|
+
for color in self.coloring:
|
|
336
|
+
coloring_wp.append(wp.array(color, dtype=wp.int32, device=self.model.device))
|
|
337
|
+
self.model.coloring = coloring_wp
|
|
338
|
+
|
|
339
|
+
self.dt = self.dt / self.num_substeps
|
|
340
|
+
self.fixed_particles = [0, 9]
|
|
341
|
+
|
|
342
|
+
self.set_points_fixed(self.model, self.fixed_particles)
|
|
343
|
+
|
|
344
|
+
self.integrator = wp.sim.VBDIntegrator(self.model, self.iterations)
|
|
345
|
+
self.state0 = self.model.state()
|
|
346
|
+
self.state1 = self.model.state()
|
|
347
|
+
|
|
348
|
+
self.init_pos = np.array(self.state0.particle_q.numpy(), copy=True)
|
|
349
|
+
|
|
350
|
+
def run(self, test):
|
|
351
|
+
for _step in range(self.num_substeps * self.num_test_frames):
|
|
352
|
+
self.integrator.simulate(self.model, self.state0, self.state1, self.dt, None)
|
|
353
|
+
(self.state0, self.state1) = (self.state1, self.state0)
|
|
354
|
+
|
|
355
|
+
# examine that the simulation does not explode
|
|
356
|
+
final_pos = self.state0.particle_q.numpy()
|
|
357
|
+
test.assertTrue((final_pos < 1e5).all())
|
|
358
|
+
# examine that the simulation have moved
|
|
359
|
+
test.assertTrue((self.init_pos != final_pos).any())
|
|
360
|
+
|
|
361
|
+
def set_points_fixed(self, model, fixed_particles):
|
|
362
|
+
if len(fixed_particles):
|
|
363
|
+
flags = model.particle_flags.numpy()
|
|
364
|
+
for fixed_v_id in fixed_particles:
|
|
365
|
+
flags[fixed_v_id] = wp.uint32(int(flags[fixed_v_id]) & ~int(PARTICLE_FLAG_ACTIVE))
|
|
366
|
+
|
|
367
|
+
model.particle_flags = wp.array(flags, device=model.device)
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
def test_vbd_cloth(test, device):
|
|
371
|
+
example = VBDClothSim(device)
|
|
372
|
+
example.run(test)
|
|
373
|
+
|
|
374
|
+
|
|
375
|
+
devices = get_test_devices()
|
|
376
|
+
|
|
377
|
+
|
|
378
|
+
class TestVBD(unittest.TestCase):
|
|
379
|
+
pass
|
|
380
|
+
|
|
381
|
+
|
|
382
|
+
add_function_test(TestVBD, "test_vbd_cloth", test_vbd_cloth, devices=devices)
|
|
383
|
+
|
|
384
|
+
if __name__ == "__main__":
|
|
385
|
+
wp.clear_kernel_cache()
|
|
386
|
+
unittest.main(verbosity=2)
|