warp-lang 1.5.0__py3-none-win_amd64.whl → 1.6.0__py3-none-win_amd64.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.

Files changed (132) hide show
  1. warp/__init__.py +5 -0
  2. warp/autograd.py +414 -191
  3. warp/bin/warp-clang.dll +0 -0
  4. warp/bin/warp.dll +0 -0
  5. warp/build.py +40 -12
  6. warp/build_dll.py +13 -6
  7. warp/builtins.py +1124 -497
  8. warp/codegen.py +261 -136
  9. warp/config.py +1 -1
  10. warp/context.py +357 -119
  11. warp/examples/assets/square_cloth.usd +0 -0
  12. warp/examples/benchmarks/benchmark_gemm.py +27 -18
  13. warp/examples/benchmarks/benchmark_interop_paddle.py +3 -3
  14. warp/examples/benchmarks/benchmark_interop_torch.py +3 -3
  15. warp/examples/core/example_torch.py +18 -34
  16. warp/examples/fem/example_apic_fluid.py +1 -0
  17. warp/examples/fem/example_mixed_elasticity.py +1 -1
  18. warp/examples/optim/example_bounce.py +1 -1
  19. warp/examples/optim/example_cloth_throw.py +1 -1
  20. warp/examples/optim/example_diffray.py +4 -15
  21. warp/examples/optim/example_drone.py +1 -1
  22. warp/examples/optim/example_softbody_properties.py +392 -0
  23. warp/examples/optim/example_trajectory.py +1 -3
  24. warp/examples/optim/example_walker.py +5 -0
  25. warp/examples/sim/example_cartpole.py +0 -2
  26. warp/examples/sim/example_cloth.py +3 -1
  27. warp/examples/sim/example_cloth_self_contact.py +260 -0
  28. warp/examples/sim/example_granular_collision_sdf.py +4 -5
  29. warp/examples/sim/example_jacobian_ik.py +0 -2
  30. warp/examples/sim/example_quadruped.py +5 -2
  31. warp/examples/tile/example_tile_cholesky.py +79 -0
  32. warp/examples/tile/example_tile_convolution.py +2 -2
  33. warp/examples/tile/example_tile_fft.py +2 -2
  34. warp/examples/tile/example_tile_filtering.py +3 -3
  35. warp/examples/tile/example_tile_matmul.py +4 -4
  36. warp/examples/tile/example_tile_mlp.py +12 -12
  37. warp/examples/tile/example_tile_nbody.py +180 -0
  38. warp/examples/tile/example_tile_walker.py +319 -0
  39. warp/fem/geometry/geometry.py +0 -2
  40. warp/math.py +147 -0
  41. warp/native/array.h +12 -0
  42. warp/native/builtin.h +0 -1
  43. warp/native/bvh.cpp +149 -70
  44. warp/native/bvh.cu +287 -68
  45. warp/native/bvh.h +195 -85
  46. warp/native/clang/clang.cpp +5 -1
  47. warp/native/coloring.cpp +5 -1
  48. warp/native/cuda_util.cpp +91 -53
  49. warp/native/cuda_util.h +5 -0
  50. warp/native/exports.h +40 -40
  51. warp/native/intersect.h +17 -0
  52. warp/native/mat.h +41 -0
  53. warp/native/mathdx.cpp +19 -0
  54. warp/native/mesh.cpp +25 -8
  55. warp/native/mesh.cu +153 -101
  56. warp/native/mesh.h +482 -403
  57. warp/native/quat.h +40 -0
  58. warp/native/solid_angle.h +7 -0
  59. warp/native/sort.cpp +85 -0
  60. warp/native/sort.cu +34 -0
  61. warp/native/sort.h +3 -1
  62. warp/native/spatial.h +11 -0
  63. warp/native/tile.h +1187 -669
  64. warp/native/tile_reduce.h +8 -6
  65. warp/native/vec.h +41 -0
  66. warp/native/warp.cpp +8 -1
  67. warp/native/warp.cu +263 -40
  68. warp/native/warp.h +19 -5
  69. warp/optim/linear.py +22 -4
  70. warp/render/render_opengl.py +130 -64
  71. warp/sim/__init__.py +6 -1
  72. warp/sim/collide.py +270 -26
  73. warp/sim/import_urdf.py +8 -8
  74. warp/sim/integrator_euler.py +25 -7
  75. warp/sim/integrator_featherstone.py +154 -35
  76. warp/sim/integrator_vbd.py +842 -40
  77. warp/sim/model.py +134 -72
  78. warp/sparse.py +1 -1
  79. warp/stubs.py +265 -132
  80. warp/tape.py +28 -30
  81. warp/tests/aux_test_module_unload.py +15 -0
  82. warp/tests/{test_sim_grad.py → flaky_test_sim_grad.py} +104 -63
  83. warp/tests/test_array.py +74 -0
  84. warp/tests/test_assert.py +242 -0
  85. warp/tests/test_codegen.py +14 -61
  86. warp/tests/test_collision.py +2 -2
  87. warp/tests/test_coloring.py +12 -2
  88. warp/tests/test_examples.py +12 -1
  89. warp/tests/test_func.py +21 -4
  90. warp/tests/test_grad_debug.py +87 -2
  91. warp/tests/test_hash_grid.py +1 -1
  92. warp/tests/test_ipc.py +116 -0
  93. warp/tests/test_lerp.py +13 -87
  94. warp/tests/test_mat.py +138 -167
  95. warp/tests/test_math.py +47 -1
  96. warp/tests/test_matmul.py +17 -16
  97. warp/tests/test_matmul_lite.py +10 -15
  98. warp/tests/test_mesh.py +84 -60
  99. warp/tests/test_mesh_query_aabb.py +165 -0
  100. warp/tests/test_mesh_query_point.py +328 -286
  101. warp/tests/test_mesh_query_ray.py +134 -121
  102. warp/tests/test_mlp.py +2 -2
  103. warp/tests/test_operators.py +43 -0
  104. warp/tests/test_overwrite.py +47 -2
  105. warp/tests/test_quat.py +77 -0
  106. warp/tests/test_reload.py +29 -0
  107. warp/tests/test_sim_grad_bounce_linear.py +204 -0
  108. warp/tests/test_smoothstep.py +17 -83
  109. warp/tests/test_static.py +19 -3
  110. warp/tests/test_tape.py +25 -0
  111. warp/tests/test_tile.py +178 -191
  112. warp/tests/test_tile_load.py +356 -0
  113. warp/tests/test_tile_mathdx.py +61 -8
  114. warp/tests/test_tile_mlp.py +17 -17
  115. warp/tests/test_tile_reduce.py +24 -18
  116. warp/tests/test_tile_shared_memory.py +66 -17
  117. warp/tests/test_tile_view.py +165 -0
  118. warp/tests/test_torch.py +35 -0
  119. warp/tests/test_utils.py +36 -24
  120. warp/tests/test_vec.py +110 -0
  121. warp/tests/unittest_suites.py +29 -4
  122. warp/tests/unittest_utils.py +30 -13
  123. warp/thirdparty/unittest_parallel.py +2 -2
  124. warp/types.py +411 -101
  125. warp/utils.py +10 -7
  126. {warp_lang-1.5.0.dist-info → warp_lang-1.6.0.dist-info}/METADATA +92 -69
  127. {warp_lang-1.5.0.dist-info → warp_lang-1.6.0.dist-info}/RECORD +130 -119
  128. {warp_lang-1.5.0.dist-info → warp_lang-1.6.0.dist-info}/WHEEL +1 -1
  129. warp/examples/benchmarks/benchmark_tile.py +0 -179
  130. warp/native/tile_gemm.h +0 -341
  131. {warp_lang-1.5.0.dist-info → warp_lang-1.6.0.dist-info}/LICENSE.md +0 -0
  132. {warp_lang-1.5.0.dist-info → warp_lang-1.6.0.dist-info}/top_level.txt +0 -0
