warp-lang 1.7.2rc1__py3-none-macosx_10_13_universal2.whl → 1.8.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 (180) hide show
  1. warp/__init__.py +3 -1
  2. warp/__init__.pyi +3489 -1
  3. warp/autograd.py +45 -122
  4. warp/bin/libwarp.dylib +0 -0
  5. warp/build.py +241 -252
  6. warp/build_dll.py +125 -26
  7. warp/builtins.py +1907 -384
  8. warp/codegen.py +257 -101
  9. warp/config.py +12 -1
  10. warp/constants.py +1 -1
  11. warp/context.py +657 -223
  12. warp/dlpack.py +1 -1
  13. warp/examples/benchmarks/benchmark_cloth.py +2 -2
  14. warp/examples/benchmarks/benchmark_tile_sort.py +155 -0
  15. warp/examples/core/example_sample_mesh.py +1 -1
  16. warp/examples/core/example_spin_lock.py +93 -0
  17. warp/examples/core/example_work_queue.py +118 -0
  18. warp/examples/fem/example_adaptive_grid.py +5 -5
  19. warp/examples/fem/example_apic_fluid.py +1 -1
  20. warp/examples/fem/example_burgers.py +1 -1
  21. warp/examples/fem/example_convection_diffusion.py +9 -6
  22. warp/examples/fem/example_darcy_ls_optimization.py +489 -0
  23. warp/examples/fem/example_deformed_geometry.py +1 -1
  24. warp/examples/fem/example_diffusion.py +2 -2
  25. warp/examples/fem/example_diffusion_3d.py +1 -1
  26. warp/examples/fem/example_distortion_energy.py +1 -1
  27. warp/examples/fem/example_elastic_shape_optimization.py +387 -0
  28. warp/examples/fem/example_magnetostatics.py +5 -3
  29. warp/examples/fem/example_mixed_elasticity.py +5 -3
  30. warp/examples/fem/example_navier_stokes.py +11 -9
  31. warp/examples/fem/example_nonconforming_contact.py +5 -3
  32. warp/examples/fem/example_streamlines.py +8 -3
  33. warp/examples/fem/utils.py +9 -8
  34. warp/examples/interop/example_jax_ffi_callback.py +2 -2
  35. warp/examples/optim/example_drone.py +1 -1
  36. warp/examples/sim/example_cloth.py +1 -1
  37. warp/examples/sim/example_cloth_self_contact.py +48 -54
  38. warp/examples/tile/example_tile_block_cholesky.py +502 -0
  39. warp/examples/tile/example_tile_cholesky.py +2 -1
  40. warp/examples/tile/example_tile_convolution.py +1 -1
  41. warp/examples/tile/example_tile_filtering.py +1 -1
  42. warp/examples/tile/example_tile_matmul.py +1 -1
  43. warp/examples/tile/example_tile_mlp.py +2 -0
  44. warp/fabric.py +7 -7
  45. warp/fem/__init__.py +5 -0
  46. warp/fem/adaptivity.py +1 -1
  47. warp/fem/cache.py +152 -63
  48. warp/fem/dirichlet.py +2 -2
  49. warp/fem/domain.py +136 -6
  50. warp/fem/field/field.py +141 -99
  51. warp/fem/field/nodal_field.py +85 -39
  52. warp/fem/field/virtual.py +97 -52
  53. warp/fem/geometry/adaptive_nanogrid.py +91 -86
  54. warp/fem/geometry/closest_point.py +13 -0
  55. warp/fem/geometry/deformed_geometry.py +102 -40
  56. warp/fem/geometry/element.py +56 -2
  57. warp/fem/geometry/geometry.py +323 -22
  58. warp/fem/geometry/grid_2d.py +157 -62
  59. warp/fem/geometry/grid_3d.py +116 -20
  60. warp/fem/geometry/hexmesh.py +86 -20
  61. warp/fem/geometry/nanogrid.py +166 -86
  62. warp/fem/geometry/partition.py +59 -25
  63. warp/fem/geometry/quadmesh.py +86 -135
  64. warp/fem/geometry/tetmesh.py +47 -119
  65. warp/fem/geometry/trimesh.py +77 -270
  66. warp/fem/integrate.py +107 -52
  67. warp/fem/linalg.py +25 -58
  68. warp/fem/operator.py +124 -27
  69. warp/fem/quadrature/pic_quadrature.py +36 -14
  70. warp/fem/quadrature/quadrature.py +40 -16
  71. warp/fem/space/__init__.py +1 -1
  72. warp/fem/space/basis_function_space.py +66 -46
  73. warp/fem/space/basis_space.py +17 -4
  74. warp/fem/space/dof_mapper.py +1 -1
  75. warp/fem/space/function_space.py +2 -2
  76. warp/fem/space/grid_2d_function_space.py +4 -1
  77. warp/fem/space/hexmesh_function_space.py +4 -2
  78. warp/fem/space/nanogrid_function_space.py +3 -1
  79. warp/fem/space/partition.py +11 -2
  80. warp/fem/space/quadmesh_function_space.py +4 -1
  81. warp/fem/space/restriction.py +5 -2
  82. warp/fem/space/shape/__init__.py +10 -8
  83. warp/fem/space/tetmesh_function_space.py +4 -1
  84. warp/fem/space/topology.py +52 -21
  85. warp/fem/space/trimesh_function_space.py +4 -1
  86. warp/fem/utils.py +53 -8
  87. warp/jax.py +1 -2
  88. warp/jax_experimental/ffi.py +12 -17
  89. warp/jax_experimental/xla_ffi.py +37 -24
  90. warp/math.py +171 -1
  91. warp/native/array.h +99 -0
  92. warp/native/builtin.h +174 -31
  93. warp/native/coloring.cpp +1 -1
  94. warp/native/exports.h +118 -63
  95. warp/native/intersect.h +3 -3
  96. warp/native/mat.h +5 -10
  97. warp/native/mathdx.cpp +11 -5
  98. warp/native/matnn.h +1 -123
  99. warp/native/quat.h +28 -4
  100. warp/native/sparse.cpp +121 -258
  101. warp/native/sparse.cu +181 -274
  102. warp/native/spatial.h +305 -17
  103. warp/native/tile.h +583 -72
  104. warp/native/tile_radix_sort.h +1108 -0
  105. warp/native/tile_reduce.h +237 -2
  106. warp/native/tile_scan.h +240 -0
  107. warp/native/tuple.h +189 -0
  108. warp/native/vec.h +6 -16
  109. warp/native/warp.cpp +36 -4
  110. warp/native/warp.cu +574 -51
  111. warp/native/warp.h +47 -74
  112. warp/optim/linear.py +5 -1
  113. warp/paddle.py +7 -8
  114. warp/py.typed +0 -0
  115. warp/render/render_opengl.py +58 -29
  116. warp/render/render_usd.py +124 -61
  117. warp/sim/__init__.py +9 -0
  118. warp/sim/collide.py +252 -78
  119. warp/sim/graph_coloring.py +8 -1
  120. warp/sim/import_mjcf.py +4 -3
  121. warp/sim/import_usd.py +11 -7
  122. warp/sim/integrator.py +5 -2
  123. warp/sim/integrator_euler.py +1 -1
  124. warp/sim/integrator_featherstone.py +1 -1
  125. warp/sim/integrator_vbd.py +751 -320
  126. warp/sim/integrator_xpbd.py +1 -1
  127. warp/sim/model.py +265 -260
  128. warp/sim/utils.py +10 -7
  129. warp/sparse.py +303 -166
  130. warp/tape.py +52 -51
  131. warp/tests/cuda/test_conditional_captures.py +1046 -0
  132. warp/tests/cuda/test_streams.py +1 -1
  133. warp/tests/geometry/test_volume.py +2 -2
  134. warp/tests/interop/test_dlpack.py +9 -9
  135. warp/tests/interop/test_jax.py +0 -1
  136. warp/tests/run_coverage_serial.py +1 -1
  137. warp/tests/sim/disabled_kinematics.py +2 -2
  138. warp/tests/sim/{test_vbd.py → test_cloth.py} +296 -113
  139. warp/tests/sim/test_collision.py +159 -51
  140. warp/tests/sim/test_coloring.py +15 -1
  141. warp/tests/test_array.py +254 -2
  142. warp/tests/test_array_reduce.py +2 -2
  143. warp/tests/test_atomic_cas.py +299 -0
  144. warp/tests/test_codegen.py +142 -19
  145. warp/tests/test_conditional.py +47 -1
  146. warp/tests/test_ctypes.py +0 -20
  147. warp/tests/test_devices.py +8 -0
  148. warp/tests/test_fabricarray.py +4 -2
  149. warp/tests/test_fem.py +58 -25
  150. warp/tests/test_func.py +42 -1
  151. warp/tests/test_grad.py +1 -1
  152. warp/tests/test_lerp.py +1 -3
  153. warp/tests/test_map.py +481 -0
  154. warp/tests/test_mat.py +1 -24
  155. warp/tests/test_quat.py +6 -15
  156. warp/tests/test_rounding.py +10 -38
  157. warp/tests/test_runlength_encode.py +7 -7
  158. warp/tests/test_smoothstep.py +1 -1
  159. warp/tests/test_sparse.py +51 -2
  160. warp/tests/test_spatial.py +507 -1
  161. warp/tests/test_struct.py +2 -2
  162. warp/tests/test_tuple.py +265 -0
  163. warp/tests/test_types.py +2 -2
  164. warp/tests/test_utils.py +24 -18
  165. warp/tests/tile/test_tile.py +420 -1
  166. warp/tests/tile/test_tile_mathdx.py +518 -14
  167. warp/tests/tile/test_tile_reduce.py +213 -0
  168. warp/tests/tile/test_tile_shared_memory.py +130 -1
  169. warp/tests/tile/test_tile_sort.py +117 -0
  170. warp/tests/unittest_suites.py +4 -6
  171. warp/types.py +462 -308
  172. warp/utils.py +647 -86
  173. {warp_lang-1.7.2rc1.dist-info → warp_lang-1.8.0.dist-info}/METADATA +20 -6
  174. {warp_lang-1.7.2rc1.dist-info → warp_lang-1.8.0.dist-info}/RECORD +177 -165
  175. warp/stubs.py +0 -3381
  176. warp/tests/sim/test_xpbd.py +0 -399
  177. warp/tests/test_mlp.py +0 -282
  178. {warp_lang-1.7.2rc1.dist-info → warp_lang-1.8.0.dist-info}/WHEEL +0 -0
  179. {warp_lang-1.7.2rc1.dist-info → warp_lang-1.8.0.dist-info}/licenses/LICENSE.md +0 -0
  180. {warp_lang-1.7.2rc1.dist-info → warp_lang-1.8.0.dist-info}/top_level.txt +0 -0
