lavavu 1.9.5__cp313-cp313-macosx_11_0_arm64.whl → 1.9.7__cp313-cp313-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.
- lavavu/_LavaVuPython.cpython-313-darwin.so +0 -0
- lavavu/html/control.js +1 -1
- lavavu/html/menu.js +9 -4
- lavavu/html/webview.html +1 -1
- lavavu/lavavu.py +127 -61
- {lavavu-1.9.5.dist-info → lavavu-1.9.7.dist-info}/METADATA +2 -2
- {lavavu-1.9.5.dist-info → lavavu-1.9.7.dist-info}/RECORD +11 -11
- {lavavu-1.9.5.dist-info → lavavu-1.9.7.dist-info}/WHEEL +1 -1
- {lavavu-1.9.5.dist-info → lavavu-1.9.7.dist-info}/entry_points.txt +0 -0
- {lavavu-1.9.5.dist-info → lavavu-1.9.7.dist-info}/licenses/LICENSE.md +0 -0
- {lavavu-1.9.5.dist-info → lavavu-1.9.7.dist-info}/top_level.txt +0 -0
Binary file
|
lavavu/html/control.js
CHANGED
@@ -87,7 +87,7 @@ function WindowInteractor(id, uid, port) {
|
|
87
87
|
|
88
88
|
//Several possible modes to try
|
89
89
|
//Modern JupyterHub lab URL
|
90
|
-
var regex = /\/lab
|
90
|
+
var regex = /\/lab(\/|\?|$)/; //Match "/lab" at end of url or "/lab/" or "/lab?" anywhere
|
91
91
|
var parsed = regex.exec(loc.href);
|
92
92
|
if (parsed && parsed.length > 0) {
|
93
93
|
connect(loc.href.substring(0,parsed.index) + "/proxy/" + port);
|
lavavu/html/menu.js
CHANGED
@@ -123,7 +123,12 @@ function menu_addctrls(menu, obj, viewer, onchange) {
|
|
123
123
|
//Check if it has been set on the target object
|
124
124
|
if (prop in obj) {
|
125
125
|
//console.log(prop + " ==> " + JSON.stringify(viewer.dict[prop]));
|
126
|
-
|
126
|
+
try {
|
127
|
+
//Catch errors and continue gracefully
|
128
|
+
menu_addctrl(menu, obj, viewer, prop, onchange);
|
129
|
+
} catch(e) {
|
130
|
+
console.log("Error adding control to menu: " + e);
|
131
|
+
}
|
127
132
|
|
128
133
|
} else {
|
129
134
|
//Save list of properties without controls
|
@@ -159,9 +164,9 @@ function menu_addctrls(menu, obj, viewer, onchange) {
|
|
159
164
|
|
160
165
|
function menu_addcmaps(menu, obj, viewer, onchange) {
|
161
166
|
//Colourmap editing menu
|
162
|
-
if (viewer.cgui.prmenu) viewer.cgui.
|
163
|
-
if (viewer.cgui.cmenu) viewer.cgui.
|
164
|
-
if (viewer.cgui.pomenu) viewer.cgui.
|
167
|
+
if (viewer.cgui.prmenu) viewer.cgui.remove(viewer.cgui.prmenu);
|
168
|
+
if (viewer.cgui.cmenu) viewer.cgui.remove(viewer.cgui.cmenu);
|
169
|
+
if (viewer.cgui.pomenu) viewer.cgui.remove(viewer.cgui.pomenu);
|
165
170
|
viewer.cgui.prmenu = viewer.cgui.addFolder("Properties");
|
166
171
|
viewer.cgui.cmenu = viewer.cgui.addFolder("Colours");
|
167
172
|
viewer.cgui.pomenu = viewer.cgui.addFolder("Positions");
|
lavavu/html/webview.html
CHANGED
@@ -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.7/LavaVu-amalgamated.min.js"></script>
|
31
31
|
<!--script src="dat.gui.min.js"></script>
|
32
32
|
<script src="OK-min.js"></script>
|
33
33
|
|
lavavu/lavavu.py
CHANGED
@@ -23,7 +23,7 @@ __all__ = ['Viewer', 'Object', 'Properties', 'ColourMap', 'DrawData', 'Figure',
|
|
23
23
|
import os
|
24
24
|
#must be an object or won't be referenced from __init__.py import
|
25
25
|
#(enures values are passed on when set externally)
|
26
|
-
settings = {"default_args" : [], "echo_fails" : False, "quality_override" : None}
|
26
|
+
settings = {"default_args" : [], "echo_fails" : False, "quality_override" : None, "test_mode" : False}
|
27
27
|
#Default arguments for viewer creation
|
28
28
|
_val = os.environ.get('LV_ARGS')
|
29
29
|
if _val:
|
@@ -36,6 +36,10 @@ if _val:
|
|
36
36
|
_val = os.environ.get('LV_QUALITY')
|
37
37
|
if _val:
|
38
38
|
settings["quality_override"] = int(_val)
|
39
|
+
#Test mode - changes some behaviour to support automated testing
|
40
|
+
_val = os.environ.get('LV_TEST')
|
41
|
+
if _val:
|
42
|
+
settings["test_mode"] = bool(_val)
|
39
43
|
|
40
44
|
import json
|
41
45
|
import math
|
@@ -54,6 +58,7 @@ import asyncio
|
|
54
58
|
import quaternion as quat
|
55
59
|
import platform
|
56
60
|
import matplotlib
|
61
|
+
from pathlib import Path
|
57
62
|
|
58
63
|
if sys.version_info[0] < 3:
|
59
64
|
print("Python 3 required. LavaVu no longer supports Python 2.7.")
|
@@ -3562,7 +3567,6 @@ class Viewer(dict):
|
|
3562
3567
|
ll = len(self.objects.list) #Save list length before load
|
3563
3568
|
if not self.app.loadFile(filename):
|
3564
3569
|
#Support trimesh formats
|
3565
|
-
from pathlib import Path
|
3566
3570
|
path = Path(filename)
|
3567
3571
|
ext = path.suffix.lower()[1:]
|
3568
3572
|
import convert
|
@@ -3876,6 +3880,9 @@ class Viewer(dict):
|
|
3876
3880
|
"""
|
3877
3881
|
Render a new frame, explicit display update
|
3878
3882
|
"""
|
3883
|
+
if settings["test_mode"] and self.recording and self.recording.framecount != 0:
|
3884
|
+
#Skip rendering all except first and last frames when testing
|
3885
|
+
return
|
3879
3886
|
self.app.render()
|
3880
3887
|
#Video recording?
|
3881
3888
|
if self.recording:
|
@@ -4187,7 +4194,7 @@ class Viewer(dict):
|
|
4187
4194
|
from IPython.display import display,HTML,Javascript
|
4188
4195
|
display(Javascript(js + code))
|
4189
4196
|
|
4190
|
-
def video(self, filename="", resolution=(0,0), fps=30, quality=
|
4197
|
+
def video(self, filename="", resolution=(0,0), fps=30, quality=2, encoder="h264", embed=False, player=None, options={}, **kwargs):
|
4191
4198
|
"""
|
4192
4199
|
Record and show the generated video inline within an ipython notebook.
|
4193
4200
|
|
@@ -4214,6 +4221,9 @@ class Viewer(dict):
|
|
4214
4221
|
If omitted will use default settings, can fine tune settings in kwargs
|
4215
4222
|
encoder : str
|
4216
4223
|
Name of encoder to use, eg: "h264" (default), "mpeg"
|
4224
|
+
embed : bool
|
4225
|
+
Set to true to embed the video file rather than link to url
|
4226
|
+
Not recommended for large videos, default is False
|
4217
4227
|
player : dict
|
4218
4228
|
Args to pass to the player when the video is finished, eg:
|
4219
4229
|
{"width" : 800, "height", 400, "params": "controls autoplay"}
|
@@ -4228,12 +4238,11 @@ class Viewer(dict):
|
|
4228
4238
|
recorder : Video(object)
|
4229
4239
|
Context manager object that controls the video recording
|
4230
4240
|
"""
|
4231
|
-
return Video(self, filename, resolution, fps, quality, encoder, player, options, **kwargs)
|
4241
|
+
return Video(self, filename, resolution, fps, quality, encoder, embed, player, options, **kwargs)
|
4232
4242
|
|
4233
|
-
def video_steps(self, filename="", start=0, end=0, resolution=(0,0), fps=30, quality=2, encoder="h264", player=None, options={}, **kwargs):
|
4243
|
+
def video_steps(self, filename="", start=0, end=0, resolution=(0,0), fps=30, quality=2, encoder="h264", embed=False, player=None, options={}, **kwargs):
|
4244
|
+
my_func.__doc__
|
4234
4245
|
"""
|
4235
|
-
TODO: Fix to use pyAV
|
4236
|
-
|
4237
4246
|
Record a video of the model by looping through all time steps
|
4238
4247
|
|
4239
4248
|
Shows the generated video inline within an ipython notebook.
|
@@ -4245,21 +4254,12 @@ class Viewer(dict):
|
|
4245
4254
|
|
4246
4255
|
Parameters
|
4247
4256
|
----------
|
4248
|
-
filename : str
|
4249
|
-
Name of the file to save, if not provided a default will be used
|
4250
4257
|
start : int
|
4251
4258
|
First timestep to record, if not specified will use first available
|
4252
4259
|
end : int
|
4253
4260
|
Last timestep to record, if not specified will use last available
|
4254
|
-
|
4255
|
-
|
4256
|
-
fps : int
|
4257
|
-
Frames to output per second of video
|
4258
|
-
quality : int
|
4259
|
-
Encoding quality, 1=low, 2=medium(default), 3=high, higher quality reduces
|
4260
|
-
encoding artifacts at cost of larger file size
|
4261
|
-
**kwargs :
|
4262
|
-
Any additional keyword args will also be passed as options to the encoder
|
4261
|
+
|
4262
|
+
All other parameters same as video()
|
4263
4263
|
"""
|
4264
4264
|
|
4265
4265
|
try:
|
@@ -4267,7 +4267,7 @@ class Viewer(dict):
|
|
4267
4267
|
if end == 0: end = len(steps)
|
4268
4268
|
steps = steps[start:end]
|
4269
4269
|
from tqdm.notebook import tqdm
|
4270
|
-
with Video(self, filename, resolution, fps, quality, encoder, player, options, **kwargs):
|
4270
|
+
with Video(self, filename, resolution, fps, quality, encoder, embed, player, options, **kwargs):
|
4271
4271
|
for s in tqdm(steps, desc='Rendering loop'):
|
4272
4272
|
self.timestep(s)
|
4273
4273
|
self.render()
|
@@ -4312,7 +4312,7 @@ class Viewer(dict):
|
|
4312
4312
|
#This is thread safe as doesn't load texture
|
4313
4313
|
return self.app.imageFromFile(filename)
|
4314
4314
|
|
4315
|
-
def testimages(self, imagelist=None, tolerance=TOL_DEFAULT, expectedPath='expected/', outputPath='./', clear=True):
|
4315
|
+
def testimages(self, imagelist=None, tolerance=TOL_DEFAULT, expectedPath='expected/', outputPath='./', png=True, jpg=False, clear=True):
|
4316
4316
|
"""
|
4317
4317
|
Compare a list of images to expected images for testing
|
4318
4318
|
|
@@ -4327,6 +4327,10 @@ class Viewer(dict):
|
|
4327
4327
|
Where to find the expected result images (should have the same filenames as output images)
|
4328
4328
|
outputPath : str
|
4329
4329
|
Where to find the output images
|
4330
|
+
png : boolean
|
4331
|
+
Check png image outputs, defaults to True
|
4332
|
+
jpng : boolean
|
4333
|
+
Check jpg image outputs, defaults to False
|
4330
4334
|
clear : boolean
|
4331
4335
|
If the test passes the output images will be deleted, set to False to disable deletion
|
4332
4336
|
"""
|
@@ -4340,14 +4344,17 @@ class Viewer(dict):
|
|
4340
4344
|
#No expected images yet, just get images in cwd
|
4341
4345
|
#will be copied in to expected in testimage()
|
4342
4346
|
pass
|
4343
|
-
imagelist =
|
4344
|
-
|
4347
|
+
imagelist = []
|
4348
|
+
if png:
|
4349
|
+
imagelist += glob.glob("*.png")
|
4350
|
+
if jpg:
|
4351
|
+
imagelist += glob.glob("*.jpg")
|
4345
4352
|
imagelist.sort(key=os.path.getmtime)
|
4346
4353
|
os.chdir(cwd)
|
4347
4354
|
|
4348
4355
|
for f in sorted(imagelist):
|
4349
|
-
outfile = outputPath
|
4350
|
-
expfile = expectedPath
|
4356
|
+
outfile = os.path.join(outputPath, f)
|
4357
|
+
expfile = os.path.join(expectedPath, f)
|
4351
4358
|
results.append(self.testimage(expfile, outfile, tolerance, clear))
|
4352
4359
|
|
4353
4360
|
#Combined result
|
@@ -5415,37 +5422,44 @@ def player(filename, params="controls autoplay loop", **kwargs):
|
|
5415
5422
|
|
5416
5423
|
if is_notebook():
|
5417
5424
|
from IPython.display import display,HTML,Video,Javascript
|
5418
|
-
import uuid
|
5419
|
-
vid = 'video_' + str(uuid.uuid4())[:8]
|
5420
5425
|
|
5421
5426
|
# Fallback - replace url on gadi and similar jupyterhub installs with
|
5422
5427
|
# fixed working directory that doesn't match notebook dir
|
5423
5428
|
# check the video tag url and remove subpath on 404 error
|
5424
|
-
|
5425
|
-
|
5426
|
-
|
5427
|
-
|
5428
|
-
|
5429
|
-
|
5430
|
-
|
5431
|
-
|
5432
|
-
|
5433
|
-
|
5434
|
-
|
5429
|
+
onerror = """{
|
5430
|
+
let url = this.src;
|
5431
|
+
console.log('Error in video url: ' + url);
|
5432
|
+
var urlp = new window.URL(url);
|
5433
|
+
let toppath = '/files/home/';
|
5434
|
+
let startidx = urlp.pathname.indexOf(toppath);
|
5435
|
+
if (startidx < 0) {
|
5436
|
+
toppath = '/files/';
|
5437
|
+
startidx = urlp.pathname.indexOf(toppath);
|
5438
|
+
}
|
5439
|
+
if (startidx >= 0) {
|
5440
|
+
let filename = urlp.pathname.split('/').pop();
|
5441
|
+
let base = urlp.pathname.substring(0, startidx+toppath.length);
|
5442
|
+
urlp.pathname = base + filename;
|
5443
|
+
if (url != urlp.href) {
|
5444
|
+
console.log('Replaced video url: ' + urlp.href);
|
5445
|
+
this.src = urlp.href;
|
5435
5446
|
//Also fix download link
|
5436
|
-
document.getElementById('link_
|
5437
|
-
|
5438
|
-
|
5439
|
-
|
5440
|
-
}
|
5441
|
-
"""))
|
5442
|
-
|
5443
|
-
#Embed player
|
5444
|
-
filename = os.path.relpath(filename)
|
5445
|
-
display(Video(url=filename, html_attributes=f'id="{vid}" onerror="video_error(this)"' + params, **kwargs))
|
5447
|
+
let link = document.getElementById('link_' + this.id);
|
5448
|
+
if (link) link.href = urlp.href;
|
5449
|
+
}
|
5450
|
+
}
|
5451
|
+
}"""
|
5446
5452
|
|
5447
|
-
|
5448
|
-
|
5453
|
+
if "embed" in kwargs:
|
5454
|
+
#Not needed if embedding
|
5455
|
+
onerror = ""
|
5456
|
+
|
5457
|
+
#Display player and download link
|
5458
|
+
import uuid
|
5459
|
+
vid = 'video_' + str(uuid.uuid4())[:8]
|
5460
|
+
filename = os.path.relpath(filename)
|
5461
|
+
display(Video(filename=filename, html_attributes=f'id="{vid}" onerror="{onerror}" ' + params, **kwargs),
|
5462
|
+
HTML(f'<a id="link_{vid}" href="{filename}" download>Download Video</a>'))
|
5449
5463
|
|
5450
5464
|
#Class for managing video animation recording
|
5451
5465
|
class Video(object):
|
@@ -5465,7 +5479,7 @@ class Video(object):
|
|
5465
5479
|
... lv.rotate('y', 10) # doctest: +SKIP
|
5466
5480
|
... lv.render() # doctest: +SKIP
|
5467
5481
|
"""
|
5468
|
-
def __init__(self, viewer, filename="output.mp4", resolution=(0,0), framerate=30, quality=2, encoder="h264", player=None, options={}, **kwargs):
|
5482
|
+
def __init__(self, viewer, filename="output.mp4", resolution=(0,0), framerate=30, quality=2, encoder="h264", embed=False, player=None, options={}, **kwargs):
|
5469
5483
|
"""
|
5470
5484
|
Record and show the generated video inline within an ipython notebook.
|
5471
5485
|
|
@@ -5492,6 +5506,9 @@ class Video(object):
|
|
5492
5506
|
Video resolution in pixels [x,y]
|
5493
5507
|
encoder : str
|
5494
5508
|
Name of encoder to use, eg: "h264" (default), "mpeg"
|
5509
|
+
embed : bool
|
5510
|
+
Set to true to embed the video file rather than link to url
|
5511
|
+
Not recommended for large videos, default is False
|
5495
5512
|
player : dict
|
5496
5513
|
Args to pass to the player when the video is finished, eg:
|
5497
5514
|
{"width" : 800, "height", 400, "params": "controls autoplay"}
|
@@ -5501,9 +5518,6 @@ class Video(object):
|
|
5501
5518
|
**kwargs :
|
5502
5519
|
Any additional keyword args will also be passed as options to the encoder
|
5503
5520
|
"""
|
5504
|
-
if av is None:
|
5505
|
-
raise(ImportError("Video output not supported without pyAV - pip install av"))
|
5506
|
-
return
|
5507
5521
|
self.resolution = list(resolution)
|
5508
5522
|
if self.resolution[0] == 0 or self.resolution[1] == 0:
|
5509
5523
|
self.resolution = (viewer.app.viewer.width, viewer.app.viewer.height)
|
@@ -5512,7 +5526,20 @@ class Video(object):
|
|
5512
5526
|
self.framerate = framerate
|
5513
5527
|
self.quality = quality
|
5514
5528
|
self.viewer = viewer
|
5515
|
-
self.filename = filename
|
5529
|
+
self.filename = Path(filename)
|
5530
|
+
if settings["test_mode"]:
|
5531
|
+
#Force png output when testing
|
5532
|
+
encoder = 'png'
|
5533
|
+
if av is None or encoder == 'png' or encoder == 'jpg':
|
5534
|
+
if av is None:
|
5535
|
+
print("Video output not supported without pyAV - pip install av, writing image frames instead")
|
5536
|
+
self.encoder = 'png' if encoder == 'png' else 'jpg'
|
5537
|
+
p = self.filename
|
5538
|
+
self.basename = p.stem
|
5539
|
+
self.filename = p.parent / p.stem
|
5540
|
+
self.framecount = 0
|
5541
|
+
return
|
5542
|
+
|
5516
5543
|
self.player = player
|
5517
5544
|
if self.player is None:
|
5518
5545
|
#Default player is half output resolution, unless < 900 then full
|
@@ -5526,6 +5553,8 @@ class Video(object):
|
|
5526
5553
|
self.player = {"width": self.resolution[0]//2, "height": self.resolution[1]//2}
|
5527
5554
|
else:
|
5528
5555
|
self.player = {}
|
5556
|
+
if embed:
|
5557
|
+
self.player["embed"] = True
|
5529
5558
|
self.encoder = encoder
|
5530
5559
|
self.options = options
|
5531
5560
|
#Also include extra args
|
@@ -5542,6 +5571,12 @@ class Video(object):
|
|
5542
5571
|
#Compression level, lower = high quality
|
5543
5572
|
#See also: https://github.com/PyAV-Org/PyAV/blob/main/tests/test_encode.py
|
5544
5573
|
options = {}
|
5574
|
+
if self.encoder == 'jpg' or self.encoder == 'png':
|
5575
|
+
if not settings["test_mode"]:
|
5576
|
+
self.filename.mkdir(exist_ok=True)
|
5577
|
+
self.viewer.recording = self
|
5578
|
+
return
|
5579
|
+
|
5545
5580
|
if self.encoder == 'h264' or self.encoder == 'libx265':
|
5546
5581
|
#Only have default options for h264/265 for now
|
5547
5582
|
if self.quality == 1:
|
@@ -5571,7 +5606,7 @@ class Video(object):
|
|
5571
5606
|
options.update(self.options)
|
5572
5607
|
|
5573
5608
|
#print(options)
|
5574
|
-
self.container = av.open(self.filename, mode="w")
|
5609
|
+
self.container = av.open(str(self.filename), mode="w")
|
5575
5610
|
self.stream = self.container.add_stream(self.encoder, rate=self.framerate, options=options)
|
5576
5611
|
self.stream.width = self.resolution[0]
|
5577
5612
|
self.stream.height = self.resolution[1]
|
@@ -5597,10 +5632,19 @@ class Video(object):
|
|
5597
5632
|
Write a frame, called when viewer.render() is called
|
5598
5633
|
while a recording is in progress
|
5599
5634
|
"""
|
5600
|
-
|
5601
|
-
|
5602
|
-
|
5603
|
-
|
5635
|
+
if self.encoder == 'jpg' or self.encoder == 'png':
|
5636
|
+
if settings["test_mode"]:
|
5637
|
+
#Don't output in subdir
|
5638
|
+
fn = f"{self.framecount:06}_{self.basename}.{self.encoder}"
|
5639
|
+
else:
|
5640
|
+
fn = self.filename / f"{self.framecount:06}_{self.basename}.{self.encoder}"
|
5641
|
+
self.framecount += 1
|
5642
|
+
self.viewer.image(str(fn), resolution=self.resolution)
|
5643
|
+
else:
|
5644
|
+
img = self.viewer.rawimage(resolution=self.resolution, channels=3)
|
5645
|
+
frame = av.VideoFrame.from_ndarray(img.data, format="rgb24")
|
5646
|
+
for packet in self.stream.encode(frame):
|
5647
|
+
self.container.mux(packet)
|
5604
5648
|
|
5605
5649
|
def pause(self):
|
5606
5650
|
"""
|
@@ -5616,6 +5660,15 @@ class Video(object):
|
|
5616
5660
|
Stop recording, final frames will be written and file closed, ready to play.
|
5617
5661
|
No further frames will be added to the video
|
5618
5662
|
"""
|
5663
|
+
if self.encoder == 'jpg' or self.encoder == 'png':
|
5664
|
+
self.viewer.recording = None
|
5665
|
+
if settings["test_mode"]:
|
5666
|
+
#Render the last frame for tests
|
5667
|
+
self.viewer.app.render()
|
5668
|
+
fn = f"{self.framecount:06}_{self.basename}.{self.encoder}"
|
5669
|
+
self.viewer.image(str(fn), resolution=self.resolution)
|
5670
|
+
self.framecount = 0
|
5671
|
+
return
|
5619
5672
|
# Flush stream
|
5620
5673
|
for packet in self.stream.encode():
|
5621
5674
|
self.container.mux(packet)
|
@@ -5643,7 +5696,14 @@ class Video(object):
|
|
5643
5696
|
if image.size == self.resolution[0] * self.resolution[1] * 4:
|
5644
5697
|
image = image.reshape(self.resolution[0], self.resolution[1], 4)
|
5645
5698
|
image = image[::,::,:3] #Remove alpha channel
|
5646
|
-
|
5699
|
+
|
5700
|
+
if self.encoder == 'jpg' or self.encoder == 'png':
|
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
|
5647
5707
|
|
5648
5708
|
frame = av.VideoFrame.from_ndarray(image, format="rgb24")
|
5649
5709
|
for packet in self.stream.encode(frame):
|
@@ -5653,7 +5713,11 @@ class Video(object):
|
|
5653
5713
|
"""
|
5654
5714
|
Show the video in an inline player if in an interactive notebook
|
5655
5715
|
"""
|
5656
|
-
|
5716
|
+
if self.encoder == 'jpg' or self.encoder == 'png':
|
5717
|
+
from IPython.display import display,HTML
|
5718
|
+
display(HTML('<p>Video written to images, no player available</p>'))
|
5719
|
+
else:
|
5720
|
+
player(self.filename, **self.player)
|
5657
5721
|
|
5658
5722
|
def __enter__(self):
|
5659
5723
|
self.start()
|
@@ -5666,6 +5730,8 @@ class Video(object):
|
|
5666
5730
|
self.play()
|
5667
5731
|
else:
|
5668
5732
|
print('Recording failed: ', exc_value)
|
5733
|
+
import traceback
|
5734
|
+
print(traceback.format_exc())
|
5669
5735
|
return True
|
5670
5736
|
|
5671
5737
|
#Wrapper class for raw image data
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: lavavu
|
3
|
-
Version: 1.9.
|
3
|
+
Version: 1.9.7
|
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
|
@@ -224,7 +224,7 @@ Dynamic: license-file
|
|
224
224
|
[](https://github.com/lavavu/LavaVu/actions?query=workflow:Test)
|
225
225
|
[](https://github.com/lavavu/LavaVu/actions?query=workflow:Deploy)
|
226
226
|
[](https://zenodo.org/badge/latestdoi/45163055)
|
227
|
-
[](https://mybinder.org/v2/gh/lavavu/LavaVu/1.9.
|
227
|
+
[](https://mybinder.org/v2/gh/lavavu/LavaVu/1.9.7)
|
228
228
|
|
229
229
|
A scientific visualisation tool with a python interface for fast and flexible visual analysis.
|
230
230
|
|
@@ -1,10 +1,4 @@
|
|
1
|
-
lavavu
|
2
|
-
lavavu-1.9.5.dist-info/WHEEL,sha256=Cxq5pla4scSj9raD9htoFbIhfTk0lSQlQLVCyAjgIi4,136
|
3
|
-
lavavu-1.9.5.dist-info/entry_points.txt,sha256=LC2qXR6EMe45Cb7zGAF99R9HFrAECP6Qkp_YuG6HZB0,44
|
4
|
-
lavavu-1.9.5.dist-info/top_level.txt,sha256=JptS0k1nlBumjLs_0hITr3_XUJhxqvKBXD2jGho3E3A,7
|
5
|
-
lavavu-1.9.5.dist-info/METADATA,sha256=kZSwyc4jj393jf3xRoK7AM4B1x6gZaFAUNsPl6YqKdQ,17877
|
6
|
-
lavavu-1.9.5.dist-info/licenses/LICENSE.md,sha256=EhfNgC6BYh5gDEaq4tcrN3S0wbO4CtJO46botJnCF8c,8603
|
7
|
-
lavavu/lavavu.py,sha256=FX4KuzAW_-JZqG976lZUHkw-_j6Due8l2Z8W4ZBToxU,218332
|
1
|
+
lavavu/lavavu.py,sha256=v7tXwp6gQzu1F05hHyALng8FXznv4rVwdCJ3sO65O8o,221223
|
8
2
|
lavavu/vutils.py,sha256=6Vm_xl1bp9mWlfk7jgLDwbRw-tdE_oxin77YkLel3_4,5437
|
9
3
|
lavavu/dict.json,sha256=lsZEHc7Bb6_lt7tkSBQMgkq7AEn_2hnhWzzdokmvIY8,52729
|
10
4
|
lavavu/server.py,sha256=L-_yPCbNfwYxJCPjDQtr_lxPnDp4oMNVFyxXhBERYrQ,12468
|
@@ -15,12 +9,12 @@ lavavu/convert.py,sha256=tbYRjLE2l1hI4d6tsW41Lia1JXmrWSc0-JAYCiMrjys,35516
|
|
15
9
|
lavavu/control.py,sha256=s32rtLPXXYtxpeXd6-iHdupmaMTJ3KhK6Vq-CLjf9OQ,66755
|
16
10
|
lavavu/__init__.py,sha256=JroZQiUbuVN7ifixk2zNDGlyLGaM8bqfRbw4D_F9qIQ,191
|
17
11
|
lavavu/amalgamate.py,sha256=Xloq1IZ4VUvYiROzQtwKcQIWC65c7EZrdiGVhZdolL8,586
|
18
|
-
lavavu/_LavaVuPython.cpython-313-darwin.so,sha256=
|
12
|
+
lavavu/_LavaVuPython.cpython-313-darwin.so,sha256=7BX8bLplJs0YG-UIabUasfipkxPCMXkE7N9w9K_csxY,3927376
|
19
13
|
lavavu/aserver.py,sha256=SfFvLeDTcx1XtS8fY_HIrDmh3q9HicCBRSAriY5yyOE,12003
|
20
14
|
lavavu/font.bin,sha256=fvi5zkvmq6gh9v3jXedBVuxNJWKmHtbjECzv6eT9wb4,225360
|
21
15
|
lavavu/__main__.py,sha256=EbDetijCjyoiNxmExqnDGoRVs996tSVave5DML9zuMY,235
|
22
16
|
lavavu/html/control.css,sha256=PVLwmle00ciEckUV5ZIRmI3Whxhl7-mlVexnyyxoU70,3259
|
23
|
-
lavavu/html/control.js,sha256=
|
17
|
+
lavavu/html/control.js,sha256=dBjFHgDal3aixVWoQuMOt_ZyhiGSAcEUFJJx9I_ndOQ,11719
|
24
18
|
lavavu/html/gui.css,sha256=PRDLsYwM6cgLC9zZsEAG0dnnSd-HYH6oSEfsdEBkuxk,582
|
25
19
|
lavavu/html/favicon.ico,sha256=OrIWwvxOSnOCuynrGRUyEIVQng0ZwA9Rrz89S9eiog0,1150
|
26
20
|
lavavu/html/LavaVu-amalgamated.css,sha256=iE2xrxFcwmY0AcASrXxNa_RpvFEbS_YO4H5OILbPteE,8640
|
@@ -33,11 +27,11 @@ lavavu/html/dat.gui.min.js,sha256=S4_QjoXe4IOpU0f0Sj5jEQLTWPoX9uRl1ohB91jyhuw,56
|
|
33
27
|
lavavu/html/OK-min.js,sha256=-4Gc1-dWfxP_w6r9ZOHa8u-X2BlGUoSQbX68lwCxQ3E,39115
|
34
28
|
lavavu/html/emscripten.css,sha256=wkaIJhXaxuMchinQX9Z8c12cJomyvFQMeIZ62WGQEPQ,1813
|
35
29
|
lavavu/html/drawbox.js,sha256=SJxFSmWd7QVFI5__66hFkKzLKeqg1JPcx-gJuqdMkXw,34590
|
36
|
-
lavavu/html/webview.html,sha256=
|
30
|
+
lavavu/html/webview.html,sha256=Tjv9TWx1k6ovHY8xxaG_NGwHwuiDC0Hz5Npm39afHAU,1521
|
37
31
|
lavavu/html/emscripten-template.js,sha256=h63mzl3Lv7aQT1wMOiOucPOvHTJjpKkzsL-SFVYaZlA,6135
|
38
32
|
lavavu/html/draw.js,sha256=57LlHlYRh0IvWVwzGDnF6PaCxYLzokpokLNCuZlG1ds,84108
|
39
33
|
lavavu/html/dat-gui-light-theme.css,sha256=uPhvJs-1IAsdxudItyOw8lZy8Hrih0zmFM1u-xRwZ-M,1142
|
40
|
-
lavavu/html/menu.js,sha256=
|
34
|
+
lavavu/html/menu.js,sha256=42h-BCnrmEpW4IdZRKC_FIXUVczJP0sm4ciZ2ccfs-k,21630
|
41
35
|
lavavu/html/baseviewer.js,sha256=u3UhC1At6rMBKmcQ7d2DXTRxQ20wsQkc4lqA-7sL7i4,9567
|
42
36
|
lavavu/osmesa/LavaVuPython.py,sha256=ixhceiAr0gGGfCe3d2cY0IIgS4hbgoYJGa_RfgAmmrU,33207
|
43
37
|
lavavu/osmesa/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -53,3 +47,9 @@ lavavu/shaders/fontShader.vert,sha256=yCBmRugaPUeUQUdIh62-AK_5KELiJqVS2M82iyIqPw
|
|
53
47
|
lavavu/shaders/pointShader.frag,sha256=3zREBdsimlL9fAXBPjhzomGaFUWmlG_QYkhwMTVURHQ,3291
|
54
48
|
lavavu/shaders/volumeShader.vert,sha256=uGdQjGqi7V5kE6V7nxymfugtU4cbf6u570xBy13RgmY,78
|
55
49
|
lavavu/shaders/default.frag,sha256=5XLYVfLwzN0sFT3aMYGmxbyquA_cmndp55YCOuy1t4E,180
|
50
|
+
lavavu-1.9.7.dist-info/RECORD,,
|
51
|
+
lavavu-1.9.7.dist-info/WHEEL,sha256=89IgJaLF6X8hMUjC4DKLcrcADd48Z33aA8odPAkCuhg,136
|
52
|
+
lavavu-1.9.7.dist-info/entry_points.txt,sha256=LC2qXR6EMe45Cb7zGAF99R9HFrAECP6Qkp_YuG6HZB0,44
|
53
|
+
lavavu-1.9.7.dist-info/top_level.txt,sha256=JptS0k1nlBumjLs_0hITr3_XUJhxqvKBXD2jGho3E3A,7
|
54
|
+
lavavu-1.9.7.dist-info/METADATA,sha256=pDV89WKg6njzJArxsKbduk1rcj2NHSb75oV1lUtNx30,17877
|
55
|
+
lavavu-1.9.7.dist-info/licenses/LICENSE.md,sha256=EhfNgC6BYh5gDEaq4tcrN3S0wbO4CtJO46botJnCF8c,8603
|
File without changes
|
File without changes
|
File without changes
|