warp/sim/model.py CHANGED
@@ -578,19 +578,20 @@ class Model:
578
578
 
579
579
  This setting is not supported by :class:`FeatherstoneIntegrator`.
580
580
 
581
- joint_limit_lower (array): Joint lower position limits, shape [joint_count], float
582
- joint_limit_upper (array): Joint upper position limits, shape [joint_count], float
583
- joint_limit_ke (array): Joint position limit stiffness (used by the Euler integrators), shape [joint_count], float
584
- joint_limit_kd (array): Joint position limit damping (used by the Euler integrators), shape [joint_count], float
581
+ joint_limit_lower (array): Joint lower position limits, shape [joint_axis_count], float
582
+ joint_limit_upper (array): Joint upper position limits, shape [joint_axis_count], float
583
+ joint_limit_ke (array): Joint position limit stiffness (used by the Euler integrators), shape [joint_axis_count], float
584
+ joint_limit_kd (array): Joint position limit damping (used by the Euler integrators), shape [joint_axis_count], float
585
585
  joint_twist_lower (array): Joint lower twist limit, shape [joint_count], float
586
586
  joint_twist_upper (array): Joint upper twist limit, shape [joint_count], float
587
- joint_q_start (array): Start index of the first position coordinate per joint, shape [joint_count], int
588
- joint_qd_start (array): Start index of the first velocity coordinate per joint, shape [joint_count], int
587
+ joint_q_start (array): Start index of the first position coordinate per joint (note the last value is an additional sentinel entry to allow for querying the q dimensionality of joint i via ``joint_q_start[i+1] - joint_q_start[i]``), shape [joint_count + 1], int
588
+ joint_qd_start (array): Start index of the first velocity coordinate per joint (note the last value is an additional sentinel entry to allow for querying the qd dimensionality of joint i via ``joint_qd_start[i+1] - joint_qd_start[i]``), shape [joint_count + 1], int
589
589
  articulation_start (array): Articulation start index, shape [articulation_count], int
