lavavu-osmesa 1.8.43__cp311-cp311-manylinux_2_24_x86_64.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.
Files changed (138) hide show
  1. lavavu/LavaVuPython.py +578 -0
  2. lavavu/_LavaVuPython.cpython-311-x86_64-linux-gnu.so +0 -0
  3. lavavu/__init__.py +15 -0
  4. lavavu/__main__.py +12 -0
  5. lavavu/amalgamate.py +11 -0
  6. lavavu/aserver.py +357 -0
  7. lavavu/control.py +1699 -0
  8. lavavu/convert.py +853 -0
  9. lavavu/dict.json +2485 -0
  10. lavavu/font.bin +0 -0
  11. lavavu/html/LavaVu-amalgamated.css +282 -0
  12. lavavu/html/OK-min.js +99 -0
  13. lavavu/html/baseviewer.js +307 -0
  14. lavavu/html/control.css +104 -0
  15. lavavu/html/control.js +335 -0
  16. lavavu/html/dat-gui-light-theme.css +68 -0
  17. lavavu/html/dat.gui.min.js +2 -0
  18. lavavu/html/draw.js +2259 -0
  19. lavavu/html/drawbox.js +1030 -0
  20. lavavu/html/emscripten-template.js +184 -0
  21. lavavu/html/emscripten.css +92 -0
  22. lavavu/html/favicon.ico +0 -0
  23. lavavu/html/gl-matrix-min.js +47 -0
  24. lavavu/html/gui.css +25 -0
  25. lavavu/html/menu.js +609 -0
  26. lavavu/html/server.js +226 -0
  27. lavavu/html/stats.min.js +5 -0
  28. lavavu/html/styles.css +58 -0
  29. lavavu/html/webview-template.html +43 -0
  30. lavavu/html/webview.html +43 -0
  31. lavavu/lavavu.py +5635 -0
  32. lavavu/points.py +191 -0
  33. lavavu/server.py +343 -0
  34. lavavu/shaders/default.frag +20 -0
  35. lavavu/shaders/default.vert +17 -0
  36. lavavu/shaders/fontShader.frag +25 -0
  37. lavavu/shaders/fontShader.vert +18 -0
  38. lavavu/shaders/lineShader.frag +43 -0
  39. lavavu/shaders/lineShader.vert +28 -0
  40. lavavu/shaders/pointShader.frag +132 -0
  41. lavavu/shaders/pointShader.vert +57 -0
  42. lavavu/shaders/triShader.frag +170 -0
  43. lavavu/shaders/triShader.vert +55 -0
  44. lavavu/shaders/volumeShader.frag +463 -0
  45. lavavu/shaders/volumeShader.vert +5 -0
  46. lavavu/tracers.py +124 -0
  47. lavavu/vutils.py +213 -0
  48. lavavu_osmesa-1.8.43.dist-info/LICENSE.md +179 -0
  49. lavavu_osmesa-1.8.43.dist-info/METADATA +33 -0
  50. lavavu_osmesa-1.8.43.dist-info/RECORD +138 -0
  51. lavavu_osmesa-1.8.43.dist-info/WHEEL +5 -0
  52. lavavu_osmesa-1.8.43.dist-info/entry_points.txt +3 -0
  53. lavavu_osmesa-1.8.43.dist-info/top_level.txt +1 -0
  54. lavavu_osmesa.libs/libLLVM-3-6d00db57.8.so.1 +0 -0
  55. lavavu_osmesa.libs/libOSMesa-29f606eb.so.8.0.0 +0 -0
  56. lavavu_osmesa.libs/libXau-6ab8808d.so.6.0.0 +0 -0
  57. lavavu_osmesa.libs/libXdmcp-911ecd1c.so.6.0.0 +0 -0
  58. lavavu_osmesa.libs/libXfixes-af4baa9b.so.3.1.0 +0 -0
  59. lavavu_osmesa.libs/libavcodec-10cacdd4.so.57.64.101 +0 -0
  60. lavavu_osmesa.libs/libavformat-afa92877.so.57.56.101 +0 -0
  61. lavavu_osmesa.libs/libavutil-837eb790.so.55.34.101 +0 -0
  62. lavavu_osmesa.libs/libbluray-0b5d9dbd.so.1.10.0 +0 -0
  63. lavavu_osmesa.libs/libbsd-4a4ec721.so.0.8.3 +0 -0
  64. lavavu_osmesa.libs/libbz2-9ebec8ea.so.1.0.4 +0 -0
  65. lavavu_osmesa.libs/libcairo-4217ca50.so.2.11400.8 +0 -0
  66. lavavu_osmesa.libs/libchromaprint-c4f82352.so.1.4.2 +0 -0
  67. lavavu_osmesa.libs/libcom_err-b4bd5c72.so.2.1 +0 -0
  68. lavavu_osmesa.libs/libcrystalhd-e4ea0de0.so.3.6 +0 -0
  69. lavavu_osmesa.libs/libdrm-28f5b5e7.so.2.4.0 +0 -0
  70. lavavu_osmesa.libs/libedit-7f8577df.so.2.0.55 +0 -0
  71. lavavu_osmesa.libs/libffi-1c6807d3.so.6.0.4 +0 -0
  72. lavavu_osmesa.libs/libfontconfig-e9a06300.so.1.8.0 +0 -0
  73. lavavu_osmesa.libs/libfreetype-851758a3.so.6.12.3 +0 -0
  74. lavavu_osmesa.libs/libgcrypt-0005395c.so.20.1.6 +0 -0
  75. lavavu_osmesa.libs/libglapi-cf95372b.so.0.0.0 +0 -0
  76. lavavu_osmesa.libs/libgme-5f850ce8.so.0.6.0 +0 -0
  77. lavavu_osmesa.libs/libgmp-742f5e74.so.10.3.2 +0 -0
  78. lavavu_osmesa.libs/libgnutls-1ec2cd13.so.30.13.1 +0 -0
  79. lavavu_osmesa.libs/libgomp-ce6cf6a9.so.1.0.0 +0 -0
  80. lavavu_osmesa.libs/libgpg-error-24781f22.so.0.21.0 +0 -0
  81. lavavu_osmesa.libs/libgsm-aa736f52.so.1.0.12 +0 -0
  82. lavavu_osmesa.libs/libgssapi_krb5-e296a08d.so.2.2 +0 -0
  83. lavavu_osmesa.libs/libhogweed-9d325a8d.so.4.3 +0 -0
  84. lavavu_osmesa.libs/libicudata-79cf9efa.so.57.1 +0 -0
  85. lavavu_osmesa.libs/libicui18n-03536ef3.so.57.1 +0 -0
  86. lavavu_osmesa.libs/libicuuc-5743fca1.so.57.1 +0 -0
  87. lavavu_osmesa.libs/libidn-fd653b64.so.11.6.16 +0 -0
  88. lavavu_osmesa.libs/libjbig-b30cd8bd.so.0 +0 -0
  89. lavavu_osmesa.libs/libjpeg-8afa139c.so.62.2.0 +0 -0
  90. lavavu_osmesa.libs/libk5crypto-93afd15e.so.3.1 +0 -0
  91. lavavu_osmesa.libs/libkeyutils-46318358.so.1.5 +0 -0
  92. lavavu_osmesa.libs/libkrb5-061fe33b.so.3.3 +0 -0
  93. lavavu_osmesa.libs/libkrb5support-86ac49ad.so.0.1 +0 -0
  94. lavavu_osmesa.libs/liblzma-9c0610aa.so.5.2.2 +0 -0
  95. lavavu_osmesa.libs/libmp3lame-249ae4b0.so.0.0.0 +0 -0
  96. lavavu_osmesa.libs/libmpg123-13a39b0e.so.0.42.3 +0 -0
  97. lavavu_osmesa.libs/libncurses-09dfda50.so.5.9 +0 -0
  98. lavavu_osmesa.libs/libnettle-2482db45.so.6.3 +0 -0
  99. lavavu_osmesa.libs/libnuma-c8473f23.so.1.0.0 +0 -0
  100. lavavu_osmesa.libs/libogg-b6ceea65.so.0.8.2 +0 -0
  101. lavavu_osmesa.libs/libopenjp2-a0c5d12e.so.2.1.2 +0 -0
  102. lavavu_osmesa.libs/libopenmpt-58b855da.so.0.0.20 +0 -0
  103. lavavu_osmesa.libs/libopus-37a3229e.so.0.5.3 +0 -0
  104. lavavu_osmesa.libs/libp11-kit-d06ac4a7.so.0.2.0 +0 -0
  105. lavavu_osmesa.libs/libpixman-1-7369dbb3.so.0.34.0 +0 -0
  106. lavavu_osmesa.libs/libpng16-121b9de7.so.16.28.0 +0 -0
  107. lavavu_osmesa.libs/libshine-b48eced9.so.3.0.1 +0 -0
  108. lavavu_osmesa.libs/libsnappy-1125e350.so.1.3.0 +0 -0
  109. lavavu_osmesa.libs/libsoxr-e0d4d3e4.so.0.1.1 +0 -0
  110. lavavu_osmesa.libs/libspeex-6f258c6c.so.1.5.0 +0 -0
  111. lavavu_osmesa.libs/libssh-gcrypt-90c7dd19.so.4.5.1 +0 -0
  112. lavavu_osmesa.libs/libswresample-cb1bf771.so.2.3.100 +0 -0
  113. lavavu_osmesa.libs/libswscale-876dcddb.so.4.2.100 +0 -0
  114. lavavu_osmesa.libs/libtasn1-44938221.so.6.5.3 +0 -0
  115. lavavu_osmesa.libs/libtheoradec-02a81176.so.1.1.4 +0 -0
  116. lavavu_osmesa.libs/libtheoraenc-b508ccf1.so.1.1.2 +0 -0
  117. lavavu_osmesa.libs/libtiff-e2a5092b.so.5.2.6 +0 -0
  118. lavavu_osmesa.libs/libtinfo-33626a82.so.5.9 +0 -0
  119. lavavu_osmesa.libs/libtwolame-6fcc2d32.so.0.0.0 +0 -0
  120. lavavu_osmesa.libs/libva-0f7a824e.so.1.3904.0 +0 -0
  121. lavavu_osmesa.libs/libva-drm-178eb7ac.so.1.3904.0 +0 -0
  122. lavavu_osmesa.libs/libva-x11-d220c497.so.1.3904.0 +0 -0
  123. lavavu_osmesa.libs/libvdpau-0391b780.so.1.0.0 +0 -0
  124. lavavu_osmesa.libs/libvorbis-378bad15.so.0.4.8 +0 -0
  125. lavavu_osmesa.libs/libvorbisenc-d605e0e1.so.2.0.11 +0 -0
  126. lavavu_osmesa.libs/libvorbisfile-5692671f.so.3.3.7 +0 -0
  127. lavavu_osmesa.libs/libvpx-560f7a88.so.4.1.0 +0 -0
  128. lavavu_osmesa.libs/libwavpack-8339806a.so.1.2.0 +0 -0
  129. lavavu_osmesa.libs/libwebp-63152597.so.6.0.2 +0 -0
  130. lavavu_osmesa.libs/libwebpmux-38ab8eb3.so.2.0.2 +0 -0
  131. lavavu_osmesa.libs/libx264-1c898326.so.148 +0 -0
  132. lavavu_osmesa.libs/libx265-51947861.so.95 +0 -0
  133. lavavu_osmesa.libs/libxcb-ffedb2d4.so.1.1.0 +0 -0
  134. lavavu_osmesa.libs/libxcb-render-f7692d1d.so.0.0.0 +0 -0
  135. lavavu_osmesa.libs/libxcb-shm-5702672e.so.0.0.0 +0 -0
  136. lavavu_osmesa.libs/libxml2-b8b306ab.so.2.9.4 +0 -0
  137. lavavu_osmesa.libs/libxvidcore-a773eded.so.4.3 +0 -0
  138. lavavu_osmesa.libs/libzvbi-2db02ce4.so.0.13.2 +0 -0