@@ -23,15 +23,13 @@ from warp.fem.cache import (
23
23
  cached_arg_value,
24
24
  )
25
25
  from warp.fem.types import (
26
- NULL_ELEMENT_INDEX,
27
26
  OUTSIDE,
28
27
  Coords,
29
28
  ElementIndex,
30
29
  Sample,
31
- make_free_sample,
32
30
  )
33
31
 
34
- from .closest_point import project_on_tri_at_origin
32
+ from .closest_point import project_on_seg_at_origin, project_on_tri_at_origin
35
33
  from .element import LinearEdge, Triangle
36
34
  from .geometry import Geometry
37
35
 
@@ -40,10 +38,6 @@ from .geometry import Geometry
40
38
  class TrimeshCellArg:
41
39
  tri_vertex_indices: wp.array2d(dtype=int)
42
40
 
43
- # for neighbor cell lookup
44
- vertex_tri_offsets: wp.array(dtype=int)
45
- vertex_tri_indices: wp.array(dtype=int)
46
-
47
41
  # for global cell lookup
48
42
  tri_bvh: wp.uint64
49
43
 
@@ -55,19 +49,6 @@ class TrimeshSideArg:
55
49
  edge_tri_indices: wp.array(dtype=wp.vec2i)
56
50
 
57
51
 