590
590
  joint_name (list): Joint names, shape [joint_count], str
591
591
  joint_attach_ke (float): Joint attachment force stiffness (used by :class:`SemiImplicitIntegrator`)
592
592
  joint_attach_kd (float): Joint attachment force damping (used by :class:`SemiImplicitIntegrator`)
593
593
 
594
+ soft_contact_radius (float): Contact radius used for self-collisions in the VBD integrator.
594
595
  soft_contact_margin (float): Contact margin for generation of soft contacts
595
596
  soft_contact_ke (float): Stiffness of soft contacts (used by the Euler integrators)
596
597
  soft_contact_kd (float): Damping of soft contacts (used by the Euler integrators)
@@ -761,6 +762,7 @@ class Model:
761
762
  self.joint_attach_ke = 1.0e3
762
763
  self.joint_attach_kd = 1.0e2
763
764
 
765
+ self.soft_contact_radius = 0.2
764
766
  self.soft_contact_margin = 0.2
765
767
  self.soft_contact_ke = 1.0e3
766
768
  self.soft_contact_kd = 10.0
@@ -1046,6 +1048,8 @@ class Model:
1046
1048
  @property
1047
1049
  def soft_contact_max(self):
1048
1050
  """Maximum number of soft contacts that can be registered"""
1051
+ if self.soft_contact_particle is None:
1052
+ return 0
1049
1053
  return len(self.soft_contact_particle)
1050
1054
 
1051
1055
 
@@ -1442,12 +1446,14 @@ class ModelBuilder:
1442
1446
  self.shape_collision_filter_pairs.add((i + shape_count, j + shape_count))
1443
1447
  for group, shapes in builder.shape_collision_group_map.items():
1444
1448
  if separate_collision_group:
1445
- group = self.last_collision_group + 1
1449
+ extend_group = self.last_collision_group + 1
1446
1450
  else:
1447
- group = group + self.last_collision_group if group > -1 else -1
1448
- if group not in self.shape_collision_group_map:
1449
- self.shape_collision_group_map[group] = []
1450
- self.shape_collision_group_map[group].extend([s + shape_count for s in shapes])
1451
+ extend_group = group + self.last_collision_group if group > -1 else -1
1452
+
1453
+ if extend_group not in self.shape_collision_group_map:
1454
+ self.shape_collision_group_map[extend_group] = []
1455
+
1456
+ self.shape_collision_group_map[extend_group].extend([s + shape_count for s in shapes])
1451
1457
 
1452
1458
  # update last collision group counter
1453
1459
  if separate_collision_group:
@@ -1745,8 +1751,8 @@ class ModelBuilder:
1745
1751
  mode: int = JOINT_MODE_FORCE,
1746
1752
  limit_lower: float = -2 * math.pi,
