warp-lang 1.6.1__py3-none-macosx_10_13_universal2.whl → 1.7.0__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.

Files changed (401) hide show
  1. warp/__init__.py +21 -7
  2. warp/autograd.py +14 -6
  3. warp/bin/libwarp-clang.dylib +0 -0
  4. warp/bin/libwarp.dylib +0 -0
  5. warp/build.py +424 -6
  6. warp/build_dll.py +20 -20
  7. warp/builtins.py +467 -368
  8. warp/codegen.py +193 -125
  9. warp/config.py +56 -12
  10. warp/constants.py +14 -6
  11. warp/context.py +524 -277
  12. warp/dlpack.py +22 -12
  13. warp/examples/__init__.py +14 -6
  14. warp/examples/assets/nonuniform.usd +0 -0
  15. warp/examples/assets/nvidia_logo.png +0 -0
  16. warp/examples/benchmarks/benchmark_api.py +14 -6
  17. warp/examples/benchmarks/benchmark_cloth.py +14 -6
  18. warp/examples/benchmarks/benchmark_cloth_cupy.py +14 -6
  19. warp/examples/benchmarks/benchmark_cloth_jax.py +14 -6
  20. warp/examples/benchmarks/benchmark_cloth_numba.py +15 -0
  21. warp/examples/benchmarks/benchmark_cloth_numpy.py +14 -6
  22. warp/examples/benchmarks/benchmark_cloth_paddle.py +14 -6
  23. warp/examples/benchmarks/benchmark_cloth_pytorch.py +14 -6
  24. warp/examples/benchmarks/benchmark_cloth_taichi.py +14 -6
  25. warp/examples/benchmarks/benchmark_cloth_warp.py +14 -6
  26. warp/examples/benchmarks/benchmark_gemm.py +82 -48
  27. warp/examples/benchmarks/benchmark_interop_paddle.py +14 -6
  28. warp/examples/benchmarks/benchmark_interop_torch.py +14 -6
  29. warp/examples/benchmarks/benchmark_launches.py +14 -6
  30. warp/examples/benchmarks/benchmark_tile_load_store.py +103 -0
  31. warp/examples/browse.py +14 -6
  32. warp/examples/core/example_cupy.py +14 -6
  33. warp/examples/core/example_dem.py +14 -6
  34. warp/examples/core/example_fluid.py +14 -6
  35. warp/examples/core/example_graph_capture.py +14 -6
  36. warp/examples/core/example_marching_cubes.py +14 -6
  37. warp/examples/core/example_mesh.py +14 -6
  38. warp/examples/core/example_mesh_intersect.py +14 -6
  39. warp/examples/core/example_nvdb.py +14 -6
  40. warp/examples/core/example_raycast.py +14 -6
  41. warp/examples/core/example_raymarch.py +14 -6
  42. warp/examples/core/example_render_opengl.py +14 -6
  43. warp/examples/core/example_sample_mesh.py +300 -0
  44. warp/examples/core/example_sph.py +14 -6
  45. warp/examples/core/example_torch.py +14 -6
  46. warp/examples/core/example_wave.py +14 -6
  47. warp/examples/fem/example_adaptive_grid.py +14 -6
  48. warp/examples/fem/example_apic_fluid.py +15 -7
  49. warp/examples/fem/example_burgers.py +16 -8
  50. warp/examples/fem/example_convection_diffusion.py +14 -6
  51. warp/examples/fem/example_convection_diffusion_dg.py +14 -6
  52. warp/examples/fem/example_deformed_geometry.py +15 -7
  53. warp/examples/fem/example_diffusion.py +14 -6
  54. warp/examples/fem/example_diffusion_3d.py +14 -6
  55. warp/examples/fem/example_diffusion_mgpu.py +14 -6
  56. warp/examples/fem/example_distortion_energy.py +15 -7
  57. warp/examples/fem/example_magnetostatics.py +20 -12
  58. warp/examples/fem/example_mixed_elasticity.py +14 -6
  59. warp/examples/fem/example_navier_stokes.py +14 -6
  60. warp/examples/fem/example_nonconforming_contact.py +14 -6
  61. warp/examples/fem/example_stokes.py +14 -6
  62. warp/examples/fem/example_stokes_transfer.py +14 -6
  63. warp/examples/fem/example_streamlines.py +14 -6
  64. warp/examples/fem/utils.py +24 -3
  65. warp/examples/interop/example_jax_callable.py +116 -0
  66. warp/examples/interop/example_jax_ffi_callback.py +132 -0
  67. warp/examples/interop/example_jax_kernel.py +205 -0
  68. warp/examples/optim/example_bounce.py +14 -6
  69. warp/examples/optim/example_cloth_throw.py +14 -6
  70. warp/examples/optim/example_diffray.py +14 -6
  71. warp/examples/optim/example_drone.py +14 -6
  72. warp/examples/optim/example_fluid_checkpoint.py +497 -0
  73. warp/examples/optim/example_inverse_kinematics.py +14 -6
  74. warp/examples/optim/example_inverse_kinematics_torch.py +14 -6
  75. warp/examples/optim/example_softbody_properties.py +14 -6
  76. warp/examples/optim/example_spring_cage.py +14 -6
  77. warp/examples/optim/example_trajectory.py +14 -6
  78. warp/examples/sim/example_cartpole.py +14 -6
  79. warp/examples/sim/example_cloth.py +14 -6
  80. warp/examples/sim/example_cloth_self_contact.py +14 -6
  81. warp/examples/sim/example_granular.py +14 -6
  82. warp/examples/sim/example_granular_collision_sdf.py +14 -6
  83. warp/examples/sim/example_jacobian_ik.py +14 -6
  84. warp/examples/sim/example_particle_chain.py +14 -6
  85. warp/examples/sim/example_quadruped.py +14 -6
  86. warp/examples/sim/example_rigid_chain.py +14 -6
  87. warp/examples/sim/example_rigid_contact.py +14 -6
  88. warp/examples/sim/example_rigid_force.py +14 -6
  89. warp/examples/sim/example_rigid_gyroscopic.py +14 -6
  90. warp/examples/sim/example_rigid_soft_contact.py +14 -6
  91. warp/examples/sim/example_soft_body.py +14 -6
  92. warp/examples/tile/example_tile_cholesky.py +14 -6
  93. warp/examples/tile/example_tile_convolution.py +14 -6
  94. warp/examples/tile/example_tile_fft.py +14 -6
  95. warp/examples/tile/example_tile_filtering.py +14 -6
  96. warp/examples/tile/example_tile_matmul.py +16 -10
  97. warp/examples/tile/example_tile_mlp.py +14 -6
  98. warp/examples/tile/example_tile_nbody.py +14 -6
  99. warp/examples/tile/example_tile_walker.py +14 -6
  100. warp/fabric.py +15 -0
  101. warp/fem/__init__.py +26 -1
  102. warp/fem/adaptivity.py +19 -4
  103. warp/fem/cache.py +15 -0
  104. warp/fem/dirichlet.py +15 -0
  105. warp/fem/domain.py +15 -0
  106. warp/fem/field/__init__.py +15 -0
  107. warp/fem/field/field.py +15 -0
  108. warp/fem/field/nodal_field.py +37 -68
  109. warp/fem/field/restriction.py +15 -0
  110. warp/fem/field/virtual.py +77 -23
  111. warp/fem/geometry/__init__.py +15 -0
  112. warp/fem/geometry/adaptive_nanogrid.py +24 -10
  113. warp/fem/geometry/closest_point.py +16 -1
  114. warp/fem/geometry/deformed_geometry.py +20 -2
  115. warp/fem/geometry/element.py +15 -0
  116. warp/fem/geometry/geometry.py +20 -0
  117. warp/fem/geometry/grid_2d.py +27 -12
  118. warp/fem/geometry/grid_3d.py +27 -15
  119. warp/fem/geometry/hexmesh.py +20 -7
  120. warp/fem/geometry/nanogrid.py +24 -11
  121. warp/fem/geometry/partition.py +15 -0
  122. warp/fem/geometry/quadmesh.py +28 -13
  123. warp/fem/geometry/tetmesh.py +18 -4
  124. warp/fem/geometry/trimesh.py +18 -8
  125. warp/fem/integrate.py +277 -93
  126. warp/fem/linalg.py +20 -5
  127. warp/fem/operator.py +15 -0
  128. warp/fem/polynomial.py +15 -0
  129. warp/fem/quadrature/__init__.py +15 -0
  130. warp/fem/quadrature/pic_quadrature.py +52 -22
  131. warp/fem/quadrature/quadrature.py +209 -25
  132. warp/fem/space/__init__.py +16 -1
  133. warp/fem/space/basis_function_space.py +19 -2
  134. warp/fem/space/basis_space.py +40 -18
  135. warp/fem/space/dof_mapper.py +15 -0
  136. warp/fem/space/function_space.py +15 -0
  137. warp/fem/space/grid_2d_function_space.py +15 -0
  138. warp/fem/space/grid_3d_function_space.py +15 -0
  139. warp/fem/space/hexmesh_function_space.py +17 -2
  140. warp/fem/space/nanogrid_function_space.py +15 -0
  141. warp/fem/space/partition.py +21 -2
  142. warp/fem/space/quadmesh_function_space.py +23 -8
  143. warp/fem/space/restriction.py +15 -0
  144. warp/fem/space/shape/__init__.py +15 -0
  145. warp/fem/space/shape/cube_shape_function.py +38 -23
  146. warp/fem/space/shape/shape_function.py +15 -0
  147. warp/fem/space/shape/square_shape_function.py +27 -12
  148. warp/fem/space/shape/tet_shape_function.py +15 -0
  149. warp/fem/space/shape/triangle_shape_function.py +16 -1
  150. warp/fem/space/tetmesh_function_space.py +18 -3
  151. warp/fem/space/topology.py +15 -0
  152. warp/fem/space/trimesh_function_space.py +17 -2
  153. warp/fem/types.py +15 -0
  154. warp/fem/utils.py +27 -6
  155. warp/jax.py +28 -7
  156. warp/jax_experimental/__init__.py +16 -0
  157. warp/{jax_experimental.py → jax_experimental/custom_call.py} +28 -33
  158. warp/jax_experimental/ffi.py +698 -0
  159. warp/jax_experimental/xla_ffi.py +602 -0
  160. warp/math.py +103 -6
  161. warp/native/array.h +28 -6
  162. warp/native/builtin.h +44 -9
  163. warp/native/bvh.cpp +18 -7
  164. warp/native/bvh.cu +57 -20
  165. warp/native/bvh.h +17 -7
  166. warp/native/clang/clang.cpp +45 -9
  167. warp/native/coloring.cpp +15 -6
  168. warp/native/crt.cpp +15 -6
  169. warp/native/crt.h +15 -6
  170. warp/native/cuda_crt.h +15 -6
  171. warp/native/cuda_util.cpp +29 -6
  172. warp/native/cuda_util.h +17 -6
  173. warp/native/error.cpp +15 -6
  174. warp/native/error.h +15 -6
  175. warp/native/exports.h +85 -63
  176. warp/native/fabric.h +15 -6
  177. warp/native/hashgrid.cpp +15 -6
  178. warp/native/hashgrid.cu +15 -6
  179. warp/native/hashgrid.h +15 -6
  180. warp/native/initializer_array.h +15 -6
  181. warp/native/intersect.h +41 -32
  182. warp/native/intersect_adj.h +48 -39
  183. warp/native/intersect_tri.h +17 -0
  184. warp/native/marching.cpp +16 -0
  185. warp/native/marching.cu +16 -7
  186. warp/native/marching.h +17 -0
  187. warp/native/mat.h +528 -15
  188. warp/native/mathdx.cpp +15 -6
  189. warp/native/matnn.h +15 -6
  190. warp/native/mesh.cpp +15 -6
  191. warp/native/mesh.cu +15 -6
  192. warp/native/mesh.h +25 -16
  193. warp/native/noise.h +15 -6
  194. warp/native/quat.h +114 -17
  195. warp/native/rand.h +21 -6
  196. warp/native/range.h +15 -6
  197. warp/native/reduce.cpp +15 -6
  198. warp/native/reduce.cu +15 -6
  199. warp/native/runlength_encode.cpp +15 -6
  200. warp/native/runlength_encode.cu +15 -6
  201. warp/native/scan.cpp +15 -6
  202. warp/native/scan.cu +15 -6
  203. warp/native/scan.h +15 -6
  204. warp/native/solid_angle.h +17 -0
  205. warp/native/sort.cpp +137 -65
  206. warp/native/sort.cu +167 -21
  207. warp/native/sort.h +23 -7
  208. warp/native/sparse.cpp +58 -28
  209. warp/native/sparse.cu +67 -23
  210. warp/native/spatial.h +15 -6
  211. warp/native/svd.h +131 -6
  212. warp/native/temp_buffer.h +15 -6
  213. warp/native/tile.h +316 -111
  214. warp/native/tile_reduce.h +61 -9
  215. warp/native/vec.h +83 -13
  216. warp/native/volume.cpp +100 -119
  217. warp/native/volume.cu +15 -6
  218. warp/native/volume.h +15 -6
  219. warp/native/volume_builder.cu +40 -16
  220. warp/native/volume_builder.h +21 -6
  221. warp/native/volume_impl.h +15 -6
  222. warp/native/warp.cpp +20 -12
  223. warp/native/warp.cu +114 -16
  224. warp/native/warp.h +34 -16
  225. warp/optim/__init__.py +14 -6
  226. warp/optim/adam.py +14 -6
  227. warp/optim/linear.py +25 -10
  228. warp/optim/sgd.py +14 -6
  229. warp/paddle.py +14 -6
  230. warp/render/__init__.py +14 -6
  231. warp/render/render_opengl.py +14 -6
  232. warp/render/render_usd.py +14 -6
  233. warp/render/utils.py +14 -6
  234. warp/sim/__init__.py +14 -7
  235. warp/sim/articulation.py +18 -10
  236. warp/sim/collide.py +35 -16
  237. warp/sim/graph_coloring.py +14 -6
  238. warp/sim/import_mjcf.py +463 -162
  239. warp/sim/import_snu.py +14 -7
  240. warp/sim/import_urdf.py +46 -18
  241. warp/sim/import_usd.py +14 -7
  242. warp/sim/inertia.py +14 -6
  243. warp/sim/integrator.py +14 -6
  244. warp/sim/integrator_euler.py +19 -11
  245. warp/sim/integrator_featherstone.py +17 -16
  246. warp/sim/integrator_vbd.py +222 -8
  247. warp/sim/integrator_xpbd.py +19 -11
  248. warp/sim/model.py +56 -19
  249. warp/sim/particles.py +14 -6
  250. warp/sim/render.py +14 -6
  251. warp/sim/utils.py +17 -2
  252. warp/sparse.py +657 -555
  253. warp/stubs.py +231 -19
  254. warp/tape.py +14 -6
  255. warp/tests/aux_test_class_kernel.py +14 -6
  256. warp/tests/aux_test_compile_consts_dummy.py +14 -6
  257. warp/tests/aux_test_conditional_unequal_types_kernels.py +14 -6
  258. warp/tests/aux_test_dependent.py +14 -6
  259. warp/tests/aux_test_grad_customs.py +14 -6
  260. warp/tests/aux_test_instancing_gc.py +14 -6
  261. warp/tests/aux_test_module_unload.py +14 -6
  262. warp/tests/aux_test_name_clash1.py +14 -6
  263. warp/tests/aux_test_name_clash2.py +14 -6
  264. warp/tests/aux_test_unresolved_func.py +14 -6
  265. warp/tests/aux_test_unresolved_symbol.py +14 -6
  266. warp/tests/cuda/__init__.py +0 -0
  267. warp/tests/{test_async.py → cuda/test_async.py} +14 -6
  268. warp/tests/{test_ipc.py → cuda/test_ipc.py} +14 -6
  269. warp/tests/{test_mempool.py → cuda/test_mempool.py} +53 -6
  270. warp/tests/{test_multigpu.py → cuda/test_multigpu.py} +14 -6
  271. warp/tests/{test_peer.py → cuda/test_peer.py} +14 -6
  272. warp/tests/{test_pinned.py → cuda/test_pinned.py} +14 -6
  273. warp/tests/{test_streams.py → cuda/test_streams.py} +85 -6
  274. warp/tests/geometry/__init__.py +0 -0
  275. warp/tests/{test_bvh.py → geometry/test_bvh.py} +14 -6
  276. warp/tests/{test_hash_grid.py → geometry/test_hash_grid.py} +14 -6
  277. warp/tests/{test_marching_cubes.py → geometry/test_marching_cubes.py} +14 -6
  278. warp/tests/{test_mesh.py → geometry/test_mesh.py} +14 -6
  279. warp/tests/{test_mesh_query_aabb.py → geometry/test_mesh_query_aabb.py} +14 -6
  280. warp/tests/{test_mesh_query_point.py → geometry/test_mesh_query_point.py} +80 -69
  281. warp/tests/{test_mesh_query_ray.py → geometry/test_mesh_query_ray.py} +15 -7
  282. warp/tests/{test_volume.py → geometry/test_volume.py} +55 -12
  283. warp/tests/{test_volume_write.py → geometry/test_volume_write.py} +14 -6
  284. warp/tests/interop/__init__.py +0 -0
  285. warp/tests/{test_dlpack.py → interop/test_dlpack.py} +42 -11
  286. warp/tests/{test_jax.py → interop/test_jax.py} +14 -6
  287. warp/tests/{test_paddle.py → interop/test_paddle.py} +14 -6
  288. warp/tests/{test_torch.py → interop/test_torch.py} +14 -6
  289. warp/tests/run_coverage_serial.py +14 -6
  290. warp/tests/sim/__init__.py +0 -0
  291. warp/tests/{disabled_kinematics.py → sim/disabled_kinematics.py} +23 -16
  292. warp/tests/{flaky_test_sim_grad.py → sim/flaky_test_sim_grad.py} +14 -6
  293. warp/tests/{test_collision.py → sim/test_collision.py} +16 -8
  294. warp/tests/{test_coloring.py → sim/test_coloring.py} +14 -7
  295. warp/tests/{test_model.py → sim/test_model.py} +55 -7
  296. warp/tests/{test_sim_grad_bounce_linear.py → sim/test_sim_grad_bounce_linear.py} +14 -6
  297. warp/tests/{test_sim_kinematics.py → sim/test_sim_kinematics.py} +16 -7
  298. warp/tests/sim/test_vbd.py +597 -0
  299. warp/tests/test_adam.py +14 -6
  300. warp/tests/test_arithmetic.py +14 -6
  301. warp/tests/test_array.py +14 -6
  302. warp/tests/test_array_reduce.py +14 -6
  303. warp/tests/test_assert.py +14 -6
  304. warp/tests/test_atomic.py +14 -6
  305. warp/tests/test_bool.py +15 -7
  306. warp/tests/test_builtins_resolution.py +14 -6
  307. warp/tests/test_closest_point_edge_edge.py +14 -6
  308. warp/tests/test_codegen.py +14 -6
  309. warp/tests/test_codegen_instancing.py +14 -6
  310. warp/tests/test_compile_consts.py +14 -6
  311. warp/tests/test_conditional.py +14 -6
  312. warp/tests/test_context.py +14 -6
  313. warp/tests/test_copy.py +14 -6
  314. warp/tests/test_ctypes.py +14 -6
  315. warp/tests/test_dense.py +14 -6
  316. warp/tests/test_devices.py +14 -6
  317. warp/tests/test_examples.py +42 -42
  318. warp/tests/test_fabricarray.py +14 -6
  319. warp/tests/test_fast_math.py +14 -6
  320. warp/tests/test_fem.py +37 -10
  321. warp/tests/test_fp16.py +14 -6
  322. warp/tests/test_func.py +14 -6
  323. warp/tests/test_future_annotations.py +14 -6
  324. warp/tests/test_generics.py +14 -6
  325. warp/tests/test_grad.py +14 -6
  326. warp/tests/test_grad_customs.py +14 -6
  327. warp/tests/test_grad_debug.py +14 -6
  328. warp/tests/test_implicit_init.py +14 -6
  329. warp/tests/test_import.py +14 -6
  330. warp/tests/test_indexedarray.py +14 -6
  331. warp/tests/test_intersect.py +14 -6
  332. warp/tests/test_iter.py +14 -6
  333. warp/tests/test_large.py +14 -6
  334. warp/tests/test_launch.py +14 -6
  335. warp/tests/test_lerp.py +14 -6
  336. warp/tests/test_linear_solvers.py +15 -11
  337. warp/tests/test_lvalue.py +14 -6
  338. warp/tests/test_mat.py +247 -85
  339. warp/tests/test_mat_lite.py +14 -6
  340. warp/tests/test_mat_scalar_ops.py +18 -10
  341. warp/tests/test_math.py +14 -6
  342. warp/tests/test_mlp.py +14 -6
  343. warp/tests/test_module_hashing.py +14 -6
  344. warp/tests/test_modules_lite.py +14 -6
  345. warp/tests/test_noise.py +14 -6
  346. warp/tests/test_operators.py +14 -6
  347. warp/tests/test_options.py +14 -6
  348. warp/tests/test_overwrite.py +15 -60
  349. warp/tests/test_print.py +14 -6
  350. warp/tests/test_quat.py +81 -52
  351. warp/tests/test_rand.py +58 -43
  352. warp/tests/test_reload.py +14 -6
  353. warp/tests/test_rounding.py +14 -6
  354. warp/tests/test_runlength_encode.py +14 -6
  355. warp/tests/test_scalar_ops.py +14 -6
  356. warp/tests/test_smoothstep.py +14 -6
  357. warp/tests/test_snippet.py +15 -0
  358. warp/tests/test_sparse.py +61 -12
  359. warp/tests/test_spatial.py +89 -6
  360. warp/tests/test_special_values.py +14 -6
  361. warp/tests/test_static.py +15 -7
  362. warp/tests/test_struct.py +14 -6
  363. warp/tests/test_tape.py +14 -6
  364. warp/tests/test_transient_module.py +14 -6
  365. warp/tests/test_triangle_closest_point.py +14 -6
  366. warp/tests/test_types.py +14 -6
  367. warp/tests/test_utils.py +98 -10
  368. warp/tests/test_vec.py +60 -40
  369. warp/tests/test_vec_lite.py +14 -6
  370. warp/tests/test_vec_scalar_ops.py +14 -6
  371. warp/tests/test_verify_fp.py +14 -6
  372. warp/tests/tile/__init__.py +0 -0
  373. warp/tests/{test_tile.py → tile/test_tile.py} +150 -57
  374. warp/tests/{test_tile_load.py → tile/test_tile_load.py} +15 -7
  375. warp/tests/{test_tile_mathdx.py → tile/test_tile_mathdx.py} +23 -12
  376. warp/tests/{test_tile_mlp.py → tile/test_tile_mlp.py} +39 -20
  377. warp/tests/{test_tile_reduce.py → tile/test_tile_reduce.py} +74 -7
  378. warp/tests/{test_tile_shared_memory.py → tile/test_tile_shared_memory.py} +14 -6
  379. warp/tests/{test_tile_view.py → tile/test_tile_view.py} +15 -7
  380. warp/tests/unittest_serial.py +15 -6
  381. warp/tests/unittest_suites.py +59 -65
  382. warp/tests/unittest_utils.py +16 -7
  383. warp/tests/walkthrough_debug.py +14 -6
  384. warp/thirdparty/unittest_parallel.py +15 -8
  385. warp/torch.py +14 -6
  386. warp/types.py +124 -664
  387. warp/utils.py +151 -78
  388. {warp_lang-1.6.1.dist-info → warp_lang-1.7.0.dist-info}/METADATA +39 -12
  389. warp_lang-1.7.0.dist-info/RECORD +429 -0
  390. {warp_lang-1.6.1.dist-info → warp_lang-1.7.0.dist-info}/WHEEL +1 -1
  391. warp_lang-1.7.0.dist-info/licenses/LICENSE.md +202 -0
  392. warp/examples/optim/example_walker.py +0 -309
  393. warp/native/cutlass_gemm.cpp +0 -34
  394. warp/native/cutlass_gemm.cu +0 -373
  395. warp/tests/test_matmul.py +0 -503
  396. warp/tests/test_matmul_lite.py +0 -403
  397. warp/tests/test_vbd.py +0 -378
  398. warp/tests/unused_test_misc.py +0 -69
  399. warp_lang-1.6.1.dist-info/LICENSE.md +0 -126
  400. warp_lang-1.6.1.dist-info/RECORD +0 -419
  401. {warp_lang-1.6.1.dist-info → warp_lang-1.7.0.dist-info}/top_level.txt +0 -0