58
- _NULL_BVH = wp.constant(wp.uint64(0))
59
-
60
-
61
- @wp.func
62
- def _bvh_vec(v: wp.vec3):
63
- return v
64
-
65
-
66
- @wp.func
67
- def _bvh_vec(v: wp.vec2):
68
- return wp.vec3(v[0], v[1], 0.0)
69
-
70
-
71
52
  class Trimesh(Geometry):
72
53
  """Triangular mesh geometry"""
73
54
 
@@ -93,14 +74,8 @@ class Trimesh(Geometry):
93
74
 
94
75
  self._edge_vertex_indices: wp.array = None
95
76
  self._edge_tri_indices: wp.array = None
96
- self._vertex_tri_offsets: wp.array = None
97
- self._vertex_tri_indices: wp.array = None
98
77
  self._build_topology(temporary_store)
99
78
 
100
- self._tri_bvh: wp.Bvh = None
101
- if build_bvh:
102
- self._build_bvh()
103
-
104
79
  # Flip edges so that normals point away from inner cell
105
80
  wp.launch(
106
81
  kernel=self._orient_edges,
@@ -110,34 +85,11 @@ class Trimesh(Geometry):
110
85
  )
111
86
 
112
87
  self._make_default_dependent_implementations()
88
+ self.cell_coordinates = self._make_cell_coordinates(assume_linear=True)
89
+ self.side_coordinates = self._make_side_coordinates(assume_linear=True)
113
90
 