1747
1753
  limit_upper: float = 2 * math.pi,
1748
- limit_ke: float = default_joint_limit_ke,
1749
- limit_kd: float = default_joint_limit_kd,
1754
+ limit_ke: float = None,
1755
+ limit_kd: float = None,
1750
1756
  linear_compliance: float = 0.0,
1751
1757
  angular_compliance: float = 0.0,
1752
1758
  armature: float = 1e-2,
@@ -1767,8 +1773,8 @@ class ModelBuilder:
1767
1773
  target_kd: The damping of the joint target
1768
1774
  limit_lower: The lower limit of the joint
1769
1775
  limit_upper: The upper limit of the joint
1770
- limit_ke: The stiffness of the joint limit
1771
- limit_kd: The damping of the joint limit
1776
+ limit_ke: The stiffness of the joint limit (None to use the default value :attr:`default_joint_limit_ke`)
1777
+ limit_kd: The damping of the joint limit (None to use the default value :attr:`default_joint_limit_kd`)
1772
1778
  linear_compliance: The linear compliance of the joint
1773
1779
  angular_compliance: The angular compliance of the joint
1774
1780
  armature: Artificial inertia added around the joint axis
@@ -1786,6 +1792,9 @@ class ModelBuilder:
1786
1792
  if child_xform is None:
1787
1793
  child_xform = wp.transform()
1788
1794
 
1795
+ limit_ke = limit_ke if limit_ke is not None else self.default_joint_limit_ke
1796
+ limit_kd = limit_kd if limit_kd is not None else self.default_joint_limit_kd
1797
+
1789
1798
  action = 0.0
1790
1799
  if target is None and mode == JOINT_MODE_TARGET_POSITION:
1791
1800
  action = 0.5 * (limit_lower + limit_upper)
@@ -1832,8 +1841,8 @@ class ModelBuilder:
1832
1841
  mode: int = JOINT_MODE_FORCE,
1833
1842
  limit_lower: float = -1e4,
1834
1843
  limit_upper: float = 1e4,
1835
- limit_ke: float = default_joint_limit_ke,
1836
- limit_kd: float = default_joint_limit_kd,
1844
+ limit_ke: float = None,
1845
+ limit_kd: float = None,
1837
1846
  linear_compliance: float = 0.0,
1838
1847
  angular_compliance: float = 0.0,
1839
1848
  armature: float = 1e-2,
@@ -1854,8 +1863,8 @@ class ModelBuilder:
1854
1863
  target_kd: The damping of the joint target
1855
1864
  limit_lower: The lower limit of the joint
1856
1865
  limit_upper: The upper limit of the joint
1857
- limit_ke: The stiffness of the joint limit
1858
- limit_kd: The damping of the joint limit
1866
+ limit_ke: The stiffness of the joint limit (None to use the default value :attr:`default_joint_limit_ke`)
1867
+ limit_kd: The damping of the joint limit (None to use the default value :attr:`default_joint_limit_ke`)
1859
1868
  linear_compliance: The linear compliance of the joint
1860
1869
  angular_compliance: The angular compliance of the joint
1861
1870
  armature: Artificial inertia added around the joint axis
@@ -1873,6 +1882,9 @@ class ModelBuilder:
1873
1882
  if child_xform is None:
1874
1883
  child_xform = wp.transform()
1875
1884
 
1885
+ limit_ke = limit_ke if limit_ke is not None else self.default_joint_limit_ke
1886
+ limit_kd = limit_kd if limit_kd is not None else self.default_joint_limit_kd
1887
+
1876
1888
  action = 0.0
1877
1889
  if target is None and mode == JOINT_MODE_TARGET_POSITION:
1878
1890
  action = 0.5 * (limit_lower + limit_upper)
@@ -2521,7 +2533,7 @@ class ModelBuilder:
2521
2533
  last_dynamic_body_name = self.body_name[last_dynamic_body] if last_dynamic_body > -1 else "world"
2522
2534
  if verbose:
2523
2535
  print(
2524
- f'Remove fixed joint {joint["name"]} between {parent_name} and {child_name}, '
2536
+ f"Remove fixed joint {joint['name']} between {parent_name} and {child_name}, "
2525
2537
  f"merging {child_name} into {last_dynamic_body_name}"
2526
2538
  )
