warp-lang 1.7.2rc1__py3-none-macosx_10_13_universal2.whl → 1.8.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 +3 -1
- warp/__init__.pyi +3489 -1
- warp/autograd.py +45 -122
- warp/bin/libwarp.dylib +0 -0
- warp/build.py +241 -252
- warp/build_dll.py +130 -26
- warp/builtins.py +1907 -384
- warp/codegen.py +272 -104
- warp/config.py +12 -1
- warp/constants.py +1 -1
- warp/context.py +770 -238
- warp/dlpack.py +1 -1
- warp/examples/benchmarks/benchmark_cloth.py +2 -2
- warp/examples/benchmarks/benchmark_tile_sort.py +155 -0
- warp/examples/core/example_sample_mesh.py +1 -1
- warp/examples/core/example_spin_lock.py +93 -0
- warp/examples/core/example_work_queue.py +118 -0
- warp/examples/fem/example_adaptive_grid.py +5 -5
- warp/examples/fem/example_apic_fluid.py +1 -1
- warp/examples/fem/example_burgers.py +1 -1
- warp/examples/fem/example_convection_diffusion.py +9 -6
- warp/examples/fem/example_darcy_ls_optimization.py +489 -0
- warp/examples/fem/example_deformed_geometry.py +1 -1
- warp/examples/fem/example_diffusion.py +2 -2
- warp/examples/fem/example_diffusion_3d.py +1 -1
- warp/examples/fem/example_distortion_energy.py +1 -1
- warp/examples/fem/example_elastic_shape_optimization.py +387 -0
- warp/examples/fem/example_magnetostatics.py +5 -3
- warp/examples/fem/example_mixed_elasticity.py +5 -3
- warp/examples/fem/example_navier_stokes.py +11 -9
- warp/examples/fem/example_nonconforming_contact.py +5 -3
- warp/examples/fem/example_streamlines.py +8 -3
- warp/examples/fem/utils.py +9 -8
- warp/examples/interop/example_jax_callable.py +34 -4
- warp/examples/interop/example_jax_ffi_callback.py +2 -2
- warp/examples/interop/example_jax_kernel.py +27 -1
- warp/examples/optim/example_drone.py +1 -1
- warp/examples/sim/example_cloth.py +1 -1
- warp/examples/sim/example_cloth_self_contact.py +48 -54
- warp/examples/tile/example_tile_block_cholesky.py +502 -0
- warp/examples/tile/example_tile_cholesky.py +2 -1
- warp/examples/tile/example_tile_convolution.py +1 -1
- warp/examples/tile/example_tile_filtering.py +1 -1
- warp/examples/tile/example_tile_matmul.py +1 -1
- warp/examples/tile/example_tile_mlp.py +2 -0
- warp/fabric.py +7 -7
- warp/fem/__init__.py +5 -0
- warp/fem/adaptivity.py +1 -1
- warp/fem/cache.py +152 -63
- warp/fem/dirichlet.py +2 -2
- warp/fem/domain.py +136 -6
- warp/fem/field/field.py +141 -99
- warp/fem/field/nodal_field.py +85 -39
- warp/fem/field/virtual.py +99 -52
- warp/fem/geometry/adaptive_nanogrid.py +91 -86
- warp/fem/geometry/closest_point.py +13 -0
- warp/fem/geometry/deformed_geometry.py +102 -40
- warp/fem/geometry/element.py +56 -2
- warp/fem/geometry/geometry.py +323 -22
- warp/fem/geometry/grid_2d.py +157 -62
- warp/fem/geometry/grid_3d.py +116 -20
- warp/fem/geometry/hexmesh.py +86 -20
- warp/fem/geometry/nanogrid.py +166 -86
- warp/fem/geometry/partition.py +59 -25
- warp/fem/geometry/quadmesh.py +86 -135
- warp/fem/geometry/tetmesh.py +47 -119
- warp/fem/geometry/trimesh.py +77 -270
- warp/fem/integrate.py +181 -95
- warp/fem/linalg.py +25 -58
- warp/fem/operator.py +124 -27
- warp/fem/quadrature/pic_quadrature.py +36 -14
- warp/fem/quadrature/quadrature.py +40 -16
- warp/fem/space/__init__.py +1 -1
- warp/fem/space/basis_function_space.py +66 -46
- warp/fem/space/basis_space.py +17 -4
- warp/fem/space/dof_mapper.py +1 -1
- warp/fem/space/function_space.py +2 -2
- warp/fem/space/grid_2d_function_space.py +4 -1
- warp/fem/space/hexmesh_function_space.py +4 -2
- warp/fem/space/nanogrid_function_space.py +3 -1
- warp/fem/space/partition.py +11 -2
- warp/fem/space/quadmesh_function_space.py +4 -1
- warp/fem/space/restriction.py +5 -2
- warp/fem/space/shape/__init__.py +10 -8
- warp/fem/space/tetmesh_function_space.py +4 -1
- warp/fem/space/topology.py +52 -21
- warp/fem/space/trimesh_function_space.py +4 -1
- warp/fem/utils.py +53 -8
- warp/jax.py +1 -2
- warp/jax_experimental/ffi.py +210 -67
- warp/jax_experimental/xla_ffi.py +37 -24
- warp/math.py +171 -1
- warp/native/array.h +103 -4
- warp/native/builtin.h +182 -35
- warp/native/coloring.cpp +6 -2
- warp/native/cuda_util.cpp +1 -1
- warp/native/exports.h +118 -63
- warp/native/intersect.h +5 -5
- warp/native/mat.h +8 -13
- warp/native/mathdx.cpp +11 -5
- warp/native/matnn.h +1 -123
- warp/native/mesh.h +1 -1
- warp/native/quat.h +34 -6
- warp/native/rand.h +7 -7
- warp/native/sparse.cpp +121 -258
- warp/native/sparse.cu +181 -274
- warp/native/spatial.h +305 -17
- warp/native/svd.h +23 -8
- warp/native/tile.h +603 -73
- warp/native/tile_radix_sort.h +1112 -0
- warp/native/tile_reduce.h +239 -13
- warp/native/tile_scan.h +240 -0
- warp/native/tuple.h +189 -0
- warp/native/vec.h +10 -20
- warp/native/warp.cpp +36 -4
- warp/native/warp.cu +588 -52
- warp/native/warp.h +47 -74
- warp/optim/linear.py +5 -1
- warp/paddle.py +7 -8
- warp/py.typed +0 -0
- warp/render/render_opengl.py +110 -80
- warp/render/render_usd.py +124 -62
- warp/sim/__init__.py +9 -0
- warp/sim/collide.py +253 -80
- warp/sim/graph_coloring.py +8 -1
- warp/sim/import_mjcf.py +4 -3
- warp/sim/import_usd.py +11 -7
- warp/sim/integrator.py +5 -2
- warp/sim/integrator_euler.py +1 -1
- warp/sim/integrator_featherstone.py +1 -1
- warp/sim/integrator_vbd.py +761 -322
- warp/sim/integrator_xpbd.py +1 -1
- warp/sim/model.py +265 -260
- warp/sim/utils.py +10 -7
- warp/sparse.py +303 -166
- warp/tape.py +54 -51
- warp/tests/cuda/test_conditional_captures.py +1046 -0
- warp/tests/cuda/test_streams.py +1 -1
- warp/tests/geometry/test_volume.py +2 -2
- warp/tests/interop/test_dlpack.py +9 -9
- warp/tests/interop/test_jax.py +0 -1
- warp/tests/run_coverage_serial.py +1 -1
- warp/tests/sim/disabled_kinematics.py +2 -2
- warp/tests/sim/{test_vbd.py → test_cloth.py} +378 -112
- warp/tests/sim/test_collision.py +159 -51
- warp/tests/sim/test_coloring.py +91 -2
- warp/tests/test_array.py +254 -2
- warp/tests/test_array_reduce.py +2 -2
- warp/tests/test_assert.py +53 -0
- warp/tests/test_atomic_cas.py +312 -0
- warp/tests/test_codegen.py +142 -19
- warp/tests/test_conditional.py +47 -1
- warp/tests/test_ctypes.py +0 -20
- warp/tests/test_devices.py +8 -0
- warp/tests/test_fabricarray.py +4 -2
- warp/tests/test_fem.py +58 -25
- warp/tests/test_func.py +42 -1
- warp/tests/test_grad.py +1 -1
- warp/tests/test_lerp.py +1 -3
- warp/tests/test_map.py +481 -0
- warp/tests/test_mat.py +23 -24
- warp/tests/test_quat.py +28 -15
- warp/tests/test_rounding.py +10 -38
- warp/tests/test_runlength_encode.py +7 -7
- warp/tests/test_smoothstep.py +1 -1
- warp/tests/test_sparse.py +83 -2
- warp/tests/test_spatial.py +507 -1
- warp/tests/test_static.py +48 -0
- warp/tests/test_struct.py +2 -2
- warp/tests/test_tape.py +38 -0
- warp/tests/test_tuple.py +265 -0
- warp/tests/test_types.py +2 -2
- warp/tests/test_utils.py +24 -18
- warp/tests/test_vec.py +38 -408
- warp/tests/test_vec_constructors.py +325 -0
- warp/tests/tile/test_tile.py +438 -131
- warp/tests/tile/test_tile_mathdx.py +518 -14
- warp/tests/tile/test_tile_matmul.py +179 -0
- warp/tests/tile/test_tile_reduce.py +307 -5
- warp/tests/tile/test_tile_shared_memory.py +136 -7
- warp/tests/tile/test_tile_sort.py +121 -0
- warp/tests/unittest_suites.py +14 -6
- warp/types.py +462 -308
- warp/utils.py +647 -86
- {warp_lang-1.7.2rc1.dist-info → warp_lang-1.8.1.dist-info}/METADATA +20 -6
- {warp_lang-1.7.2rc1.dist-info → warp_lang-1.8.1.dist-info}/RECORD +189 -175
- warp/stubs.py +0 -3381
- warp/tests/sim/test_xpbd.py +0 -399
- warp/tests/test_mlp.py +0 -282
- {warp_lang-1.7.2rc1.dist-info → warp_lang-1.8.1.dist-info}/WHEEL +0 -0
- {warp_lang-1.7.2rc1.dist-info → warp_lang-1.8.1.dist-info}/licenses/LICENSE.md +0 -0
- {warp_lang-1.7.2rc1.dist-info → warp_lang-1.8.1.dist-info}/top_level.txt +0 -0
|
@@ -13,15 +13,19 @@
|
|
|
13
13
|
# See the License for the specific language governing permissions and
|
|
14
14
|
# limitations under the License.
|
|
15
15
|
|
|
16
|
-
import contextlib
|
|
17
|
-
import io
|
|
18
16
|
import unittest
|
|
17
|
+
from functools import partial
|
|
18
|
+
|
|
19
|
+
import numpy as np
|
|
19
20
|
|
|
20
21
|
import warp as wp
|
|
21
|
-
import warp.optim
|
|
22
22
|
import warp.sim
|
|
23
|
-
import warp.sim.
|
|
23
|
+
import warp.sim.integrator
|
|
24
|
+
import warp.sim.integrator_euler
|
|
24
25
|
import warp.sim.integrator_vbd
|
|
26
|
+
import warp.sim.integrator_xpbd
|
|
27
|
+
import warp.sim.particles
|
|
28
|
+
import warp.sim.render
|
|
25
29
|
from warp.sim.model import PARTICLE_FLAG_ACTIVE
|
|
26
30
|
from warp.tests.unittest_utils import *
|
|
27
31
|
|
|
@@ -295,40 +299,64 @@ CLOTH_FACES = [
|
|
|
295
299
|
]
|
|
296
300
|
|
|
297
301
|
# fmt: on
|
|
298
|
-
class
|
|
299
|
-
def __init__(self, device, use_cuda_graph=False):
|
|
302
|
+
class ClothSim:
|
|
303
|
+
def __init__(self, device, solver, use_cuda_graph=False, do_rendering=False):
|
|
300
304
|
self.frame_dt = 1 / 60
|
|
301
|
-
self.num_test_frames =
|
|
302
|
-
self.
|
|
303
|
-
self.
|
|
304
|
-
self.dt = self.frame_dt / self.num_substeps
|
|
305
|
+
self.num_test_frames = 50
|
|
306
|
+
self.iterations = 5
|
|
307
|
+
self.do_rendering = do_rendering
|
|
305
308
|
self.device = device
|
|
306
309
|
self.use_cuda_graph = self.device.is_cuda and use_cuda_graph
|
|
307
310
|
self.builder = wp.sim.ModelBuilder()
|
|
311
|
+
self.solver = solver
|
|
312
|
+
self.renderer_scale_factor = 1.0
|
|
308
313
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
314
|
+
if solver != "semi_implicit":
|
|
315
|
+
self.num_substeps = 10
|
|
316
|
+
else:
|
|
317
|
+
self.num_substeps = 32
|
|
318
|
+
self.dt = self.frame_dt / self.num_substeps
|
|
312
319
|
|
|
320
|
+
def set_up_sagging_experiment(self):
|
|
313
321
|
self.input_scale_factor = 1.0
|
|
314
322
|
self.renderer_scale_factor = 0.01
|
|
315
323
|
vertices = [wp.vec3(v) * self.input_scale_factor for v in CLOTH_POINTS]
|
|
316
324
|
faces_flatten = [fv - 1 for fv in CLOTH_FACES]
|
|
317
325
|
|
|
326
|
+
kd = 1.0e-7
|
|
327
|
+
|
|
328
|
+
if self.solver != "semi_implicit":
|
|
329
|
+
stretching_stiffness = 1e4
|
|
330
|
+
spring_ke = 1e3
|
|
331
|
+
bending_ke = 10
|
|
332
|
+
else:
|
|
333
|
+
stretching_stiffness = 1e5
|
|
334
|
+
spring_ke = 1e2
|
|
335
|
+
bending_ke = 0.0
|
|
336
|
+
|
|
318
337
|
self.builder.add_cloth_mesh(
|
|
319
|
-
pos=wp.vec3(0.0,
|
|
338
|
+
pos=wp.vec3(0.0, 0.0, 0.0),
|
|
320
339
|
rot=wp.quat_from_axis_angle(wp.vec3(1.0, 0.0, 0.0), 0.0),
|
|
321
340
|
scale=1.0,
|
|
322
341
|
vertices=vertices,
|
|
323
342
|
indices=faces_flatten,
|
|
324
343
|
vel=wp.vec3(0.0, 0.0, 0.0),
|
|
325
|
-
density=0.
|
|
326
|
-
tri_ke=
|
|
327
|
-
tri_ka=
|
|
344
|
+
density=0.1,
|
|
345
|
+
tri_ke=stretching_stiffness,
|
|
346
|
+
tri_ka=stretching_stiffness,
|
|
328
347
|
tri_kd=kd,
|
|
348
|
+
edge_ke=bending_ke,
|
|
349
|
+
add_springs=self.solver == "xpbd",
|
|
350
|
+
spring_ke=spring_ke,
|
|
351
|
+
spring_kd=0.0,
|
|
329
352
|
)
|
|
353
|
+
|
|
330
354
|
self.fixed_particles = [0, 9]
|
|
331
355
|
|
|
356
|
+
self.finalize(ground=False)
|
|
357
|
+
|
|
358
|
+
self.state1.particle_q.fill_(0.0)
|
|
359
|
+
|
|
332
360
|
def set_up_bending_experiment(self):
|
|
333
361
|
stretching_stiffness = 1e4
|
|
334
362
|
stretching_damping = 1e-6
|
|
@@ -364,6 +392,9 @@ class VBDClothSim:
|
|
|
364
392
|
tri_kd=stretching_damping,
|
|
365
393
|
edge_ke=10,
|
|
366
394
|
edge_kd=bending_damping,
|
|
395
|
+
add_springs=self.solver == "xpbd",
|
|
396
|
+
spring_ke=1.0e3,
|
|
397
|
+
spring_kd=0.0,
|
|
367
398
|
)
|
|
368
399
|
|
|
369
400
|
self.builder.add_cloth_mesh(
|
|
@@ -379,6 +410,9 @@ class VBDClothSim:
|
|
|
379
410
|
tri_kd=stretching_damping,
|
|
380
411
|
edge_ke=100,
|
|
381
412
|
edge_kd=bending_damping,
|
|
413
|
+
add_springs=self.solver == "xpbd",
|
|
414
|
+
spring_ke=1.0e3,
|
|
415
|
+
spring_kd=0.0,
|
|
382
416
|
)
|
|
383
417
|
|
|
384
418
|
self.builder.add_cloth_mesh(
|
|
@@ -394,57 +428,155 @@ class VBDClothSim:
|
|
|
394
428
|
tri_kd=stretching_damping,
|
|
395
429
|
edge_ke=1000,
|
|
396
430
|
edge_kd=bending_damping,
|
|
431
|
+
add_springs=self.solver == "xpbd",
|
|
432
|
+
spring_ke=1.0e3,
|
|
433
|
+
spring_kd=0.0,
|
|
397
434
|
)
|
|
398
435
|
|
|
399
436
|
self.fixed_particles = [0, 29, 36, 65, 72, 101]
|
|
400
437
|
|
|
438
|
+
self.finalize()
|
|
439
|
+
|
|
440
|
+
def set_self_collision_experiment(self):
|
|
441
|
+
elasticity_ke = 1e4
|
|
442
|
+
elasticity_kd = 1e-6
|
|
443
|
+
|
|
444
|
+
vs1 = [wp.vec3(v) for v in [[0, 0, 0], [1, 0, 0], [1, 0, 1], [0, 0, 1]]]
|
|
445
|
+
fs1 = [0, 1, 2, 0, 2, 3]
|
|
446
|
+
|
|
447
|
+
self.builder.add_cloth_mesh(
|
|
448
|
+
pos=wp.vec3(0.0, 0.0, 0.0),
|
|
449
|
+
rot=wp.quat_from_axis_angle(wp.vec3(1.0, 0.0, 0.0), 0.0),
|
|
450
|
+
scale=1.0,
|
|
451
|
+
vertices=vs1,
|
|
452
|
+
indices=fs1,
|
|
453
|
+
vel=wp.vec3(0.0, 0.0, 0.0),
|
|
454
|
+
density=0.02,
|
|
455
|
+
tri_ke=elasticity_ke,
|
|
456
|
+
tri_ka=elasticity_ke,
|
|
457
|
+
tri_kd=elasticity_kd,
|
|
458
|
+
add_springs=self.solver == "xpbd",
|
|
459
|
+
spring_ke=1.0e3,
|
|
460
|
+
spring_kd=0.0,
|
|
461
|
+
)
|
|
462
|
+
|
|
463
|
+
vs2 = [wp.vec3(v) for v in [[0.3, 0, 0.7], [0.3, 0, 0.2], [0.8, 0, 0.4]]]
|
|
464
|
+
fs2 = [0, 1, 2]
|
|
465
|
+
|
|
466
|
+
self.builder.add_cloth_mesh(
|
|
467
|
+
pos=wp.vec3(0.0, 0.5, 0.0),
|
|
468
|
+
rot=wp.quat_from_axis_angle(wp.vec3(1.0, 0.0, 0.0), 0.0),
|
|
469
|
+
scale=1.0,
|
|
470
|
+
vertices=vs2,
|
|
471
|
+
indices=fs2,
|
|
472
|
+
vel=wp.vec3(0.0, 0.0, 0.0),
|
|
473
|
+
density=0.02,
|
|
474
|
+
tri_ke=elasticity_ke,
|
|
475
|
+
tri_ka=elasticity_ke,
|
|
476
|
+
tri_kd=elasticity_kd,
|
|
477
|
+
add_springs=self.solver == "xpbd",
|
|
478
|
+
spring_ke=1.0e3,
|
|
479
|
+
spring_kd=0.0,
|
|
480
|
+
)
|
|
481
|
+
|
|
482
|
+
self.fixed_particles = range(0, 4)
|
|
483
|
+
|
|
484
|
+
self.finalize(handle_self_contact=True, ground=False)
|
|
485
|
+
self.model.soft_contact_radius = 0.1
|
|
486
|
+
self.model.soft_contact_margin = 0.1
|
|
487
|
+
self.model.soft_contact_ke = 1e4
|
|
488
|
+
self.model.soft_contact_kd = 1e-3
|
|
489
|
+
self.model.soft_contact_mu = 0.2
|
|
490
|
+
self.model.gravity = wp.vec3(0.0, -1000.0, 0)
|
|
491
|
+
self.num_test_frames = 30
|
|
492
|
+
|
|
493
|
+
def set_body_collision_experiment(self, handle_self_contact=False):
|
|
494
|
+
self.renderer_scale_factor = 1.0
|
|
495
|
+
elasticity_ke = 1e4
|
|
496
|
+
elasticity_kd = 1e-6
|
|
497
|
+
|
|
498
|
+
vs1 = [wp.vec3(v) for v in [[0, 0, 0], [1, 0, 0], [1, 0, 1], [0, 0, 1]]]
|
|
499
|
+
fs1 = [0, 1, 2, 0, 2, 3]
|
|
500
|
+
|
|
501
|
+
self.builder.add_cloth_mesh(
|
|
502
|
+
pos=wp.vec3(0.0, 0.0, 0.0),
|
|
503
|
+
rot=wp.quat_from_axis_angle(wp.vec3(1.0, 0.0, 0.0), 0.0),
|
|
504
|
+
scale=1.0,
|
|
505
|
+
vertices=vs1,
|
|
506
|
+
indices=fs1,
|
|
507
|
+
vel=wp.vec3(0.0, 0.0, 0.0),
|
|
508
|
+
density=0.02,
|
|
509
|
+
tri_ke=elasticity_ke,
|
|
510
|
+
tri_ka=elasticity_ke,
|
|
511
|
+
tri_kd=elasticity_kd,
|
|
512
|
+
add_springs=self.solver == "xpbd",
|
|
513
|
+
spring_ke=1.0e3,
|
|
514
|
+
spring_kd=0.0,
|
|
515
|
+
particle_radius=0.1,
|
|
516
|
+
)
|
|
517
|
+
|
|
518
|
+
self.builder.add_shape_box(-1, pos=wp.vec3(0, -3.3, 0), hx=3, hy=3, hz=3)
|
|
519
|
+
|
|
520
|
+
self.fixed_particles = []
|
|
521
|
+
|
|
522
|
+
self.finalize(handle_self_contact=handle_self_contact, ground=False)
|
|
523
|
+
self.model.soft_contact_radius = 0.1
|
|
524
|
+
self.model.soft_contact_margin = 0.1
|
|
525
|
+
self.model.soft_contact_ke = 1e4
|
|
526
|
+
self.model.soft_contact_kd = 1e-3
|
|
527
|
+
self.model.soft_contact_mu = 0.2
|
|
528
|
+
self.model.gravity = wp.vec3(0.0, -1000.0, 0)
|
|
529
|
+
self.num_test_frames = 30
|
|
530
|
+
|
|
401
531
|
def set_up_non_zero_rest_angle_bending_experiment(self):
|
|
402
532
|
# fmt: off
|
|
403
|
-
vs =
|
|
404
|
-
[
|
|
405
|
-
[
|
|
406
|
-
[
|
|
407
|
-
[
|
|
408
|
-
[
|
|
409
|
-
[
|
|
410
|
-
[
|
|
411
|
-
[
|
|
412
|
-
[
|
|
413
|
-
[
|
|
414
|
-
[
|
|
415
|
-
[
|
|
416
|
-
[-
|
|
417
|
-
[-
|
|
418
|
-
[
|
|
419
|
-
[
|
|
533
|
+
vs =[
|
|
534
|
+
[ 0. , 1. , -1. ],
|
|
535
|
+
[ 0. , 1. , 1. ],
|
|
536
|
+
[ 0.70711, 0.70711, -1. ],
|
|
537
|
+
[ 0.70711, 0.70711, 1. ],
|
|
538
|
+
[ 1. , 0. , -1. ],
|
|
539
|
+
[ 1. , -0. , 1. ],
|
|
540
|
+
[ 0.70711, -0.70711, -1. ],
|
|
541
|
+
[ 0.70711, -0.70711, 1. ],
|
|
542
|
+
[ 0. , -1. , -1. ],
|
|
543
|
+
[ 0. , -1. , 1. ],
|
|
544
|
+
[-0.70711, -0.70711, -1. ],
|
|
545
|
+
[-0.70711, -0.70711, 1. ],
|
|
546
|
+
[-1. , 0. , -1. ],
|
|
547
|
+
[-1. , -0. , 1. ],
|
|
548
|
+
[-0.70711, 0.70711, -1. ],
|
|
549
|
+
[-0.70711, 0.70711, 1. ],
|
|
420
550
|
]
|
|
421
551
|
fs = [
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
552
|
+
1, 2, 0,
|
|
553
|
+
3, 4, 2,
|
|
554
|
+
5, 6, 4,
|
|
555
|
+
7, 8, 6,
|
|
556
|
+
9, 10, 8,
|
|
557
|
+
11, 12, 10,
|
|
558
|
+
3, 5, 4,
|
|
559
|
+
13, 14, 12,
|
|
560
|
+
15, 0, 14,
|
|
561
|
+
1, 3, 2,
|
|
562
|
+
5, 7, 6,
|
|
563
|
+
7, 9, 8,
|
|
564
|
+
9, 11, 10,
|
|
565
|
+
11, 13, 12,
|
|
566
|
+
13, 15, 14,
|
|
567
|
+
15, 1, 0,
|
|
436
568
|
]
|
|
437
569
|
# fmt: on
|
|
438
570
|
|
|
439
|
-
stretching_stiffness =
|
|
440
|
-
stretching_damping = 1e-
|
|
441
|
-
edge_ke =
|
|
442
|
-
bending_damping = 1e-
|
|
571
|
+
stretching_stiffness = 1e5
|
|
572
|
+
stretching_damping = 1e-5
|
|
573
|
+
edge_ke = 100
|
|
574
|
+
bending_damping = 1e-4
|
|
443
575
|
vs = [wp.vec3(v) for v in vs]
|
|
444
576
|
|
|
445
577
|
self.builder.add_cloth_mesh(
|
|
446
|
-
pos=wp.vec3(0.0,
|
|
447
|
-
rot=wp.
|
|
578
|
+
pos=wp.vec3(0.0, 0.0, 0.0),
|
|
579
|
+
rot=wp.quat_identity(),
|
|
448
580
|
scale=1.0,
|
|
449
581
|
vertices=vs,
|
|
450
582
|
indices=fs,
|
|
@@ -455,21 +587,71 @@ class VBDClothSim:
|
|
|
455
587
|
tri_kd=stretching_damping,
|
|
456
588
|
edge_ke=edge_ke,
|
|
457
589
|
edge_kd=bending_damping,
|
|
590
|
+
add_springs=self.solver == "xpbd",
|
|
591
|
+
spring_ke=1.0e3,
|
|
592
|
+
spring_kd=0.0,
|
|
458
593
|
)
|
|
459
594
|
self.fixed_particles = [0, 1]
|
|
460
595
|
|
|
461
|
-
|
|
462
|
-
|
|
596
|
+
self.finalize(handle_self_contact=False, ground=False)
|
|
597
|
+
|
|
598
|
+
def set_free_falling_experiment(self):
|
|
599
|
+
self.input_scale_factor = 1.0
|
|
600
|
+
self.renderer_scale_factor = 0.01
|
|
601
|
+
vertices = [wp.vec3(v) * self.input_scale_factor for v in CLOTH_POINTS]
|
|
602
|
+
faces_flatten = [fv - 1 for fv in CLOTH_FACES]
|
|
603
|
+
if self.solver != "semi_implicit":
|
|
604
|
+
stretching_stiffness = 1e4
|
|
605
|
+
spring_ke = 1e3
|
|
606
|
+
bending_ke = 10
|
|
607
|
+
else:
|
|
608
|
+
stretching_stiffness = 1e2
|
|
609
|
+
spring_ke = 1e2
|
|
610
|
+
bending_ke = 10
|
|
611
|
+
|
|
612
|
+
self.builder.add_cloth_mesh(
|
|
613
|
+
vertices=vertices,
|
|
614
|
+
indices=faces_flatten,
|
|
615
|
+
scale=0.1,
|
|
616
|
+
density=2,
|
|
617
|
+
pos=wp.vec3(0.0, 4.0, 0.0),
|
|
618
|
+
rot=wp.quat_identity(),
|
|
619
|
+
vel=wp.vec3(0.0, 0.0, 0.0),
|
|
620
|
+
edge_ke=bending_ke,
|
|
621
|
+
edge_kd=0.0,
|
|
622
|
+
tri_ke=stretching_stiffness,
|
|
623
|
+
tri_ka=stretching_stiffness,
|
|
624
|
+
tri_kd=0.0,
|
|
625
|
+
add_springs=self.solver == "xpbd",
|
|
626
|
+
spring_ke=spring_ke,
|
|
627
|
+
spring_kd=0.0,
|
|
628
|
+
)
|
|
629
|
+
self.fixed_particles = []
|
|
630
|
+
self.num_test_frames = 30
|
|
631
|
+
self.finalize(ground=False)
|
|
632
|
+
|
|
633
|
+
def finalize(self, handle_self_contact=False, ground=True):
|
|
634
|
+
self.builder.color(include_bending=True)
|
|
463
635
|
|
|
464
636
|
self.model = self.builder.finalize(device=self.device)
|
|
465
|
-
self.model.ground =
|
|
637
|
+
self.model.ground = ground
|
|
466
638
|
self.model.gravity = wp.vec3(0, -1000.0, 0)
|
|
467
639
|
self.model.soft_contact_ke = 1.0e4
|
|
468
|
-
self.model.soft_contact_kd = 1.
|
|
640
|
+
self.model.soft_contact_kd = 1.0e-2
|
|
469
641
|
|
|
470
642
|
self.set_points_fixed(self.model, self.fixed_particles)
|
|
471
643
|
|
|
472
|
-
self.
|
|
644
|
+
if self.solver == "vbd":
|
|
645
|
+
self.integrator = wp.sim.VBDIntegrator(self.model, self.iterations, handle_self_contact=handle_self_contact)
|
|
646
|
+
elif self.solver == "xpbd":
|
|
647
|
+
self.integrator = wp.sim.XPBDIntegrator(
|
|
648
|
+
self.iterations,
|
|
649
|
+
)
|
|
650
|
+
elif self.solver == "semi_implicit":
|
|
651
|
+
self.integrator = wp.sim.SemiImplicitIntegrator()
|
|
652
|
+
else:
|
|
653
|
+
raise ValueError("Unsupported solver type: " + self.solver)
|
|
654
|
+
|
|
473
655
|
self.state0 = self.model.state()
|
|
474
656
|
self.state1 = self.model.state()
|
|
475
657
|
|
|
@@ -477,23 +659,53 @@ class VBDClothSim:
|
|
|
477
659
|
|
|
478
660
|
self.graph = None
|
|
479
661
|
if self.use_cuda_graph:
|
|
662
|
+
if self.solver == "vbd":
|
|
663
|
+
wp.set_module_options({"block_dim": 256}, warp.sim.integrator_vbd)
|
|
664
|
+
wp.load_module(warp.sim.integrator_vbd, device=self.device)
|
|
665
|
+
elif self.solver == "xpbd":
|
|
666
|
+
wp.set_module_options({"block_dim": 256}, warp.sim.integrator_xpbd)
|
|
667
|
+
wp.load_module(warp.sim.integrator_xpbd, device=self.device)
|
|
668
|
+
elif self.solver == "semi_implicit":
|
|
669
|
+
wp.set_module_options({"block_dim": 256}, warp.sim.integrator_euler)
|
|
670
|
+
wp.load_module(warp.sim.integrator_euler, device=self.device)
|
|
671
|
+
wp.load_module(warp.sim.particles, device=self.device)
|
|
672
|
+
wp.load_module(warp.sim.integrator, device=self.device)
|
|
673
|
+
collide_module = importlib.import_module("warp.sim.collide")
|
|
674
|
+
wp.set_module_options({"block_dim": 256}, collide_module)
|
|
675
|
+
wp.load_module(collide_module, device=self.device)
|
|
480
676
|
wp.load_module(device=self.device)
|
|
481
|
-
wp.set_module_options({"block_dim": 256}, warp.sim.integrator_vbd)
|
|
482
|
-
wp.load_module(warp.sim.integrator_vbd, device=self.device)
|
|
483
677
|
with wp.ScopedCapture(device=self.device, force_module_load=False) as capture:
|
|
484
678
|
self.simulate()
|
|
485
679
|
self.graph = capture.graph
|
|
486
680
|
|
|
487
681
|
def simulate(self):
|
|
488
|
-
for _step in range(self.num_substeps
|
|
682
|
+
for _step in range(self.num_substeps):
|
|
683
|
+
self.state0.clear_forces()
|
|
684
|
+
wp.sim.collide(self.model, self.state0)
|
|
685
|
+
|
|
489
686
|
self.integrator.simulate(self.model, self.state0, self.state1, self.dt, None)
|
|
490
687
|
(self.state0, self.state1) = (self.state1, self.state0)
|
|
491
688
|
|
|
492
689
|
def run(self):
|
|
493
|
-
|
|
494
|
-
|
|
690
|
+
self.sim_time = 0.0
|
|
691
|
+
|
|
692
|
+
if self.do_rendering:
|
|
693
|
+
self.renderer = wp.sim.render.SimRendererOpenGL(self.model, "cloth_sim", scaling=self.renderer_scale_factor)
|
|
495
694
|
else:
|
|
496
|
-
self.
|
|
695
|
+
self.renderer = None
|
|
696
|
+
|
|
697
|
+
for _frame in range(self.num_test_frames):
|
|
698
|
+
if self.graph:
|
|
699
|
+
wp.capture_launch(self.graph)
|
|
700
|
+
else:
|
|
701
|
+
self.simulate()
|
|
702
|
+
|
|
703
|
+
if self.renderer is not None:
|
|
704
|
+
self.renderer.begin_frame()
|
|
705
|
+
self.renderer.render(self.state0)
|
|
706
|
+
self.renderer.end_frame()
|
|
707
|
+
|
|
708
|
+
self.sim_time = self.sim_time + self.frame_dt
|
|
497
709
|
|
|
498
710
|
def set_points_fixed(self, model, fixed_particles):
|
|
499
711
|
if len(fixed_particles):
|
|
@@ -504,94 +716,148 @@ class VBDClothSim:
|
|
|
504
716
|
model.particle_flags = wp.array(flags, device=model.device)
|
|
505
717
|
|
|
506
718
|
|
|
507
|
-
def
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
example.set_up_bending_experiment()
|
|
511
|
-
example.finalize()
|
|
512
|
-
example.model.ground = False
|
|
719
|
+
def test_cloth_sagging(test, device, solver):
|
|
720
|
+
example = ClothSim(device, solver, use_cuda_graph=True)
|
|
721
|
+
example.set_up_sagging_experiment()
|
|
513
722
|
|
|
514
|
-
|
|
515
|
-
f.getvalue(),
|
|
516
|
-
r"Warp UserWarning: The graph is not optimizable anymore, terminated with a max/min ratio: 2.0 without reaching the target ratio: 1.1",
|
|
517
|
-
)
|
|
723
|
+
initial_pos = example.state0.particle_q.numpy().copy()
|
|
518
724
|
|
|
519
725
|
example.run()
|
|
520
726
|
|
|
727
|
+
fixed_points = np.where(np.logical_not(example.model.particle_flags.numpy()))
|
|
521
728
|
# examine that the simulation does not explode
|
|
522
729
|
final_pos = example.state0.particle_q.numpy()
|
|
730
|
+
test.assertTrue((initial_pos[fixed_points, :] == final_pos[fixed_points, :]).all())
|
|
523
731
|
test.assertTrue((final_pos < 1e5).all())
|
|
524
|
-
# examine that the simulation
|
|
732
|
+
# examine that the simulation has moved
|
|
525
733
|
test.assertTrue((example.init_pos != final_pos).any())
|
|
526
734
|
|
|
527
735
|
|
|
528
|
-
def
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
example.set_up_sagging_experiment()
|
|
532
|
-
example.finalize()
|
|
533
|
-
|
|
534
|
-
test.assertRegex(
|
|
535
|
-
f.getvalue(),
|
|
536
|
-
r"Warp UserWarning: The graph is not optimizable anymore, terminated with a max/min ratio: 2.0 without reaching the target ratio: 1.1",
|
|
537
|
-
)
|
|
736
|
+
def test_cloth_bending(test, device, solver):
|
|
737
|
+
example = ClothSim(device, solver, use_cuda_graph=True)
|
|
738
|
+
example.set_up_bending_experiment()
|
|
538
739
|
|
|
539
740
|
example.run()
|
|
540
741
|
|
|
541
742
|
# examine that the simulation does not explode
|
|
542
743
|
final_pos = example.state0.particle_q.numpy()
|
|
543
744
|
test.assertTrue((final_pos < 1e5).all())
|
|
544
|
-
# examine that the simulation
|
|
745
|
+
# examine that the simulation has moved
|
|
545
746
|
test.assertTrue((example.init_pos != final_pos).any())
|
|
546
747
|
|
|
547
748
|
|
|
548
|
-
def
|
|
549
|
-
example =
|
|
550
|
-
example.
|
|
551
|
-
example.finalize()
|
|
749
|
+
def test_cloth_bending_non_zero_rest_angle_bending(test, device, solver):
|
|
750
|
+
example = ClothSim(device, solver, use_cuda_graph=True)
|
|
751
|
+
example.set_up_non_zero_rest_angle_bending_experiment()
|
|
552
752
|
|
|
553
753
|
example.run()
|
|
554
754
|
|
|
555
755
|
# examine that the simulation does not explode
|
|
556
756
|
final_pos = example.state0.particle_q.numpy()
|
|
557
|
-
test.assertTrue((final_pos < 1e5).all())
|
|
558
|
-
# examine that the simulation
|
|
757
|
+
test.assertTrue((np.abs(final_pos) < 1e5).all())
|
|
758
|
+
# examine that the simulation has moved
|
|
559
759
|
test.assertTrue((example.init_pos != final_pos).any())
|
|
560
760
|
|
|
561
761
|
|
|
562
|
-
def
|
|
563
|
-
example =
|
|
564
|
-
example.
|
|
565
|
-
|
|
762
|
+
def test_cloth_body_collision(test, device, solver):
|
|
763
|
+
example = ClothSim(device, solver, use_cuda_graph=True)
|
|
764
|
+
example.set_body_collision_experiment(handle_self_contact=False)
|
|
765
|
+
|
|
766
|
+
example.run()
|
|
767
|
+
|
|
768
|
+
# examine that the velocity has died out
|
|
769
|
+
final_vel = example.state0.particle_qd.numpy()
|
|
770
|
+
final_pos = example.state0.particle_q.numpy()
|
|
771
|
+
test.assertTrue((np.linalg.norm(final_vel, axis=1) < 1.0).all())
|
|
772
|
+
# examine that the simulation has moved
|
|
773
|
+
test.assertTrue((example.init_pos[:, 1] != final_pos[:, 1]).any())
|
|
774
|
+
|
|
775
|
+
# run again with handle_self_contact=True
|
|
776
|
+
example = ClothSim(device, solver, use_cuda_graph=True)
|
|
777
|
+
example.set_body_collision_experiment(handle_self_contact=True)
|
|
778
|
+
example.run()
|
|
779
|
+
# examine that the velocity has died out
|
|
780
|
+
final_vel = example.state0.particle_qd.numpy()
|
|
781
|
+
final_pos = example.state0.particle_q.numpy()
|
|
782
|
+
test.assertTrue((np.linalg.norm(final_vel, axis=1) < 1.0).all())
|
|
783
|
+
# examine that the simulation has moved
|
|
784
|
+
test.assertTrue((example.init_pos[:, 1] != final_pos[:, 1]).any())
|
|
785
|
+
|
|
786
|
+
|
|
787
|
+
def test_cloth_self_collision(test, device, solver):
|
|
788
|
+
example = ClothSim(device, solver, use_cuda_graph=True)
|
|
789
|
+
example.set_self_collision_experiment()
|
|
790
|
+
|
|
791
|
+
example.run()
|
|
792
|
+
|
|
793
|
+
# examine that the velocity has died out
|
|
794
|
+
final_vel = example.state0.particle_qd.numpy()
|
|
795
|
+
final_pos = example.state0.particle_q.numpy()
|
|
796
|
+
test.assertTrue((np.linalg.norm(final_vel, axis=1) < 1.0).all())
|
|
797
|
+
# examine that the simulation has moved
|
|
798
|
+
test.assertTrue((example.init_pos != final_pos).any())
|
|
799
|
+
|
|
800
|
+
|
|
801
|
+
def test_cloth_free_fall(test, device, solver):
|
|
802
|
+
example = ClothSim(device, solver)
|
|
803
|
+
example.set_free_falling_experiment()
|
|
804
|
+
|
|
805
|
+
initial_pos = example.state0.particle_q.numpy().copy()
|
|
806
|
+
|
|
566
807
|
example.run()
|
|
567
808
|
|
|
568
809
|
# examine that the simulation does not explode
|
|
569
810
|
final_pos = example.state0.particle_q.numpy()
|
|
570
811
|
test.assertTrue((final_pos < 1e5).all())
|
|
571
|
-
# examine that the simulation
|
|
812
|
+
# examine that the simulation has moved
|
|
572
813
|
test.assertTrue((example.init_pos != final_pos).any())
|
|
573
814
|
|
|
815
|
+
gravity = np.array(example.model.gravity)
|
|
816
|
+
diff = final_pos - initial_pos
|
|
817
|
+
vertical_translation_norm = diff @ gravity[..., None] / (np.linalg.norm(gravity) ** 2)
|
|
818
|
+
# ensure it's free-falling
|
|
819
|
+
test.assertTrue((np.abs(vertical_translation_norm - 0.5 * np.linalg.norm(gravity) * (example.dt**2)) < 2e-1).all())
|
|
820
|
+
horizontal_move = diff - (vertical_translation_norm * gravity)
|
|
821
|
+
# ensure its horizontal translation is minimal
|
|
822
|
+
test.assertTrue((np.abs(horizontal_move) < 1e-1).all())
|
|
823
|
+
|
|
574
824
|
|
|
575
|
-
devices = get_test_devices()
|
|
576
|
-
cuda_devices = get_selected_cuda_test_devices()
|
|
825
|
+
devices = get_test_devices(mode="basic")
|
|
577
826
|
|
|
578
827
|
|
|
579
|
-
class
|
|
828
|
+
class TestCloth(unittest.TestCase):
|
|
580
829
|
pass
|
|
581
830
|
|
|
582
831
|
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
832
|
+
tests_to_run = {
|
|
833
|
+
"xpbd": [
|
|
834
|
+
test_cloth_free_fall,
|
|
835
|
+
test_cloth_sagging,
|
|
836
|
+
test_cloth_bending,
|
|
837
|
+
test_cloth_bending_non_zero_rest_angle_bending,
|
|
838
|
+
],
|
|
839
|
+
"semi_implicit": [
|
|
840
|
+
test_cloth_free_fall,
|
|
841
|
+
test_cloth_sagging,
|
|
842
|
+
test_cloth_bending,
|
|
843
|
+
],
|
|
844
|
+
"vbd": [
|
|
845
|
+
test_cloth_free_fall,
|
|
846
|
+
test_cloth_sagging,
|
|
847
|
+
test_cloth_bending,
|
|
848
|
+
test_cloth_self_collision,
|
|
849
|
+
test_cloth_body_collision,
|
|
850
|
+
test_cloth_bending_non_zero_rest_angle_bending,
|
|
851
|
+
],
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
for solver, tests in tests_to_run.items():
|
|
855
|
+
for test in tests:
|
|
856
|
+
add_function_test(
|
|
857
|
+
TestCloth, f"{test.__name__}_{solver}", partial(test, solver=solver), devices=devices, check_output=False
|
|
858
|
+
)
|
|
593
859
|
|
|
594
860
|
|
|
595
861
|
if __name__ == "__main__":
|
|
596
862
|
wp.clear_kernel_cache()
|
|
597
|
-
unittest.main(verbosity=2)
|
|
863
|
+
unittest.main(verbosity=2, failfast=True)
|