warp/sim/import_snu.py CHANGED
@@ -1,10 +1,17 @@
1
- # Copyright (c) 2022 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
-
1
+ # SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
8
15
 
9
16
  import os
10
17
  import xml.etree.ElementTree as ET
warp/sim/import_urdf.py CHANGED
@@ -1,9 +1,17 @@
1
- # Copyright (c) 2022 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.
1
+ # SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
7
15
 
8
16
  import os
9
17
  import xml.etree.ElementTree as ET
@@ -12,7 +20,6 @@ from typing import Union
12
20
  import numpy as np
13
21
 
14
22
  import warp as wp
15
- import warp.sim
16
23
  from warp.sim.model import Mesh
17
24
 
18
25
 
@@ -38,6 +45,7 @@ def parse_urdf(
38
45
  joint_limit_lower=-1e6,
39
46
  joint_limit_upper=1e6,
40
47
  scale=1.0,
48
+ hide_visuals=False,
41
49
  parse_visuals_as_colliders=False,
42
50
  force_show_colliders=False,
43
51
  enable_self_collisions=True,
@@ -71,6 +79,7 @@ def parse_urdf(
71
79
  joint_limit_lower (float): The default lower joint limit if not specified in the URDF.
72
80
  joint_limit_upper (float): The default upper joint limit if not specified in the URDF.
73
81
  scale (float): The scaling factor to apply to the imported mechanism.
82
+ hide_visuals (bool): If True, hide visual shapes.
74
83
  parse_visuals_as_colliders (bool): If True, the geometry defined under the `<visual>` tags is used for collision handling instead of the `<collision>` geometries.
75
84
  force_show_colliders (bool): If True, the collision shapes are always shown, even if there are visual shapes.
76
85
  enable_self_collisions (bool): If True, self-collisions are enabled.
@@ -165,6 +174,22 @@ def parse_urdf(
165
174
  )
166
175
  shapes.append(s)
167
176
 
177
+ for capsule in geo.findall("capsule"):
178
+ s = builder.add_shape_capsule(
179
+ body=link,
180
+ pos=wp.vec3(tf.p),
181
+ rot=wp.quat(tf.q),
182
+ radius=float(capsule.get("radius") or "1") * scale,
183
+ half_height=float(capsule.get("height") or "1") * 0.5 * scale,
184
+ density=density,
185
+ up_axis=2, # capsules in URDF are aligned with z-axis
186
+ is_visible=visible,
187
+ has_ground_collision=not just_visual,
188
+ has_shape_collision=not just_visual,
189
+ **contact_vars,
190
+ )
191
+ shapes.append(s)
192
+
168
193
  for mesh in geo.findall("mesh"):
169
194
  filename = mesh.get("filename")
170
195
  if filename is None:
@@ -211,15 +236,15 @@ def parse_urdf(
211
236
  scaling = np.array([float(x) * scale for x in scaling.split()])
212
237
  if hasattr(m, "geometry"):
213
238
  # multiple meshes are contained in a scene
214
- for geom in m.geometry.values():
215
- geom_vertices = np.array(geom.vertices, dtype=np.float32) * scaling
216
- geom_faces = np.array(geom.faces.flatten(), dtype=np.int32)
217
- geom_mesh = Mesh(geom_vertices, geom_faces)
239
+ for m_geom in m.geometry.values():
240
+ m_vertices = np.array(m_geom.vertices, dtype=np.float32) * scaling
241
+ m_faces = np.array(m_geom.faces.flatten(), dtype=np.int32)
242
+ m_mesh = Mesh(m_vertices, m_faces)
218
243
  s = builder.add_shape_mesh(
219
244
  body=link,
220
245
  pos=wp.vec3(tf.p),
221
246
  rot=wp.quat(tf.q),
222
- mesh=geom_mesh,
247
+ mesh=m_mesh,
223
248
  density=density,
224
249
  is_visible=visible,
225
250
  has_ground_collision=not just_visual,
@@ -270,7 +295,7 @@ def parse_urdf(
270
295
  if parse_visuals_as_colliders:
271
296
  colliders = visuals
272
297
  else:
273
- s = parse_shapes(link, visuals, density=0.0, just_visual=True)
298
+ s = parse_shapes(link, visuals, density=0.0, just_visual=True, visible=not hide_visuals)
274
299
  visual_shapes.extend(s)
275
300
 
276
301
  show_colliders = force_show_colliders
@@ -301,10 +326,13 @@ def parse_urdf(
301
326
  I_m = rot @ wp.mat33(I_m)
302
327
  m = float(inertial.find("mass").get("value") or "0")
303
328
  builder.body_mass[link] = m
304
- builder.body_inv_mass[link] = 1.0 / m
329
+ builder.body_inv_mass[link] = 1.0 / m if m > 0.0 else 0.0
305
330
  builder.body_com[link] = com
306
331
  builder.body_inertia[link] = I_m
307
- builder.body_inv_inertia[link] = wp.inverse(I_m)
332
+ if any(x for x in I_m):
333
+ builder.body_inv_inertia[link] = wp.inverse(I_m)
334
+ else:
335
+ builder.body_inv_inertia[link] = I_m
308
336
  if m == 0.0 and ensure_nonstatic_links:
309
337
  # set the mass to something nonzero to ensure the body is dynamic
310
338
  m = static_link_mass
@@ -361,7 +389,7 @@ def parse_urdf(
361
389
 
362
390
  # topological sorting of joints because the FK solver will resolve body transforms
363
391
  # in joint order and needs the parent link transform to be resolved before the child
364
- visited = {name: False for name in link_index.keys()}
392
+ visited = dict.fromkeys(link_index.keys(), False)
365
393
  sorted_joints = []
366
394
 
367
395
  # depth-first search
@@ -512,7 +540,7 @@ def parse_urdf(
512
540
 
513
541
  builder.add_joint_d6(
514
542
  linear_axes=[
515
- warp.sim.JointAxis(
543
+ wp.sim.JointAxis(
516
544
  u,
517
545
  limit_lower=lower * scale,
518
546
  limit_upper=upper * scale,
@@ -522,7 +550,7 @@ def parse_urdf(
522
550
  target_kd=joint_damping,
523
551
  mode=joint_mode,
524
552
  ),
525
- warp.sim.JointAxis(
553
+ wp.sim.JointAxis(
526
554
  v,
527
555
  limit_lower=lower * scale,
528
556
  limit_upper=upper * scale,
warp/sim/import_usd.py CHANGED
@@ -1,10 +1,17 @@
1
- # Copyright (c) 2022 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
-
1
+ # SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
8
15
 
9
16
  import re
10
17
 
warp/sim/inertia.py CHANGED
@@ -1,9 +1,17 @@
1
- # Copyright (c) 2022 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.
1
+ # SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
7
15
 
8
16
  """Helper functions for computing rigid body inertia properties."""
9
17
 
warp/sim/integrator.py CHANGED
@@ -1,9 +1,17 @@
1
- # Copyright (c) 2022 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.
1
+ # SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
7
15
 
8
16
  import warp as wp
9
17
 
@@ -1,9 +1,17 @@
1
- # Copyright (c) 2022 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.
1
+ # SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
7
15
 
8
16
  """This module contains time-integration objects for simulating
9
17
  models + state forward in time.
@@ -551,7 +559,7 @@ def eval_tetrahedra(
551
559
  v20 = v2 - v0
552
560
  v30 = v3 - v0
553
561
 
554
- Ds = wp.mat33(x10, x20, x30)
562
+ Ds = wp.matrix_from_cols(x10, x20, x30)
555
563
  Dm = pose[tid]
556
564
 
557
565
  inv_rest_volume = wp.determinant(Dm) * 6.0
@@ -566,7 +574,7 @@ def eval_tetrahedra(
566
574
 
567
575
  # F = Xs*Xm^-1
568
576
  F = Ds * Dm
569
- dFdt = wp.mat33(v10, v20, v30) * Dm
577
+ dFdt = wp.matrix_from_cols(v10, v20, v30) * Dm
570
578
 
571
579
  col1 = wp.vec3(F[0, 0], F[1, 0], F[2, 0])
572
580
  col2 = wp.vec3(F[0, 1], F[1, 1], F[2, 1])
@@ -652,9 +660,9 @@ def eval_tetrahedra(
652
660
 
653
661
  # alpha = 1.0
654
662
 
655
- # I = wp.mat33(wp.vec3(1.0, 0.0, 0.0),
656
- # wp.vec3(0.0, 1.0, 0.0),
657
- # wp.vec3(0.0, 0.0, 1.0))
663
+ # I = wp.matrix_from_cols(wp.vec3(1.0, 0.0, 0.0),
664
+ # wp.vec3(0.0, 1.0, 0.0),
665
+ # wp.vec3(0.0, 0.0, 1.0))
658
666
 
659
667
  # P = (F + wp.transpose(F) + I*(0.0-2.0))*k_mu
660
668
  # H = P * wp.transpose(Dm)
@@ -1,9 +1,17 @@
1
- # Copyright (c) 2022 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.
1
+ # SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
7
15
 
8
16
  import warp as wp
9
17
 
@@ -120,7 +128,7 @@ def spatial_transform_inertia(t: wp.transform, I: wp.spatial_matrix):
120
128
  r2 = wp.quat_rotate(q, wp.vec3(0.0, 1.0, 0.0))
121
129
  r3 = wp.quat_rotate(q, wp.vec3(0.0, 0.0, 1.0))
122
130
 
123
- R = wp.mat33(r1, r2, r3)
131
+ R = wp.matrix_from_cols(r1, r2, r3)
124
132
  S = wp.skew(p) @ R
125
133
 
126
134
  T = spatial_adjoint(R, S)
@@ -290,7 +298,7 @@ def jcalc_motion(
290
298
  if type == wp.sim.JOINT_UNIVERSAL:
291
299
  axis_0 = joint_axis[axis_start + 0]
292
300
  axis_1 = joint_axis[axis_start + 1]
293
- q_off = wp.quat_from_matrix(wp.mat33(axis_0, axis_1, wp.cross(axis_0, axis_1)))
301
+ q_off = wp.quat_from_matrix(wp.matrix_from_cols(axis_0, axis_1, wp.cross(axis_0, axis_1)))
294
302
  local_0 = wp.quat_rotate(q_off, wp.vec3(1.0, 0.0, 0.0))
295
303
  local_1 = wp.quat_rotate(q_off, wp.vec3(0.0, 1.0, 0.0))
296
304
 
@@ -311,7 +319,7 @@ def jcalc_motion(
311
319
  axis_0 = joint_axis[axis_start + 0]
312
320
  axis_1 = joint_axis[axis_start + 1]
313
321
  axis_2 = joint_axis[axis_start + 2]
314
- q_off = wp.quat_from_matrix(wp.mat33(axis_0, axis_1, axis_2))
322
+ q_off = wp.quat_from_matrix(wp.matrix_from_cols(axis_0, axis_1, axis_2))
315
323
  local_0 = wp.quat_rotate(q_off, wp.vec3(1.0, 0.0, 0.0))
316
324
  local_1 = wp.quat_rotate(q_off, wp.vec3(0.0, 1.0, 0.0))
317
325
  local_2 = wp.quat_rotate(q_off, wp.vec3(0.0, 0.0, 1.0))
@@ -2058,13 +2066,6 @@ class FeatherstoneIntegrator(Integrator):
2058
2066
  ],
2059
2067
  device=model.device,
2060
2068
  )
2061
- # if wp.context.runtime.tape:
2062
- # wp.context.runtime.tape.record_func(
2063
- # backward=lambda: adj_matmul(
2064
- # a, b, c, a.grad, b.grad, c.grad, d.grad, alpha, beta, allow_tf32x3_arith, device
2065
- # ),
2066
- # arrays=[a, b, c, d],
2067
- # )
2068
2069
  # print("joint_qdd:")
2069
2070
  # print(state_aug.joint_qdd.numpy())
2070
2071
  # print("\n\n")
@@ -1,9 +1,18 @@
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.
1
+ # SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
7
16
  import numpy as np
8
17
 
9
18
  import warp as wp
@@ -337,6 +346,172 @@ def evaluate_stvk_force_hessian(
337
346
  return f, h
338
347
 
339
348
 
349
+ @wp.func
350
+ def mat_vec_cross_from_3_basis(e1: wp.vec3, e2: wp.vec3, e3: wp.vec3, a: wp.vec3):
351
+ e1_cross_a = wp.cross(e1, a)
352
+ e2_cross_a = wp.cross(e2, a)
353
+ e3_cross_a = wp.cross(e3, a)
354
+
355
+ return wp.mat33(
356
+ e1_cross_a[0],
357
+ e2_cross_a[0],
358
+ e3_cross_a[0],
359
+ e1_cross_a[1],
360
+ e2_cross_a[1],
361
+ e3_cross_a[1],
362
+ e1_cross_a[2],
363
+ e2_cross_a[2],
364
+ e3_cross_a[2],
365
+ )
366
+
367
+
368
+ @wp.func
369
+ def mat_vec_cross(mat: wp.mat33, a: wp.vec3):
370
+ e1 = wp.vec3(mat[0, 0], mat[1, 0], mat[2, 0])
371
+ e2 = wp.vec3(mat[0, 1], mat[1, 1], mat[2, 1])
372
+ e3 = wp.vec3(mat[0, 2], mat[1, 2], mat[2, 2])
373
+
374
+ return mat_vec_cross_from_3_basis(e1, e2, e3, a)
375
+
376
+
377
+ @wp.func
378
+ def evaluate_dihedral_angle_based_bending_force_hessian(
379
+ bending_index: int,
380
+ v_order: int,
381
+ pos: wp.array(dtype=wp.vec3),
382
+ pos_prev: wp.array(dtype=wp.vec3),
383
+ edge_indices: wp.array(dtype=wp.int32, ndim=2),
384
+ edge_rest_angle: wp.array(dtype=float),
385
+ edge_rest_length: wp.array(dtype=float),
386
+ stiffness: float,
387
+ damping: float,
388
+ dt: float,
389
+ ):
390
+ if edge_indices[bending_index, 0] == -1 or edge_indices[bending_index, 1] == -1:
391
+ return wp.vec3(0.0), wp.mat33(0.0)
392
+
393
+ x1 = pos[edge_indices[bending_index, 0]]
394
+ x2 = pos[edge_indices[bending_index, 2]]
395
+ x3 = pos[edge_indices[bending_index, 3]]
396
+ x4 = pos[edge_indices[bending_index, 1]]
397
+
398
+ e1 = wp.vec3(1.0, 0.0, 0.0)
399
+ e2 = wp.vec3(0.0, 1.0, 0.0)
400
+ e3 = wp.vec3(0.0, 0.0, 1.0)
401
+
402
+ n1 = wp.cross((x2 - x1), (x3 - x1))
403
+ n2 = wp.cross((x3 - x4), (x2 - x4))
404
+ n1_norm = wp.length(n1)
405
+ n2_norm = wp.length(n2)
406
+
407
+ # degenerated bending edge
408
+ if n1_norm < 1.0e-6 or n2_norm < 1.0e-6:
409
+ return wp.vec3(0.0), wp.mat33(0.0)
410
+
411
+ n1_n = n1 / n1_norm
412
+ n2_n = n2 / n2_norm
413
+
414
+ # avoid the infinite gradient of acos at -1 or 1
415
+ cos_theta = wp.dot(n1_n, n2_n)
416
+ if wp.abs(cos_theta) > 0.9999:
417
+ cos_theta = 0.9999 * wp.sign(cos_theta)
418
+
419
+ angle_sign = wp.sign(wp.dot(wp.cross(n2, n1), x3 - x2))
420
+ theta = wp.acos(cos_theta) * angle_sign
421
+ rest_angle = edge_rest_angle[bending_index]
422
+
423
+ dE_dtheta = stiffness * (theta - rest_angle)
424
+
425
+ d_theta_d_cos_theta = angle_sign * (-1.0 / wp.sqrt(1.0 - cos_theta * cos_theta))
426
+ sin_theta = angle_sign * wp.sqrt(1.0 - cos_theta * cos_theta)
427
+ one_over_sin_theta = 1.0 / sin_theta
428
+ d_one_over_sin_theta_d_cos_theta = cos_theta / (sin_theta * sin_theta * sin_theta)
429
+
430
+ e_rest_len = edge_rest_length[bending_index]
431
+
432
+ if v_order == 0:
433
+ d_cos_theta_dx1 = 1.0 / n1_norm * (-wp.cross(x3 - x1, n2_n) + wp.cross(x2 - x1, n2_n))
434
+ d_one_over_sin_theta_dx1 = d_cos_theta_dx1 * d_one_over_sin_theta_d_cos_theta
435
+
436
+ d_theta_dx1 = d_theta_d_cos_theta * d_cos_theta_dx1
437
+ d2_theta_dx1_dx1 = -wp.outer(d_one_over_sin_theta_dx1, d_cos_theta_dx1)
438
+
439
+ dE_dx1 = e_rest_len * dE_dtheta * d_theta_d_cos_theta * d_cos_theta_dx1
440
+
441
+ d2_E_dx1_dx1 = (
442
+ e_rest_len * stiffness * (wp.outer(d_theta_dx1, d_theta_dx1) + (theta - rest_angle) * d2_theta_dx1_dx1)
443
+ )
444
+
445
+ bending_force = -dE_dx1
446
+ bending_hessian = d2_E_dx1_dx1
447
+ elif v_order == 1:
448
+ d_cos_theta_dx4 = 1.0 / n2_norm * (-wp.cross(x2 - x4, n1_n) + wp.cross(x3 - x4, n1_n))
449
+ d_one_over_sin_theta_dx4 = d_cos_theta_dx4 * d_one_over_sin_theta_d_cos_theta
450
+
451
+ d_theta_dx4 = d_theta_d_cos_theta * d_cos_theta_dx4
452
+ d2_theta_dx4_dx4 = -wp.outer(d_one_over_sin_theta_dx4, d_cos_theta_dx4)
453
+
454
+ dE_dx4 = e_rest_len * dE_dtheta * d_theta_d_cos_theta * d_cos_theta_dx4
455
+ d2_E_dx4_dx4 = (
456
+ e_rest_len * stiffness * (wp.outer(d_theta_dx4, d_theta_dx4) + (theta - rest_angle) * (d2_theta_dx4_dx4))
457
+ )
458
+
459
+ bending_force = -dE_dx4
460
+ bending_hessian = d2_E_dx4_dx4
461
+ elif v_order == 2:
462
+ d_cos_theta_dx2 = 1.0 / n1_norm * wp.cross(x3 - x1, n2_n) - 1.0 / n2_norm * wp.cross(x3 - x4, n1_n)
463
+ dn1_dx2 = mat_vec_cross_from_3_basis(e1, e2, e3, x3 - x1)
464
+ dn2_dx2 = -mat_vec_cross_from_3_basis(e1, e2, e3, x3 - x4)
465
+ d_one_over_sin_theta_dx2 = d_cos_theta_dx2 * d_one_over_sin_theta_d_cos_theta
466
+ d2_cos_theta_dx2_dx2 = -mat_vec_cross(dn2_dx2, (x3 - x1)) / (n1_norm * n2_norm) + mat_vec_cross(
467
+ dn1_dx2, x3 - x4
468
+ ) / (n1_norm * n2_norm)
469
+
470
+ d_theta_dx2 = d_theta_d_cos_theta * d_cos_theta_dx2
471
+ d2_theta_dx2_dx2 = (
472
+ -wp.outer(d_one_over_sin_theta_dx2, d_cos_theta_dx2) - one_over_sin_theta * d2_cos_theta_dx2_dx2
473
+ )
474
+
475
+ dE_dx2 = e_rest_len * dE_dtheta * d_theta_d_cos_theta * d_cos_theta_dx2
476
+ d2_E_dx2_dx2 = (
477
+ e_rest_len * stiffness * (wp.outer(d_theta_dx2, d_theta_dx2) + (theta - rest_angle) * d2_theta_dx2_dx2)
478
+ )
479
+
480
+ bending_force = -dE_dx2
481
+ bending_hessian = d2_E_dx2_dx2
482
+ else:
483
+ d_cos_theta_dx3 = -1.0 / n1_norm * wp.cross(x2 - x1, n2_n) + 1.0 / n2_norm * wp.cross(x2 - x4, n1_n)
484
+ dn1_dx3 = -mat_vec_cross_from_3_basis(e1, e2, e3, x2 - x1)
485
+ dn2_dx3 = mat_vec_cross_from_3_basis(e1, e2, e3, x2 - x4)
486
+ d_one_over_sin_theta_dx3 = d_cos_theta_dx3 * d_one_over_sin_theta_d_cos_theta
487
+ d2_cos_theta_dx3_dx3 = mat_vec_cross(dn2_dx3, (x2 - x1)) / (n1_norm * n2_norm) - mat_vec_cross(
488
+ dn1_dx3, x2 - x4
489
+ ) / (n1_norm * n2_norm)
490
+
491
+ d_theta_dx3 = d_theta_d_cos_theta * d_cos_theta_dx3
492
+ d2_theta_dx3_dx3 = (
493
+ -wp.outer(d_one_over_sin_theta_dx3, d_cos_theta_dx3) - one_over_sin_theta * d2_cos_theta_dx3_dx3
494
+ )
495
+
496
+ dE_dx3 = e_rest_len * dE_dtheta * d_theta_d_cos_theta * d_cos_theta_dx3
497
+
498
+ d2_E_dx3_dx3 = (
499
+ e_rest_len * stiffness * (wp.outer(d_theta_dx3, d_theta_dx3) + (theta - rest_angle) * d2_theta_dx3_dx3)
500
+ )
501
+
502
+ bending_force = -dE_dx3
503
+ bending_hessian = d2_E_dx3_dx3
504
+
505
+ displacement = pos_prev[edge_indices[bending_index, v_order]] - pos[edge_indices[bending_index, v_order]]
506
+ h_d = bending_hessian * (damping / dt)
507
+ f_d = h_d * displacement
508
+
509
+ bending_force = bending_force + f_d
510
+ bending_hessian = bending_hessian + h_d
511
+
512
+ return bending_force, bending_hessian
513
+
514
+
340
515
  @wp.func
341
516
  def evaluate_ground_contact_force_hessian(
342
517
  particle_pos: wp.vec3,
@@ -857,6 +1032,9 @@ def VBD_solve_trimesh_no_self_contact(
857
1032
  tri_materials: wp.array(dtype=float, ndim=2),
858
1033
  tri_areas: wp.array(dtype=float),
859
1034
  edge_indices: wp.array(dtype=wp.int32, ndim=2),
1035
+ edge_rest_angles: wp.array(dtype=float),
1036
+ edge_rest_length: wp.array(dtype=float),
1037
+ edge_bending_properties: wp.array(dtype=float, ndim=2),
860
1038
  adjacency: ForceElementAdjacencyInfo,
861
1039
  # contact info
862
1040
  # self contact
@@ -948,6 +1126,24 @@ def VBD_solve_trimesh_no_self_contact(
948
1126
  )
949
1127
  # fmt: on
950
1128
 
1129
+ for i_adj_edge in range(get_vertex_num_adjacent_edges(adjacency, particle_index)):
1130
+ nei_edge_index, vertex_order_on_edge = get_vertex_adjacent_edge_id_order(adjacency, particle_index, i_adj_edge)
1131
+ f_edge, h_edge = evaluate_dihedral_angle_based_bending_force_hessian(
1132
+ nei_edge_index,
1133
+ vertex_order_on_edge,
1134
+ pos,
1135
+ prev_pos,
1136
+ edge_indices,
1137
+ edge_rest_angles,
1138
+ edge_rest_length,
1139
+ edge_bending_properties[nei_edge_index, 0],
1140
+ edge_bending_properties[nei_edge_index, 1],
1141
+ dt,
1142
+ )
1143
+
1144
+ f = f + f_edge
1145
+ h = h + h_edge
1146
+
951
1147
  # body-particle contact
952
1148
  particle_contact_count = min(body_particle_contact_count[particle_index], body_particle_contact_buffer_pre_alloc)
953
1149
 
@@ -1063,6 +1259,9 @@ def VBD_solve_trimesh_with_self_contact_penetration_free(
1063
1259
  tri_materials: wp.array(dtype=float, ndim=2),
1064
1260
  tri_areas: wp.array(dtype=float),
1065
1261
  edge_indices: wp.array(dtype=wp.int32, ndim=2),
1262
+ edge_rest_angles: wp.array(dtype=float),
1263
+ edge_rest_length: wp.array(dtype=float),
1264
+ edge_bending_properties: wp.array(dtype=float, ndim=2),
1066
1265
  adjacency: ForceElementAdjacencyInfo,
1067
1266
  # contact info
1068
1267
  # self contact
@@ -1230,6 +1429,15 @@ def VBD_solve_trimesh_with_self_contact_penetration_free(
1230
1429
  for i_adj_edge in range(get_vertex_num_adjacent_edges(adjacency, particle_index)):
1231
1430
  nei_edge_index, vertex_order_on_edge = get_vertex_adjacent_edge_id_order(adjacency, particle_index, i_adj_edge)
1232
1431
  # vertex is on the edge; otherwise it only effects the bending energy n
1432
+ if edge_bending_properties[nei_edge_index, 0] != 0:
1433
+ f_edge, h_edge = evaluate_dihedral_angle_based_bending_force_hessian(
1434
+ nei_edge_index, vertex_order_on_edge, pos, pos_prev, edge_indices, edge_rest_angles, edge_rest_length,
1435
+ edge_bending_properties[nei_edge_index, 0], edge_bending_properties[nei_edge_index, 1], dt
1436
+ )
1437
+
1438
+ f = f + f_edge
1439
+ h = h + h_edge
1440
+
1233
1441
  if vertex_order_on_edge == 2 or vertex_order_on_edge == 3:
1234
1442
  # collisions of neighbor triangles
1235
1443
  if wp.static("contact_info" in VBD_DEBUG_PRINTING_OPTIONS):
@@ -1563,6 +1771,9 @@ class VBDIntegrator(Integrator):
1563
1771
  self.model.tri_materials,
1564
1772
  self.model.tri_areas,
1565
1773
  self.model.edge_indices,
1774
+ self.model.edge_rest_angle,
1775
+ self.model.edge_rest_length,
1776
+ self.model.edge_bending_properties,
1566
1777
  self.adjacency,
1567
1778
  self.model.soft_contact_ke,
1568
1779
  self.model.soft_contact_mu,
@@ -1650,6 +1861,9 @@ class VBDIntegrator(Integrator):
1650
1861
  self.model.tri_materials,
1651
1862
  self.model.tri_areas,
1652
1863
  self.model.edge_indices,
1864
+ self.model.edge_rest_angle,
1865
+ self.model.edge_rest_length,
1866
+ self.model.edge_bending_properties,
1653
1867
  self.adjacency,
1654
1868
  # self-contact
1655
1869
  self.trimesh_collision_detector.collision_info,
@@ -1774,7 +1988,7 @@ class VBDIntegrator(Integrator):
1774
1988
  vertex_adjacent_edges[buffer_offset_v1 + fill_count_v1 * 2 + 1] = 3
1775
1989
  vertex_adjacent_edges_fill_count[v1] = fill_count_v1 + 1
1776
1990
 
1777
- o0 = edges_array[edge_id, 2]
1991
+ o0 = edges_array[edge_id, 0]
1778
1992
  if o0 != -1:
1779
1993
  fill_count_o0 = vertex_adjacent_edges_fill_count[o0]
1780
1994
  buffer_offset_o0 = vertex_adjacent_edges_offsets[o0]
@@ -1782,7 +1996,7 @@ class VBDIntegrator(Integrator):
1782
1996
  vertex_adjacent_edges[buffer_offset_o0 + fill_count_o0 * 2 + 1] = 0
1783
1997
  vertex_adjacent_edges_fill_count[o0] = fill_count_o0 + 1
1784
1998
 
1785
- o1 = edges_array[edge_id, 3]
1999
+ o1 = edges_array[edge_id, 1]
1786
2000
  if o1 != -1:
1787
2001
  fill_count_o1 = vertex_adjacent_edges_fill_count[o1]
1788
2002
  buffer_offset_o1 = vertex_adjacent_edges_offsets[o1]