2527
2539
  child_id = body_data[child_body]["original_id"]
@@ -2616,11 +2628,12 @@ class ModelBuilder:
2616
2628
  joint_remap[joint["original_id"]] = i
2617
2629
  # update articulation_start
2618
2630
  for i, old_i in enumerate(self.articulation_start):
2619
- while old_i not in joint_remap:
2620
- old_i += 1
2621
- if old_i >= self.joint_count:
2631
+ start_i = old_i
2632
+ while start_i not in joint_remap:
2633
+ start_i += 1
2634
+ if start_i >= self.joint_count:
2622
2635
  break
2623
- self.articulation_start[i] = joint_remap.get(old_i, old_i)
2636
+ self.articulation_start[i] = joint_remap.get(start_i, start_i)
2624
2637
  # remove empty articulation starts, i.e. where the start and end are the same
2625
2638
  self.articulation_start = list(set(self.articulation_start))
2626
2639
 
@@ -2772,7 +2785,7 @@ class ModelBuilder:
2772
2785
  c = np.cross(normal, (0.0, 1.0, 0.0))
2773
2786
  angle = np.arcsin(np.linalg.norm(c))
2774
2787
  axis = np.abs(c) / np.linalg.norm(c)
2775
- rot = wp.quat_from_axis_angle(axis, angle)
2788
+ rot = wp.quat_from_axis_angle(wp.vec3(*axis), wp.float32(angle))
2776
2789
  scale = wp.vec3(width, length, 0.0)
2777
2790
 
2778
2791
  return self._add_shape(
@@ -3498,11 +3511,11 @@ class ModelBuilder:
3498
3511
  i: int,
3499
3512
  j: int,
3500
3513
  k: int,
3501
- tri_ke: float = default_tri_ke,
3502
- tri_ka: float = default_tri_ka,
3503
- tri_kd: float = default_tri_kd,
3504
- tri_drag: float = default_tri_drag,
3505
- tri_lift: float = default_tri_lift,
3514
+ tri_ke: float = None,
3515
+ tri_ka: float = None,
3516
+ tri_kd: float = None,
3517
+ tri_drag: float = None,
3518
+ tri_lift: float = None,
3506
3519
  ) -> float:
3507
3520
  """Adds a triangular FEM element between three particles in the system.
3508
3521
 
@@ -3522,6 +3535,11 @@ class ModelBuilder:
3522
3535
  between the particles in their initial configuration.
3523
3536
  """
3524
3537
  # TODO: Expose elastic parameters on a per-element basis
3538
+ tri_ke = tri_ke if tri_ke is not None else self.default_tri_ke
3539
+ tri_ka = tri_ka if tri_ka is not None else self.default_tri_ka
3540
+ tri_kd = tri_kd if tri_kd is not None else self.default_tri_kd
3541
+ tri_drag = tri_drag if tri_drag is not None else self.default_tri_drag
3542
+ tri_lift = tri_lift if tri_lift is not None else self.default_tri_lift
3525
3543
 
3526
3544
  # compute basis for 2D rest pose
3527
3545
  p = self.particle_q[i]
@@ -3702,8 +3720,8 @@ class ModelBuilder:
3702
3720
  k: int,
3703
3721
  l: int,
3704
3722
  rest: float = None,
3705
- edge_ke: float = default_edge_ke,
3706
- edge_kd: float = default_edge_kd,
3723
+ edge_ke: float = None,
3724
+ edge_kd: float = None,
3707
3725
  ):
3708
3726
  """Adds a bending edge element between four particles in the system.
3709
3727
 
@@ -3724,6 +3742,9 @@ class ModelBuilder:
3724
3742
  winding: (i, k, l), (j, l, k).
3725
3743
 
3726
3744
  """
3745
+ edge_ke = edge_ke if edge_ke is not None else self.default_edge_ke
3746
+ edge_kd = edge_kd if edge_kd is not None else self.default_edge_kd
3747
+
3727
3748
  # compute rest angle
3728
3749
  if rest is None:
3729
3750
  x1 = self.particle_q[i]
@@ -3831,17 +3852,17 @@ class ModelBuilder:
3831
3852
  fix_right: bool = False,
3832
3853
  fix_top: bool = False,
3833
3854
  fix_bottom: bool = False,