114
- def update_bvh(self, force_rebuild: bool = False):
115
- """
116
- Refits the BVH, or rebuilds it from scratch if `force_rebuild` is ``True``.
117
- """
118
-
119
- if self._tri_bvh is None or force_rebuild:
120
- return self.build_bvh()
121
-
122
- wp.launch(
123
- Trimesh._compute_tri_bounds,
124
- self.tri_vertex_indices,
125
- self.positions,
126
- self._tri_bvh.lowers,
127
- self._tri_bvh.uppers,
128
- )
129
- self._tri_bvh.refit()
130
-
131
- def _build_bvh(self, temporary_store: Optional[TemporaryStore] = None):
132
- lowers = wp.array(shape=self.cell_count(), dtype=wp.vec3, device=self.positions.device)
133
- uppers = wp.array(shape=self.cell_count(), dtype=wp.vec3, device=self.positions.device)
134
- wp.launch(
135
- Trimesh._compute_tri_bounds,
136
- device=self.positions.device,
137
- dim=self.cell_count(),
138
- inputs=[self.tri_vertex_indices, self.positions, lowers, uppers],
139
- )
140
- self._tri_bvh = wp.Bvh(lowers, uppers)
91
+ if build_bvh:
92
+ self.build_bvh(self.positions.device)
141
93
 
142
94
  def cell_count(self):
143
95
  return self.tri_vertex_indices.shape[0]
@@ -169,106 +121,42 @@ class Trimesh(Geometry):
169
121
  class SideIndexArg:
170
122
  boundary_edge_indices: wp.array(dtype=int)
171
123
 
172
- @cached_arg_value
173
- def _cell_topo_arg_value(self, device):
174
- args = TrimeshCellArg()
175
-
124
+ def _fill_cell_topo_arg(self, args: TrimeshCellArg, device):
176
125
  args.tri_vertex_indices = self.tri_vertex_indices.to(device)
177
- args.vertex_tri_offsets = self._vertex_tri_offsets.to(device)
178
- args.vertex_tri_indices = self._vertex_tri_indices.to(device)
179
-
180
- return args
181
-
182
- @cached_arg_value
183
- def _side_topo_arg_value(self, device):
184
- args = TrimeshSideArg()
126
+ args.tri_bvh = self.bvh_id(device)
185
127
 
186
- args.cell_arg = self._cell_topo_arg_value(device)
128
+ def _fill_side_topo_arg(self, args: TrimeshSideArg, device):
129
+ self._fill_cell_topo_arg(args.cell_arg, device)
187
130
  args.edge_vertex_indices = self._edge_vertex_indices.to(device)
188
131
  args.edge_tri_indices = self._edge_tri_indices.to(device)
189
132
 
190
- return args
191
-
192
- def _bvh_id(self, device):
193
- if self._tri_bvh is None or self._tri_bvh.device != wp.get_device(device):
194
- return _NULL_BVH
195
- return self._tri_bvh.id
196
-
197
133
  def cell_arg_value(self, device):
198
134
  args = self.CellArg()
135
+ self.fill_cell_arg(args, device)
136
+ return args
199
137
 
200
- args.topology = self._cell_topo_arg_value(device)
138
+ def fill_cell_arg(self, args: TrimeshCellArg, device):
139
+ self._fill_cell_topo_arg(args.topology, device)
201
140
  args.positions = self.positions.to(device)
202
- args.topology.tri_bvh = self._bvh_id(device)
203
-
204
- return args
205
141
 
206
142
  def side_arg_value(self, device):
207
143
  args = self.SideArg()
