warp-lang 1.8.1__py3-none-win_amd64.whl → 1.9.0__py3-none-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of warp-lang might be problematic. Click here for more details.
- warp/__init__.py +282 -103
- warp/__init__.pyi +482 -110
- warp/bin/warp-clang.dll +0 -0
- warp/bin/warp.dll +0 -0
- warp/build.py +93 -30
- warp/build_dll.py +47 -67
- warp/builtins.py +955 -137
- warp/codegen.py +312 -206
- warp/config.py +1 -1
- warp/context.py +1249 -784
- warp/examples/core/example_marching_cubes.py +1 -0
- warp/examples/core/example_render_opengl.py +100 -3
- warp/examples/fem/example_apic_fluid.py +98 -52
- warp/examples/fem/example_convection_diffusion_dg.py +25 -4
- warp/examples/fem/example_diffusion_mgpu.py +8 -3
- warp/examples/fem/utils.py +68 -22
- warp/fabric.py +1 -1
- warp/fem/cache.py +27 -19
- warp/fem/domain.py +2 -2
- warp/fem/field/nodal_field.py +2 -2
- warp/fem/field/virtual.py +264 -166
- warp/fem/geometry/geometry.py +5 -5
- warp/fem/integrate.py +129 -51
- warp/fem/space/restriction.py +4 -0
- warp/fem/space/shape/tet_shape_function.py +3 -10
- warp/jax_experimental/custom_call.py +1 -1
- warp/jax_experimental/ffi.py +2 -1
- warp/marching_cubes.py +708 -0
- warp/native/array.h +99 -4
- warp/native/builtin.h +82 -5
- warp/native/bvh.cpp +64 -28
- warp/native/bvh.cu +58 -58
- warp/native/bvh.h +2 -2
- warp/native/clang/clang.cpp +7 -7
- warp/native/coloring.cpp +8 -2
- warp/native/crt.cpp +2 -2
- warp/native/crt.h +3 -5
- warp/native/cuda_util.cpp +41 -10
- warp/native/cuda_util.h +10 -4
- warp/native/exports.h +1842 -1908
- warp/native/fabric.h +2 -1
- warp/native/hashgrid.cpp +37 -37
- warp/native/hashgrid.cu +2 -2
- warp/native/initializer_array.h +1 -1
- warp/native/intersect.h +2 -2
- warp/native/mat.h +1910 -116
- warp/native/mathdx.cpp +43 -43
- warp/native/mesh.cpp +24 -24
- warp/native/mesh.cu +26 -26
- warp/native/mesh.h +4 -2
- warp/native/nanovdb/GridHandle.h +179 -12
- warp/native/nanovdb/HostBuffer.h +8 -7
- warp/native/nanovdb/NanoVDB.h +517 -895
- warp/native/nanovdb/NodeManager.h +323 -0
- warp/native/nanovdb/PNanoVDB.h +2 -2
- warp/native/quat.h +331 -14
- warp/native/range.h +7 -1
- warp/native/reduce.cpp +10 -10
- warp/native/reduce.cu +13 -14
- warp/native/runlength_encode.cpp +2 -2
- warp/native/runlength_encode.cu +5 -5
- warp/native/scan.cpp +3 -3
- warp/native/scan.cu +4 -4
- warp/native/sort.cpp +10 -10
- warp/native/sort.cu +22 -22
- warp/native/sparse.cpp +8 -8
- warp/native/sparse.cu +13 -13
- warp/native/spatial.h +366 -17
- warp/native/temp_buffer.h +2 -2
- warp/native/tile.h +283 -69
- warp/native/vec.h +381 -14
- warp/native/volume.cpp +54 -54
- warp/native/volume.cu +1 -1
- warp/native/volume.h +2 -1
- warp/native/volume_builder.cu +30 -37
- warp/native/warp.cpp +150 -149
- warp/native/warp.cu +323 -192
- warp/native/warp.h +227 -226
- warp/optim/linear.py +736 -271
- warp/render/imgui_manager.py +289 -0
- warp/render/render_opengl.py +85 -6
- warp/sim/graph_coloring.py +2 -2
- warp/sparse.py +558 -175
- warp/tests/aux_test_module_aot.py +7 -0
- warp/tests/cuda/test_async.py +3 -3
- warp/tests/cuda/test_conditional_captures.py +101 -0
- warp/tests/geometry/test_marching_cubes.py +233 -12
- warp/tests/sim/test_coloring.py +6 -6
- warp/tests/test_array.py +56 -5
- warp/tests/test_codegen.py +3 -2
- warp/tests/test_context.py +8 -15
- warp/tests/test_enum.py +136 -0
- warp/tests/test_examples.py +2 -2
- warp/tests/test_fem.py +45 -2
- warp/tests/test_fixedarray.py +229 -0
- warp/tests/test_func.py +18 -15
- warp/tests/test_future_annotations.py +7 -5
- warp/tests/test_linear_solvers.py +30 -0
- warp/tests/test_map.py +1 -1
- warp/tests/test_mat.py +1518 -378
- warp/tests/test_mat_assign_copy.py +178 -0
- warp/tests/test_mat_constructors.py +574 -0
- warp/tests/test_module_aot.py +287 -0
- warp/tests/test_print.py +69 -0
- warp/tests/test_quat.py +140 -34
- warp/tests/test_quat_assign_copy.py +145 -0
- warp/tests/test_reload.py +2 -1
- warp/tests/test_sparse.py +71 -0
- warp/tests/test_spatial.py +140 -34
- warp/tests/test_spatial_assign_copy.py +160 -0
- warp/tests/test_struct.py +43 -3
- warp/tests/test_types.py +0 -20
- warp/tests/test_vec.py +179 -34
- warp/tests/test_vec_assign_copy.py +143 -0
- warp/tests/tile/test_tile.py +184 -18
- warp/tests/tile/test_tile_cholesky.py +605 -0
- warp/tests/tile/test_tile_load.py +169 -0
- warp/tests/tile/test_tile_mathdx.py +2 -558
- warp/tests/tile/test_tile_matmul.py +1 -1
- warp/tests/tile/test_tile_mlp.py +1 -1
- warp/tests/tile/test_tile_shared_memory.py +5 -5
- warp/tests/unittest_suites.py +6 -0
- warp/tests/walkthrough_debug.py +1 -1
- warp/thirdparty/unittest_parallel.py +108 -9
- warp/types.py +554 -264
- warp/utils.py +68 -86
- {warp_lang-1.8.1.dist-info → warp_lang-1.9.0.dist-info}/METADATA +28 -65
- {warp_lang-1.8.1.dist-info → warp_lang-1.9.0.dist-info}/RECORD +131 -121
- warp/native/marching.cpp +0 -19
- warp/native/marching.cu +0 -514
- warp/native/marching.h +0 -19
- {warp_lang-1.8.1.dist-info → warp_lang-1.9.0.dist-info}/WHEEL +0 -0
- {warp_lang-1.8.1.dist-info → warp_lang-1.9.0.dist-info}/licenses/LICENSE.md +0 -0
- {warp_lang-1.8.1.dist-info → warp_lang-1.9.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2025 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 __future__ import annotations
|
|
17
|
+
|
|
18
|
+
import warp as wp
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class ImGuiManager:
|
|
22
|
+
"""Base class for managing an ImGui UI."""
|
|
23
|
+
|
|
24
|
+
def __init__(self, renderer):
|
|
25
|
+
try:
|
|
26
|
+
import imgui
|
|
27
|
+
from imgui.integrations.pyglet import PygletProgrammablePipelineRenderer
|
|
28
|
+
|
|
29
|
+
self.imgui = imgui
|
|
30
|
+
self.is_available = True
|
|
31
|
+
except ImportError:
|
|
32
|
+
self.is_available = False
|
|
33
|
+
print('Warning: imgui not found. To use the UI, please install it with: pip install "imgui[pyglet]"')
|
|
34
|
+
return
|
|
35
|
+
|
|
36
|
+
self.imgui.create_context()
|
|
37
|
+
self.renderer = renderer
|
|
38
|
+
self.impl = PygletProgrammablePipelineRenderer(self.renderer.window)
|
|
39
|
+
|
|
40
|
+
def render_frame(self):
|
|
41
|
+
"""Renders a single frame of the UI. This should be called from the main render loop."""
|
|
42
|
+
if not self.is_available:
|
|
43
|
+
return
|
|
44
|
+
|
|
45
|
+
io = self.imgui.get_io()
|
|
46
|
+
self.renderer.enable_mouse_interaction = not io.want_capture_mouse
|
|
47
|
+
self.renderer.enable_keyboard_interaction = not io.want_capture_keyboard
|
|
48
|
+
io.display_size = self.renderer.screen_width, self.renderer.screen_height
|
|
49
|
+
|
|
50
|
+
self.imgui.new_frame()
|
|
51
|
+
|
|
52
|
+
self.draw_ui()
|
|
53
|
+
|
|
54
|
+
self.imgui.render()
|
|
55
|
+
self.imgui.end_frame()
|
|
56
|
+
self.impl.render(self.imgui.get_draw_data())
|
|
57
|
+
|
|
58
|
+
def draw_ui(self):
|
|
59
|
+
"""Draws the UI. To be implemented by subclasses."""
|
|
60
|
+
pass
|
|
61
|
+
|
|
62
|
+
def open_save_file_dialog(
|
|
63
|
+
self,
|
|
64
|
+
title: str = "Save File",
|
|
65
|
+
defaultextension: str = "",
|
|
66
|
+
filetypes: list[tuple[str, str]] | None = None,
|
|
67
|
+
) -> str | None:
|
|
68
|
+
"""Opens a file dialog for saving a file and returns the selected path."""
|
|
69
|
+
try:
|
|
70
|
+
import tkinter as tk
|
|
71
|
+
from tkinter import filedialog
|
|
72
|
+
except ImportError:
|
|
73
|
+
print("Warning: tkinter not found. To use the file dialog, please install it.")
|
|
74
|
+
return None
|
|
75
|
+
|
|
76
|
+
try:
|
|
77
|
+
root = tk.Tk()
|
|
78
|
+
except tk.TclError:
|
|
79
|
+
print("Warning: no display found - cannot open file dialog.")
|
|
80
|
+
return None
|
|
81
|
+
|
|
82
|
+
root.withdraw() # Hide the main window
|
|
83
|
+
file_path = filedialog.asksaveasfilename(
|
|
84
|
+
defaultextension=defaultextension,
|
|
85
|
+
filetypes=filetypes or [("All Files", "*.*")],
|
|
86
|
+
title=title,
|
|
87
|
+
)
|
|
88
|
+
root.destroy()
|
|
89
|
+
return file_path
|
|
90
|
+
|
|
91
|
+
def open_load_file_dialog(
|
|
92
|
+
self, title: str = "Open File", filetypes: list[tuple[str, str]] | None = None
|
|
93
|
+
) -> str | None:
|
|
94
|
+
"""Opens a file dialog for loading a file and returns the selected path."""
|
|
95
|
+
try:
|
|
96
|
+
import tkinter as tk
|
|
97
|
+
from tkinter import filedialog
|
|
98
|
+
except ImportError:
|
|
99
|
+
print("Warning: tkinter not found. To use the file dialog, please install it.")
|
|
100
|
+
return None
|
|
101
|
+
|
|
102
|
+
try:
|
|
103
|
+
root = tk.Tk()
|
|
104
|
+
except tk.TclError:
|
|
105
|
+
print("Warning: no display found - cannot open file dialog.")
|
|
106
|
+
return None
|
|
107
|
+
|
|
108
|
+
root.withdraw() # Hide the main window
|
|
109
|
+
file_path = filedialog.askopenfilename(
|
|
110
|
+
filetypes=filetypes or [("All Files", "*.*")],
|
|
111
|
+
title=title,
|
|
112
|
+
)
|
|
113
|
+
root.destroy()
|
|
114
|
+
return file_path
|
|
115
|
+
|
|
116
|
+
def drag_vec3(self, label, vec, speed=0.1, min_val=0.0, max_val=100.0):
|
|
117
|
+
"""Helper method to create a drag widget for a wp.vec3"""
|
|
118
|
+
changed, *values = self.imgui.drag_float3(label, *vec, speed, min_val, max_val)
|
|
119
|
+
if changed:
|
|
120
|
+
vec = wp.vec3(*values)
|
|
121
|
+
return changed, vec
|
|
122
|
+
|
|
123
|
+
def drag_vec3_list(
|
|
124
|
+
self,
|
|
125
|
+
label_prefix: str,
|
|
126
|
+
vec_list: list[wp.vec3] | wp.array,
|
|
127
|
+
speed: float = 0.1,
|
|
128
|
+
min_val: float = 0.0,
|
|
129
|
+
max_val: float = 100.0,
|
|
130
|
+
max_num_elements: int = 10,
|
|
131
|
+
) -> tuple[bool, list[wp.vec3] | wp.array]:
|
|
132
|
+
"""Helper method to create drag widgets for a list of wp.vec3.
|
|
133
|
+
|
|
134
|
+
Note: The `label_prefix` is used to create unique IDs for each widget.
|
|
135
|
+
If you are displaying multiple lists, ensure that `label_prefix` is unique
|
|
136
|
+
for each list to prevent UI elements from interfering with each other.
|
|
137
|
+
"""
|
|
138
|
+
self.imgui.text(f"List: {label_prefix} with {len(vec_list)} elements")
|
|
139
|
+
changed = False
|
|
140
|
+
|
|
141
|
+
# Convert to numpy array if it's a warp array
|
|
142
|
+
is_warp_array = isinstance(vec_list, wp.array)
|
|
143
|
+
working_array = vec_list.numpy() if is_warp_array else vec_list
|
|
144
|
+
|
|
145
|
+
for i, vec in enumerate(working_array[:max_num_elements]):
|
|
146
|
+
vec_changed, new_vec = self.drag_vec3(f"{label_prefix} {i}", vec, speed, min_val, max_val)
|
|
147
|
+
if vec_changed:
|
|
148
|
+
working_array[i] = new_vec
|
|
149
|
+
changed = True
|
|
150
|
+
|
|
151
|
+
if is_warp_array:
|
|
152
|
+
if changed:
|
|
153
|
+
return changed, wp.array(working_array, dtype=wp.vec3)
|
|
154
|
+
return changed, vec_list
|
|
155
|
+
return changed, working_array
|
|
156
|
+
|
|
157
|
+
def drag_vec2(
|
|
158
|
+
self, label: str, vec: wp.vec2, speed: float = 0.1, min_val: float = 0.0, max_val: float = 100.0
|
|
159
|
+
) -> tuple[bool, wp.vec2]:
|
|
160
|
+
"""Helper method to create a drag widget for a wp.vec2"""
|
|
161
|
+
changed, *values = self.imgui.drag_float2(label, *vec, speed, min_val, max_val)
|
|
162
|
+
if changed:
|
|
163
|
+
vec = wp.vec2(*values)
|
|
164
|
+
return changed, vec
|
|
165
|
+
|
|
166
|
+
def drag_vec2_list(
|
|
167
|
+
self,
|
|
168
|
+
label_prefix: str,
|
|
169
|
+
vec_list: list[wp.vec2] | wp.array,
|
|
170
|
+
speed: float = 0.1,
|
|
171
|
+
min_val: float = 0.0,
|
|
172
|
+
max_val: float = 100.0,
|
|
173
|
+
max_num_elements: int = 10,
|
|
174
|
+
) -> tuple[bool, list[wp.vec2] | wp.array]:
|
|
175
|
+
"""Helper method to create drag widgets for a list of wp.vec2.
|
|
176
|
+
|
|
177
|
+
Note: The `label_prefix` is used to create unique IDs for each widget.
|
|
178
|
+
If you are displaying multiple lists, ensure that `label_prefix` is unique
|
|
179
|
+
for each list to prevent UI elements from interfering with each other.
|
|
180
|
+
"""
|
|
181
|
+
self.imgui.text(f"List: {label_prefix} with {len(vec_list)} elements")
|
|
182
|
+
changed = False
|
|
183
|
+
|
|
184
|
+
# Convert to numpy array if it's a warp array
|
|
185
|
+
is_warp_array = isinstance(vec_list, wp.array)
|
|
186
|
+
working_array = vec_list.numpy() if is_warp_array else vec_list
|
|
187
|
+
|
|
188
|
+
for i, vec in enumerate(working_array[:max_num_elements]):
|
|
189
|
+
vec_changed, new_vec = self.drag_vec2(f"{label_prefix} {i}", vec, speed, min_val, max_val)
|
|
190
|
+
if vec_changed:
|
|
191
|
+
working_array[i] = new_vec
|
|
192
|
+
changed = True
|
|
193
|
+
|
|
194
|
+
if is_warp_array:
|
|
195
|
+
if changed:
|
|
196
|
+
return changed, wp.array(working_array, dtype=wp.vec2)
|
|
197
|
+
return changed, vec_list
|
|
198
|
+
return changed, working_array
|
|
199
|
+
|
|
200
|
+
def drag_vec4(
|
|
201
|
+
self, label: str, vec: wp.vec4, speed: float = 0.1, min_val: float = 0.0, max_val: float = 100.0
|
|
202
|
+
) -> tuple[bool, wp.vec4]:
|
|
203
|
+
"""Helper method to create a drag widget for a wp.vec4"""
|
|
204
|
+
changed, *values = self.imgui.drag_float4(label, *vec, speed, min_val, max_val)
|
|
205
|
+
if changed:
|
|
206
|
+
vec = wp.vec4(*values)
|
|
207
|
+
return changed, vec
|
|
208
|
+
|
|
209
|
+
def drag_vec4_list(
|
|
210
|
+
self,
|
|
211
|
+
label_prefix: str,
|
|
212
|
+
vec_list: list[wp.vec4] | wp.array,
|
|
213
|
+
speed: float = 0.1,
|
|
214
|
+
min_val: float = 0.0,
|
|
215
|
+
max_val: float = 100.0,
|
|
216
|
+
max_num_elements: int = 10,
|
|
217
|
+
) -> tuple[bool, list[wp.vec4] | wp.array]:
|
|
218
|
+
"""Helper method to create drag widgets for a list of wp.vec4.
|
|
219
|
+
|
|
220
|
+
Note: The `label_prefix` is used to create unique IDs for each widget.
|
|
221
|
+
If you are displaying multiple lists, ensure that `label_prefix` is unique
|
|
222
|
+
for each list to prevent UI elements from interfering with each other.
|
|
223
|
+
"""
|
|
224
|
+
self.imgui.text(f"List: {label_prefix} with {len(vec_list)} elements")
|
|
225
|
+
changed = False
|
|
226
|
+
|
|
227
|
+
# Convert to numpy array if it's a warp array
|
|
228
|
+
is_warp_array = isinstance(vec_list, wp.array)
|
|
229
|
+
working_array = vec_list.numpy() if is_warp_array else vec_list
|
|
230
|
+
|
|
231
|
+
for i, vec in enumerate(working_array[:max_num_elements]):
|
|
232
|
+
vec_changed, new_vec = self.drag_vec4(f"{label_prefix} {i}", vec, speed, min_val, max_val)
|
|
233
|
+
if vec_changed:
|
|
234
|
+
working_array[i] = new_vec
|
|
235
|
+
changed = True
|
|
236
|
+
|
|
237
|
+
if is_warp_array:
|
|
238
|
+
if changed:
|
|
239
|
+
return changed, wp.array(working_array, dtype=wp.vec4)
|
|
240
|
+
return changed, vec_list
|
|
241
|
+
return changed, working_array
|
|
242
|
+
|
|
243
|
+
def drag_float(
|
|
244
|
+
self, label: str, val: float, speed: float = 0.1, min_val: float = 0.0, max_val: float = 100.0
|
|
245
|
+
) -> tuple[bool, float]:
|
|
246
|
+
"""Helper method to create a drag widget for a float"""
|
|
247
|
+
changed, value = self.imgui.drag_float(label, val, speed, min_val, max_val)
|
|
248
|
+
if changed:
|
|
249
|
+
val = value
|
|
250
|
+
return changed, val
|
|
251
|
+
|
|
252
|
+
def drag_float_list(
|
|
253
|
+
self,
|
|
254
|
+
label_prefix: str,
|
|
255
|
+
float_list: list[float] | wp.array,
|
|
256
|
+
speed: float = 0.1,
|
|
257
|
+
min_val: float = 0.0,
|
|
258
|
+
max_val: float = 100.0,
|
|
259
|
+
max_num_elements: int = 10,
|
|
260
|
+
) -> tuple[bool, list[float] | wp.array]:
|
|
261
|
+
"""Helper method to create drag widgets for a list of floats.
|
|
262
|
+
|
|
263
|
+
Note: The `label_prefix` is used to create unique IDs for each widget.
|
|
264
|
+
If you are displaying multiple lists, ensure that `label_prefix` is unique
|
|
265
|
+
for each list to prevent UI elements from interfering with each other.
|
|
266
|
+
"""
|
|
267
|
+
self.imgui.text(f"List: {label_prefix} with {len(float_list)} elements")
|
|
268
|
+
changed = False
|
|
269
|
+
|
|
270
|
+
# Convert to numpy array if it's a warp array
|
|
271
|
+
is_warp_array = isinstance(float_list, wp.array)
|
|
272
|
+
working_array = float_list.numpy() if is_warp_array else float_list
|
|
273
|
+
|
|
274
|
+
for i, val in enumerate(working_array[:max_num_elements]):
|
|
275
|
+
val_changed, new_val = self.drag_float(f"{label_prefix} {i}", val, speed, min_val, max_val)
|
|
276
|
+
if val_changed:
|
|
277
|
+
working_array[i] = new_val
|
|
278
|
+
changed = True
|
|
279
|
+
|
|
280
|
+
if is_warp_array:
|
|
281
|
+
if changed:
|
|
282
|
+
return changed, wp.array(working_array, dtype=float_list.dtype)
|
|
283
|
+
return changed, float_list
|
|
284
|
+
return changed, working_array
|
|
285
|
+
|
|
286
|
+
def shutdown(self):
|
|
287
|
+
if not self.is_available:
|
|
288
|
+
return
|
|
289
|
+
self.impl.shutdown()
|
warp/render/render_opengl.py
CHANGED
|
@@ -998,6 +998,7 @@ class OpenGLRenderer:
|
|
|
998
998
|
enable_mouse_interaction=True,
|
|
999
999
|
enable_keyboard_interaction=True,
|
|
1000
1000
|
device=None,
|
|
1001
|
+
use_legacy_opengl: bool | None = None,
|
|
1001
1002
|
):
|
|
1002
1003
|
"""
|
|
1003
1004
|
Args:
|
|
@@ -1028,6 +1029,7 @@ class OpenGLRenderer:
|
|
|
1028
1029
|
enable_mouse_interaction (bool): Whether to enable mouse interaction.
|
|
1029
1030
|
enable_keyboard_interaction (bool): Whether to enable keyboard interaction.
|
|
1030
1031
|
device (Devicelike): Where to store the internal data.
|
|
1032
|
+
use_legacy_opengl (bool | None): Whether to use a legacy OpenGL implementation that is more compatible with macOS. If ``None``, it will be automatically detected based on the operating system.
|
|
1031
1033
|
|
|
1032
1034
|
Note:
|
|
1033
1035
|
|
|
@@ -1073,6 +1075,11 @@ class OpenGLRenderer:
|
|
|
1073
1075
|
self.render_depth = render_depth
|
|
1074
1076
|
self.enable_backface_culling = enable_backface_culling
|
|
1075
1077
|
|
|
1078
|
+
if use_legacy_opengl is None:
|
|
1079
|
+
self.use_legacy_opengl = sys.platform == "darwin"
|
|
1080
|
+
else:
|
|
1081
|
+
self.use_legacy_opengl = use_legacy_opengl
|
|
1082
|
+
|
|
1076
1083
|
if device is None:
|
|
1077
1084
|
self._device = wp.get_preferred_device()
|
|
1078
1085
|
else:
|
|
@@ -1162,6 +1169,8 @@ class OpenGLRenderer:
|
|
|
1162
1169
|
self._wp_instance_bodies = None
|
|
1163
1170
|
self._update_shape_instances = False
|
|
1164
1171
|
self._add_shape_instances = False
|
|
1172
|
+
self.instance_matrix_size = 0
|
|
1173
|
+
self.instance_color_size = 0
|
|
1165
1174
|
|
|
1166
1175
|
# additional shape instancer used for points and line rendering
|
|
1167
1176
|
self._shape_instancers = {}
|
|
@@ -2051,9 +2060,43 @@ Instances: {len(self._instances)}"""
|
|
|
2051
2060
|
num_instances = len(self._shape_instances[shape])
|
|
2052
2061
|
|
|
2053
2062
|
gl.glBindVertexArray(vao)
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2063
|
+
if self.use_legacy_opengl:
|
|
2064
|
+
if self.instance_matrix_size > 0 and self.instance_color_size:
|
|
2065
|
+
# update attribute pointers
|
|
2066
|
+
matrix_size = self.instance_matrix_size
|
|
2067
|
+
color_size = self.instance_color_size
|
|
2068
|
+
|
|
2069
|
+
# update transforms
|
|
2070
|
+
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._instance_transform_gl_buffer)
|
|
2071
|
+
for i in range(4):
|
|
2072
|
+
gl.glVertexAttribPointer(
|
|
2073
|
+
3 + i,
|
|
2074
|
+
4,
|
|
2075
|
+
gl.GL_FLOAT,
|
|
2076
|
+
gl.GL_FALSE,
|
|
2077
|
+
matrix_size,
|
|
2078
|
+
ctypes.c_void_p(start_instance_idx * matrix_size + i * matrix_size // 4),
|
|
2079
|
+
)
|
|
2080
|
+
gl.glVertexAttribDivisor(3 + i, 1)
|
|
2081
|
+
|
|
2082
|
+
# update colors
|
|
2083
|
+
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._instance_color1_buffer)
|
|
2084
|
+
gl.glVertexAttribPointer(
|
|
2085
|
+
7, 3, gl.GL_FLOAT, gl.GL_FALSE, color_size, ctypes.c_void_p(start_instance_idx * color_size)
|
|
2086
|
+
)
|
|
2087
|
+
gl.glVertexAttribDivisor(7, 1)
|
|
2088
|
+
|
|
2089
|
+
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._instance_color2_buffer)
|
|
2090
|
+
gl.glVertexAttribPointer(
|
|
2091
|
+
8, 3, gl.GL_FLOAT, gl.GL_FALSE, color_size, ctypes.c_void_p(start_instance_idx * color_size)
|
|
2092
|
+
)
|
|
2093
|
+
gl.glVertexAttribDivisor(8, 1)
|
|
2094
|
+
|
|
2095
|
+
gl.glDrawElementsInstanced(gl.GL_TRIANGLES, tri_count, gl.GL_UNSIGNED_INT, None, num_instances)
|
|
2096
|
+
else:
|
|
2097
|
+
gl.glDrawElementsInstancedBaseInstance(
|
|
2098
|
+
gl.GL_TRIANGLES, tri_count, gl.GL_UNSIGNED_INT, None, num_instances, start_instance_idx
|
|
2099
|
+
)
|
|
2057
2100
|
|
|
2058
2101
|
start_instance_idx += num_instances
|
|
2059
2102
|
|
|
@@ -2103,9 +2146,43 @@ Instances: {len(self._instances)}"""
|
|
|
2103
2146
|
start_instance_idx = self._inverse_instance_ids[instance]
|
|
2104
2147
|
|
|
2105
2148
|
gl.glBindVertexArray(vao)
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2149
|
+
if self.use_legacy_opengl:
|
|
2150
|
+
if self.instance_matrix_size > 0 and self.instance_color_size:
|
|
2151
|
+
# update attribute pointers
|
|
2152
|
+
matrix_size = self.instance_matrix_size
|
|
2153
|
+
color_size = self.instance_color_size
|
|
2154
|
+
|
|
2155
|
+
# update transforms
|
|
2156
|
+
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._instance_transform_gl_buffer)
|
|
2157
|
+
for j in range(4):
|
|
2158
|
+
gl.glVertexAttribPointer(
|
|
2159
|
+
3 + j,
|
|
2160
|
+
4,
|
|
2161
|
+
gl.GL_FLOAT,
|
|
2162
|
+
gl.GL_FALSE,
|
|
2163
|
+
matrix_size,
|
|
2164
|
+
ctypes.c_void_p(start_instance_idx * matrix_size + j * matrix_size // 4),
|
|
2165
|
+
)
|
|
2166
|
+
gl.glVertexAttribDivisor(3 + j, 1)
|
|
2167
|
+
|
|
2168
|
+
# update colors
|
|
2169
|
+
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._instance_color1_buffer)
|
|
2170
|
+
gl.glVertexAttribPointer(
|
|
2171
|
+
7, 3, gl.GL_FLOAT, gl.GL_FALSE, color_size, ctypes.c_void_p(start_instance_idx * color_size)
|
|
2172
|
+
)
|
|
2173
|
+
gl.glVertexAttribDivisor(7, 1)
|
|
2174
|
+
|
|
2175
|
+
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._instance_color2_buffer)
|
|
2176
|
+
gl.glVertexAttribPointer(
|
|
2177
|
+
8, 3, gl.GL_FLOAT, gl.GL_FALSE, color_size, ctypes.c_void_p(start_instance_idx * color_size)
|
|
2178
|
+
)
|
|
2179
|
+
gl.glVertexAttribDivisor(8, 1)
|
|
2180
|
+
|
|
2181
|
+
gl.glDrawElementsInstanced(gl.GL_TRIANGLES, tri_count, gl.GL_UNSIGNED_INT, None, 1)
|
|
2182
|
+
else:
|
|
2183
|
+
gl.glDrawElementsInstancedBaseInstance(
|
|
2184
|
+
gl.GL_TRIANGLES, tri_count, gl.GL_UNSIGNED_INT, None, 1, start_instance_idx
|
|
2185
|
+
)
|
|
2109
2186
|
|
|
2110
2187
|
if self.draw_axis:
|
|
2111
2188
|
self._axis_instancer.render()
|
|
@@ -2393,6 +2470,7 @@ Instances: {len(self._instances)}"""
|
|
|
2393
2470
|
|
|
2394
2471
|
# set up instance attribute pointers
|
|
2395
2472
|
matrix_size = transforms[0].nbytes
|
|
2473
|
+
self.instance_matrix_size = matrix_size
|
|
2396
2474
|
|
|
2397
2475
|
instance_ids = []
|
|
2398
2476
|
instance_custom_ids = []
|
|
@@ -2401,6 +2479,7 @@ Instances: {len(self._instances)}"""
|
|
|
2401
2479
|
inverse_instance_ids = {}
|
|
2402
2480
|
instance_count = 0
|
|
2403
2481
|
colors_size = np.zeros(3, dtype=np.float32).nbytes
|
|
2482
|
+
self.instance_color_size = colors_size
|
|
2404
2483
|
for shape, (vao, _vbo, _ebo, _tri_count, _vertex_cuda_buffer) in self._shape_gl_buffers.items():
|
|
2405
2484
|
gl.glBindVertexArray(vao)
|
|
2406
2485
|
|
warp/sim/graph_coloring.py
CHANGED
|
@@ -234,7 +234,7 @@ def color_graph(
|
|
|
234
234
|
f"graph_edge_indices must be a 2 dimensional array! The provided one is {graph_edge_indices.ndim} dimensional."
|
|
235
235
|
)
|
|
236
236
|
|
|
237
|
-
num_colors = wp.context.runtime.core.
|
|
237
|
+
num_colors = wp.context.runtime.core.wp_graph_coloring(
|
|
238
238
|
num_nodes,
|
|
239
239
|
graph_edge_indices.__ctype__(),
|
|
240
240
|
algorithm.value,
|
|
@@ -242,7 +242,7 @@ def color_graph(
|
|
|
242
242
|
)
|
|
243
243
|
|
|
244
244
|
if balance_colors:
|
|
245
|
-
max_min_ratio = wp.context.runtime.core.
|
|
245
|
+
max_min_ratio = wp.context.runtime.core.wp_balance_coloring(
|
|
246
246
|
num_nodes,
|
|
247
247
|
graph_edge_indices.__ctype__(),
|
|
248
248
|
num_colors,
|