3834
- tri_ke: float = default_tri_ke,
3835
- tri_ka: float = default_tri_ka,
3836
- tri_kd: float = default_tri_kd,
3837
- tri_drag: float = default_tri_drag,
3838
- tri_lift: float = default_tri_lift,
3839
- edge_ke: float = default_edge_ke,
3840
- edge_kd: float = default_edge_kd,
3855
+ tri_ke: float = None,
3856
+ tri_ka: float = None,
3857
+ tri_kd: float = None,
3858
+ tri_drag: float = None,
3859
+ tri_lift: float = None,
3860
+ edge_ke: float = None,
3861
+ edge_kd: float = None,
3841
3862
  add_springs: bool = False,
3842
- spring_ke: float = default_spring_ke,
3843
- spring_kd: float = default_spring_kd,
3844
- particle_radius: float = default_particle_radius,
3863
+ spring_ke: float = None,
3864
+ spring_kd: float = None,
3865
+ particle_radius: float = None,
3845
3866
  ):
3846
3867
  """Helper to create a regular planar cloth grid
3847
3868
 
@@ -3863,6 +3884,16 @@ class ModelBuilder:
3863
3884
  fix_top: Make the top-most edge of particles kinematic
3864
3885
  fix_bottom: Make the bottom-most edge of particles kinematic
3865
3886
  """
3887
+ tri_ke = tri_ke if tri_ke is not None else self.default_tri_ke
3888
+ tri_ka = tri_ka if tri_ka is not None else self.default_tri_ka
3889
+ tri_kd = tri_kd if tri_kd is not None else self.default_tri_kd
3890
+ tri_drag = tri_drag if tri_drag is not None else self.default_tri_drag
3891
+ tri_lift = tri_lift if tri_lift is not None else self.default_tri_lift
3892
+ edge_ke = edge_ke if edge_ke is not None else self.default_edge_ke
3893
+ edge_kd = edge_kd if edge_kd is not None else self.default_edge_kd
3894
+ spring_ke = spring_ke if spring_ke is not None else self.default_spring_ke
3895
+ spring_kd = spring_kd if spring_kd is not None else self.default_spring_kd
3896
+ particle_radius = particle_radius if particle_radius is not None else self.default_particle_radius
3866
3897
 
3867
3898
  def grid_index(x, y, dim_x):
3868
3899
  return y * dim_x + x
@@ -3965,17 +3996,17 @@ class ModelBuilder:
3965
3996
  density: float,
3966
3997
  edge_callback=None,
3967
3998
  face_callback=None,
3968
- tri_ke: float = default_tri_ke,
3969
- tri_ka: float = default_tri_ka,
3970
- tri_kd: float = default_tri_kd,
3971
- tri_drag: float = default_tri_drag,
3972
- tri_lift: float = default_tri_lift,
3973
- edge_ke: float = default_edge_ke,
3974
- edge_kd: float = default_edge_kd,
3999
+ tri_ke: float = None,
4000
+ tri_ka: float = None,
4001
+ tri_kd: float = None,
4002
+ tri_drag: float = None,
4003
+ tri_lift: float = None,
4004
+ edge_ke: float = None,
4005
+ edge_kd: float = None,
3975
4006
  add_springs: bool = False,
3976
- spring_ke: float = default_spring_ke,
3977
- spring_kd: float = default_spring_kd,
3978
- particle_radius: float = default_particle_radius,
4007
+ spring_ke: float = None,
4008
+ spring_kd: float = None,
4009
+ particle_radius: float = None,
3979
4010
  ):
3980
4011
  """Helper to create a cloth model from a regular triangle mesh
3981
4012
 
@@ -3996,6 +4027,17 @@ class ModelBuilder:
3996
4027
 
3997
4028
  The mesh should be two manifold.
3998
4029
  """