lavavu/html/menu.js ADDED
@@ -0,0 +1,609 @@
1
+ /* dat.gui menu */
2
+
3
+ function parseColour(input) {
4
+ if (typeof(input) != 'object') {
5
+ //var div = document.createElement('div');
6
+ var div = document.getElementById('hidden_style_div');
7
+ div.style.color = input;
8
+ //This triggers a full layout calc - can slow things down
9
+ c = getComputedStyle(div).color;
10
+ o = getComputedStyle(div).opacity;
11
+ C = new Colour(c);
12
+ //c.alpha = o;
13
+ //toFixed() / 1 rounds to fixed position and removes trailing zeros
14
+ c.alpha = parseFloat(o).toFixed(2) / 1;
15
+ } else {
16
+ C = new Colour(input);
17
+ }
18
+ return C.html();
19
+ }
20
+
21
+ //Attempts to get range from data/volume objects for range controls
22
+ function menu_getrange(obj, ctrl) {
23
+ //Ranged?
24
+ if (ctrl.length > 1 && ctrl[1].length == 3) {
25
+ var range = [ctrl[1][0], ctrl[1][1]];
26
+ //Mapped range?
27
+ if (ctrl[1][0] === ctrl[1][1] && ctrl[1][0] === 0.0) {
28
+ //Try volume range
29
+ if (obj.volume && obj.volume.minimum < obj.volume.maximum)
30
+ range = [obj.volume.minimum, obj.volume.maximum];
31
+ //Or value data range
32
+ else if (obj.values && obj.values.minimum < obj.values.maximum)
33
+ range = [obj.values.minimum, obj.values.maximum];
34
+ }
35
+ if (range[1] <= range[0]) {
36
+ //console.log(obj.name + " : range (invalid) = " + range);
37
+ return [0.0, 1.0]; //No valid range data, use a default
38
+ }
39
+ //console.log(obj.name + " : range = " + range);
40
+ return range;
41
+ }
42
+ return null;
43
+ }
44
+
45
+ //Add controls to menu, using property metadata
46
+ function menu_addctrl(menu, obj, viewer, prop, changefn) {
47
+ //TODO: implement delayed high quality render for faster interaction
48
+ //var changefn = function(value) {viewer.delayedRender(250);};
49
+ var ctrl = viewer.dict[prop].control;
50
+
51
+ //Query prop dict for data type, default, min/max/step etc
52
+ var dtype = viewer.dict[prop].type;
53
+ if (prop === 'colourmap') {
54
+ var maps = ['']
55
+ for (var i=0; i<viewer.vis.colourmaps.length; i++)
56
+ maps.push(viewer.vis.colourmaps[i].name);
57
+ //console.log(JSON.stringify(maps));
58
+ menu.add(obj, prop, maps).onFinishChange(changefn);
59
+
60
+ } else if (ctrl.length > 2 && ctrl[2] != null) {
61
+ //Select from list of options
62
+ menu.add(obj, prop, ctrl[2]).onFinishChange(changefn);
63
+
64
+ } else if ((dtype.indexOf('real') >= 0 || dtype.indexOf('integer') >= 0)) { // && typeof(obj[prop]) == 'number') {
65
+
66
+ //Ranged?
67
+ var range = menu_getrange(obj, ctrl);
68
+ var addnumeric = function(menu, obj, prop, range, changefn) {
69
+ if (range) {
70
+ if (obj[prop] < range[0]) obj[prop] = range[0];
71
+ if (obj[prop] > range[1]) obj[prop] = range[1];
72
+ return menu.add(obj, prop, range[0], range[1], ctrl[1][2]).onFinishChange(changefn);
73
+ } else {
74
+ return menu.add(obj, prop).onFinishChange(changefn);
75
+ }
76
+ }
77
+
78
+ //Array quantities
79
+ var dims = 1;
80
+ var p0 = dtype.indexOf('[');
81
+ var p1 = dtype.indexOf(']');
82
+ if (p0 >= 0 && p1 >= 0)
83
+ dims = parseInt(dtype.slice(p0+1, p1));
84
+ if (dims > 1) {
85
+ //2d, 3d ?
86
+ for (var d=0; d<dims; d++) {
87
+ //console.log("Adding DIM " + d);
88
+ var added = addnumeric(menu, obj[prop], "" + d, range, changefn)
89
+ added.name(prop + '[' + d + ']');
90
+ }
91
+
92
+ //Only add if a number, anything else will cause dat.gui to error
93
+ } else if (typeof(obj[prop]) == 'number') {
94
+ //1d
95
+ console.log("Adding ", prop, typeof(obj[prop]));
96
+ addnumeric(menu, obj, prop, range, changefn)
97
+ }
98
+
99
+ } else if (dtype === 'string' || dtype === 'boolean') {
100
+ menu.add(obj, prop).onFinishChange(changefn);
101
+ } else if (dtype === 'boolean') {
102
+ menu.add(obj, prop).onFinishChange(changefn);
103
+ } else if (dtype === 'colour') {
104
+ try {
105
+ //Convert to html colour first
106
+ obj[prop] = parseColour(obj[prop]);
107
+ menu.addColor(obj, prop).onChange(changefn);
108
+ } catch(e) {
109
+ console.log(e);
110
+ }
111
+ }
112
+ }
113
+
114
+ function menu_addctrls(menu, obj, viewer, onchange) {
115
+ //Loop through every available property
116
+ var extras = [];
117
+ for (var prop in viewer.dict) {
118
+
119
+ //Check if it is enabled in GUI
120
+ var ctrl = viewer.dict[prop].control;
121
+ if (!ctrl || ctrl[0] === false) continue; //Control disabled
122
+
123
+ //Check if it has been set on the target object
124
+ if (prop in obj) {
125
+ //console.log(prop + " ==> " + JSON.stringify(viewer.dict[prop]));
126
+ menu_addctrl(menu, obj, viewer, prop, onchange);
127
+
128
+ } else {
129
+ //Save list of properties without controls
130
+ extras.push(prop);
131
+ continue;
132
+ }
133
+ }
134
+
135
+ //Sort into alphabetical order
136
+ extras.sort();
137
+
138
+ //Add the extra properties to a dropdown list
139
+ //Selecting a property will add a controller for it
140
+ var propadd = {"properties" : ""};
141
+ var propselfn = function(prop) {
142
+ //Set the property to the default value
143
+ propadd.ref[prop] = viewer.dict[prop]["default"];
144
+ //Add new property controller
145
+ menu_addctrl(propadd.menu, propadd.ref, viewer, prop, onchange);
146
+ //Remove, then add the props list back at the bottom, minus new prop
147
+ propadd.menu.remove(propadd.controller);
148
+ //Save the new filtered list
149
+ propadd.list = propadd.list.filter(word => word != prop);
150
+ propadd.controller = propadd.menu.add(propadd, "properties", propadd.list).name("More properties").onFinishChange(propadd.fn);
151
+ }
152
+ propadd.controller = menu.add(propadd, "properties", extras).name("More properties").onFinishChange(propselfn);
153
+ propadd.ref = obj;
154
+ propadd.menu = menu;
155
+ propadd.fn = propselfn;
156
+ propadd.list = extras;
157
+ }
158
+
159
+
160
+ function menu_addcmaps(menu, obj, viewer, onchange) {
161
+ //Colourmap editing menu
162
+ if (viewer.cgui.prmenu) viewer.cgui.removeFolder(viewer.cgui.prmenu);
163
+ if (viewer.cgui.cmenu) viewer.cgui.removeFolder(viewer.cgui.cmenu);
164
+ if (viewer.cgui.pomenu) viewer.cgui.removeFolder(viewer.cgui.pomenu);
165
+ viewer.cgui.prmenu = viewer.cgui.addFolder("Properties");
166
+ viewer.cgui.cmenu = viewer.cgui.addFolder("Colours");
167
+ viewer.cgui.pomenu = viewer.cgui.addFolder("Positions");
168
+ //Loop through every available property
169
+ for (var prop in viewer.dict) {
170
+ //Check if it is enabled in GUI
171
+ var ctrl = viewer.dict[prop].control;
172
+ if (!ctrl || ctrl[0] === false) continue; //Control disabled
173
+
174
+ //Check if it applies to colourmap object
175
+ if (viewer.dict[prop]["target"] == 'colourmap') {
176
+ //console.log(prop + " ==> " + JSON.stringify(viewer.dict[prop]));
177
+ //Need to add property default if not set
178
+ if (!obj[prop])
179
+ obj[prop] = viewer.dict[prop].default;
180
+ menu_addctrl(menu.prmenu, obj, viewer, prop, onchange);
181
+ }
182
+ }
183
+
184
+ var reload_onchange = function() {onchange("", true);};
185
+
186
+ //Loop through colours
187
+ menu.cmenu.add({"Add Colour" : function() {obj.colours.unshift({"colour" : "rgba(0,0,0,1)", "position" : 0.0}); viewer.gui.close(); reload_onchange(); }}, "Add Colour");
188
+ //Need to add delete buttons in closure to get correct pos/index
189
+ function del_btn(pos) {menu.pomenu.add({"Delete" : function() {obj.colours.splice(pos, 1); viewer.gui.close(); reload_onchange(); }}, 'Delete').name('Delete ' + pos);}
190
+ for (var c in obj.colours) {
191
+ var o = obj.colours[c];
192
+ //Convert to html colour first
193
+ o.colour = parseColour(o.colour);
194
+ o.opacity = 1.0;
195
+ menu.cmenu.addColor(o, 'colour').onChange(reload_onchange).name('Colour ' + c);
196
+ menu.pomenu.add(o, 'position', 0.0, 1.0, 0.01).onFinishChange(reload_onchange).name('Position ' + c);
197
+ del_btn(c);
198
+ }
199
+ }
200
+
201
+ function createMenu(viewer, onchange, webglmode, global) {
202
+ if (!dat) return null;
203
+ //var t0 = performance.now();
204
+
205
+ //Exists? Destroy
206
+ if (viewer.gui)
207
+ viewer.gui.destroy();
208
+
209
+ var el = null;
210
+ //Insert within element rather than whole document
211
+ if (!global && viewer.canvas && viewer.canvas.parentElement != document.body && viewer.canvas.parentElement.parentElement != document.body) {
212
+ var pel = viewer.canvas.parentElement;
213
+ //A bit of a hack to detect converted HTML output and skip going up two parent elements
214
+ if (pel.parentElement.className != 'section')
215
+ pel = pel.parentElement;
216
+ pel.style.position = 'relative'; //Parent element relative prevents menu escaping wrapper div
217
+ //Jupyter notebook overflow hacks (allows gui to be larger than cell)
218
+ var e = pel;
219
+ //These parent elements need 'overflow: visible' to prevent scrolling or cut-off of menu
220
+ //Add the "pgui" class to all the parent containers
221
+ while (e != document.body) {
222
+ e.classList.add("pgui");
223
+ e = e.parentElement;
224
+ }
225
+ //pel.style.overflow = 'visible'; //Parent element relative prevents menu escaping wrapper div
226
+ //pel.parentElement.style.overflow = 'visible'; //Parent element relative prevents menu escaping wrapper div
227
+ var id = 'dat_gui_menu_' + (viewer.canvas ? viewer.canvas.id : 'default');
228
+ el = document.getElementById(id)
229
+ if (el)
230
+ el.parentNode.removeChild(el);
231
+ el = document.createElement("div");
232
+ el.id = id;
233
+ el.style.cssText = "position: absolute; top: 0em; right: 0em; z-index: 255;";
234
+ pel.insertBefore(el, pel.childNodes[0]);
235
+ }
236
+
237
+ var gui;
238
+ //Insert within element rather than whole document
239
+ if (el) {
240
+ gui = new dat.GUI({ autoPlace: false, width: 275, hideable: false });
241
+ el.appendChild(gui.domElement);
242
+ } else {
243
+ gui = new dat.GUI({ hideable: false, width: 275 });
244
+ }
245
+
246
+ //Re-create menu on element mouse down if we need to reload
247
+ //(Instead of calling whenever state changes, re-creation is slow!)
248
+ gui.domElement.onmousedown = function(e) {
249
+ if (viewer.reloadgui)
250
+ viewer.menu();
251
+ return true;
252
+ }
253
+
254
+ //Horrible hack to stop codemirror stealing events when menu is over an editor element
255
+ gui.domElement.onmouseenter = function(e) {
256
+ //console.log('mouseenter');
257
+ var stylesheet = document.styleSheets[0];
258
+ stylesheet.insertRule('.CodeMirror-code { pointer-events: none;}', 0);
259
+ };
260
+
261
+ gui.domElement.onmouseleave = function(e) {
262
+ //console.log('mouseleave');
263
+ var stylesheet = document.styleSheets[0];
264
+ if (stylesheet.cssRules[0].cssText.indexOf('CodeMirror') >= 0)
265
+ stylesheet.deleteRule(0);
266
+ };
267
+
268
+ //Hidden element for style compute, required to be on page for chrome, can't just use createElement
269
+ var elem = document.getElementById('hidden_style_div');
270
+ if (!elem) {
271
+ elem = document.createElement('div');
272
+ elem.style.display = 'none';
273
+ elem.id = 'hidden_style_div';
274
+ document.body.appendChild(elem);
275
+ }
276
+
277
+ //Move above other controls
278
+ gui.domElement.parentElement.style.zIndex = '255';
279
+ //Save close button for hide menu check
280
+ gui.closebtn = gui.domElement.getElementsByClassName('close-button')[0];
281
+ //Hide/show on mouseover (only if overlapping)
282
+ if (!viewer.reloadgui) {
283
+ //Create closed and hidden for the first time, leave as is otherwise
284
+ gui.close();
285
+ hideMenu(viewer.canvas, gui);
286
+ }
287
+
288
+ gui.add({"Reload" : function() {viewer.reload();}}, "Reload");
289
+ //VR supported? (WebGL only)
290
+ if (webglmode === 1 && navigator.getVRDisplays) {
291
+ viewer.vrDisplay = null;
292
+ viewer.inVR = false;
293
+ gui.add({"VR Mode" : function() {start_VR(viewer);}}, 'VR Mode');
294
+ }
295
+
296
+ if (!!window.chrome) //Stupid chrome disabled data URL open
297
+ gui.add({"Export" : function() {var w = window.open(); w.document.write('<pre>' + viewer.toString() + '</pre>');}}, 'Export');
298
+ else
299
+ gui.add({"Export" : function() {window.open('data:application/json;base64,' + window.btoa(viewer.toString()));}}, 'Export');
300
+ //gui.add({"loadFile" : function() {document.getElementById('fileupload').click();}}, 'loadFile'). name('Load Image file');
301
+
302
+ //Non-persistent settings
303
+ gui.add(viewer, "mode", ['Rotate', 'Translate', 'Zoom']);
304
+ if (webglmode === 0) {
305
+ viewer.cmd = '';
306
+ gui.add(viewer, "cmd").onFinishChange(function(cmd) {if (cmd.length) {viewer.command(cmd); viewer.cmd = '';}}).name('Command');
307
+ }
308
+
309
+ //var s = gui.addFolder('Settings');
310
+ if (webglmode === 1) {
311
+ //Old WebGL 1.0 mode
312
+ gui.add(viewer.vis, "interactive").name("Interactive Render");
313
+ gui.add(viewer.vis, "immediatesort").name("Immediate Sort");
314
+ gui.add(viewer.vis, "sortenabled").name('Sort Enabled');
315
+ } else if (webglmode === 2) {
316
+ //Emscripten WebGL2 mode
317
+ gui.add({"Full Screen" : function() {Module.requestFullscreen(false,true);}}, 'Full Screen');
318
+ var params = {loadBrowserFile : function() { document.getElementById('fileinput').click(); } };
319
+ gui.add(params, 'loadBrowserFile').name('Load file');
320
+ gui.add({"Export GLDB" : function() {window.commands.push('export');}}, 'Export GLDB');
321
+ } else if (viewer.canvas) {
322
+ //Server render
323
+ var url = viewer.canvas.imgtarget.baseurl;
324
+ if (url)
325
+ gui.add({"Popup Viewer" : function() {window.open(url, "LavaVu", "toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=no,width=1024,height=768");}}, 'Popup Viewer');
326
+ }
327
+
328
+ var g = gui.addFolder('Globals/Defaults');
329
+ menu_addctrls(g, viewer.vis.properties, viewer, onchange);
330
+
331
+ var v = gui.addFolder('Views');
332
+ var ir2 = 1.0 / Math.sqrt(2.0);
333
+ v.add({"Reset" : function() {viewer.reset(); }}, 'Reset');
334
+ v.add({"XY" : function() {viewer.syncRotation([0, 0, 0, 1]); }}, 'XY');
335
+ v.add({"YX" : function() {viewer.syncRotation([0, 1, 0, 0]);}}, 'YX');
336
+ v.add({"XZ" : function() {viewer.syncRotation([ir2, 0, 0, -ir2]);}}, 'XZ');
337
+ v.add({"ZX" : function() {viewer.syncRotation([ir2, 0, 0, ir2]);}}, 'ZX');
338
+ v.add({"YZ" : function() {viewer.syncRotation([0, -ir2, 0, -ir2]);}}, 'YZ');
339
+ v.add({"ZY" : function() {viewer.syncRotation([0, -ir2, 0, ir2]);}}, 'ZY');
340
+ //console.log(JSON.stringify(viewer.view));
341
+ if (viewer.view)
342
+ menu_addctrls(v, viewer.view, viewer, onchange);
343
+ else
344
+ menu_addctrls(v, viewer.vis.views[0], viewer, onchange);
345
+
346
+ var o = gui.addFolder('Objects');
347
+ for (var id in viewer.vis.objects) {
348
+ var of = o.addFolder(viewer.vis.objects[id].name);
349
+ menu_addctrls(of, viewer.vis.objects[id], viewer, onchange);
350
+ }
351
+
352
+ viewer.gui = gui;
353
+ if (!viewer.selectedcolourmap) {
354
+ viewer.selectedcolourmap = "";
355
+ viewer.newcolourmap = "";
356
+ }
357
+ viewer.cgui = viewer.gui.addFolder('ColourMaps');
358
+
359
+ createColourMapMenu(viewer, onchange, webglmode === 1);
360
+
361
+ //var t1 = performance.now();
362
+ //console.log("Call to menu() took " + (t1 - t0) + " milliseconds.")
363
+ }
364
+
365
+ function createColourMapMenu(viewer, onchange, webglmode) {
366
+ //Remove existing entries
367
+ for (var i in viewer.cgui.__controllers)
368
+ viewer.cgui.__controllers[i].remove();
369
+
370
+ var cms = [];
371
+
372
+ //Dropdown to select a colourmap, when selected the editing menu will be populated
373
+ for (var id in viewer.vis.colourmaps)
374
+ cms.push(viewer.vis.colourmaps[id].name);
375
+
376
+ if (webglmode) {
377
+ //Add a default colourmap
378
+ viewer.cgui.add({"Add" : function() {viewer.addColourMap(); viewer.gui.close();}}, 'Add');
379
+ } else {
380
+ //Add a colourmap from list of defaults
381
+ cmapaddfn = function(value) {
382
+ if (!value || !value.length) return;
383
+ viewer.command("select; colourmap " + value + " " + value);
384
+ viewer.gui.close();
385
+ };
386
+
387
+ viewer.cgui.add(viewer, "newcolourmap", viewer.defaultcolourmaps).onFinishChange(cmapaddfn).name("Add");
388
+ }
389
+
390
+ //Do the rest only if colourmaps exist...
391
+ if (cms.length == 0) return;
392
+
393
+ //When selected, populate the Colours & Positions menus
394
+ cmapselfn = function(value) {
395
+ if (!value) return;
396
+ for (var id in viewer.vis.colourmaps) {
397
+ if (value == viewer.vis.colourmaps[id].name)
398
+ menu_addcmaps(viewer.cgui, viewer.vis.colourmaps[id], viewer, onchange);
399
+ }
400
+ };
401
+
402
+ viewer.cgui.cmap = viewer.cgui.add(viewer, "selectedcolourmap", cms).onFinishChange(cmapselfn).name("Colourmap");
403
+
404
+ //Re-select if previous value if any
405
+ if (viewer.selectedcolourmap)
406
+ cmapselfn(viewer.selectedcolourmap);
407
+ }
408
+
409
+ function updateMenu(viewer, onchange) {
410
+ //Attempt to update DAT.GUI controls
411
+ function updateDisplay(gui) {
412
+ for (var i in gui.__controllers)
413
+ gui.__controllers[i].updateDisplay();
414
+ for (var f in gui.__folders)
415
+ updateDisplay(gui.__folders[f]);
416
+ }
417
+ updateDisplay(viewer.gui);
418
+ updateDisplay(viewer.cgui);
419
+ }
420
+
421
+ function hideMenu(canvas, gui) {
422
+ //No menu, but hide the mode controls
423
+ if (!gui) {
424
+ if (canvas && canvas.imgtarget)
425
+ canvas.imgtarget.nextElementSibling.style.display = "none";
426
+ return;
427
+ }
428
+
429
+ //Requires menu to be closed and hiding enabled
430
+ if (!gui.closed) return;
431
+
432
+ //Only hide if overlapping the canvas (unless no canvas passed)
433
+ if (canvas) {
434
+ var rect0 = gui.closebtn.getBoundingClientRect();
435
+ var rect1 = canvas.getBoundingClientRect();
436
+ if (rect0.right < rect1.left || rect0.left > rect1.right ||
437
+ rect0.bottom < rect1.top || rect0.top > rect1.bottom) {
438
+ //No overlap, don't hide
439
+ return;
440
+ }
441
+ }
442
+
443
+ //Reached this point? Menu needs hiding
444
+ gui.domElement.style.display = "none";
445
+ }
446
+
447
+ //https://hacks.mozilla.org/2018/09/converting-a-webgl-application-to-webvr/
448
+ //https://github.com/Manishearth/webgl-to-webvr/
449
+ // This function is triggered when the user clicks the "enter VR" button
450
+ function start_VR(viewer) {
451
+ if (viewer.vrDisplay != null) {
452
+ if (!viewer.inVR) {
453
+ viewer.inVR = true;
454
+ // hand the canvas to the WebVR API
455
+ viewer.vrDisplay.requestPresent([{ source: viewer.canvas }]);
456
+ // requestPresent() will request permission to enter VR mode,
457
+ // and once the user has done this our `vrdisplaypresentchange`
458
+ // callback will be triggered
459
+
460
+ //Show stats
461
+ if (!document.getElementById("stats_info")) {
462
+ var stats = new Stats();
463
+ document.body.appendChild(stats.dom);
464
+ requestAnimationFrame(function loop() {
465
+ stats.update();
466
+ requestAnimationFrame(loop)
467
+ });
468
+ }
469
+
470
+ } else {
471
+ stop_VR(viewer);
472
+ }
473
+ }
474
+ }
475
+
476
+ function stop_VR(viewer) {
477
+ viewer.inVR = false;
478
+ // resize canvas to regular non-VR size if necessary
479
+ viewer.width = 0; //Auto resize
480
+ viewer.height = 0;
481
+ viewer.canvas.style.width = "100%";
482
+ viewer.canvas.style.height = "100%";
483
+
484
+ viewer.drawFrame();
485
+ viewer.draw();
486
+ }
487
+
488
+ function setup_VR(viewer) {
489
+ if (!navigator.getVRDisplays) {
490
+ alert("Your browser does not support WebVR");
491
+ return;
492
+ }
493
+
494
+ function display_setup(displays) {
495
+ if (displays.length === 0)
496
+ return;
497
+ //Use last in list
498
+ viewer.vrDisplay = displays[displays.length-1];
499
+ }
500
+
501
+ navigator.getVRDisplays().then(display_setup);
502
+
503
+ function VR_change() {
504
+ // no VR display, exit
505
+ if (viewer.vrDisplay == null)
506
+ return;
507
+
508
+ // are we entering or exiting VR?
509
+ if (viewer.vrDisplay.isPresenting) {
510
+ // optional, but recommended
511
+ viewer.vrDisplay.depthNear = viewer.near_clip;
512
+ viewer.vrDisplay.depthFar = viewer.far_clip;
513
+
514
+ // We should make our canvas the size expected
515
+ // by WebVR
516
+ const eye = viewer.vrDisplay.getEyeParameters("left");
517
+ // multiply by two since we're rendering both eyes side
518
+ // by side
519
+ viewer.width = eye.renderWidth * 2;
520
+ viewer.height = eye.renderHeight;
521
+ viewer.canvas.style.width = viewer.width + "px";
522
+ viewer.canvas.style.height = viewer.height + "px";
523
+ viewer.canvas.width = viewer.canvas.clientWidth;
524
+ viewer.canvas.height = viewer.canvas.clientHeight;
525
+
526
+ const vrCallback = () => {
527
+ if (viewer.vrDisplay == null || !viewer.inVR)
528
+ return;
529
+
530
+ // reregister callback if we're still in VR
531
+ viewer.vrDisplay.requestAnimationFrame(vrCallback);
532
+
533
+ // render scene
534
+ renderVR(viewer);
535
+ };
536
+
537
+ // register callback
538
+ viewer.vrDisplay.requestAnimationFrame(vrCallback);
539
+
540
+ } else {
541
+ stop_VR(viewer);
542
+ }
543
+ }
544
+
545
+ window.addEventListener('vrdisplaypresentchange', VR_change);
546
+ }
547
+
548
+ function renderVR(viewer) {
549
+ //Clear full canvas
550
+ viewer.gl.viewport(0, 0, viewer.canvas.width, viewer.canvas.height);
551
+ viewer.gl.clear(viewer.gl.COLOR_BUFFER_BIT | viewer.gl.DEPTH_BUFFER_BIT);
552
+
553
+ //Left eye
554
+ renderEye(viewer, true);
555
+
556
+ //Right eye
557
+ renderEye(viewer, false);
558
+
559
+ viewer.vrDisplay.submitFrame();
560
+ }
561
+
562
+ function renderEye(viewer, isLeft) {
563
+ let projection, mview;
564
+ let frameData = new VRFrameData();
565
+ var gl = viewer.webgl.gl;
566
+ var width = viewer.canvas.width / 2;
567
+ var height = viewer.canvas.height;
568
+
569
+ viewer.vrDisplay.getFrameData(frameData);
570
+
571
+ // choose which half of the canvas to draw on
572
+ if (isLeft) {
573
+ viewer.webgl.viewport = new Viewport(0, 0, width, height);
574
+ gl.viewport(0, 0, width, height);
575
+ //Apply the default camera
576
+ viewer.webgl.apply(viewer);
577
+
578
+ projection = frameData.leftProjectionMatrix;
579
+ mview = frameData.leftViewMatrix;
580
+ } else {
581
+ viewer.webgl.viewport = new Viewport(width, 0, width, height);
582
+ gl.viewport(width, 0, width, height);
583
+ //viewer.webgl.viewport = new Viewport(0, 0, width, height);
584
+ //gl.viewport(0, 0, width, height);
585
+ projection = frameData.rightProjectionMatrix;
586
+ mview = frameData.rightViewMatrix;
587
+ }
588
+
589
+ //Apply the default camera
590
+ viewer.webgl.apply(viewer);
591
+
592
+ //Update matrices with VR modified versions
593
+ //mat4.multiply(mview, viewer.webgl.modelView.matrix);
594
+ //viewer.webgl.modelView.matrix = mview;
595
+ mat4.multiply(viewer.webgl.modelView.matrix, mview);
596
+ //console.log(isLeft ? "LEFT " : "RIGHT "); printMatrix(mview);
597
+ //gl.uniformMatrix4fv(viewer.webgl.program.mvMatrixUniform, false, mview);
598
+
599
+ viewer.webgl.projection.matrix = projection;
600
+
601
+ //Render objects
602
+ for (var r in viewer.renderers) {
603
+ if (viewer.renderers[r].border && !viewer.showBorder) continue;
604
+ viewer.renderers[r].draw();
605
+ }
606
+
607
+ viewer.rotated = false; //Clear rotation flag
608
+ }
609
+