lavavu 1.9.9__tar.gz → 1.9.10__tar.gz
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.
- {lavavu-1.9.9 → lavavu-1.9.10}/Makefile +2 -1
- {lavavu-1.9.9/lavavu.egg-info → lavavu-1.9.10}/PKG-INFO +3 -2
- {lavavu-1.9.9 → lavavu-1.9.10}/README.md +1 -1
- {lavavu-1.9.9 → lavavu-1.9.10}/lavavu/LavaVuPython.py +5 -3
- {lavavu-1.9.9 → lavavu-1.9.10}/lavavu/html/webview.html +1 -1
- {lavavu-1.9.9 → lavavu-1.9.10}/lavavu/lavavu.py +94 -41
- {lavavu-1.9.9 → lavavu-1.9.10}/lavavu/tracers.py +19 -24
- {lavavu-1.9.9 → lavavu-1.9.10/lavavu.egg-info}/PKG-INFO +3 -2
- {lavavu-1.9.9 → lavavu-1.9.10}/lavavu.egg-info/SOURCES.txt +0 -1
- {lavavu-1.9.9 → lavavu-1.9.10}/lavavu.egg-info/requires.txt +1 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/requirements.txt +1 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/setup.py +2 -2
- {lavavu-1.9.9 → lavavu-1.9.10}/src/LavaVuPython_wrap.cxx +142 -139
- {lavavu-1.9.9 → lavavu-1.9.10}/src/OpenGLViewer.cpp +4 -8
- {lavavu-1.9.9 → lavavu-1.9.10}/src/OpenGLViewer.h +1 -0
- lavavu-1.9.10/src/version.cpp +2 -0
- lavavu-1.9.9/lavavu/osmesa/LavaVuPython.py +0 -561
- lavavu-1.9.9/src/version.cpp +0 -2
- {lavavu-1.9.9 → lavavu-1.9.10}/LICENSE.md +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/MANIFEST.in +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/lavavu/__init__.py +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/lavavu/__main__.py +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/lavavu/amalgamate.py +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/lavavu/aserver.py +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/lavavu/control.py +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/lavavu/convert.py +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/lavavu/dict.json +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/lavavu/font.bin +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/lavavu/html/LavaVu-amalgamated.css +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/lavavu/html/OK-min.js +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/lavavu/html/baseviewer.js +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/lavavu/html/control.css +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/lavavu/html/control.js +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/lavavu/html/dat-gui-light-theme.css +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/lavavu/html/dat.gui.min.js +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/lavavu/html/draw.js +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/lavavu/html/drawbox.js +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/lavavu/html/emscripten-template.js +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/lavavu/html/emscripten.css +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/lavavu/html/favicon.ico +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/lavavu/html/gl-matrix-min.js +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/lavavu/html/gui.css +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/lavavu/html/menu.js +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/lavavu/html/server.js +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/lavavu/html/stats.min.js +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/lavavu/html/styles.css +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/lavavu/html/webview-template.html +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/lavavu/osmesa/__init__.py +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/lavavu/points.py +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/lavavu/server.py +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/lavavu/shaders/default.frag +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/lavavu/shaders/default.vert +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/lavavu/shaders/fontShader.frag +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/lavavu/shaders/fontShader.vert +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/lavavu/shaders/lineShader.frag +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/lavavu/shaders/lineShader.vert +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/lavavu/shaders/pointShader.frag +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/lavavu/shaders/pointShader.vert +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/lavavu/shaders/triShader.frag +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/lavavu/shaders/triShader.vert +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/lavavu/shaders/volumeShader.frag +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/lavavu/shaders/volumeShader.vert +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/lavavu/vutils.py +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/lavavu.egg-info/dependency_links.txt +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/lavavu.egg-info/entry_points.txt +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/lavavu.egg-info/top_level.txt +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/pyproject.toml +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/setup.cfg +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/ApplicationInterface.h +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/ColourMap.cpp +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/ColourMap.h +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/Colours.cpp +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/Colours.h +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/Contour.cpp +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/Contour.h +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/DrawingObject.cpp +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/DrawingObject.h +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/Extensions.cpp +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/Extensions.h +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/FontLine.h +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/FontSans.h +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/GLUtils.cpp +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/GLUtils.h +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/Geometry.cpp +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/Geometry.h +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/GraphicsUtil.cpp +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/GraphicsUtil.h +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/Include.h +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/InputInterface.h +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/InteractiveViewer.cpp +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/IsoSurface.cpp +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/IsoSurface.h +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/LavaVu.cpp +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/LavaVu.h +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/Lines.cpp +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/LinesSorted.cpp +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/Links.cpp +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/Main/CGLViewer.cpp +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/Main/CGLViewer.h +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/Main/CocoaViewer.h +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/Main/CocoaViewer.mm +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/Main/EGLViewer.cpp +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/Main/EGLViewer.h +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/Main/GLFWViewer.cpp +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/Main/GLFWViewer.h +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/Main/OSMesaViewer.cpp +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/Main/OSMesaViewer.h +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/Main/X11Viewer.cpp +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/Main/X11Viewer.h +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/Main/main.cpp +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/Model.cpp +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/Model.h +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/OutputInterface.h +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/Points.cpp +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/QuadSurfaces.cpp +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/RenderContext.cpp +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/RenderContext.h +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/Session.cpp +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/Session.h +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/Shaders.cpp +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/Shaders.h +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/Shapes.cpp +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/TimeStep.h +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/Tracers.cpp +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/TriSurfaces.cpp +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/Triangles.cpp +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/Util.cpp +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/Util.h +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/Vectors.cpp +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/VideoEncoder.cpp +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/VideoEncoder.h +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/View.cpp +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/View.h +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/ViewerApp.h +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/ViewerTypes.h +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/Volumes.cpp +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/base64.cpp +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/base64.h +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/fifo_map.hpp +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/jpeg/jpgd.cpp +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/jpeg/jpgd.h +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/jpeg/jpge.cpp +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/jpeg/jpge.h +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/json.hpp +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/linalg.h +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/miniz/miniz.c +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/miniz/miniz.h +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/png/lodepng.cpp +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/png/lodepng.h +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/sqlite3/sqlite3.c +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/sqlite3/sqlite3.h +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/stb_image_resize.h +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/tiny_obj_loader.h +0 -0
- {lavavu-1.9.9 → lavavu-1.9.10}/src/version.h +0 -0
@@ -256,8 +256,9 @@ endif
|
|
256
256
|
|
257
257
|
.PHONY: swig
|
258
258
|
swig : $(INC) src/LavaVuPython.i | paths
|
259
|
+
#NOTE: bug in swig requires pip install swig==4.2 until fixed
|
259
260
|
swig -v -Wextra -python -py3 -ignoremissing -O -c++ -DSWIG_DO_NOT_WRAP -outdir $(PREFIX) src/LavaVuPython.i
|
260
|
-
cd $(PREFIX)/osmesa;
|
261
|
+
cd $(PREFIX)/osmesa; touch __init__.py
|
261
262
|
|
262
263
|
$(SWIGLIB) : $(LIBRARY) $(SWIGOBJ)
|
263
264
|
-rm -f $(PREFIX)/_LavaVuPython.*
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: lavavu
|
3
|
-
Version: 1.9.
|
3
|
+
Version: 1.9.10
|
4
4
|
Summary: Python interface to LavaVu OpenGL 3D scientific visualisation utilities
|
5
5
|
Author-email: Owen Kaluza <owen@kaluza.id.au>
|
6
6
|
License: ### Licensing
|
@@ -217,6 +217,7 @@ Requires-Dist: aiohttp
|
|
217
217
|
Requires-Dist: jupyter_server_proxy
|
218
218
|
Requires-Dist: matplotlib
|
219
219
|
Requires-Dist: numpy-quaternion
|
220
|
+
Requires-Dist: pillow
|
220
221
|
Dynamic: license-file
|
221
222
|
|
222
223
|