208
-
209
- args.topology = self._side_topo_arg_value(device)
210
- args.positions = self.positions.to(device)
211
- args.topology.cell_arg.tri_bvh = self._bvh_id(device)
212
-
144
+ self.fill_side_arg(args, device)
213
145
  return args
214
146
 
215
- @wp.func
216
- def _project_on_tri(args: TrimeshCellArg, positions: wp.array(dtype=Any), pos: Any, tri_index: int):
217
- p0 = positions[args.tri_vertex_indices[tri_index, 0]]
218
-
219
- q = pos - p0
220
- e1 = positions[args.tri_vertex_indices[tri_index, 1]] - p0
221
- e2 = positions[args.tri_vertex_indices[tri_index, 2]] - p0
222
-
223
- dist, coords = project_on_tri_at_origin(q, e1, e2)
224
- return dist, coords
225
-
226
- @wp.func
227
- def _bvh_lookup(args: TrimeshCellArg, positions: wp.array(dtype=Any), pos: Any):
228
- closest_tri = int(NULL_ELEMENT_INDEX)
229
- closest_coords = Coords(OUTSIDE)
230
- closest_dist = float(1.0e8)
231
-
232
- if args.tri_bvh != _NULL_BVH:
233
- bvh_pos = _bvh_vec(pos)
234
- query = wp.bvh_query_aabb(args.tri_bvh, bvh_pos, bvh_pos)
235
- tri = int(0)
236
- while wp.bvh_query_next(query, tri):
237
- dist, coords = Trimesh._project_on_tri(args, positions, pos, tri)
238
- if dist <= closest_dist:
239
- closest_dist = dist
240
- closest_tri = tri
241
- closest_coords = coords
242
-
243
- return closest_dist, closest_tri, closest_coords
244
-
245
- @wp.func
246
- def _cell_neighbor_lookup(args: TrimeshCellArg, positions: wp.array(dtype=Any), pos: Any, cell_index: int):
247
- closest_dist = float(1.0e8)
248
-
249
- for v in range(3):
250
- vtx = args.tri_vertex_indices[cell_index, v]
251
- tri_beg = args.vertex_tri_offsets[vtx]
252
- tri_end = args.vertex_tri_offsets[vtx + 1]
253
-
254
- for t in range(tri_beg, tri_end):
255
- tri = args.vertex_tri_indices[t]
256
- dist, coords = Trimesh._project_on_tri(args, positions, pos, tri)
257
- if dist <= closest_dist:
258
- closest_dist = dist
259
- closest_tri = tri
260
- closest_coords = coords
261
-
262
- return closest_dist, closest_tri, closest_coords
147
+ def fill_side_arg(self, args: TrimeshSideArg, device):
148
+ self._fill_side_topo_arg(args.topology, device)
149
+ args.positions = self.positions.to(device)
263
150
 
264
151
  @cached_arg_value
265
152
  def side_index_arg_value(self, device) -> SideIndexArg:
266
153
  args = self.SideIndexArg()
154
+ self.fill_side_index_arg(args, device)
155
+ return args
267
156
 
157
+ def fill_side_index_arg(self, args: SideIndexArg, device):
268
158
  args.boundary_edge_indices = self._boundary_edge_indices.to(device)
269
159
 
270
- return args
271
-
272
160
  @wp.func
273
161
  def boundary_side_index(args: SideIndexArg, boundary_side_index: int):
274
162
  """Boundary side to side index"""
@@ -516,43 +404,20 @@ class Trimesh(Geometry):
516
404
  else:
517
405
  boundary_mask[edge_index] = 0
518
406
 
519
- @wp.kernel
520
- def _compute_tri_bounds(
521
- tri_vertex_indices: wp.array2d(dtype=int),
522
- positions: wp.array(dtype=Any),
523
- lowers: wp.array(dtype=wp.vec3),
524
- uppers: wp.array(dtype=wp.vec3),
525
- ):
526
- t = wp.tid()
527
- p0 = _bvh_vec(positions[tri_vertex_indices[t, 0]])
528
- p1 = _bvh_vec(positions[tri_vertex_indices[t, 1]])
529
- p2 = _bvh_vec(positions[tri_vertex_indices[t, 2]])
530
-
531
- lowers[t] = wp.min(wp.min(p0, p1), p2)
532
- uppers[t] = wp.max(wp.max(p0, p1), p2)
533
-
534
-
535
- @wp.struct
536
- class Trimesh2DCellArg:
537
- topology: TrimeshCellArg
538
- positions: wp.array(dtype=wp.vec2)
539
-
540
-
541
- @wp.struct
542
- class Trimesh2DSideArg:
543
- topology: TrimeshSideArg
544
- positions: wp.array(dtype=wp.vec2)
545
-
407
+ @wp.func
408
+ def cell_bvh_id(cell_arg: Any):
409
+ return cell_arg.topology.tri_bvh
546
410
 