4030
+ tri_ke = tri_ke if tri_ke is not None else self.default_tri_ke
4031
+ tri_ka = tri_ka if tri_ka is not None else self.default_tri_ka
4032
+ tri_kd = tri_kd if tri_kd is not None else self.default_tri_kd
4033
+ tri_drag = tri_drag if tri_drag is not None else self.default_tri_drag
4034
+ tri_lift = tri_lift if tri_lift is not None else self.default_tri_lift
4035
+ edge_ke = edge_ke if edge_ke is not None else self.default_edge_ke
4036
+ edge_kd = edge_kd if edge_kd is not None else self.default_edge_kd
4037
+ spring_ke = spring_ke if spring_ke is not None else self.default_spring_ke
4038
+ spring_kd = spring_kd if spring_kd is not None else self.default_spring_kd
4039
+ particle_radius = particle_radius if particle_radius is not None else self.default_particle_radius
4040
+
3999
4041
  num_tris = int(len(indices) / 3)
4000
4042
 
4001
4043
  start_vertex = len(self.particle_q)
@@ -4073,9 +4115,11 @@ class ModelBuilder:
4073
4115
  cell_z: float,
4074
4116
  mass: float,
4075
4117
  jitter: float,
4076
- radius_mean: float = default_particle_radius,
4118
+ radius_mean: float = None,
4077
4119
  radius_std: float = 0.0,
4078
4120
  ):
4121
+ radius_mean = radius_mean if radius_mean is not None else self.default_particle_radius
4122
+
4079
4123
  rng = np.random.default_rng(42)
4080
4124
  for z in range(dim_z):
4081
4125
  for y in range(dim_y):
@@ -4110,11 +4154,11 @@ class ModelBuilder:
4110
4154
  fix_right: bool = False,
4111
4155
  fix_top: bool = False,
4112
4156
  fix_bottom: bool = False,
4113
- tri_ke: float = default_tri_ke,
4114
- tri_ka: float = default_tri_ka,
4115
- tri_kd: float = default_tri_kd,
4116
- tri_drag: float = default_tri_drag,
4117
- tri_lift: float = default_tri_lift,
4157
+ tri_ke: float = None,
4158
+ tri_ka: float = None,
4159
+ tri_kd: float = None,
4160
+ tri_drag: float = None,
4161
+ tri_lift: float = None,
4118
4162
  ):
4119
4163
  """Helper to create a rectangular tetrahedral FEM grid
4120
4164
 
@@ -4141,6 +4185,11 @@ class ModelBuilder:
4141
4185
  fix_top: Make the top-most edge of particles kinematic
4142
4186
  fix_bottom: Make the bottom-most edge of particles kinematic
4143
4187
  """
4188
+ tri_ke = tri_ke if tri_ke is not None else self.default_tri_ke
4189
+ tri_ka = tri_ka if tri_ka is not None else self.default_tri_ka
4190
+ tri_kd = tri_kd if tri_kd is not None else self.default_tri_kd
4191
+ tri_drag = tri_drag if tri_drag is not None else self.default_tri_drag
4192
+ tri_lift = tri_lift if tri_lift is not None else self.default_tri_lift
4144
4193
 
4145
4194
  start_vertex = len(self.particle_q)
4146
4195
 
@@ -4232,11 +4281,11 @@ class ModelBuilder:
4232
4281
  k_mu: float,
4233
4282
  k_lambda: float,
4234
4283
  k_damp: float,
4235
- tri_ke: float = default_tri_ke,
4236
- tri_ka: float = default_tri_ka,
4237
- tri_kd: float = default_tri_kd,
4238
- tri_drag: float = default_tri_drag,
4239
- tri_lift: float = default_tri_lift,
4284
+ tri_ke: float = None,
4285
+ tri_ka: float = None,
4286
+ tri_kd: float = None,
4287
+ tri_drag: float = None,
4288
+ tri_lift: float = None,
4240
4289
  ):
4241
4290
  """Helper to create a tetrahedral model from an input tetrahedral mesh
4242
4291
 
@@ -4251,6 +4300,12 @@ class ModelBuilder:
4251
4300
  k_lambda: The second elastic Lame parameter
4252
4301
  k_damp: The damping stiffness
4253
4302
  """
4303
+ tri_ke = tri_ke if tri_ke is not None else self.default_tri_ke
4304
+ tri_ka = tri_ka if tri_ka is not None else self.default_tri_ka
4305
+ tri_kd = tri_kd if tri_kd is not None else self.default_tri_kd
4306
+ tri_drag = tri_drag if tri_drag is not None else self.default_tri_drag
4307
+ tri_lift = tri_lift if tri_lift is not None else self.default_tri_lift
4308
+
4254
4309
  num_tets = int(len(indices) / 4)