|
@@ -224,7 +225,7 @@ Dynamic: license-file
|
|
224
225
|
[](https://github.com/lavavu/LavaVu/actions?query=workflow:Test)
|
225
226
|
[](https://github.com/lavavu/LavaVu/actions?query=workflow:Deploy)
|
226
227
|
[](https://zenodo.org/badge/latestdoi/45163055)
|
227
|
-
[](https://mybinder.org/v2/gh/lavavu/LavaVu/1.9.
|
228
|
+
[](https://mybinder.org/v2/gh/lavavu/LavaVu/1.9.10)
|
228
229
|
|
229
230
|
A scientific visualisation tool with a python interface for fast and flexible visual analysis.
|
230
231
|
|
@@ -3,7 +3,7 @@
|
|
3
3
|
[](https://github.com/lavavu/LavaVu/actions?query=workflow:Test)
|
4
4
|
[](https://github.com/lavavu/LavaVu/actions?query=workflow:Deploy)
|
5
5
|
[](https://zenodo.org/badge/latestdoi/45163055)
|
6
|
-
[](https://mybinder.org/v2/gh/lavavu/LavaVu/1.9.
|
6
|
+
[](https://mybinder.org/v2/gh/lavavu/LavaVu/1.9.10)
|
7
7
|
|
8
8
|
A scientific visualisation tool with a python interface for fast and flexible visual analysis.
|
9
9
|
|
@@ -5,12 +5,14 @@
|
|
5
5
|
# the SWIG interface file instead.
|
6
6
|
|
7
7
|
from sys import version_info as _swig_python_version_info
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
|
9
|
+
import os
|
10
|
+
if 'osmesa' in os.environ.get('LV_CONTEXT', ''):
|
11
|
+
from osmesa import _LavaVuPython
|
11
12
|
else:
|
12
13
|
import _LavaVuPython
|
13
14
|
|
15
|
+
|
14
16
|
try:
|
15
17
|
import builtins as __builtin__
|
16
18
|
except ImportError:
|
@@ -27,7 +27,7 @@
|
|
27
27
|
|
28
28
|
<input id="fileinput" type="file" style="visibility:hidden" onchange="useFileInput(this)" />
|
29
29
|
|
30
|
-
<script async src="https://cdn.jsdelivr.net/gh/lavavu/lavavu.github.io@1.9.
|
30
|
+
<script async src="https://cdn.jsdelivr.net/gh/lavavu/lavavu.github.io@1.9.10/LavaVu-amalgamated.min.js"></script>
|
31
31
|
<!--script src="dat.gui.min.js"></script>
|
32
32
|
<script src="OK-min.js"></script>
|
33
33
|
|
@@ -59,6 +59,7 @@ import quaternion as quat
|
|
59
59
|
import platform
|
60
60
|
import matplotlib
|
61
61
|
from pathlib import Path
|
62
|
+
from PIL import Image as PILImage
|
62
63
|
|
63
64
|
if sys.version_info[0] < 3:
|
64
65
|
print("Python 3 required. LavaVu no longer supports Python 2.7.")
|
@@ -101,10 +102,7 @@ if platform.system() == 'Linux':
|
|
101
102
|
context = 'moderngl'
|
102
103
|
except Exception as e:
|
103
104
|
context = 'osmesa'
|
104
|
-
|
105
|
-
if context == 'osmesa':
|
106
|
-
#OSMesa fallback, CPU only, multicore
|
107
|
-
from osmesa import LavaVuPython
|
105
|
+
os.environ['LV_CONTEXT'] = context
|
108
106
|
|
109
107
|
#Default module if none already loaded
|
110
108
|
try:
|
@@ -112,8 +110,6 @@ try:
|
|
112
110
|
except:
|
113
111
|
import LavaVuPython
|
114
112
|
|
115
|
-
os.environ['LV_CONTEXT'] = context
|
116
|
-
|
117
113
|
version = LavaVuPython.version
|
118
114
|
server_ports = []
|
119
115
|
|
@@ -4194,7 +4190,7 @@ class Viewer(dict):
|
|
4194
4190
|
from IPython.display import display,HTML,Javascript
|
4195
4191
|
display(Javascript(js + code))
|
4196
4192
|
|
4197
|
-
def video(self, filename="", resolution=(0,0), fps=30, quality=2, encoder=
|
4193
|
+
def video(self, filename="", resolution=(0,0), fps=30, quality=2, encoder=None, embed=False, player=None, options={}, **kwargs):
|
4198
4194
|
"""
|
4199
4195
|
Record and show the generated video inline within an ipython notebook.
|
4200
4196
|
|
@@ -4220,7 +4216,7 @@ class Viewer(dict):
|
|
4220
4216
|
encoding artifacts at cost of larger file size
|
4221
4217
|
If omitted will use default settings, can fine tune settings in kwargs
|
4222
4218
|
encoder : str
|
4223
|
-
Name of encoder to use, eg: "h264" (default),
|
4219
|
+
Name of encoder to use, eg: "h264" (default for .mp4), default will be selected based on filename extension
|
4224
4220
|
embed : bool
|
4225
4221
|
Set to true to embed the video file rather than link to url
|
4226
4222
|
Not recommended for large videos, default is False
|
@@ -4240,8 +4236,7 @@ class Viewer(dict):
|
|
4240
4236
|
"""
|
4241
4237
|
return Video(self, filename, resolution, fps, quality, encoder, embed, player, options, **kwargs)
|
4242
4238
|
|
4243
|
-
def video_steps(self, filename="", start=0, end=0, resolution=(0,0), fps=30, quality=2, encoder=
|
4244
|
-
my_func.__doc__
|
4239
|
+
def video_steps(self, filename="", start=0, end=0, resolution=(0,0), fps=30, quality=2, encoder=None, embed=False, player=None, options={}, **kwargs):
|
4245
4240
|
"""
|
4246
4241
|
Record a video of the model by looping through all time steps
|
4247
4242
|
|
@@ -5479,7 +5474,7 @@ class Video(object):
|
|
5479
5474
|
... lv.rotate('y', 10) # doctest: +SKIP
|
5480
5475
|
... lv.render() # doctest: +SKIP
|
5481
5476
|
"""
|
5482
|
-
def __init__(self, viewer, filename="output.mp4", resolution=(0,0), framerate=30, quality=2, encoder=
|
5477
|
+
def __init__(self, viewer, filename="output.mp4", resolution=(0,0), framerate=30, quality=2, encoder=None, embed=False, player=None, options={}, **kwargs):
|
5483
5478
|
"""
|
5484
5479
|
Record and show the generated video inline within an ipython notebook.
|
5485
5480
|
|
@@ -5505,7 +5500,7 @@ class Video(object):
|
|
5505
5500
|
resolution : list or tuple
|
5506
5501
|
Video resolution in pixels [x,y]
|
5507
5502
|
encoder : str
|
5508
|
-
Name of encoder to use, eg: "h264" (default),
|
5503
|
+
Name of encoder to use, eg: "h264" (default for .mp4), default will be selected based on filename extension
|
5509
5504
|
embed : bool
|
5510
5505
|
Set to true to embed the video file rather than link to url
|
5511
5506
|
Not recommended for large videos, default is False
|
@@ -5555,6 +5550,22 @@ class Video(object):
|
|
5555
5550
|
self.player = {}
|
5556
5551
|
if embed:
|
5557
5552
|
self.player["embed"] = True
|
5553
|
+
if encoder is None:
|
5554
|
+
if self.filename.suffix.lower() == '.mp4':
|
5555
|
+
encoder = 'h264'
|
5556
|
+
elif self.filename.suffix.lower() == '.webm':
|
5557
|
+
encoder = 'libvpx-vp9'
|
5558
|
+
elif self.filename.suffix.lower() == '.webp':
|
5559
|
+
encoder = 'libwebp_anim'
|
5560
|
+
options["lossless"] = "1"
|
5561
|
+
options['pix_fmt'] = "rgb32" #Required for lossless
|
5562
|
+
options["loop"] = "0" #This doesn't work, quality also has no effect
|
5563
|
+
options["quality"] = str(min(30 + self.quality * 20, 100))
|
5564
|
+
elif self.filename.suffix.lower() == '.gif':
|
5565
|
+
encoder = 'gif'
|
5566
|
+
options['pix_fmt'] = "rgb8"
|
5567
|
+
else:
|
5568
|
+
encoder = 'h264'
|
5558
5569
|
self.encoder = encoder
|
5559
5570
|
self.options = options
|
5560
5571
|
#Also include extra args
|
@@ -5565,7 +5576,6 @@ class Video(object):
|
|
5565
5576
|
"""
|
5566
5577
|
Start recording, all rendered frames will be added to the video
|
5567
5578
|
"""
|
5568
|
-
#https://trac.ffmpeg.org/wiki/Encode/H.264
|
5569
5579
|
# The range of the CRF scale is 0–51, where 0 is lossless (for 8 bit only, for 10 bit use -qp 0),
|
5570
5580
|
# 23 is the default, and 51 is worst quality possible
|
5571
5581
|
#Compression level, lower = high quality
|
@@ -5578,7 +5588,8 @@ class Video(object):
|
|
5578
5588
|
return
|
5579
5589
|
|
5580
5590
|
if self.encoder == 'h264' or self.encoder == 'libx265':
|
5581
|
-
#
|
5591
|
+
#https://trac.ffmpeg.org/wiki/Encode/H.264
|
5592
|
+
#options['pix_fmt'] = "yuv420"
|
5582
5593
|
if self.quality == 1:
|
5583
5594
|
options['qmin'] = '30' #'20' #'8'
|
5584
5595
|
options['qmax'] = '35' #'41'
|
@@ -5596,21 +5607,26 @@ class Video(object):
|
|
5596
5607
|
options["preset"] = 'veryfast' #'veryfast' 'medium' 'slow'
|
5597
5608
|
options["tune"] = 'animation' #'film'
|
5598
5609
|
|
5599
|
-
|
5600
|
-
#
|
5601
|
-
|
5602
|
-
|
5603
|
-
|
5610
|
+
elif self.encoder == 'libvpx-vp9':
|
5611
|
+
#https://trac.ffmpeg.org/wiki/Encode/VP9
|
5612
|
+
options['crf'] = '15'
|
5613
|
+
options['b:v'] = '0' #Required for constant quality single pass
|
5614
|
+
if self.quality == 1:
|
5615
|
+
options['crf'] = '30' #'40'
|
5616
|
+
elif self.quality == 2:
|
5617
|
+
options['crf'] = '20' #'23'
|
5618
|
+
elif self.quality == 3:
|
5619
|
+
options['crf'] = '10' #'10'
|
5620
|
+
#options['pix_fmt'] = "yuv444p"
|
5604
5621
|
|
5605
5622
|
#Merge user options, allowing override of above settings
|
5606
5623
|
options.update(self.options)
|
5624
|
+
#print(options, self.encoder)
|
5607
5625
|
|
5608
|
-
#print(options)
|
5609
5626
|
self.container = av.open(str(self.filename), mode="w")
|
5610
5627
|
self.stream = self.container.add_stream(self.encoder, rate=self.framerate, options=options)
|
5611
5628
|
self.stream.width = self.resolution[0]
|
5612
5629
|
self.stream.height = self.resolution[1]
|
5613
|
-
self.stream.pix_fmt = "yuv420p"
|
5614
5630
|
self.viewer.recording = self
|
5615
5631
|
|
5616
5632
|
stream = self.stream
|
@@ -5620,14 +5636,52 @@ class Video(object):
|
|
5620
5636
|
#print(stream.profiles)
|
5621
5637
|
#print(stream.profile)
|
5622
5638
|
#print(stream.options)
|
5639
|
+
|
5640
|
+
if 'pix_fmt' in options:
|
5641
|
+
self.stream.pix_fmt = options['pix_fmt']
|
5642
|
+
#Select higher quality colour where supported
|
5643
|
+
elif self.encoder == 'h264' or self.encoder == 'libx265' or self.encoder == 'libvpx-vp9':
|
5644
|
+
#Reduce chroma subsampling for better colour output
|
5645
|
+
if self.quality < 3:
|
5646
|
+
self.stream.pix_fmt = "yuv420p"
|
5647
|
+
else:
|
5648
|
+
self.stream.pix_fmt = "yuv422p"
|
5649
|
+
#10 bit formats
|
5650
|
+
#self.stream.pix_fmt = "yuv444p10le"
|
5651
|
+
#self.stream.pix_fmt = "yuv422p10le"
|
5652
|
+
|
5623
5653
|
#Need to set profile here or it isn't applied
|
5624
|
-
#(
|
5625
|
-
|
5654
|
+
#(better chroma sampling requires the correct profile)
|
5655
|
+
if 'profile' in options:
|
5656
|
+
stream.profile = options['profile']
|
5657
|
+
elif self.encoder == 'h264' or self.encoder == 'libx265':
|
5658
|
+
#['Baseline', 'Constrained Baseline', 'Main', 'Extended',
|
5659
|
+
# 'High', 'High 10', 'High 10 Intra', 'High 4:2:2',
|
5660
|
+
# 'High 4:2:2 Intra', 'High 4:4:4', 'High 4:4:4 Predictive',
|
5661
|
+
# 'High 4:4:4 Intra', 'CAVLC 4:4:4', 'Multiview High', 'Stereo High']
|
5662
|
+
#stream.profile = 'High 4:4:4'
|
5663
|
+
if self.stream.pix_fmt == 'yuv420p':
|
5664
|
+
stream.profile = 'Main'
|
5665
|
+
elif 'yuv422' in self.stream.pix_fmt:
|
5666
|
+
stream.profile = 'High 4:2:2'
|
5667
|
+
elif 'yuv444' in self.stream.pix_fmt:
|
5668
|
+
stream.profile = 'High 4:4:4'
|
5669
|
+
elif self.encoder == 'libvpx-vp9':
|
5670
|
+
#Profile Color Depth Chroma Subsampling
|
5671
|
+
#0 8 bit/sample 4:2:0
|
5672
|
+
#1 8 bit 4:2:2,4:4:4
|
5673
|
+
#2 10 or 12 bit 4:2:0
|
5674
|
+
#3 10 or 12 bit 4:2:2, 4:4:4
|
5675
|
+
if self.stream.pix_fmt == 'yuv420p':
|
5676
|
+
stream.profile = 'Profile 0'
|
5677
|
+
elif 'yuv422' in self.stream.pix_fmt or 'yuv444' in self.stream.pix_fmt:
|
5678
|
+
stream.profile = 'Profile 1'
|
5679
|
+
|
5626
5680
|
cc = stream.codec_context
|
5627
5681
|
#print(cc.options)
|
5628
|
-
#print(cc.profile)
|
5682
|
+
#print(cc.profile, stream.pix_fmt)
|
5629
5683
|
|
5630
|
-
def frame(self):
|
5684
|
+
def frame(self, img=None):
|
5631
5685
|
"""
|
5632
5686
|
Write a frame, called when viewer.render() is called
|
5633
5687
|
while a recording is in progress
|
@@ -5639,10 +5693,17 @@ class Video(object):
|
|
5639
5693
|
else:
|
5640
5694
|
fn = self.filename / f"{self.framecount:06}_{self.basename}.{self.encoder}"
|
5641
5695
|
self.framecount += 1
|
5642
|
-
|
5696
|
+
if img:
|
5697
|
+
image = PILImage.fromarray(img)
|
5698
|
+
image.save(fn)
|
5699
|
+
image.save(fn, subsampling=0, quality=95)
|
5700
|
+
else:
|
5701
|
+
self.viewer.image(str(fn), resolution=self.resolution)
|
5643
5702
|
else:
|
5644
|
-
img
|
5645
|
-
|
5703
|
+
if img is None:
|
5704
|
+
img = self.viewer.rawimage(resolution=self.resolution, channels=3).data
|
5705
|
+
frame = av.VideoFrame.from_ndarray(img, format="rgb24")
|
5706
|
+
#frame = av.VideoFrame.from_image(PILImage.fromarray(img)) #, format="rgb24")
|
5646
5707
|
for packet in self.stream.encode(frame):
|
5647
5708
|
self.container.mux(packet)
|
5648
5709
|
|
@@ -5697,23 +5758,16 @@ class Video(object):
|
|
5697
5758
|
image = image.reshape(self.resolution[0], self.resolution[1], 4)
|
5698
5759
|
image = image[::,::,:3] #Remove alpha channel
|
5699
5760
|
|
5700
|
-
|
5701
|
-
from PIL import Image as PILImage
|
5702
|
-
img = PILImage.fromarray(image)
|
5703
|
-
fn = self.filename / f"{self.framecount:06}_{self.basename}.{self.encoder}"
|
5704
|
-
self.framecount += 1
|
5705
|
-
img.save(fn)
|
5706
|
-
return
|
5707
|
-
|
5708
|
-
frame = av.VideoFrame.from_ndarray(image, format="rgb24")
|
5709
|
-
for packet in self.stream.encode(frame):
|
5710
|
-
self.container.mux(packet)
|
5761
|
+
self.frame(image)
|
5711
5762
|
|
5712
5763
|
def play(self):
|
5713
5764
|
"""
|
5714
5765
|
Show the video in an inline player if in an interactive notebook
|
5715
5766
|
"""
|
5716
|
-
if self.encoder == '
|
5767
|
+
if self.encoder == 'gif' or self.encoder == 'libwebp_anim':
|
5768
|
+
from IPython.display import display,Image
|
5769
|
+
display(Image(self.filename, **self.player))
|
5770
|
+
elif self.encoder == 'jpg' or self.encoder == 'png':
|
5717
5771
|
from IPython.display import display,HTML
|
5718
5772
|
display(HTML('<p>Video written to images, no player available</p>'))
|
5719
5773
|
else:
|
@@ -5841,7 +5895,6 @@ class Image(object):
|
|
5841
5895
|
"""
|
5842
5896
|
try:
|
5843
5897
|
#Get array from PIL images
|
5844
|
-
from PIL import Image as PILImage
|
5845
5898
|
if isinstance(source, PILImage.Image):
|
5846
5899
|
source = numpy.array(source)
|
5847
5900
|
except (ImportError) as e:
|
@@ -24,7 +24,7 @@ def random_particles(count, lowerbound=[0,0,0], upperbound=[1,1,1], dims=3):
|
|
24
24
|
return numpy.stack(p).T
|
25
25
|
|
26
26
|
class Tracers():
|
27
|
-
def __init__(self, grid, count=1000, lowerbound=None, upperbound=None, limit=
|
27
|
+
def __init__(self, grid, count=1000, lowerbound=None, upperbound=None, limit=0, age=4, respawn_chance=0.2, speed_multiply=1.0, height=0.0, label='', viewer=None, seed=0):
|
28
28
|
"""
|
29
29
|
Seed random particles into a vector field and trace their positions
|
30
30
|
|
@@ -40,10 +40,7 @@ class Tracers():
|
|
40
40
|
upperbound : optional maximum vertex point defining particle bounding box,
|
41
41
|
if not provided will be taken from grid upper corner
|
42
42
|
limit : float
|
43
|
-
Distance limit over which tracers are not
|
44
|
-
For example if using a periodic boundary, setting limit to
|
45
|
-
half the bounding box size will prevent tracer lines being
|
46
|
-
connected when passing through the boundary
|
43
|
+
Distance limit over which tracers are not drawn
|
47
44
|
age : int
|
48
45
|
Minimum particle age in steps after which particle can be deleted and respawned, defaults to 4
|
49
46
|
respawn : float
|
@@ -56,6 +53,9 @@ class Tracers():
|
|
56
53
|
Name label prefix for the visualisation objects when plotting
|
57
54
|
viewer : lavavu.Viewer
|
58
55
|
Viewer object for plotting functions
|
56
|
+
seed : int
|
57
|
+
Random seed for deterministic random particle positions, default=0, set to None to use
|
58
|
+
system time which will produce non-deterministic results (different each run)
|
59
59
|
"""
|
60
60
|
if len(grid) == 2:
|
61
61
|
self.gridx = grid[0]
|
@@ -108,20 +108,18 @@ class Tracers():
|
|
108
108
|
self.arrows = None
|
109
109
|
self.tracers = None
|
110
110
|
|
111
|
+
if seed is not None:
|
112
|
+
random.seed(seed)
|
111
113
|
|
112
114
|
def respawn(self, r):
|
113
115
|
#Dead or out of bounds particle, start at new position
|
114
116
|
#Loop until new position further from current position than limit
|
115
117
|
old_pos = self.positions[r]
|
116
118
|
pos = numpy.array([0.] * self.dims)
|
117
|
-
|
118
|
-
pos = random_particles(1, self.lowerbound, self.upperbound, self.dims)
|
119
|
-
dist = numpy.linalg.norm(old_pos - pos)
|
120
|
-
if dist > self.limit*1.01:
|
121
|
-
break
|
122
|
-
|
119
|
+
pos = random_particles(1, self.lowerbound, self.upperbound, self.dims)
|
123
120
|
self.ages[r] = 0
|
124
121
|
self.positions[r] = pos
|
122
|
+
self.velocities[r] = numpy.array([0.0] * self.dims)
|
125
123
|
|
126
124
|
def update(self, vectors=None):
|
127
125
|
#Interpolate velocity at all positions,
|
@@ -140,24 +138,21 @@ class Tracers():
|
|
140
138
|
|
141
139
|
for r in range(len(self.velocities)):
|
142
140
|
#Lookup velocity at this index, multiply by position to get delta and add
|
143
|
-
self.
|
144
|
-
if numpy.isnan(self.speed[r]): self.speed[r] = 0.0
|
145
|
-
if self.speed[r] == 0.0: #numpy.any(numpy.isinf(self.old_pos[r])) or numpy.any(numpy.isinf(self.positions[r])):
|
141
|
+
if self.ages[r] < 0:
|
146
142
|
self.respawn(r)
|
147
143
|
else:
|
144
|
+
self.speed[r] = numpy.linalg.norm(self.velocities[r])
|
145
|
+
if numpy.isnan(self.speed[r]) or numpy.isinf(self.speed[r]): self.speed[r] = 0.0
|
148
146
|
self.positions[r] = self.positions[r] + self.speed_multiply * self.velocities[r]
|
149
147
|
self.ages[r] += 1
|
150
148
|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
self.respawn(r)
|
159
|
-
self.velocities[r] = numpy.array([0.0] * self.dims)
|
160
|
-
self.speed[r] = 0.0
|
149
|
+
#Bounds checks
|
150
|
+
#Chance of killing particle when over age, default 1 in 5 (0.2)
|
151
|
+
if (any(self.positions[r] < self.lowerbound[0:self.dims]) or any(self.positions[r] > self.upperbound[0:self.dims])
|
152
|
+
or (self.ages[r] > self.age and numpy.random.uniform() <= self.respawn_chance)):
|
153
|
+
self.positions[r] = numpy.array([numpy.nan] * self.dims)
|
154
|
+
self.ages[r] = -1
|
155
|
+
self.velocities[r] = numpy.array([0.0] * self.dims)
|
161
156
|
|
162
157
|
if self.lv:
|
163
158
|
positions = self.get_positions()
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: lavavu
|
3
|
-
Version: 1.9.
|
3
|
+
Version: 1.9.10
|
4
4
|
Summary: Python interface to LavaVu OpenGL 3D scientific visualisation utilities
|
5
5
|
Author-email: Owen Kaluza <owen@kaluza.id.au>
|
6
6
|
License: ### Licensing
|
@@ -217,6 +217,7 @@ Requires-Dist: aiohttp
|
|
217
217
|
Requires-Dist: jupyter_server_proxy
|
218
218
|
Requires-Dist: matplotlib
|
219
219
|
Requires-Dist: numpy-quaternion
|
220
|
+
Requires-Dist: pillow
|
220
221
|
Dynamic: license-file
|
221
222
|
|
222
223
|

|
@@ -224,7 +225,7 @@ Dynamic: license-file
|
|
224
225
|
[](https://github.com/lavavu/LavaVu/actions?query=workflow:Test)
|
225
226
|
[](https://github.com/lavavu/LavaVu/actions?query=workflow:Deploy)
|
226
227
|
[](https://zenodo.org/badge/latestdoi/45163055)
|
227
|
-
[](https://mybinder.org/v2/gh/lavavu/LavaVu/1.9.
|
228
|
+
[](https://mybinder.org/v2/gh/lavavu/LavaVu/1.9.10)
|
228
229
|
|
229
230
|
A scientific visualisation tool with a python interface for fast and flexible visual analysis.
|
230
231
|
|
@@ -19,7 +19,7 @@ import shutil
|
|
19
19
|
|
20
20
|
#Current version
|
21
21
|
#(must be of the form X.Y.Z to trigger wheel builds)
|
22
|
-
version = "1.9.
|
22
|
+
version = "1.9.10"
|
23
23
|
|
24
24
|
"""
|
25
25
|
To release a new verison:
|
@@ -368,7 +368,7 @@ if __name__ == "__main__":
|
|
368
368
|
defines += [('HAVE_LIBTIFF', 1)]
|
369
369
|
libs += ['tiff']
|
370
370
|
|
371
|
-
if (find_library('avcodec') and find_library('avformat') and find_library('avutil')
|
371
|
+
if ("LV_VIDEO" in os.environ and find_library('avcodec') and find_library('avformat') and find_library('avutil')
|
372
372
|
and check_libraries(['avcodec', 'avformat', 'avutil'],
|
373
373
|
['libavformat/avformat.h', 'libavcodec/avcodec.h', 'libavutil/mathematics.h',
|
374
374
|
'libavutil/imgutils.h'])):
|