547
- class Trimesh2D(Trimesh):
548
- """2D Triangular mesh geometry"""
411
+ @wp.func
412
+ def cell_bounds(cell_arg: Any, cell_index: ElementIndex):
413
+ p0 = cell_arg.positions[cell_arg.topology.tri_vertex_indices[cell_index, 0]]
414
+ p1 = cell_arg.positions[cell_arg.topology.tri_vertex_indices[cell_index, 1]]
415
+ p2 = cell_arg.positions[cell_arg.topology.tri_vertex_indices[cell_index, 2]]
549
416
 
550
- dimension = 2
551
- CellArg = Trimesh2DCellArg
552
- SideArg = Trimesh2DSideArg
417
+ return wp.min(wp.min(p0, p1), p2), wp.max(wp.max(p0, p1), p2)
553
418
 
554
419
  @wp.func
555
- def cell_position(args: CellArg, s: Sample):
420
+ def cell_position(args: Any, s: Sample):
556
421
  tri_idx = args.topology.tri_vertex_indices[s.element_index]
557
422
  return (
558
423
  s.element_coords[0] * args.positions[tri_idx[0]]
@@ -561,7 +426,7 @@ class Trimesh2D(Trimesh):
561
426
  )
562
427
 
563
428
  @wp.func
564
- def cell_deformation_gradient(args: CellArg, s: Sample):
429
+ def cell_deformation_gradient(args: Any, s: Sample):
565
430
  tri_idx = args.topology.tri_vertex_indices[s.element_index]
566
431
  p0 = args.positions[tri_idx[0]]
567
432
  p1 = args.positions[tri_idx[1]]
@@ -569,72 +434,89 @@ class Trimesh2D(Trimesh):
569
434
  return wp.matrix_from_cols(p1 - p0, p2 - p0)
570
435
 
571
436
  @wp.func
572
- def cell_lookup(args: CellArg, pos: wp.vec2):
573
- closest_dist, closest_tri, closest_coords = Trimesh._bvh_lookup(args.topology, args.positions, pos)
437
+ def cell_closest_point(args: Any, tri_index: ElementIndex, pos: Any):
438
+ vidx = args.topology.tri_vertex_indices[tri_index]
439
+ p0 = args.positions[vidx[0]]
574
440
 
575
- return make_free_sample(closest_tri, closest_coords)
576
-
577
- @wp.func
578
- def cell_lookup(args: CellArg, pos: wp.vec2, guess: Sample):
579
- closest_dist, closest_tri, closest_coords = Trimesh._bvh_lookup(args.topology, args.positions, pos)
580
-
581
- if closest_tri == NULL_ELEMENT_INDEX:
582
- closest_dist, closest_tri, closest_coords = Trimesh._cell_neighbor_lookup(
583
- args.topology, args.positions, pos, guess.element_index
584
- )
441
+ q = pos - p0
442
+ e1 = args.positions[vidx[1]] - p0
443
+ e2 = args.positions[vidx[2]] - p0
585
444
 
586
- return make_free_sample(closest_tri, closest_coords)
445
+ dist, coords = project_on_tri_at_origin(q, e1, e2)
446
+ return coords, dist
587
447
 
588
448
  @wp.func
589
- def side_position(args: SideArg, s: Sample):
449
+ def side_position(args: Any, s: Sample):
590
450
  edge_idx = args.topology.edge_vertex_indices[s.element_index]
591
451
  return (1.0 - s.element_coords[0]) * args.positions[edge_idx[0]] + s.element_coords[0] * args.positions[
592
452
  edge_idx[1]
593
453
  ]
594
454
 
595
455
  @wp.func
596
- def side_deformation_gradient(args: SideArg, s: Sample):
456
+ def side_deformation_gradient(args: Any, s: Sample):
597
457
  edge_idx = args.topology.edge_vertex_indices[s.element_index]
