warp-lang 1.0.0b5__py3-none-manylinux2014_x86_64.whl → 1.0.0b6__py3-none-manylinux2014_x86_64.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.
Files changed (187) hide show
  1. docs/conf.py +3 -4
  2. examples/env/env_ant.py +1 -1
  3. examples/env/env_cartpole.py +1 -1
  4. examples/env/env_humanoid.py +1 -1
  5. examples/example_dem.py +28 -26
  6. examples/example_diffray.py +37 -30
  7. examples/example_fluid.py +7 -3
  8. examples/example_jacobian_ik.py +1 -1
  9. examples/example_mesh_intersect.py +10 -7
  10. examples/example_nvdb.py +3 -3
  11. examples/example_render_opengl.py +19 -10
  12. examples/example_sim_cartpole.py +9 -5
  13. examples/example_sim_cloth.py +29 -25
  14. examples/example_sim_fk_grad.py +2 -2
  15. examples/example_sim_fk_grad_torch.py +3 -3
  16. examples/example_sim_grad_bounce.py +11 -8
  17. examples/example_sim_grad_cloth.py +12 -9
  18. examples/example_sim_granular.py +2 -2
  19. examples/example_sim_granular_collision_sdf.py +13 -13
  20. examples/example_sim_neo_hookean.py +3 -3
  21. examples/example_sim_particle_chain.py +2 -2
  22. examples/example_sim_quadruped.py +8 -5
  23. examples/example_sim_rigid_chain.py +8 -5
  24. examples/example_sim_rigid_contact.py +13 -10
  25. examples/example_sim_rigid_fem.py +2 -2
  26. examples/example_sim_rigid_gyroscopic.py +2 -2
  27. examples/example_sim_rigid_kinematics.py +1 -1
  28. examples/example_sim_trajopt.py +3 -2
  29. examples/fem/example_apic_fluid.py +5 -7
  30. examples/fem/example_diffusion_mgpu.py +18 -16
  31. warp/__init__.py +3 -2
  32. warp/bin/warp.so +0 -0
  33. warp/build_dll.py +29 -9
  34. warp/builtins.py +206 -7
  35. warp/codegen.py +58 -38
  36. warp/config.py +3 -1
  37. warp/context.py +234 -128
  38. warp/fem/__init__.py +2 -2
  39. warp/fem/cache.py +2 -1
  40. warp/fem/field/nodal_field.py +18 -17
  41. warp/fem/geometry/hexmesh.py +11 -6
  42. warp/fem/geometry/quadmesh_2d.py +16 -12
  43. warp/fem/geometry/tetmesh.py +19 -8
  44. warp/fem/geometry/trimesh_2d.py +18 -7
  45. warp/fem/integrate.py +341 -196
  46. warp/fem/quadrature/__init__.py +1 -1
  47. warp/fem/quadrature/pic_quadrature.py +138 -53
  48. warp/fem/quadrature/quadrature.py +81 -9
  49. warp/fem/space/__init__.py +1 -1
  50. warp/fem/space/basis_space.py +169 -51
  51. warp/fem/space/grid_2d_function_space.py +2 -2
  52. warp/fem/space/grid_3d_function_space.py +2 -2
  53. warp/fem/space/hexmesh_function_space.py +2 -2
  54. warp/fem/space/partition.py +9 -6
  55. warp/fem/space/quadmesh_2d_function_space.py +2 -2
  56. warp/fem/space/shape/cube_shape_function.py +27 -15
  57. warp/fem/space/shape/square_shape_function.py +29 -18
  58. warp/fem/space/tetmesh_function_space.py +2 -2
  59. warp/fem/space/topology.py +10 -0
  60. warp/fem/space/trimesh_2d_function_space.py +2 -2
  61. warp/fem/utils.py +10 -5
  62. warp/native/array.h +49 -8
  63. warp/native/builtin.h +31 -14
  64. warp/native/cuda_util.cpp +8 -3
  65. warp/native/cuda_util.h +1 -0
  66. warp/native/exports.h +1177 -1108
  67. warp/native/intersect.h +4 -4
  68. warp/native/intersect_adj.h +8 -8
  69. warp/native/mat.h +65 -6
  70. warp/native/mesh.h +126 -5
  71. warp/native/quat.h +28 -4
  72. warp/native/vec.h +76 -14
  73. warp/native/warp.cu +1 -6
  74. warp/render/render_opengl.py +261 -109
  75. warp/sim/import_mjcf.py +13 -7
  76. warp/sim/import_urdf.py +14 -14
  77. warp/sim/inertia.py +17 -18
  78. warp/sim/model.py +67 -67
  79. warp/sim/render.py +1 -1
  80. warp/sparse.py +6 -6
  81. warp/stubs.py +19 -81
  82. warp/tape.py +1 -1
  83. warp/tests/__main__.py +3 -6
  84. warp/tests/{test_class_kernel.py → aux_test_class_kernel.py} +9 -1
  85. warp/tests/aux_test_conditional_unequal_types_kernels.py +21 -0
  86. warp/tests/{test_dependent.py → aux_test_dependent.py} +2 -2
  87. warp/tests/{test_reference.py → aux_test_reference.py} +1 -1
  88. warp/tests/aux_test_unresolved_func.py +14 -0
  89. warp/tests/aux_test_unresolved_symbol.py +14 -0
  90. warp/tests/{test_kinematics.py → disabled_kinematics.py} +10 -12
  91. warp/tests/run_coverage_serial.py +31 -0
  92. warp/tests/test_adam.py +102 -106
  93. warp/tests/test_arithmetic.py +39 -40
  94. warp/tests/test_array.py +46 -48
  95. warp/tests/test_array_reduce.py +25 -19
  96. warp/tests/test_atomic.py +62 -26
  97. warp/tests/test_bool.py +16 -11
  98. warp/tests/test_builtins_resolution.py +1292 -0
  99. warp/tests/test_bvh.py +9 -12
  100. warp/tests/test_closest_point_edge_edge.py +53 -57
  101. warp/tests/test_codegen.py +164 -134
  102. warp/tests/test_compile_consts.py +13 -19
  103. warp/tests/test_conditional.py +30 -32
  104. warp/tests/test_copy.py +9 -12
  105. warp/tests/test_ctypes.py +90 -98
  106. warp/tests/test_dense.py +20 -14
  107. warp/tests/test_devices.py +34 -35
  108. warp/tests/test_dlpack.py +74 -75
  109. warp/tests/test_examples.py +215 -97
  110. warp/tests/test_fabricarray.py +15 -21
  111. warp/tests/test_fast_math.py +14 -11
  112. warp/tests/test_fem.py +280 -97
  113. warp/tests/test_fp16.py +19 -15
  114. warp/tests/test_func.py +177 -194
  115. warp/tests/test_generics.py +71 -77
  116. warp/tests/test_grad.py +83 -32
  117. warp/tests/test_grad_customs.py +7 -9
  118. warp/tests/test_hash_grid.py +6 -10
  119. warp/tests/test_import.py +9 -23
  120. warp/tests/test_indexedarray.py +19 -21
  121. warp/tests/test_intersect.py +15 -9
  122. warp/tests/test_large.py +17 -19
  123. warp/tests/test_launch.py +14 -17
  124. warp/tests/test_lerp.py +63 -63
  125. warp/tests/test_lvalue.py +84 -35
  126. warp/tests/test_marching_cubes.py +9 -13
  127. warp/tests/test_mat.py +388 -3004
  128. warp/tests/test_mat_lite.py +9 -12
  129. warp/tests/test_mat_scalar_ops.py +2889 -0
  130. warp/tests/test_math.py +10 -11
  131. warp/tests/test_matmul.py +104 -100
  132. warp/tests/test_matmul_lite.py +72 -98
  133. warp/tests/test_mesh.py +35 -32
  134. warp/tests/test_mesh_query_aabb.py +18 -25
  135. warp/tests/test_mesh_query_point.py +39 -23
  136. warp/tests/test_mesh_query_ray.py +9 -21
  137. warp/tests/test_mlp.py +8 -9
  138. warp/tests/test_model.py +89 -93
  139. warp/tests/test_modules_lite.py +15 -25
  140. warp/tests/test_multigpu.py +87 -114
  141. warp/tests/test_noise.py +10 -12
  142. warp/tests/test_operators.py +14 -21
  143. warp/tests/test_options.py +10 -11
  144. warp/tests/test_pinned.py +16 -18
  145. warp/tests/test_print.py +16 -20
  146. warp/tests/test_quat.py +121 -88
  147. warp/tests/test_rand.py +12 -13
  148. warp/tests/test_reload.py +27 -32
  149. warp/tests/test_rounding.py +7 -10
  150. warp/tests/test_runlength_encode.py +105 -106
  151. warp/tests/test_smoothstep.py +8 -9
  152. warp/tests/test_snippet.py +13 -22
  153. warp/tests/test_sparse.py +30 -29
  154. warp/tests/test_spatial.py +179 -174
  155. warp/tests/test_streams.py +100 -107
  156. warp/tests/test_struct.py +98 -67
  157. warp/tests/test_tape.py +11 -17
  158. warp/tests/test_torch.py +89 -86
  159. warp/tests/test_transient_module.py +9 -12
  160. warp/tests/test_types.py +328 -50
  161. warp/tests/test_utils.py +217 -218
  162. warp/tests/test_vec.py +133 -2133
  163. warp/tests/test_vec_lite.py +8 -11
  164. warp/tests/test_vec_scalar_ops.py +2099 -0
  165. warp/tests/test_volume.py +391 -382
  166. warp/tests/test_volume_write.py +122 -135
  167. warp/tests/unittest_serial.py +35 -0
  168. warp/tests/unittest_suites.py +291 -0
  169. warp/tests/{test_base.py → unittest_utils.py} +138 -25
  170. warp/tests/{test_misc.py → unused_test_misc.py} +13 -5
  171. warp/tests/{test_debug.py → walkthough_debug.py} +2 -15
  172. warp/thirdparty/unittest_parallel.py +257 -54
  173. warp/types.py +119 -98
  174. warp/utils.py +14 -0
  175. {warp_lang-1.0.0b5.dist-info → warp_lang-1.0.0b6.dist-info}/METADATA +2 -1
  176. {warp_lang-1.0.0b5.dist-info → warp_lang-1.0.0b6.dist-info}/RECORD +182 -178
  177. {warp_lang-1.0.0b5.dist-info → warp_lang-1.0.0b6.dist-info}/WHEEL +1 -1
  178. warp/tests/test_all.py +0 -239
  179. warp/tests/test_conditional_unequal_types_kernels.py +0 -14
  180. warp/tests/test_coverage.py +0 -38
  181. warp/tests/test_unresolved_func.py +0 -7
  182. warp/tests/test_unresolved_symbol.py +0 -7
  183. /warp/tests/{test_compile_consts_dummy.py → aux_test_compile_consts_dummy.py} +0 -0
  184. /warp/tests/{test_reference_reference.py → aux_test_reference_reference.py} +0 -0
  185. /warp/tests/{test_square.py → aux_test_square.py} +0 -0
  186. {warp_lang-1.0.0b5.dist-info → warp_lang-1.0.0b6.dist-info}/LICENSE.md +0 -0
  187. {warp_lang-1.0.0b5.dist-info → warp_lang-1.0.0b6.dist-info}/top_level.txt +0 -0
