warp-lang 1.10.0__py3-none-macosx_11_0_arm64.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 (468) hide show
  1. warp/__init__.py +334 -0
  2. warp/__init__.pyi +5856 -0
  3. warp/_src/__init__.py +14 -0
  4. warp/_src/autograd.py +1077 -0
  5. warp/_src/build.py +620 -0
  6. warp/_src/build_dll.py +642 -0
  7. warp/_src/builtins.py +10555 -0
  8. warp/_src/codegen.py +4361 -0
  9. warp/_src/config.py +178 -0
  10. warp/_src/constants.py +59 -0
  11. warp/_src/context.py +8352 -0
  12. warp/_src/dlpack.py +464 -0
  13. warp/_src/fabric.py +362 -0
  14. warp/_src/fem/__init__.py +14 -0
  15. warp/_src/fem/adaptivity.py +510 -0
  16. warp/_src/fem/cache.py +689 -0
  17. warp/_src/fem/dirichlet.py +190 -0
  18. warp/_src/fem/domain.py +553 -0
  19. warp/_src/fem/field/__init__.py +131 -0
  20. warp/_src/fem/field/field.py +703 -0
  21. warp/_src/fem/field/nodal_field.py +403 -0
  22. warp/_src/fem/field/restriction.py +39 -0
  23. warp/_src/fem/field/virtual.py +1021 -0
  24. warp/_src/fem/geometry/__init__.py +32 -0
  25. warp/_src/fem/geometry/adaptive_nanogrid.py +782 -0
  26. warp/_src/fem/geometry/closest_point.py +99 -0
  27. warp/_src/fem/geometry/deformed_geometry.py +277 -0
  28. warp/_src/fem/geometry/element.py +854 -0
  29. warp/_src/fem/geometry/geometry.py +693 -0
  30. warp/_src/fem/geometry/grid_2d.py +478 -0
  31. warp/_src/fem/geometry/grid_3d.py +539 -0
  32. warp/_src/fem/geometry/hexmesh.py +956 -0
  33. warp/_src/fem/geometry/nanogrid.py +660 -0
  34. warp/_src/fem/geometry/partition.py +483 -0
  35. warp/_src/fem/geometry/quadmesh.py +597 -0
  36. warp/_src/fem/geometry/tetmesh.py +762 -0
  37. warp/_src/fem/geometry/trimesh.py +588 -0
  38. warp/_src/fem/integrate.py +2507 -0
  39. warp/_src/fem/linalg.py +385 -0
  40. warp/_src/fem/operator.py +398 -0
  41. warp/_src/fem/polynomial.py +231 -0
  42. warp/_src/fem/quadrature/__init__.py +17 -0
  43. warp/_src/fem/quadrature/pic_quadrature.py +318 -0
  44. warp/_src/fem/quadrature/quadrature.py +665 -0
  45. warp/_src/fem/space/__init__.py +248 -0
  46. warp/_src/fem/space/basis_function_space.py +499 -0
  47. warp/_src/fem/space/basis_space.py +681 -0
  48. warp/_src/fem/space/dof_mapper.py +253 -0
  49. warp/_src/fem/space/function_space.py +312 -0
  50. warp/_src/fem/space/grid_2d_function_space.py +179 -0
  51. warp/_src/fem/space/grid_3d_function_space.py +229 -0
  52. warp/_src/fem/space/hexmesh_function_space.py +255 -0
  53. warp/_src/fem/space/nanogrid_function_space.py +199 -0
  54. warp/_src/fem/space/partition.py +435 -0
  55. warp/_src/fem/space/quadmesh_function_space.py +222 -0
  56. warp/_src/fem/space/restriction.py +221 -0
  57. warp/_src/fem/space/shape/__init__.py +152 -0
  58. warp/_src/fem/space/shape/cube_shape_function.py +1107 -0
  59. warp/_src/fem/space/shape/shape_function.py +134 -0
  60. warp/_src/fem/space/shape/square_shape_function.py +928 -0
  61. warp/_src/fem/space/shape/tet_shape_function.py +829 -0
  62. warp/_src/fem/space/shape/triangle_shape_function.py +674 -0
  63. warp/_src/fem/space/tetmesh_function_space.py +270 -0
  64. warp/_src/fem/space/topology.py +461 -0
  65. warp/_src/fem/space/trimesh_function_space.py +193 -0
  66. warp/_src/fem/types.py +114 -0
  67. warp/_src/fem/utils.py +488 -0
  68. warp/_src/jax.py +188 -0
  69. warp/_src/jax_experimental/__init__.py +14 -0
  70. warp/_src/jax_experimental/custom_call.py +389 -0
  71. warp/_src/jax_experimental/ffi.py +1286 -0
  72. warp/_src/jax_experimental/xla_ffi.py +658 -0
  73. warp/_src/marching_cubes.py +710 -0
  74. warp/_src/math.py +416 -0
  75. warp/_src/optim/__init__.py +14 -0
  76. warp/_src/optim/adam.py +165 -0
  77. warp/_src/optim/linear.py +1608 -0
  78. warp/_src/optim/sgd.py +114 -0
  79. warp/_src/paddle.py +408 -0
  80. warp/_src/render/__init__.py +14 -0
  81. warp/_src/render/imgui_manager.py +291 -0
  82. warp/_src/render/render_opengl.py +3638 -0
  83. warp/_src/render/render_usd.py +939 -0
  84. warp/_src/render/utils.py +162 -0
  85. warp/_src/sparse.py +2718 -0
  86. warp/_src/tape.py +1208 -0
  87. warp/_src/thirdparty/__init__.py +0 -0
  88. warp/_src/thirdparty/appdirs.py +598 -0
  89. warp/_src/thirdparty/dlpack.py +145 -0
  90. warp/_src/thirdparty/unittest_parallel.py +676 -0
  91. warp/_src/torch.py +393 -0
  92. warp/_src/types.py +5888 -0
  93. warp/_src/utils.py +1695 -0
  94. warp/autograd.py +33 -0
  95. warp/bin/libwarp-clang.dylib +0 -0
  96. warp/bin/libwarp.dylib +0 -0
  97. warp/build.py +29 -0
  98. warp/build_dll.py +24 -0
  99. warp/codegen.py +24 -0
  100. warp/constants.py +24 -0
  101. warp/context.py +33 -0
  102. warp/dlpack.py +24 -0
  103. warp/examples/__init__.py +24 -0
  104. warp/examples/assets/bear.usd +0 -0
  105. warp/examples/assets/bunny.usd +0 -0
  106. warp/examples/assets/cube.usd +0 -0
  107. warp/examples/assets/nonuniform.usd +0 -0
  108. warp/examples/assets/nvidia_logo.png +0 -0
  109. warp/examples/assets/pixel.jpg +0 -0
  110. warp/examples/assets/rocks.nvdb +0 -0
  111. warp/examples/assets/rocks.usd +0 -0
  112. warp/examples/assets/sphere.usd +0 -0
  113. warp/examples/assets/square_cloth.usd +0 -0
  114. warp/examples/benchmarks/benchmark_api.py +389 -0
  115. warp/examples/benchmarks/benchmark_cloth.py +296 -0
  116. warp/examples/benchmarks/benchmark_cloth_cupy.py +96 -0
  117. warp/examples/benchmarks/benchmark_cloth_jax.py +105 -0
  118. warp/examples/benchmarks/benchmark_cloth_numba.py +161 -0
  119. warp/examples/benchmarks/benchmark_cloth_numpy.py +85 -0
  120. warp/examples/benchmarks/benchmark_cloth_paddle.py +94 -0
  121. warp/examples/benchmarks/benchmark_cloth_pytorch.py +94 -0
  122. warp/examples/benchmarks/benchmark_cloth_taichi.py +120 -0
  123. warp/examples/benchmarks/benchmark_cloth_warp.py +153 -0
  124. warp/examples/benchmarks/benchmark_gemm.py +164 -0
  125. warp/examples/benchmarks/benchmark_interop_paddle.py +166 -0
  126. warp/examples/benchmarks/benchmark_interop_torch.py +166 -0
  127. warp/examples/benchmarks/benchmark_launches.py +301 -0
  128. warp/examples/benchmarks/benchmark_tile_load_store.py +103 -0
  129. warp/examples/benchmarks/benchmark_tile_sort.py +155 -0
  130. warp/examples/browse.py +37 -0
  131. warp/examples/core/example_cupy.py +86 -0
  132. warp/examples/core/example_dem.py +241 -0
  133. warp/examples/core/example_fluid.py +299 -0
  134. warp/examples/core/example_graph_capture.py +150 -0
  135. warp/examples/core/example_marching_cubes.py +195 -0
  136. warp/examples/core/example_mesh.py +180 -0
  137. warp/examples/core/example_mesh_intersect.py +211 -0
  138. warp/examples/core/example_nvdb.py +182 -0
  139. warp/examples/core/example_raycast.py +111 -0
  140. warp/examples/core/example_raymarch.py +205 -0
  141. warp/examples/core/example_render_opengl.py +290 -0
  142. warp/examples/core/example_sample_mesh.py +300 -0
  143. warp/examples/core/example_sph.py +411 -0
  144. warp/examples/core/example_spin_lock.py +93 -0
  145. warp/examples/core/example_torch.py +211 -0
  146. warp/examples/core/example_wave.py +269 -0
  147. warp/examples/core/example_work_queue.py +118 -0
  148. warp/examples/distributed/example_jacobi_mpi.py +506 -0
  149. warp/examples/fem/example_adaptive_grid.py +286 -0
  150. warp/examples/fem/example_apic_fluid.py +469 -0
  151. warp/examples/fem/example_burgers.py +261 -0
  152. warp/examples/fem/example_convection_diffusion.py +181 -0
  153. warp/examples/fem/example_convection_diffusion_dg.py +225 -0
  154. warp/examples/fem/example_darcy_ls_optimization.py +489 -0
  155. warp/examples/fem/example_deformed_geometry.py +172 -0
  156. warp/examples/fem/example_diffusion.py +196 -0
  157. warp/examples/fem/example_diffusion_3d.py +225 -0
  158. warp/examples/fem/example_diffusion_mgpu.py +225 -0
  159. warp/examples/fem/example_distortion_energy.py +228 -0
  160. warp/examples/fem/example_elastic_shape_optimization.py +387 -0
  161. warp/examples/fem/example_magnetostatics.py +242 -0
  162. warp/examples/fem/example_mixed_elasticity.py +293 -0
  163. warp/examples/fem/example_navier_stokes.py +263 -0
  164. warp/examples/fem/example_nonconforming_contact.py +300 -0
  165. warp/examples/fem/example_stokes.py +213 -0
  166. warp/examples/fem/example_stokes_transfer.py +262 -0
  167. warp/examples/fem/example_streamlines.py +357 -0
  168. warp/examples/fem/utils.py +1047 -0
  169. warp/examples/interop/example_jax_callable.py +146 -0
  170. warp/examples/interop/example_jax_ffi_callback.py +132 -0
  171. warp/examples/interop/example_jax_kernel.py +232 -0
  172. warp/examples/optim/example_diffray.py +561 -0
  173. warp/examples/optim/example_fluid_checkpoint.py +497 -0
  174. warp/examples/tile/example_tile_block_cholesky.py +502 -0
  175. warp/examples/tile/example_tile_cholesky.py +88 -0
  176. warp/examples/tile/example_tile_convolution.py +66 -0
  177. warp/examples/tile/example_tile_fft.py +55 -0
  178. warp/examples/tile/example_tile_filtering.py +113 -0
  179. warp/examples/tile/example_tile_matmul.py +85 -0
  180. warp/examples/tile/example_tile_mcgp.py +191 -0
  181. warp/examples/tile/example_tile_mlp.py +385 -0
  182. warp/examples/tile/example_tile_nbody.py +199 -0
  183. warp/fabric.py +24 -0
  184. warp/fem/__init__.py +173 -0
  185. warp/fem/adaptivity.py +26 -0
  186. warp/fem/cache.py +30 -0
  187. warp/fem/dirichlet.py +24 -0
  188. warp/fem/field/__init__.py +24 -0
  189. warp/fem/field/field.py +26 -0
  190. warp/fem/geometry/__init__.py +21 -0
  191. warp/fem/geometry/closest_point.py +31 -0
  192. warp/fem/linalg.py +38 -0
  193. warp/fem/operator.py +32 -0
  194. warp/fem/polynomial.py +29 -0
  195. warp/fem/space/__init__.py +22 -0
  196. warp/fem/space/basis_space.py +24 -0
  197. warp/fem/space/shape/__init__.py +68 -0
  198. warp/fem/space/topology.py +24 -0
  199. warp/fem/types.py +24 -0
  200. warp/fem/utils.py +32 -0
  201. warp/jax.py +29 -0
  202. warp/jax_experimental/__init__.py +29 -0
  203. warp/jax_experimental/custom_call.py +29 -0
  204. warp/jax_experimental/ffi.py +39 -0
  205. warp/jax_experimental/xla_ffi.py +24 -0
  206. warp/marching_cubes.py +24 -0
  207. warp/math.py +37 -0
  208. warp/native/array.h +1687 -0
  209. warp/native/builtin.h +2327 -0
  210. warp/native/bvh.cpp +562 -0
  211. warp/native/bvh.cu +826 -0
  212. warp/native/bvh.h +555 -0
  213. warp/native/clang/clang.cpp +541 -0
  214. warp/native/coloring.cpp +622 -0
  215. warp/native/crt.cpp +51 -0
  216. warp/native/crt.h +568 -0
  217. warp/native/cuda_crt.h +1058 -0
  218. warp/native/cuda_util.cpp +677 -0
  219. warp/native/cuda_util.h +313 -0
  220. warp/native/error.cpp +77 -0
  221. warp/native/error.h +36 -0
  222. warp/native/exports.h +2023 -0
  223. warp/native/fabric.h +246 -0
  224. warp/native/hashgrid.cpp +311 -0
  225. warp/native/hashgrid.cu +89 -0
  226. warp/native/hashgrid.h +240 -0
  227. warp/native/initializer_array.h +41 -0
  228. warp/native/intersect.h +1253 -0
  229. warp/native/intersect_adj.h +375 -0
  230. warp/native/intersect_tri.h +348 -0
  231. warp/native/mat.h +5189 -0
  232. warp/native/mathdx.cpp +93 -0
  233. warp/native/matnn.h +221 -0
  234. warp/native/mesh.cpp +266 -0
  235. warp/native/mesh.cu +406 -0
  236. warp/native/mesh.h +2097 -0
  237. warp/native/nanovdb/GridHandle.h +533 -0
  238. warp/native/nanovdb/HostBuffer.h +591 -0
  239. warp/native/nanovdb/NanoVDB.h +6246 -0
  240. warp/native/nanovdb/NodeManager.h +323 -0
  241. warp/native/nanovdb/PNanoVDB.h +3390 -0
  242. warp/native/noise.h +859 -0
  243. warp/native/quat.h +1664 -0
  244. warp/native/rand.h +342 -0
  245. warp/native/range.h +145 -0
  246. warp/native/reduce.cpp +174 -0
  247. warp/native/reduce.cu +363 -0
  248. warp/native/runlength_encode.cpp +79 -0
  249. warp/native/runlength_encode.cu +61 -0
  250. warp/native/scan.cpp +47 -0
  251. warp/native/scan.cu +55 -0
  252. warp/native/scan.h +23 -0
  253. warp/native/solid_angle.h +466 -0
  254. warp/native/sort.cpp +251 -0
  255. warp/native/sort.cu +286 -0
  256. warp/native/sort.h +35 -0
  257. warp/native/sparse.cpp +241 -0
  258. warp/native/sparse.cu +435 -0
  259. warp/native/spatial.h +1306 -0
  260. warp/native/svd.h +727 -0
  261. warp/native/temp_buffer.h +46 -0
  262. warp/native/tile.h +4124 -0
  263. warp/native/tile_radix_sort.h +1112 -0
  264. warp/native/tile_reduce.h +838 -0
  265. warp/native/tile_scan.h +240 -0
  266. warp/native/tuple.h +189 -0
  267. warp/native/vec.h +2199 -0
  268. warp/native/version.h +23 -0
  269. warp/native/volume.cpp +501 -0
  270. warp/native/volume.cu +68 -0
  271. warp/native/volume.h +970 -0
  272. warp/native/volume_builder.cu +483 -0
  273. warp/native/volume_builder.h +52 -0
  274. warp/native/volume_impl.h +70 -0
  275. warp/native/warp.cpp +1143 -0
  276. warp/native/warp.cu +4604 -0
  277. warp/native/warp.h +358 -0
  278. warp/optim/__init__.py +20 -0
  279. warp/optim/adam.py +24 -0
  280. warp/optim/linear.py +35 -0
  281. warp/optim/sgd.py +24 -0
  282. warp/paddle.py +24 -0
  283. warp/py.typed +0 -0
  284. warp/render/__init__.py +22 -0
  285. warp/render/imgui_manager.py +29 -0
  286. warp/render/render_opengl.py +24 -0
  287. warp/render/render_usd.py +24 -0
  288. warp/render/utils.py +24 -0
  289. warp/sparse.py +51 -0
  290. warp/tape.py +24 -0
  291. warp/tests/__init__.py +1 -0
  292. warp/tests/__main__.py +4 -0
  293. warp/tests/assets/curlnoise_golden.npy +0 -0
  294. warp/tests/assets/mlp_golden.npy +0 -0
  295. warp/tests/assets/pixel.npy +0 -0
  296. warp/tests/assets/pnoise_golden.npy +0 -0
  297. warp/tests/assets/spiky.usd +0 -0
  298. warp/tests/assets/test_grid.nvdb +0 -0
  299. warp/tests/assets/test_index_grid.nvdb +0 -0
  300. warp/tests/assets/test_int32_grid.nvdb +0 -0
  301. warp/tests/assets/test_vec_grid.nvdb +0 -0
  302. warp/tests/assets/torus.nvdb +0 -0
  303. warp/tests/assets/torus.usda +105 -0
  304. warp/tests/aux_test_class_kernel.py +34 -0
  305. warp/tests/aux_test_compile_consts_dummy.py +18 -0
  306. warp/tests/aux_test_conditional_unequal_types_kernels.py +29 -0
  307. warp/tests/aux_test_dependent.py +29 -0
  308. warp/tests/aux_test_grad_customs.py +29 -0
  309. warp/tests/aux_test_instancing_gc.py +26 -0
  310. warp/tests/aux_test_module_aot.py +7 -0
  311. warp/tests/aux_test_module_unload.py +23 -0
  312. warp/tests/aux_test_name_clash1.py +40 -0
  313. warp/tests/aux_test_name_clash2.py +40 -0
  314. warp/tests/aux_test_reference.py +9 -0
  315. warp/tests/aux_test_reference_reference.py +8 -0
  316. warp/tests/aux_test_square.py +16 -0
  317. warp/tests/aux_test_unresolved_func.py +22 -0
  318. warp/tests/aux_test_unresolved_symbol.py +22 -0
  319. warp/tests/cuda/__init__.py +0 -0
  320. warp/tests/cuda/test_async.py +676 -0
  321. warp/tests/cuda/test_conditional_captures.py +1147 -0
  322. warp/tests/cuda/test_ipc.py +124 -0
  323. warp/tests/cuda/test_mempool.py +233 -0
  324. warp/tests/cuda/test_multigpu.py +169 -0
  325. warp/tests/cuda/test_peer.py +139 -0
  326. warp/tests/cuda/test_pinned.py +84 -0
  327. warp/tests/cuda/test_streams.py +691 -0
  328. warp/tests/geometry/__init__.py +0 -0
  329. warp/tests/geometry/test_bvh.py +335 -0
  330. warp/tests/geometry/test_hash_grid.py +259 -0
  331. warp/tests/geometry/test_marching_cubes.py +294 -0
  332. warp/tests/geometry/test_mesh.py +318 -0
  333. warp/tests/geometry/test_mesh_query_aabb.py +392 -0
  334. warp/tests/geometry/test_mesh_query_point.py +935 -0
  335. warp/tests/geometry/test_mesh_query_ray.py +323 -0
  336. warp/tests/geometry/test_volume.py +1103 -0
  337. warp/tests/geometry/test_volume_write.py +346 -0
  338. warp/tests/interop/__init__.py +0 -0
  339. warp/tests/interop/test_dlpack.py +730 -0
  340. warp/tests/interop/test_jax.py +1673 -0
  341. warp/tests/interop/test_paddle.py +800 -0
  342. warp/tests/interop/test_torch.py +1001 -0
  343. warp/tests/run_coverage_serial.py +39 -0
  344. warp/tests/test_adam.py +162 -0
  345. warp/tests/test_arithmetic.py +1096 -0
  346. warp/tests/test_array.py +3756 -0
  347. warp/tests/test_array_reduce.py +156 -0
  348. warp/tests/test_assert.py +303 -0
  349. warp/tests/test_atomic.py +336 -0
  350. warp/tests/test_atomic_bitwise.py +209 -0
  351. warp/tests/test_atomic_cas.py +312 -0
  352. warp/tests/test_bool.py +220 -0
  353. warp/tests/test_builtins_resolution.py +732 -0
  354. warp/tests/test_closest_point_edge_edge.py +327 -0
  355. warp/tests/test_codegen.py +974 -0
  356. warp/tests/test_codegen_instancing.py +1495 -0
  357. warp/tests/test_compile_consts.py +215 -0
  358. warp/tests/test_conditional.py +298 -0
  359. warp/tests/test_context.py +35 -0
  360. warp/tests/test_copy.py +319 -0
  361. warp/tests/test_ctypes.py +618 -0
  362. warp/tests/test_dense.py +73 -0
  363. warp/tests/test_devices.py +127 -0
  364. warp/tests/test_enum.py +136 -0
  365. warp/tests/test_examples.py +424 -0
  366. warp/tests/test_fabricarray.py +998 -0
  367. warp/tests/test_fast_math.py +72 -0
  368. warp/tests/test_fem.py +2204 -0
  369. warp/tests/test_fixedarray.py +229 -0
  370. warp/tests/test_fp16.py +136 -0
  371. warp/tests/test_func.py +501 -0
  372. warp/tests/test_future_annotations.py +100 -0
  373. warp/tests/test_generics.py +656 -0
  374. warp/tests/test_grad.py +893 -0
  375. warp/tests/test_grad_customs.py +339 -0
  376. warp/tests/test_grad_debug.py +341 -0
  377. warp/tests/test_implicit_init.py +411 -0
  378. warp/tests/test_import.py +45 -0
  379. warp/tests/test_indexedarray.py +1140 -0
  380. warp/tests/test_intersect.py +103 -0
  381. warp/tests/test_iter.py +76 -0
  382. warp/tests/test_large.py +177 -0
  383. warp/tests/test_launch.py +411 -0
  384. warp/tests/test_lerp.py +151 -0
  385. warp/tests/test_linear_solvers.py +223 -0
  386. warp/tests/test_lvalue.py +427 -0
  387. warp/tests/test_map.py +526 -0
  388. warp/tests/test_mat.py +3515 -0
  389. warp/tests/test_mat_assign_copy.py +178 -0
  390. warp/tests/test_mat_constructors.py +573 -0
  391. warp/tests/test_mat_lite.py +122 -0
  392. warp/tests/test_mat_scalar_ops.py +2913 -0
  393. warp/tests/test_math.py +212 -0
  394. warp/tests/test_module_aot.py +287 -0
  395. warp/tests/test_module_hashing.py +258 -0
  396. warp/tests/test_modules_lite.py +70 -0
  397. warp/tests/test_noise.py +252 -0
  398. warp/tests/test_operators.py +299 -0
  399. warp/tests/test_options.py +129 -0
  400. warp/tests/test_overwrite.py +551 -0
  401. warp/tests/test_print.py +408 -0
  402. warp/tests/test_quat.py +2653 -0
  403. warp/tests/test_quat_assign_copy.py +145 -0
  404. warp/tests/test_rand.py +339 -0
  405. warp/tests/test_reload.py +303 -0
  406. warp/tests/test_rounding.py +157 -0
  407. warp/tests/test_runlength_encode.py +196 -0
  408. warp/tests/test_scalar_ops.py +133 -0
  409. warp/tests/test_smoothstep.py +108 -0
  410. warp/tests/test_snippet.py +318 -0
  411. warp/tests/test_sparse.py +845 -0
  412. warp/tests/test_spatial.py +2859 -0
  413. warp/tests/test_spatial_assign_copy.py +160 -0
  414. warp/tests/test_special_values.py +361 -0
  415. warp/tests/test_static.py +640 -0
  416. warp/tests/test_struct.py +901 -0
  417. warp/tests/test_tape.py +242 -0
  418. warp/tests/test_transient_module.py +93 -0
  419. warp/tests/test_triangle_closest_point.py +192 -0
  420. warp/tests/test_tuple.py +361 -0
  421. warp/tests/test_types.py +615 -0
  422. warp/tests/test_utils.py +594 -0
  423. warp/tests/test_vec.py +1408 -0
  424. warp/tests/test_vec_assign_copy.py +143 -0
  425. warp/tests/test_vec_constructors.py +325 -0
  426. warp/tests/test_vec_lite.py +80 -0
  427. warp/tests/test_vec_scalar_ops.py +2327 -0
  428. warp/tests/test_verify_fp.py +100 -0
  429. warp/tests/test_version.py +75 -0
  430. warp/tests/tile/__init__.py +0 -0
  431. warp/tests/tile/test_tile.py +1519 -0
  432. warp/tests/tile/test_tile_atomic_bitwise.py +403 -0
  433. warp/tests/tile/test_tile_cholesky.py +608 -0
  434. warp/tests/tile/test_tile_load.py +724 -0
  435. warp/tests/tile/test_tile_mathdx.py +156 -0
  436. warp/tests/tile/test_tile_matmul.py +179 -0
  437. warp/tests/tile/test_tile_mlp.py +400 -0
  438. warp/tests/tile/test_tile_reduce.py +950 -0
  439. warp/tests/tile/test_tile_shared_memory.py +376 -0
  440. warp/tests/tile/test_tile_sort.py +121 -0
  441. warp/tests/tile/test_tile_view.py +173 -0
  442. warp/tests/unittest_serial.py +47 -0
  443. warp/tests/unittest_suites.py +430 -0
  444. warp/tests/unittest_utils.py +469 -0
  445. warp/tests/walkthrough_debug.py +95 -0
  446. warp/torch.py +24 -0
  447. warp/types.py +51 -0
  448. warp/utils.py +31 -0
  449. warp_lang-1.10.0.dist-info/METADATA +459 -0
  450. warp_lang-1.10.0.dist-info/RECORD +468 -0
  451. warp_lang-1.10.0.dist-info/WHEEL +5 -0
  452. warp_lang-1.10.0.dist-info/licenses/LICENSE.md +176 -0
  453. warp_lang-1.10.0.dist-info/licenses/licenses/Gaia-LICENSE.txt +6 -0
  454. warp_lang-1.10.0.dist-info/licenses/licenses/appdirs-LICENSE.txt +22 -0
  455. warp_lang-1.10.0.dist-info/licenses/licenses/asset_pixel_jpg-LICENSE.txt +3 -0
  456. warp_lang-1.10.0.dist-info/licenses/licenses/cuda-LICENSE.txt +1582 -0
  457. warp_lang-1.10.0.dist-info/licenses/licenses/dlpack-LICENSE.txt +201 -0
  458. warp_lang-1.10.0.dist-info/licenses/licenses/fp16-LICENSE.txt +28 -0
  459. warp_lang-1.10.0.dist-info/licenses/licenses/libmathdx-LICENSE.txt +220 -0
  460. warp_lang-1.10.0.dist-info/licenses/licenses/llvm-LICENSE.txt +279 -0
  461. warp_lang-1.10.0.dist-info/licenses/licenses/moller-LICENSE.txt +16 -0
  462. warp_lang-1.10.0.dist-info/licenses/licenses/nanovdb-LICENSE.txt +2 -0
  463. warp_lang-1.10.0.dist-info/licenses/licenses/nvrtc-LICENSE.txt +1592 -0
  464. warp_lang-1.10.0.dist-info/licenses/licenses/svd-LICENSE.txt +23 -0
  465. warp_lang-1.10.0.dist-info/licenses/licenses/unittest_parallel-LICENSE.txt +21 -0
  466. warp_lang-1.10.0.dist-info/licenses/licenses/usd-LICENSE.txt +213 -0
  467. warp_lang-1.10.0.dist-info/licenses/licenses/windingnumber-LICENSE.txt +21 -0
  468. warp_lang-1.10.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,588 @@
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
+
16
+ from typing import Any, Optional
17
+
18
+ import warp as wp
19
+ from warp._src.fem.cache import (
20
+ TemporaryStore,
21
+ borrow_temporary,
22
+ borrow_temporary_like,
23
+ )
24
+ from warp._src.fem.types import (
25
+ OUTSIDE,
26
+ Coords,
27
+ ElementIndex,
28
+ Sample,
29
+ )
30
+
31
+ from .closest_point import project_on_seg_at_origin, project_on_tri_at_origin
32
+ from .element import Element
33
+ from .geometry import Geometry
34
+
35
+ _wp_module_name_ = "warp.fem.geometry.trimesh"
36
+
37
+
38
+ @wp.struct
39
+ class TrimeshCellArg:
40
+ tri_vertex_indices: wp.array2d(dtype=int)
41
+
42
+ # for global cell lookup
43
+ tri_bvh: wp.uint64
44
+
45
+
46
+ @wp.struct
47
+ class TrimeshSideArg:
48
+ cell_arg: TrimeshCellArg
49
+ edge_vertex_indices: wp.array(dtype=wp.vec2i)
50
+ edge_tri_indices: wp.array(dtype=wp.vec2i)
51
+
52
+
53
+ class Trimesh(Geometry):
54
+ """Triangular mesh geometry"""
55
+
56
+ def __init__(
57
+ self,
58
+ tri_vertex_indices: wp.array,
59
+ positions: wp.array,
60
+ build_bvh: bool = False,
61
+ temporary_store: Optional[TemporaryStore] = None,
62
+ ):
63
+ """
64
+ Constructs a D-dimensional triangular mesh.
65
+
66
+ Args:
67
+ tri_vertex_indices: warp array of shape (num_tris, 3) containing vertex indices for each tri
68
+ positions: warp array of shape (num_vertices, D) containing the position of each vertex
69
+ temporary_store: shared pool from which to allocate temporary arrays
70
+ build_bvh: Whether to also build the triangle BVH, which is necessary for the global `fem.lookup` operator to function without initial guess
71
+ """
72
+
73
+ self.tri_vertex_indices = tri_vertex_indices
74
+ self.positions = positions
75
+
76
+ self._edge_vertex_indices: wp.array = None
77
+ self._edge_tri_indices: wp.array = None
78
+ self._build_topology(temporary_store)
79
+
80
+ # Flip edges so that normals point away from inner cell
81
+ wp.launch(
82
+ kernel=self._orient_edges,
83
+ device=positions.device,
84
+ dim=self.side_count(),
85
+ inputs=[self._edge_vertex_indices, self._edge_tri_indices, self.tri_vertex_indices, self.positions],
86
+ )
87
+
88
+ self._make_default_dependent_implementations()
89
+ self.cell_coordinates = self._make_cell_coordinates(assume_linear=True)
90
+ self.side_coordinates = self._make_side_coordinates(assume_linear=True)
91
+
92
+ if build_bvh:
93
+ self.build_bvh(self.positions.device)
94
+
95
+ def cell_count(self):
96
+ return self.tri_vertex_indices.shape[0]
97
+
98
+ def vertex_count(self):
99
+ return self.positions.shape[0]
100
+
101
+ def side_count(self):
102
+ return self._edge_vertex_indices.shape[0]
103
+
104
+ def boundary_side_count(self):
105
+ return self._boundary_edge_indices.shape[0]
106
+
107
+ def reference_cell(self) -> Element:
108
+ return Element.TRIANGLE
109
+
110
+ def reference_side(self) -> Element:
111
+ return Element.LINE_SEGMENT
112
+
113
+ @property
114
+ def edge_tri_indices(self) -> wp.array:
115
+ return self._edge_tri_indices
116
+
117
+ @property
118
+ def edge_vertex_indices(self) -> wp.array:
119
+ return self._edge_vertex_indices
120
+
121
+ @wp.struct
122
+ class SideIndexArg:
123
+ boundary_edge_indices: wp.array(dtype=int)
124
+
125
+ def _fill_cell_topo_arg(self, args: TrimeshCellArg, device):
126
+ args.tri_vertex_indices = self.tri_vertex_indices.to(device)
127
+ args.tri_bvh = self.bvh_id(device)
128
+
129
+ def _fill_side_topo_arg(self, args: TrimeshSideArg, device):
130
+ self._fill_cell_topo_arg(args.cell_arg, device)
131
+ args.edge_vertex_indices = self._edge_vertex_indices.to(device)
132
+ args.edge_tri_indices = self._edge_tri_indices.to(device)
133
+
134
+ def fill_cell_arg(self, args: TrimeshCellArg, device):
135
+ self._fill_cell_topo_arg(args.topology, device)
136
+ args.positions = self.positions.to(device)
137
+
138
+ def fill_side_arg(self, args: TrimeshSideArg, device):
139
+ self._fill_side_topo_arg(args.topology, device)
140
+ args.positions = self.positions.to(device)
141
+
142
+ def fill_side_index_arg(self, args: SideIndexArg, device):
143
+ args.boundary_edge_indices = self._boundary_edge_indices.to(device)
144
+
145
+ @wp.func
146
+ def boundary_side_index(args: SideIndexArg, boundary_side_index: int):
147
+ """Boundary side to side index"""
148
+
149
+ return args.boundary_edge_indices[boundary_side_index]
150
+
151
+ @wp.func
152
+ def _edge_to_tri_coords(
153
+ args: TrimeshSideArg, side_index: ElementIndex, tri_index: ElementIndex, side_coords: Coords
154
+ ):
155
+ edge_vidx = args.edge_vertex_indices[side_index]
156
+ tri_vidx = args.cell_arg.tri_vertex_indices[tri_index]
157
+
158
+ v0 = tri_vidx[0]
159
+ v1 = tri_vidx[1]
160
+
161
+ cx = float(0.0)
162
+ cy = float(0.0)
163
+ cz = float(0.0)
164
+
165
+ if edge_vidx[0] == v0:
166
+ cx = 1.0 - side_coords[0]
167
+ elif edge_vidx[0] == v1:
168
+ cy = 1.0 - side_coords[0]
169
+ else:
170
+ cz = 1.0 - side_coords[0]
171
+
172
+ if edge_vidx[1] == v0:
173
+ cx = side_coords[0]
174
+ elif edge_vidx[1] == v1:
175
+ cy = side_coords[0]
176
+ else:
177
+ cz = side_coords[0]
178
+
179
+ return Coords(cx, cy, cz)
180
+
181
+ @wp.func
182
+ def _tri_to_edge_coords(
183
+ args: TrimeshSideArg,
184
+ side_index: ElementIndex,
185
+ tri_index: ElementIndex,
186
+ tri_coords: Coords,
187
+ ):
188
+ edge_vidx = args.edge_vertex_indices[side_index]
189
+ tri_vidx = args.cell_arg.tri_vertex_indices[tri_index]
190
+
191
+ start = int(2)
192
+ end = int(2)
193
+
194
+ for k in range(2):
195
+ v = tri_vidx[k]
196
+ if edge_vidx[1] == v:
197
+ end = k
198
+ elif edge_vidx[0] == v:
199
+ start = k
200
+
201
+ return wp.where(tri_coords[start] + tri_coords[end] > 0.999, Coords(tri_coords[end], 0.0, 0.0), Coords(OUTSIDE))
202
+
203
+ def _build_topology(self, temporary_store: TemporaryStore):
204
+ from warp._src.fem.utils import compress_node_indices, host_read_at_index, masked_indices
205
+ from warp._src.utils import array_scan
206
+
207
+ device = self.tri_vertex_indices.device
208
+
209
+ vertex_tri_offsets, vertex_tri_indices = compress_node_indices(
210
+ self.vertex_count(), self.tri_vertex_indices, temporary_store=temporary_store
211
+ )
212
+ self._vertex_tri_offsets = vertex_tri_offsets.detach()
213
+ self._vertex_tri_indices = vertex_tri_indices.detach()
214
+
215
+ vertex_start_edge_count = borrow_temporary(temporary_store, dtype=int, device=device, shape=self.vertex_count())
216
+ vertex_start_edge_count.zero_()
217
+ vertex_start_edge_offsets = borrow_temporary_like(vertex_start_edge_count, temporary_store=temporary_store)
218
+
219
+ vertex_edge_ends = borrow_temporary(temporary_store, dtype=int, device=device, shape=(3 * self.cell_count()))
220
+ vertex_edge_tris = borrow_temporary(temporary_store, dtype=int, device=device, shape=(3 * self.cell_count(), 2))
221
+
222
+ # Count face edges starting at each vertex
223
+ wp.launch(
224
+ kernel=Trimesh._count_starting_edges_kernel,
225
+ device=device,
226
+ dim=self.cell_count(),
227
+ inputs=[self.tri_vertex_indices, vertex_start_edge_count],
228
+ )
229
+
230
+ array_scan(in_array=vertex_start_edge_count, out_array=vertex_start_edge_offsets, inclusive=False)
231
+
232
+ # Count number of unique edges (deduplicate across faces)
233
+ vertex_unique_edge_count = vertex_start_edge_count
234
+ wp.launch(
235
+ kernel=Trimesh._count_unique_starting_edges_kernel,
236
+ device=device,
237
+ dim=self.vertex_count(),
238
+ inputs=[
239
+ self._vertex_tri_offsets,
240
+ self._vertex_tri_indices,
241
+ self.tri_vertex_indices,
242
+ vertex_start_edge_offsets,
243
+ vertex_unique_edge_count,
244
+ vertex_edge_ends,
245
+ vertex_edge_tris,
246
+ ],
247
+ )
248
+
249
+ vertex_unique_edge_offsets = borrow_temporary_like(vertex_start_edge_offsets, temporary_store=temporary_store)
250
+ array_scan(in_array=vertex_start_edge_count, out_array=vertex_unique_edge_offsets, inclusive=False)
251
+
252
+ # Get back edge count to host
253
+ edge_count = int(
254
+ host_read_at_index(vertex_unique_edge_offsets, self.vertex_count() - 1, temporary_store=temporary_store)
255
+ )
256
+
257
+ self._edge_vertex_indices = wp.empty(shape=(edge_count,), dtype=wp.vec2i, device=device)
258
+ self._edge_tri_indices = wp.empty(shape=(edge_count,), dtype=wp.vec2i, device=device)
259
+
260
+ boundary_mask = borrow_temporary(temporary_store=temporary_store, shape=(edge_count,), dtype=int, device=device)
261
+
262
+ # Compress edge data
263
+ wp.launch(
264
+ kernel=Trimesh._compress_edges_kernel,
265
+ device=device,
266
+ dim=self.vertex_count(),
267
+ inputs=[
268
+ vertex_start_edge_offsets,
269
+ vertex_unique_edge_offsets,
270
+ vertex_unique_edge_count,
271
+ vertex_edge_ends,
272
+ vertex_edge_tris,
273
+ self._edge_vertex_indices,
274
+ self._edge_tri_indices,
275
+ boundary_mask,
276
+ ],
277
+ )
278
+
279
+ vertex_start_edge_offsets.release()
280
+ vertex_unique_edge_offsets.release()
281
+ vertex_unique_edge_count.release()
282
+ vertex_edge_ends.release()
283
+ vertex_edge_tris.release()
284
+
285
+ boundary_edge_indices, _ = masked_indices(boundary_mask, temporary_store=temporary_store)
286
+ self._boundary_edge_indices = boundary_edge_indices.detach()
287
+
288
+ boundary_mask.release()
289
+
290
+ @wp.kernel
291
+ def _count_starting_edges_kernel(
292
+ tri_vertex_indices: wp.array2d(dtype=int), vertex_start_edge_count: wp.array(dtype=int)
293
+ ):
294
+ t = wp.tid()
295
+ for k in range(3):
296
+ v0 = tri_vertex_indices[t, k]
297
+ v1 = tri_vertex_indices[t, (k + 1) % 3]
298
+
299
+ if v0 < v1:
300
+ wp.atomic_add(vertex_start_edge_count, v0, 1)
301
+ else:
302
+ wp.atomic_add(vertex_start_edge_count, v1, 1)
303
+
304
+ @wp.func
305
+ def _find(
306
+ needle: int,
307
+ values: wp.array(dtype=int),
308
+ beg: int,
309
+ end: int,
310
+ ):
311
+ for i in range(beg, end):
312
+ if values[i] == needle:
313
+ return i
314
+
315
+ return -1
316
+
317
+ @wp.kernel
318
+ def _count_unique_starting_edges_kernel(
319
+ vertex_tri_offsets: wp.array(dtype=int),
320
+ vertex_tri_indices: wp.array(dtype=int),
321
+ tri_vertex_indices: wp.array2d(dtype=int),
322
+ vertex_start_edge_offsets: wp.array(dtype=int),
323
+ vertex_start_edge_count: wp.array(dtype=int),
324
+ edge_ends: wp.array(dtype=int),
325
+ edge_tris: wp.array2d(dtype=int),
326
+ ):
327
+ v = wp.tid()
328
+
329
+ edge_beg = vertex_start_edge_offsets[v]
330
+
331
+ tri_beg = vertex_tri_offsets[v]
332
+ tri_end = vertex_tri_offsets[v + 1]
333
+
334
+ edge_cur = edge_beg
335
+
336
+ for tri in range(tri_beg, tri_end):
337
+ t = vertex_tri_indices[tri]
338
+
339
+ for k in range(3):
340
+ v0 = tri_vertex_indices[t, k]
341
+ v1 = tri_vertex_indices[t, (k + 1) % 3]
342
+
343
+ if v == wp.min(v0, v1):
344
+ other_v = wp.max(v0, v1)
345
+
346
+ # Check if other_v has been seen
347
+ seen_idx = Trimesh._find(other_v, edge_ends, edge_beg, edge_cur)
348
+
349
+ if seen_idx == -1:
350
+ edge_ends[edge_cur] = other_v
351
+ edge_tris[edge_cur, 0] = t
352
+ edge_tris[edge_cur, 1] = t
353
+ edge_cur += 1
354
+ else:
355
+ edge_tris[seen_idx, 1] = t
356
+
357
+ vertex_start_edge_count[v] = edge_cur - edge_beg
358
+
359
+ @wp.kernel
360
+ def _compress_edges_kernel(
361
+ vertex_start_edge_offsets: wp.array(dtype=int),
362
+ vertex_unique_edge_offsets: wp.array(dtype=int),
363
+ vertex_unique_edge_count: wp.array(dtype=int),
364
+ uncompressed_edge_ends: wp.array(dtype=int),
365
+ uncompressed_edge_tris: wp.array2d(dtype=int),
366
+ edge_vertex_indices: wp.array(dtype=wp.vec2i),
367
+ edge_tri_indices: wp.array(dtype=wp.vec2i),
368
+ boundary_mask: wp.array(dtype=int),
369
+ ):
370
+ v = wp.tid()
371
+
372
+ start_beg = vertex_start_edge_offsets[v]
373
+ unique_beg = vertex_unique_edge_offsets[v]
374
+ unique_count = vertex_unique_edge_count[v]
375
+
376
+ for e in range(unique_count):
377
+ src_index = start_beg + e
378
+ edge_index = unique_beg + e
379
+
380
+ edge_vertex_indices[edge_index] = wp.vec2i(v, uncompressed_edge_ends[src_index])
381
+
382
+ t0 = uncompressed_edge_tris[src_index, 0]
383
+ t1 = uncompressed_edge_tris[src_index, 1]
384
+ edge_tri_indices[edge_index] = wp.vec2i(t0, t1)
385
+ if t0 == t1:
386
+ boundary_mask[edge_index] = 1
387
+ else:
388
+ boundary_mask[edge_index] = 0
389
+
390
+ @wp.func
391
+ def cell_bvh_id(cell_arg: Any):
392
+ return cell_arg.topology.tri_bvh
393
+
394
+ @wp.func
395
+ def cell_bounds(cell_arg: Any, cell_index: ElementIndex):
396
+ p0 = cell_arg.positions[cell_arg.topology.tri_vertex_indices[cell_index, 0]]
397
+ p1 = cell_arg.positions[cell_arg.topology.tri_vertex_indices[cell_index, 1]]
398
+ p2 = cell_arg.positions[cell_arg.topology.tri_vertex_indices[cell_index, 2]]
399
+
400
+ return wp.min(wp.min(p0, p1), p2), wp.max(wp.max(p0, p1), p2)
401
+
402
+ @wp.func
403
+ def cell_position(args: Any, s: Sample):
404
+ tri_idx = args.topology.tri_vertex_indices[s.element_index]
405
+ return (
406
+ s.element_coords[0] * args.positions[tri_idx[0]]
407
+ + s.element_coords[1] * args.positions[tri_idx[1]]
408
+ + s.element_coords[2] * args.positions[tri_idx[2]]
409
+ )
410
+
411
+ @wp.func
412
+ def cell_deformation_gradient(args: Any, s: Sample):
413
+ tri_idx = args.topology.tri_vertex_indices[s.element_index]
414
+ p0 = args.positions[tri_idx[0]]
415
+ p1 = args.positions[tri_idx[1]]
416
+ p2 = args.positions[tri_idx[2]]
417
+ return wp.matrix_from_cols(p1 - p0, p2 - p0)
418
+
419
+ @wp.func
420
+ def cell_closest_point(args: Any, tri_index: ElementIndex, pos: Any):
421
+ vidx = args.topology.tri_vertex_indices[tri_index]
422
+ p0 = args.positions[vidx[0]]
423
+
424
+ q = pos - p0
425
+ e1 = args.positions[vidx[1]] - p0
426
+ e2 = args.positions[vidx[2]] - p0
427
+
428
+ dist, coords = project_on_tri_at_origin(q, e1, e2)
429
+ return coords, dist
430
+
431
+ @wp.func
432
+ def side_position(args: Any, s: Sample):
433
+ edge_idx = args.topology.edge_vertex_indices[s.element_index]
434
+ return (1.0 - s.element_coords[0]) * args.positions[edge_idx[0]] + s.element_coords[0] * args.positions[
435
+ edge_idx[1]
436
+ ]
437
+
438
+ @wp.func
439
+ def side_deformation_gradient(args: Any, s: Sample):
440
+ edge_idx = args.topology.edge_vertex_indices[s.element_index]
441
+ v0 = args.positions[edge_idx[0]]
442
+ v1 = args.positions[edge_idx[1]]
443
+ return v1 - v0
444
+
445
+ @wp.func
446
+ def side_closest_point(args: Any, side_index: ElementIndex, pos: Any):
447
+ edge_idx = args.topology.edge_vertex_indices[side_index]
448
+ p0 = args.positions[edge_idx[0]]
449
+
450
+ q = pos - p0
451
+ e = args.positions[edge_idx[1]] - p0
452
+
453
+ dist, t = project_on_seg_at_origin(q, e, wp.length_sq(e))
454
+ return Coords(t, 0.0, 0.0), dist
455
+
456
+ @wp.func
457
+ def side_inner_cell_index(arg: Any, side_index: ElementIndex):
458
+ return arg.topology.edge_tri_indices[side_index][0]
459
+
460
+ @wp.func
461
+ def side_outer_cell_index(arg: Any, side_index: ElementIndex):
462
+ return arg.topology.edge_tri_indices[side_index][1]
463
+
464
+ @wp.func
465
+ def side_inner_cell_coords(args: Any, side_index: ElementIndex, side_coords: Coords):
466
+ inner_cell_index = Trimesh.side_inner_cell_index(args, side_index)
467
+ return Trimesh._edge_to_tri_coords(args.topology, side_index, inner_cell_index, side_coords)
468
+
469
+ @wp.func
470
+ def side_outer_cell_coords(args: Any, side_index: ElementIndex, side_coords: Coords):
471
+ outer_cell_index = Trimesh.side_outer_cell_index(args, side_index)
472
+ return Trimesh._edge_to_tri_coords(args.topology, side_index, outer_cell_index, side_coords)
473
+
474
+ @wp.func
475
+ def side_from_cell_coords(
476
+ args: Any,
477
+ side_index: ElementIndex,
478
+ tri_index: ElementIndex,
479
+ tri_coords: Coords,
480
+ ):
481
+ return Trimesh._tri_to_edge_coords(args.topology, side_index, tri_index, tri_coords)
482
+
483
+
484
+ @wp.struct
485
+ class Trimesh2DCellArg:
486
+ topology: TrimeshCellArg
487
+ positions: wp.array(dtype=wp.vec2)
488
+
489
+
490
+ @wp.struct
491
+ class Trimesh2DSideArg:
492
+ topology: TrimeshSideArg
493
+ positions: wp.array(dtype=wp.vec2)
494
+
495
+
496
+ class Trimesh2D(Trimesh):
497
+ """2D Triangular mesh geometry"""
498
+
499
+ dimension = 2
500
+ CellArg = Trimesh2DCellArg
501
+ SideArg = Trimesh2DSideArg
502
+
503
+ @wp.func
504
+ def side_to_cell_arg(side_arg: SideArg):
505
+ return Trimesh2DCellArg(side_arg.topology.cell_arg, side_arg.positions)
506
+
507
+ @wp.kernel
508
+ def _orient_edges(
509
+ edge_vertex_indices: wp.array(dtype=wp.vec2i),
510
+ edge_tri_indices: wp.array(dtype=wp.vec2i),
511
+ tri_vertex_indices: wp.array2d(dtype=int),
512
+ positions: wp.array(dtype=wp.vec2),
513
+ ):
514
+ e = wp.tid()
515
+
516
+ tri = edge_tri_indices[e][0]
517
+
518
+ tri_vidx = tri_vertex_indices[tri]
519
+ edge_vidx = edge_vertex_indices[e]
520
+
521
+ tri_centroid = (positions[tri_vidx[0]] + positions[tri_vidx[1]] + positions[tri_vidx[2]]) / 3.0
522
+
523
+ v0 = positions[edge_vidx[0]]
524
+ v1 = positions[edge_vidx[1]]
525
+
526
+ edge_center = 0.5 * (v1 + v0)
527
+ edge_vec = v1 - v0
528
+ edge_normal = Geometry._element_normal(edge_vec)
529
+
530
+ # if edge normal points toward first triangle centroid, flip indices
531
+ if wp.dot(tri_centroid - edge_center, edge_normal) > 0.0:
532
+ edge_vertex_indices[e] = wp.vec2i(edge_vidx[1], edge_vidx[0])
533
+
534
+
535
+ @wp.struct
536
+ class Trimesh3DCellArg:
537
+ topology: TrimeshCellArg
538
+ positions: wp.array(dtype=wp.vec3)
539
+
540
+
541
+ @wp.struct
542
+ class Trimesh3DSideArg:
543
+ topology: TrimeshSideArg
544
+ positions: wp.array(dtype=wp.vec3)
545
+
546
+
547
+ class Trimesh3D(Trimesh):
548
+ """3D Triangular mesh geometry"""
549
+
550
+ dimension = 3
551
+ CellArg = Trimesh3DCellArg
552
+ SideArg = Trimesh3DSideArg
553
+
554
+ @wp.func
555
+ def side_to_cell_arg(side_arg: SideArg):
556
+ return Trimesh3DCellArg(side_arg.topology.cell_arg, side_arg.positions)
557
+
558
+ @wp.kernel
559
+ def _orient_edges(
560
+ edge_vertex_indices: wp.array(dtype=wp.vec2i),
561
+ edge_tri_indices: wp.array(dtype=wp.vec2i),
562
+ tri_vertex_indices: wp.array2d(dtype=int),
563
+ positions: wp.array(dtype=wp.vec3),
564
+ ):
565
+ e = wp.tid()
566
+
567
+ tri = edge_tri_indices[e][0]
568
+
569
+ tri_vidx = tri_vertex_indices[tri]
570
+ edge_vidx = edge_vertex_indices[e]
571
+
572
+ t0 = positions[tri_vidx[0]]
573
+ t1 = positions[tri_vidx[1]]
574
+ t2 = positions[tri_vidx[2]]
575
+
576
+ tri_centroid = (t0 + t1 + t2) / 3.0
577
+ tri_normal = wp.cross(t1 - t0, t2 - t0)
578
+
579
+ v0 = positions[edge_vidx[0]]
580
+ v1 = positions[edge_vidx[1]]
581
+
582
+ edge_center = 0.5 * (v1 + v0)
583
+ edge_vec = v1 - v0
584
+ edge_normal = wp.cross(edge_vec, tri_normal)
585
+
586
+ # if edge normal points toward first triangle centroid, flip indices
587
+ if wp.dot(tri_centroid - edge_center, edge_normal) > 0.0:
588
+ edge_vertex_indices[e] = wp.vec2i(edge_vidx[1], edge_vidx[0])