598
458
  v0 = args.positions[edge_idx[0]]
599
459
  v1 = args.positions[edge_idx[1]]
600
460
  return v1 - v0
601
461
 
602
462
  @wp.func
603
- def side_normal(args: SideArg, s: Sample):
604
- edge_idx = args.topology.edge_vertex_indices[s.element_index]
605
- v0 = args.positions[edge_idx[0]]
606
- v1 = args.positions[edge_idx[1]]
607
- e = v1 - v0
463
+ def side_closest_point(args: Any, side_index: ElementIndex, pos: Any):
464
+ edge_idx = args.topology.edge_vertex_indices[side_index]
465
+ p0 = args.positions[edge_idx[0]]
466
+
467
+ q = pos - p0
468
+ e = args.positions[edge_idx[1]] - p0
608
469
 
609
- return wp.normalize(wp.vec2(-e[1], e[0]))
470
+ dist, t = project_on_seg_at_origin(q, e, wp.lengh_sq(e))
471
+ return Coords(t, 0.0, 0.0), dist
610
472
 
611
473
  @wp.func
612
- def side_inner_cell_index(arg: SideArg, side_index: ElementIndex):
474
+ def side_inner_cell_index(arg: Any, side_index: ElementIndex):
613
475
  return arg.topology.edge_tri_indices[side_index][0]
614
476
 
615
477
  @wp.func
616
- def side_outer_cell_index(arg: SideArg, side_index: ElementIndex):
478
+ def side_outer_cell_index(arg: Any, side_index: ElementIndex):
617
479
  return arg.topology.edge_tri_indices[side_index][1]
618
480
 
619
481
  @wp.func
620
- def side_inner_cell_coords(args: SideArg, side_index: ElementIndex, side_coords: Coords):
621
- inner_cell_index = Trimesh2D.side_inner_cell_index(args, side_index)
482
+ def side_inner_cell_coords(args: Any, side_index: ElementIndex, side_coords: Coords):
483
+ inner_cell_index = Trimesh.side_inner_cell_index(args, side_index)
622
484
  return Trimesh._edge_to_tri_coords(args.topology, side_index, inner_cell_index, side_coords)
623
485
 
624
486
  @wp.func
625
- def side_outer_cell_coords(args: SideArg, side_index: ElementIndex, side_coords: Coords):
626
- outer_cell_index = Trimesh2D.side_outer_cell_index(args, side_index)
487
+ def side_outer_cell_coords(args: Any, side_index: ElementIndex, side_coords: Coords):
488
+ outer_cell_index = Trimesh.side_outer_cell_index(args, side_index)
627
489
  return Trimesh._edge_to_tri_coords(args.topology, side_index, outer_cell_index, side_coords)
628
490
 
629
491
  @wp.func
630
492
  def side_from_cell_coords(
631
- args: SideArg,
493
+ args: Any,
632
494
  side_index: ElementIndex,
633
495
  tri_index: ElementIndex,
634
496
  tri_coords: Coords,
635
497
  ):
636
498
  return Trimesh._tri_to_edge_coords(args.topology, side_index, tri_index, tri_coords)
637
499
 
500
+
501
+ @wp.struct
502
+ class Trimesh2DCellArg:
503
+ topology: TrimeshCellArg
504
+ positions: wp.array(dtype=wp.vec2)
505
+
506
+
507
+ @wp.struct
508
+ class Trimesh2DSideArg:
509
+ topology: TrimeshSideArg
510
+ positions: wp.array(dtype=wp.vec2)
511
+
512
+
513
+ class Trimesh2D(Trimesh):
514
+ """2D Triangular mesh geometry"""
515
+
516
+ dimension = 2
517
+ CellArg = Trimesh2DCellArg
518
+ SideArg = Trimesh2DSideArg
519
+
638
520
  @wp.func
639
521
  def side_to_cell_arg(side_arg: SideArg):
640
522
  return Trimesh2DCellArg(side_arg.topology.cell_arg, side_arg.positions)
@@ -660,7 +542,7 @@ class Trimesh2D(Trimesh):
660
542
 
661
543
  edge_center = 0.5 * (v1 + v0)
662
544
  edge_vec = v1 - v0
663
- edge_normal = wp.vec2(-edge_vec[1], edge_vec[0])
545
+ edge_normal = Geometry._element_normal(edge_vec)
664
546
 