@@ -5,14 +5,13 @@
5
5
  # distribution of this software and related documentation without an express
6
6
  # license agreement from NVIDIA CORPORATION is strictly prohibited.
7
7
 
8
+ import math
8
9
  import unittest
9
10
 
10
11
  import numpy as np
11
- import math
12
12
 
13
13
  import warp as wp
14
- from warp.tests.test_base import *
15
-
14
+ from warp.tests.unittest_utils import *
16
15
 
17
16
  wp.init()
18
17
 
@@ -44,6 +43,12 @@ def sample_mesh_query(
44
43
  query_faces[tid] = face_index
45
44
  query_dist[tid] = wp.length(cp - p)
46
45
 
46
+ query = wp.mesh_query_point(mesh, p, max_dist)
47
+ wp.expect_eq(query.sign, sign)
48
+ wp.expect_eq(query.face, face_index)
49
+ wp.expect_eq(query.u, face_u)
50
+ wp.expect_eq(query.v, face_v)
51
+
47
52
 
48
53
  @wp.kernel
49
54
  def sample_mesh_query_no_sign(
@@ -69,6 +74,11 @@ def sample_mesh_query_no_sign(
69
74
  query_faces[tid] = face_index
70
75
  query_dist[tid] = wp.length(cp - p)
71
76
 
77
+ query = wp.mesh_query_point_no_sign(mesh, p, max_dist)
78
+ wp.expect_eq(query.face, face_index)
79
+ wp.expect_eq(query.u, face_u)
80
+ wp.expect_eq(query.v, face_v)
81
+
72
82
 
73
83
  @wp.kernel
74
84
  def sample_mesh_query_sign_normal(
@@ -97,6 +107,12 @@ def sample_mesh_query_sign_normal(
97
107
  query_faces[tid] = face_index
98
108
  query_dist[tid] = wp.length(cp - p)
99
109
 
110
+ query = wp.mesh_query_point_sign_normal(mesh, p, max_dist)
111
+ wp.expect_eq(query.sign, sign)
112
+ wp.expect_eq(query.face, face_index)
113
+ wp.expect_eq(query.u, face_u)
114
+ wp.expect_eq(query.v, face_v)
115
+
100
116
 
101
117
  @wp.kernel
102
118
  def sample_mesh_query_sign_winding_number(
@@ -125,6 +141,12 @@ def sample_mesh_query_sign_winding_number(
125
141
  query_faces[tid] = face_index
126
142
  query_dist[tid] = wp.length(cp - p)
127
143
 
144
+ query = wp.mesh_query_point_sign_winding_number(mesh, p, max_dist)
145
+ wp.expect_eq(query.sign, sign)
146
+ wp.expect_eq(query.face, face_index)
147
+ wp.expect_eq(query.u, face_u)
148
+ wp.expect_eq(query.v, face_v)
149
+
128
150
 
129
151
  @wp.func
130
152
  def triangle_closest_point(a: wp.vec3, b: wp.vec3, c: wp.vec3, p: wp.vec3):
@@ -265,6 +287,7 @@ def triangulate(face_counts, face_indices):
265
287
  return tri_indices
266
288
 
267
289
 
290
+ @unittest.skipUnless(USD_AVAILABLE, "Requires usd-core")
268
291
  def test_mesh_query_point(test, device):
269
292
  from pxr import Usd, UsdGeom
270
293
 
@@ -480,6 +503,7 @@ def mesh_query_point_loss(
480
503
  loss[tid] = dist
481
504
 
482
505
 
506
+ @unittest.skipUnless(USD_AVAILABLE, "Requires usd-core")
483
507
  def test_adj_mesh_query_point(test, device):
484
508
  from pxr import Usd, UsdGeom
485
509
 
@@ -574,6 +598,11 @@ def sample_furthest_points(mesh: wp.uint64, query_points: wp.array(dtype=wp.vec3
574
598
 
575
599
  query_result[tid] = wp.length_sq(p - closest)
576
600
 
601
+ query = wp.mesh_query_furthest_point_no_sign(mesh, p, 0.0)
602
+ wp.expect_eq(query.face, face)
603
+ wp.expect_eq(query.u, bary_u)
604
+ wp.expect_eq(query.v, bary_v)
605
+
577
606
 
578
607
  @wp.kernel
579
608
  def sample_furthest_points_brute(
@@ -593,6 +622,7 @@ def sample_furthest_points_brute(
593
622
  query_result[tid] = max_dist_sq
594
623
 
595
624
 
625
+ @unittest.skipUnless(USD_AVAILABLE, "Requires usd-core")
596
626
  def test_mesh_query_furthest_point(test, device):
597
627
  from pxr import Usd, UsdGeom
598
628
 
@@ -626,32 +656,18 @@ def test_mesh_query_furthest_point(test, device):
626
656
  assert_np_equal(dist_query.numpy(), dist_brute.numpy(), tol=1.0e-3)
627
657
 
628
658
 
629
- def register(parent):
630
- devices = get_test_devices()
659
+ devices = get_test_devices()
631
660
 
632
- class TestMeshQuery(parent):
633
- pass
634
661
 
635
- # USD import failures should not count as a test failure
636
- try:
637
- from pxr import Usd, UsdGeom
662
+ class TestMeshQueryPoint(unittest.TestCase):
663
+ pass
638
664
 
639
- have_usd = True
640
- except:
641
- have_usd = False
642
665
 
643
- if have_usd:
644
- add_function_test(TestMeshQuery, "test_mesh_query_point", test_mesh_query_point, devices=devices)
645
- add_function_test(
646
- TestMeshQuery, "test_mesh_query_furthest_point", test_mesh_query_furthest_point, devices=devices
647
- )
648
- add_function_test(TestMeshQuery, "test_adj_mesh_query_point", test_adj_mesh_query_point, devices=devices)
649
-
650
- return TestMeshQuery
666
+ add_function_test(TestMeshQueryPoint, "test_mesh_query_point", test_mesh_query_point, devices=devices)
667
+ add_function_test(TestMeshQueryPoint, "test_mesh_query_furthest_point", test_mesh_query_furthest_point, devices=devices)
668
+ add_function_test(TestMeshQueryPoint, "test_adj_mesh_query_point", test_adj_mesh_query_point, devices=devices)
651
669
 
652
670
 
653
671
  if __name__ == "__main__":
654
672
  wp.build.clear_kernel_cache()
655
- _ = register(unittest.TestCase)
656
-
657
673
  unittest.main(verbosity=2)
@@ -10,8 +10,7 @@ import unittest
10
10
  import numpy as np
11
11
 
12
12
  import warp as wp
13
- from warp.tests.test_base import *
14
-
13
+ from warp.tests.unittest_utils import *
15
14
 
16
15
  wp.init()
17
16
 
@@ -66,8 +65,9 @@ def mesh_query_ray_loss(
66
65
  loss[tid] = l
67
66
 
68
67
 
68
+ @unittest.skipUnless(USD_AVAILABLE, "Requires usd-core")
69
69
  def test_mesh_query_ray_grad(test, device):
70
- from pxr import Usd, UsdGeom, Gf, Sdf
70
+ from pxr import Usd, UsdGeom
71
71
 
72
72
  # test tri
73
73
  # print("Testing Single Triangle")
@@ -209,7 +209,7 @@ def raycast_kernel(
209
209
  sign = float(0.0) # hit face sign
210
210
  n = wp.vec3() # hit face normal
211
211
  f = int(0) # hit face index
212
- max_dist = 1e6 # max raycast disance
212
+ max_dist = 1e6 # max raycast distance
213
213
 
214
214
  # ray cast against the mesh
215
215
  tid = wp.tid()
@@ -258,29 +258,17 @@ def test_mesh_query_ray_edge(test, device):
258
258
  test.assertEqual(counts.numpy()[0], n)
259
259
 
260
260
 
261
- def register(parent):
262
- devices = get_test_devices()
263
-
264
- class TestMeshQueryRay(parent):
265
- pass
266
-
267
- add_function_test(TestMeshQueryRay, "test_mesh_query_ray_edge", test_mesh_query_ray_edge, devices=devices)
261
+ devices = get_test_devices()
268
262
 
269
- # USD import failures should not count as a test failure
270
- try:
271
- from pxr import Usd, UsdGeom
272
263
 
273
- have_usd = True
274
- except:
275
- have_usd = False
264
+ class TestMeshQueryRay(unittest.TestCase):
265
+ pass
276
266
 
277
- if have_usd:
278
- add_function_test(TestMeshQueryRay, "test_mesh_query_ray_grad", test_mesh_query_ray_grad, devices=devices)
279
267
 
280
- return TestMeshQueryRay
268
+ add_function_test(TestMeshQueryRay, "test_mesh_query_ray_edge", test_mesh_query_ray_edge, devices=devices)
269
+ add_function_test(TestMeshQueryRay, "test_mesh_query_ray_grad", test_mesh_query_ray_grad, devices=devices)
281
270
 
282
271
 
283
272
  if __name__ == "__main__":
284
273
  wp.build.clear_kernel_cache()
285
- _ = register(unittest.TestCase)
286
274
  unittest.main(verbosity=2)
warp/tests/test_mlp.py CHANGED
@@ -8,8 +8,9 @@
8
8
  import unittest
9
9
 
10
10
  import numpy as np
11
+
11
12
  import warp as wp
12
- from warp.tests.test_base import *
13
+ from warp.tests.unittest_utils import *
13
14
 
14
15
  wp.init()
15
16
 
@@ -259,19 +260,17 @@ def profile_mlp_warp(device):
259
260
  # profile_mlp_torch("cuda")
260
261
 
261
262
 
262
- def register(parent):
263
- devices = get_test_devices()
263
+ devices = get_test_devices()
264
+
264
265
 
265
- class TestMLP(parent):
266
- pass
266
+ class TestMLP(unittest.TestCase):
267
+ pass
267
268
 
268
- add_function_test(TestMLP, "test_mlp", test_mlp, devices=devices)
269
- add_function_test(TestMLP, "test_mlp_grad", test_mlp_grad, devices=devices)
270
269
 
271
- return TestMLP
270
+ add_function_test(TestMLP, "test_mlp", test_mlp, devices=devices)
271
+ add_function_test(TestMLP, "test_mlp_grad", test_mlp_grad, devices=devices)
272
272
 
273
273
 
274
274
  if __name__ == "__main__":
275
275
  wp.build.clear_kernel_cache()
276
- _ = register(unittest.TestCase)
277
276
  unittest.main(verbosity=2, failfast=False)
warp/tests/test_model.py CHANGED
@@ -7,108 +7,104 @@
7
7
 
8
8
  import unittest
9
9
 
10
+ import numpy as np
11
+
10
12
  import warp as wp
11
- from warp.tests.test_base import *
12
13
  from warp.sim import ModelBuilder
13
-
14
- import numpy as np
14
+ from warp.tests.unittest_utils import *
15
15
 
16
16
  wp.init()
17
17
 
18
18
 
19
- def register(parent):
20
- class TestModel(parent):
21
- def test_add_triangles(self):
22
- rng = np.random.default_rng(123)
23
-
24
- pts = np.array(
25
- [
26
- [-0.00585869, 0.34189449, -1.17415233],
27
- [-1.894547, 0.1788074, 0.9251329],
28
- [-1.26141048, 0.16140787, 0.08823282],
29
- [-0.08609255, -0.82722546, 0.65995427],
30
- [0.78827592, -1.77375711, -0.55582718],
31
- ]
32
- )
33
- tris = np.array([[0, 3, 4], [0, 2, 3], [2, 1, 3], [1, 4, 3]])
34
-
35
- builder1 = ModelBuilder()
36
- builder2 = ModelBuilder()
37
- for pt in pts:
38
- builder1.add_particle(pt, [0.0, 0.0, 0.0], 1.0)
39
- builder2.add_particle(pt, [0.0, 0.0, 0.0], 1.0)
40
-
41
- # test add_triangle(s) with default arguments:
42
- areas = builder2.add_triangles(tris[:, 0], tris[:, 1], tris[:, 2])
43
- for i, t in enumerate(tris):
44
- area = builder1.add_triangle(t[0], t[1], t[2])
45
- self.assertAlmostEqual(area, areas[i], places=6)
46
-
47
- # test add_triangle(s) with non default arguments:
48
- tri_ke = rng.standard_normal(size=pts.shape[0])
49
- tri_ka = rng.standard_normal(size=pts.shape[0])
50
- tri_kd = rng.standard_normal(size=pts.shape[0])
51
- tri_drag = rng.standard_normal(size=pts.shape[0])
52
- tri_lift = rng.standard_normal(size=pts.shape[0])
53
- for i, t in enumerate(tris):
54
- builder1.add_triangle(
55
- t[0],
56
- t[1],
57
- t[2],
58
- tri_ke[i],
59
- tri_ka[i],
60
- tri_kd[i],
61
- tri_drag[i],
62
- tri_lift[i],
63
- )
64
- builder2.add_triangles(tris[:, 0], tris[:, 1], tris[:, 2], tri_ke, tri_ka, tri_kd, tri_drag, tri_lift)
65
-
66
- assert_np_equal(np.array(builder1.tri_indices), np.array(builder2.tri_indices))
67
- assert_np_equal(np.array(builder1.tri_poses), np.array(builder2.tri_poses), tol=1.0e-6)
68
- assert_np_equal(np.array(builder1.tri_activations), np.array(builder2.tri_activations))
69
- assert_np_equal(np.array(builder1.tri_materials), np.array(builder2.tri_materials))
70
-
71
- def test_add_edges(self):
72
- rng = np.random.default_rng(123)
73
-
74
- pts = np.array(
75
- [
76
- [-0.00585869, 0.34189449, -1.17415233],
77
- [-1.894547, 0.1788074, 0.9251329],
78
- [-1.26141048, 0.16140787, 0.08823282],
79
- [-0.08609255, -0.82722546, 0.65995427],
80
- [0.78827592, -1.77375711, -0.55582718],
81
- ]
19
+ class TestModel(unittest.TestCase):
20
+ def test_add_triangles(self):
21
+ rng = np.random.default_rng(123)
22
+
23
+ pts = np.array(
24
+ [
25
+ [-0.00585869, 0.34189449, -1.17415233],
26
+ [-1.894547, 0.1788074, 0.9251329],
27
+ [-1.26141048, 0.16140787, 0.08823282],
28
+ [-0.08609255, -0.82722546, 0.65995427],
29
+ [0.78827592, -1.77375711, -0.55582718],
30
+ ]
31
+ )
32
+ tris = np.array([[0, 3, 4], [0, 2, 3], [2, 1, 3], [1, 4, 3]])
33
+
34
+ builder1 = ModelBuilder()
35
+ builder2 = ModelBuilder()
36
+ for pt in pts:
37
+ builder1.add_particle(wp.vec3(pt), wp.vec3(), 1.0)
38
+ builder2.add_particle(wp.vec3(pt), wp.vec3(), 1.0)
39
+
40
+ # test add_triangle(s) with default arguments:
41
+ areas = builder2.add_triangles(tris[:, 0], tris[:, 1], tris[:, 2])
42
+ for i, t in enumerate(tris):
43
+ area = builder1.add_triangle(t[0], t[1], t[2])
44
+ self.assertAlmostEqual(area, areas[i], places=6)
45
+
46
+ # test add_triangle(s) with non default arguments:
47
+ tri_ke = rng.standard_normal(size=pts.shape[0])
48
+ tri_ka = rng.standard_normal(size=pts.shape[0])
49
+ tri_kd = rng.standard_normal(size=pts.shape[0])
50
+ tri_drag = rng.standard_normal(size=pts.shape[0])
51
+ tri_lift = rng.standard_normal(size=pts.shape[0])
52
+ for i, t in enumerate(tris):
53
+ builder1.add_triangle(
54
+ t[0],
55
+ t[1],
56
+ t[2],
57
+ tri_ke[i],
58
+ tri_ka[i],
59
+ tri_kd[i],
60
+ tri_drag[i],
61
+ tri_lift[i],
82
62
  )
83
- edges = np.array([[0, 4, 3, 1], [3, 2, 4, 1]])
84
-
85
- builder1 = ModelBuilder()
86
- builder2 = ModelBuilder()
87
- for pt in pts:
88
- builder1.add_particle(pt, [0.0, 0.0, 0.0], 1.0)
89
- builder2.add_particle(pt, [0.0, 0.0, 0.0], 1.0)
90
-
91
- # test defaults:
92
- for i in range(2):
93
- builder1.add_edge(edges[i, 0], edges[i, 1], edges[i, 2], edges[i, 3])
94
- builder2.add_edges(edges[:, 0], edges[:, 1], edges[:, 2], edges[:, 3])
95
-
96
- # test non defaults:
97
- rest = rng.standard_normal(size=2)
98
- edge_ke = rng.standard_normal(size=2)
99
- edge_kd = rng.standard_normal(size=2)
100
- for i in range(2):
101
- builder1.add_edge(edges[i, 0], edges[i, 1], edges[i, 2], edges[i, 3], rest[i], edge_ke[i], edge_kd[i])
102
- builder2.add_edges(edges[:, 0], edges[:, 1], edges[:, 2], edges[:, 3], rest, edge_ke, edge_kd)
103
-
104
- assert_np_equal(np.array(builder1.edge_indices), np.array(builder2.edge_indices))
105
- assert_np_equal(np.array(builder1.edge_rest_angle), np.array(builder2.edge_rest_angle), tol=1.0e-4)
106
- assert_np_equal(np.array(builder1.edge_bending_properties), np.array(builder2.edge_bending_properties))
107
-
108
- return TestModel
63
+ builder2.add_triangles(tris[:, 0], tris[:, 1], tris[:, 2], tri_ke, tri_ka, tri_kd, tri_drag, tri_lift)
64
+
65
+ assert_np_equal(np.array(builder1.tri_indices), np.array(builder2.tri_indices))
66
+ assert_np_equal(np.array(builder1.tri_poses), np.array(builder2.tri_poses), tol=1.0e-6)
67
+ assert_np_equal(np.array(builder1.tri_activations), np.array(builder2.tri_activations))
68
+ assert_np_equal(np.array(builder1.tri_materials), np.array(builder2.tri_materials))
69
+
70
+ def test_add_edges(self):
71
+ rng = np.random.default_rng(123)
72
+
73
+ pts = np.array(
74
+ [
75
+ [-0.00585869, 0.34189449, -1.17415233],
76
+ [-1.894547, 0.1788074, 0.9251329],
77
+ [-1.26141048, 0.16140787, 0.08823282],
78
+ [-0.08609255, -0.82722546, 0.65995427],
79
+ [0.78827592, -1.77375711, -0.55582718],
80
+ ]
81
+ )
82
+ edges = np.array([[0, 4, 3, 1], [3, 2, 4, 1]])
83
+
84
+ builder1 = ModelBuilder()
85
+ builder2 = ModelBuilder()
86
+ for pt in pts:
87
+ builder1.add_particle(wp.vec3(pt), wp.vec3(), 1.0)
88
+ builder2.add_particle(wp.vec3(pt), wp.vec3(), 1.0)
89
+
90
+ # test defaults:
91
+ for i in range(2):
92
+ builder1.add_edge(edges[i, 0], edges[i, 1], edges[i, 2], edges[i, 3])
93
+ builder2.add_edges(edges[:, 0], edges[:, 1], edges[:, 2], edges[:, 3])
94
+
95
+ # test non defaults:
96
+ rest = rng.standard_normal(size=2)
97
+ edge_ke = rng.standard_normal(size=2)
98
+ edge_kd = rng.standard_normal(size=2)
99
+ for i in range(2):
100
+ builder1.add_edge(edges[i, 0], edges[i, 1], edges[i, 2], edges[i, 3], rest[i], edge_ke[i], edge_kd[i])
101
+ builder2.add_edges(edges[:, 0], edges[:, 1], edges[:, 2], edges[:, 3], rest, edge_ke, edge_kd)
102
+
103
+ assert_np_equal(np.array(builder1.edge_indices), np.array(builder2.edge_indices))
104
+ assert_np_equal(np.array(builder1.edge_rest_angle), np.array(builder2.edge_rest_angle), tol=1.0e-4)
105
+ assert_np_equal(np.array(builder1.edge_bending_properties), np.array(builder2.edge_bending_properties))
109
106
 
110
107
 
111
108
  if __name__ == "__main__":
112
109
  wp.build.clear_kernel_cache()
113
- _ = register(unittest.TestCase)
114
110
  unittest.main(verbosity=2)
@@ -8,42 +8,32 @@
8
8
  import unittest
9
9
 
10
10
  import warp as wp
11
- from warp.tests.test_base import *
11
+ from warp.tests.unittest_utils import *
12
12
 
13
13
  wp.init()
14
14
 
15
15
 
16
- def test_module_lite_load(test, device):
17
- # Load current module
18
- wp.load_module()
16
+ devices = get_test_devices()
19
17
 
20
- # Load named module
21
- wp.load_module(wp.config)
22
18
 
23
- # Load named module (string)
24
- wp.load_module(wp.config, recursive=True)
19
+ class TestModuleLite(unittest.TestCase):
20
+ def test_module_lite_load(self):
21
+ # Load current module
22
+ wp.load_module()
25
23
 
24
+ # Load named module
25
+ wp.load_module(wp.config)
26
26
 
27
- def test_module_lite_options(test, device):
28
- wp.set_module_options({"max_unroll": 8})
29
- module_options = wp.get_module_options()
30
- test.assertIsInstance(module_options, dict)
31
- test.assertEqual(module_options["max_unroll"], 8)
27
+ # Load named module (string)
28
+ wp.load_module(wp.config, recursive=True)
32
29
 
33
-
34
- def register(parent):
35
- devices = get_test_devices()
36
-
37
- class TestModuleLite(parent):
38
- pass
39
-
40
- add_function_test(TestModuleLite, "test_module_lite_load", test_module_lite_load, devices=devices)
41
- add_function_test(TestModuleLite, "test_module_lite_get_options", test_module_lite_options, devices=devices)
42
-
43
- return TestModuleLite
30
+ def test_module_lite_options(self):
31
+ wp.set_module_options({"max_unroll": 8})
32
+ module_options = wp.get_module_options()
33
+ self.assertIsInstance(module_options, dict)
34
+ self.assertEqual(module_options["max_unroll"], 8)
44
35
 
45
36
 
46
37
  if __name__ == "__main__":
47
38
  wp.build.clear_kernel_cache()
48
- _ = register(unittest.TestCase)
49
39
  unittest.main(verbosity=2)