4255
4310
 
4256
4311
  start_vertex = len(self.particle_q)
@@ -4269,8 +4324,7 @@ class ModelBuilder:
4269
4324
  pos = wp.vec3(pos[0], pos[1], pos[2])
4270
4325
  # add particles
4271
4326
  for v in vertices:
4272
- v = wp.vec3(v[0], v[1], v[2])
4273
- p = wp.quat_rotate(rot, v * scale) + pos
4327
+ p = wp.quat_rotate(rot, wp.vec3(v[0], v[1], v[2]) * scale) + pos
4274
4328
 
4275
4329
  self.add_particle(p, vel, 0.0)
4276
4330
 
@@ -4342,16 +4396,22 @@ class ModelBuilder:
4342
4396
  self,
4343
4397
  normal=None,
4344
4398
  offset=0.0,
4345
- ke: float = default_shape_ke,
4346
- kd: float = default_shape_kd,
4347
- kf: float = default_shape_kf,
4348
- mu: float = default_shape_mu,
4349
- restitution: float = default_shape_restitution,
4399
+ ke: float = None,
4400
+ kd: float = None,
4401
+ kf: float = None,
4402
+ mu: float = None,
4403
+ restitution: float = None,
4350
4404
  ):
4351
4405
  """
4352
4406
  Creates a ground plane for the world. If the normal is not specified,
4353
4407
  the up_vector of the ModelBuilder is used.
4354
4408
  """
4409
+ ke = ke if ke is not None else self.default_shape_ke
4410
+ kd = kd if kd is not None else self.default_shape_kd
4411
+ kf = kf if kf is not None else self.default_shape_kf
4412
+ mu = mu if mu is not None else self.default_shape_mu
4413
+ restitution = restitution if restitution is not None else self.default_shape_restitution
4414
+
4355
4415
  if normal is None:
4356
4416
  normal = self.up_vector
4357
4417
  self._ground_params = {
@@ -4402,16 +4462,18 @@ class ModelBuilder:
4402
4462
  balance_colors: Whether to apply the color balancing algorithm to balance the size of each color
4403
4463
  target_max_min_color_ratio: the color balancing algorithm will stop when the ratio between the largest color and
4404
4464
  the smallest color reaches this value
4405
- algorithm: Value should an enum type of ColoringAlgorithm, otherwise it will raise an error. ColoringAlgorithm.mcs means using the MCS coloring algorithm,
4465
+ algorithm: Value should be an enum type of ColoringAlgorithm, otherwise it will raise an error. ColoringAlgorithm.mcs means using the MCS coloring algorithm,
4406
4466
  while ColoringAlgorithm.ordered_greedy means using the degree-ordered greedy algorithm. The MCS algorithm typically generates 30% to 50% fewer colors
4407
4467
  compared to the ordered greedy algorithm, while maintaining the same linear complexity. Although MCS has a constant overhead that makes it about twice
4408
4468
  as slow as the greedy algorithm, it produces significantly better coloring results. We recommend using MCS, especially if coloring is only part of the
4409
- preprocessing stage.e.
4469
+ preprocessing.
4410
4470
 
4411
4471
  Note:
4412
4472
 
4413
4473
  References to the coloring algorithm:
4474
+
4414
4475
  MCS: Pereira, F. M. Q., & Palsberg, J. (2005, November). Register allocation via coloring of chordal graphs. In Asian Symposium on Programming Languages and Systems (pp. 315-329). Berlin, Heidelberg: Springer Berlin Heidelberg.
4476
+
4415
4477
  Ordered Greedy: Ton-That, Q. M., Kry, P. G., & Andrews, S. (2023). Parallel block Neo-Hookean XPBD using graph clustering. Computers & Graphics, 110, 1-10.
4416
4478
 
4417
4479
  """
warp/sparse.py CHANGED
@@ -8,7 +8,7 @@ from warp.types import Array, Cols, Rows, Scalar, Vector
8
8
 
9
9
  # typing hints
10
10
 
11
- _BlockType = TypeVar("BlockType")
11
+ _BlockType = TypeVar("BlockType") # noqa: PLC0132
12
12
 
13
13
 
14
14
  class _MatrixBlockType(Generic[Rows, Cols, Scalar]):