665
547
  # if edge normal points toward first triangle centroid, flip indices
666
548
  if wp.dot(tri_centroid - edge_center, edge_normal) > 0.0:
@@ -686,81 +568,6 @@ class Trimesh3D(Trimesh):
686
568
  CellArg = Trimesh3DCellArg
687
569
  SideArg = Trimesh3DSideArg
688
570
 
689
- @wp.func
690
- def cell_position(args: CellArg, s: Sample):
691
- tri_idx = args.topology.tri_vertex_indices[s.element_index]
692
- return (
693
- s.element_coords[0] * args.positions[tri_idx[0]]
694
- + s.element_coords[1] * args.positions[tri_idx[1]]
695
- + s.element_coords[2] * args.positions[tri_idx[2]]
696
- )
697
-
698
- @wp.func
699
- def cell_deformation_gradient(args: CellArg, s: Sample):
700
- tri_idx = args.topology.tri_vertex_indices[s.element_index]
701
- p0 = args.positions[tri_idx[0]]
702
- p1 = args.positions[tri_idx[1]]
703
- p2 = args.positions[tri_idx[2]]
704
- return wp.matrix_from_cols(p1 - p0, p2 - p0)
705
-
706
- @wp.func
707
- def cell_lookup(args: CellArg, pos: wp.vec3):
708
- closest_dist, closest_tri, closest_coords = Trimesh._bvh_lookup(args.topology, args.positions, pos)
709
-
710
- return make_free_sample(closest_tri, closest_coords)
711
-
712
- @wp.func
713
- def cell_lookup(args: CellArg, pos: wp.vec3, guess: Sample):
714
- closest_dist, closest_tri, closest_coords = Trimesh._bvh_lookup(args.topology, args.positions, pos)
715
-
716
- if closest_tri == NULL_ELEMENT_INDEX:
717
- closest_dist, closest_tri, closest_coords = Trimesh._cell_neighbor_lookup(
718
- args.topology, args.positions, pos, guess.element_index
719
- )
720
-
721
- return make_free_sample(closest_tri, closest_coords)
722
-
723
- @wp.func
724
- def side_position(args: SideArg, s: Sample):
725
- edge_idx = args.topology.edge_vertex_indices[s.element_index]
726
- return (1.0 - s.element_coords[0]) * args.positions[edge_idx[0]] + s.element_coords[0] * args.positions[
727
- edge_idx[1]
728
- ]
729
-
730
- @wp.func
731
- def side_deformation_gradient(args: SideArg, s: Sample):
732
- edge_idx = args.topology.edge_vertex_indices[s.element_index]
733
- v0 = args.positions[edge_idx[0]]
734
- v1 = args.positions[edge_idx[1]]
735
- return v1 - v0
736
-
737
- @wp.func
738
- def side_inner_cell_index(arg: SideArg, side_index: ElementIndex):
739
- return arg.topology.edge_tri_indices[side_index][0]
740
-
741
- @wp.func
742
- def side_outer_cell_index(arg: SideArg, side_index: ElementIndex):
743
- return arg.topology.edge_tri_indices[side_index][1]
744
-
745
- @wp.func
746
- def side_inner_cell_coords(args: SideArg, side_index: ElementIndex, side_coords: Coords):
747
- inner_cell_index = Trimesh3D.side_inner_cell_index(args, side_index)
748
- return Trimesh._edge_to_tri_coords(args.topology, side_index, inner_cell_index, side_coords)
749
-
750
- @wp.func
751
- def side_outer_cell_coords(args: SideArg, side_index: ElementIndex, side_coords: Coords):
752
- outer_cell_index = Trimesh3D.side_outer_cell_index(args, side_index)
753
- return Trimesh._edge_to_tri_coords(args.topology, side_index, outer_cell_index, side_coords)
754
-
755
- @wp.func
756
- def side_from_cell_coords(
757
- args: SideArg,
758
- side_index: ElementIndex,
759
- tri_index: ElementIndex,
760
- tri_coords: Coords,
761
- ):
762
- return Trimesh._tri_to_edge_coords(args.topology, side_index, tri_index, tri_coords)
763
-
764
571
  @wp.func
765
572
  def side_to_cell_arg(side_arg: SideArg):
766
573
  return Trimesh3DCellArg(side_arg.topology.cell_arg, side_arg.positions)