mirror of
https://github.com/OpenFOAM/ThirdParty-6.git
synced 2025-12-08 06:57:43 +00:00
ParaView-5.0.1: Added the source-tree to ThirdParty-dev and patched as described in the README file
Resolves bug-report http://bugs.openfoam.org/view.php?id=2098
This commit is contained in:
283
ParaView-5.0.1/VTK/Web/JavaScript/Lib/vtkweb-loader.js
Normal file
283
ParaView-5.0.1/VTK/Web/JavaScript/Lib/vtkweb-loader.js
Normal file
@ -0,0 +1,283 @@
|
||||
/**
|
||||
* vtkWebLoader JavaScript Library.
|
||||
*
|
||||
* vtkWebLoader use the vtkWeb namespace to manage JavaScript dependency and more specifically
|
||||
* vtkWeb dependencies.
|
||||
*
|
||||
* @class vtkWebLoader
|
||||
*
|
||||
* @singleton
|
||||
*/
|
||||
(function (GLOBAL) {
|
||||
|
||||
var vtkWebLibs = {
|
||||
"core" : [
|
||||
"ext/core/jquery-1.8.3.min.js",
|
||||
"ext/core/autobahn.min.js",
|
||||
"ext/core/gl-matrix.js",
|
||||
"ext/core/jquery.hammer.js",
|
||||
"ext/core/vgl.min.js",
|
||||
"lib/core/vtkweb-all.js"
|
||||
],
|
||||
"core-min": [
|
||||
"ext/core/jquery-1.8.3.min.js",
|
||||
"ext/core/autobahn.min.js",
|
||||
"ext/core/gl-matrix-min.js",
|
||||
"ext/core/jquery.hammer.min.js",
|
||||
"ext/core/vgl.min.js",
|
||||
"lib/core/vtkweb-all.min.js"
|
||||
],
|
||||
"bootstrap": [
|
||||
"ext/bootstrap/js/bootstrap.min.js",
|
||||
"ext/bootstrap/css/bootstrap-responsive.min.css",
|
||||
"ext/bootstrap/css/bootstrap.min.css"
|
||||
],
|
||||
"fontello": [
|
||||
"ext/fontello/css/animation.css",
|
||||
"ext/fontello/css/fontello.css"
|
||||
],
|
||||
"color": [
|
||||
"ext/jscolor/jscolor.js"
|
||||
],
|
||||
"filebrowser": [
|
||||
"ext/pure/pure.min.js",
|
||||
"lib/widgets/FileBrowser/vtkweb-widget-filebrowser.js",
|
||||
"lib/widgets/FileBrowser/vtkweb-widget-filebrowser.tpl",
|
||||
"lib/widgets/FileBrowser/vtkweb-widget-filebrowser.css"
|
||||
],
|
||||
"pv-pipeline": [
|
||||
"ext/jquery-ui/jquery-ui-1.10.0.css",
|
||||
"ext/jquery-ui/jquery-ui-1.10.0.min.js",
|
||||
"lib/css/paraview.ui.pipeline.css",
|
||||
"lib/js/paraview.ui.pipeline.js",
|
||||
],
|
||||
"pv-toolbar": [
|
||||
"lib/css/paraview.ui.toolbar.css",
|
||||
"lib/css/paraview.ui.toolbar.vcr.css",
|
||||
"lib/css/paraview.ui.toolbar.viewport.css",
|
||||
"lib/css/paraview.ui.toolbar.connect.css",
|
||||
"lib/js/paraview.ui.toolbar.js",
|
||||
"lib/js/paraview.ui.toolbar.vcr.js",
|
||||
"lib/js/paraview.ui.toolbar.viewport.js",
|
||||
"lib/js/paraview.ui.toolbar.connect.js"
|
||||
],
|
||||
"jquery-ui": [
|
||||
"ext/jquery-ui/jquery-ui-1.10.0.css",
|
||||
"ext/jquery-ui/jquery-ui-1.10.0.min.js"
|
||||
],
|
||||
"d3":[
|
||||
"ext/d3/d3.v2.js"
|
||||
],
|
||||
"nvd3":[
|
||||
"ext/nvd3/nv.d3.css",
|
||||
"ext/nvd3/nv.d3.js"
|
||||
],
|
||||
"rickshaw": [
|
||||
"ext/rickshaw/rickshaw.min.css",
|
||||
"ext/rickshaw/rickshaw.min.js"
|
||||
],
|
||||
"widgets": [
|
||||
"ext/pure/pure.min.js",
|
||||
"ext/d3/d3.v2.js",
|
||||
"ext/rickshaw/rickshaw.min.css",
|
||||
"ext/rickshaw/rickshaw.min.js",
|
||||
"ext/fontello/css/animation.css",
|
||||
"ext/fontello/css/fontello.css",
|
||||
"lib/widgets/FileBrowser/vtkweb-widget-filebrowser.tpl",
|
||||
"lib/widgets/TreeWidget/vtkweb-widget-tree.tpl",
|
||||
"lib/widgets/vtkweb-widgets-min.css",
|
||||
"lib/widgets/vtkweb-widgets-min.js"
|
||||
],
|
||||
"pv-visualizer": [
|
||||
"ext/fontello/css/animation.css",
|
||||
"ext/fontello/css/fontello.css",
|
||||
"ext/bootstrap3/css/bootstrap-theme.min.css",
|
||||
"ext/bootstrap3/css/bootstrap.min.css",
|
||||
"ext/bootstrap3/js/bootstrap.min.js",
|
||||
"lib/js/paraview.ui.action.list.js",
|
||||
"lib/js/paraview.ui.files.js",
|
||||
"lib/js/paraview.ui.data.js",
|
||||
"lib/js/paraview.ui.proxy.editor.js",
|
||||
"lib/css/paraview.ui.proxy.editor.css",
|
||||
"lib/js/paraview.ui.svg.pipeline.js",
|
||||
"lib/js/paraview.ui.opacity.editor.js",
|
||||
"lib/css/paraview.ui.opacity.editor.css",
|
||||
"lib/js/paraview.ui.color.editor.js",
|
||||
"lib/css/paraview.ui.color.editor.css"
|
||||
],
|
||||
"pv-visualizer-main-js": [
|
||||
"apps/Visualizer/main.js"
|
||||
],
|
||||
"pv-visualizer-main-all": [
|
||||
"apps/Visualizer/main.js",
|
||||
"apps/Visualizer/main.css"
|
||||
],
|
||||
"pv-visualizer-tpl": "apps/Visualizer/visualizer-tpl.html"
|
||||
|
||||
},
|
||||
modules = [],
|
||||
script = document.getElementsByTagName("script")[document.getElementsByTagName("script").length - 1],
|
||||
basePath = "",
|
||||
extraScripts = [];
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
function loadCss(url) {
|
||||
var link = document.createElement("link");
|
||||
link.type = "text/css";
|
||||
link.rel = "stylesheet";
|
||||
link.href = url;
|
||||
head = document.getElementsByTagName("head")[0];
|
||||
head.insertBefore(link, head.childNodes[0]);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
function loadJavaScript(url) {
|
||||
document.write('<script src="' + url + '"></script>');
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
function loadTemplate(url) {
|
||||
var templates = document.getElementById("vtk-templates");
|
||||
if(templates === null) {
|
||||
templates = document.createElement("div");
|
||||
templates.setAttribute("style", "display: none;");
|
||||
templates.setAttribute("id", "vtk-templates");
|
||||
document.getElementsByTagName("body")[0].appendChild(templates);
|
||||
}
|
||||
|
||||
// Fetch template and append to vtk-templates
|
||||
var request = makeHttpObject();
|
||||
request.open("GET", url, true);
|
||||
request.send(null);
|
||||
request.onreadystatechange = function() {
|
||||
if (request.readyState == 4) {
|
||||
var content = templates.innerHTML;
|
||||
content += request.responseText;
|
||||
templates.innerHTML = content;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
function loadGlobalTemplate(url) {
|
||||
var request = makeHttpObject();
|
||||
request.open("GET", url, true);
|
||||
request.send(null);
|
||||
request.onreadystatechange = function() {
|
||||
if (request.readyState == 4) {
|
||||
var content = request.responseText,
|
||||
body = document.getElementsByTagName("body")[0];
|
||||
body.innerHTML += content;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
function makeHttpObject() {
|
||||
try {
|
||||
return new XMLHttpRequest();
|
||||
}
|
||||
catch (error) {}
|
||||
try {
|
||||
return new ActiveXObject("Msxml2.XMLHTTP");
|
||||
}
|
||||
catch (error) {}
|
||||
try {
|
||||
return new ActiveXObject("Microsoft.XMLHTTP");
|
||||
}
|
||||
catch (error) {}
|
||||
|
||||
throw new Error("Could not create HTTP request object.");
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
function _endWith(string, end) {
|
||||
return string.lastIndexOf(end) === (string.length - end.length);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
function loadFile(url) {
|
||||
if(_endWith(url, ".js")) {
|
||||
loadJavaScript(url);
|
||||
} else if(_endWith(url, ".css")) {
|
||||
loadCss(url);
|
||||
} else if(_endWith(url, ".tpl")) {
|
||||
loadTemplate(url);
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Extract modules to load
|
||||
// ---------------------------------------------------------------------
|
||||
try {
|
||||
modules = script.getAttribute("load").split(",");
|
||||
for(var j in modules) {
|
||||
modules[j] = modules[j].replace(/^\s+|\s+$/g, ''); // Trim
|
||||
}
|
||||
} catch(e) {
|
||||
// We don't care we will use the default setup
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Extract extra script to load
|
||||
// ---------------------------------------------------------------------
|
||||
try {
|
||||
extraScripts = script.getAttribute("extra").split(",");
|
||||
for(var j in extraScripts) {
|
||||
extraScripts[j] = extraScripts[j].replace(/^\s+|\s+$/g, ''); // Trim
|
||||
}
|
||||
} catch(e) {
|
||||
// We don't care we will use the default setup
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// If no modules have been defined, just pick the default
|
||||
// ---------------------------------------------------------------------
|
||||
if(modules.length == 0) {
|
||||
modules = [ "core-min" ];
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Extract basePath
|
||||
// ---------------------------------------------------------------------
|
||||
var lastSlashIndex = script.getAttribute("src").lastIndexOf('lib/core/vtkweb-loader');
|
||||
if(lastSlashIndex != -1) {
|
||||
basePath = script.getAttribute("src").substr(0, lastSlashIndex);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// See if we have a main application template to load
|
||||
// ---------------------------------------------------------------------
|
||||
try {
|
||||
var templateKey = script.getAttribute("app-template");
|
||||
if (templateKey !== null && templateKey !== '') {
|
||||
loadGlobalTemplate(basePath + vtkWebLibs[templateKey]);
|
||||
}
|
||||
} catch (e) {
|
||||
// This is fine, you may have defined your application inline
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Add missing libs
|
||||
// ---------------------------------------------------------------------
|
||||
for(var i in modules) {
|
||||
for(var j in vtkWebLibs[modules[i]]) {
|
||||
var path = basePath + vtkWebLibs[modules[i]][j];
|
||||
loadFile(path);
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Add extra libs
|
||||
// ---------------------------------------------------------------------
|
||||
for(var i in extraScripts) {
|
||||
loadFile(extraScripts[i]);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Remove loader
|
||||
// ---------------------------------------------------------------------
|
||||
script.parentNode.removeChild(script);
|
||||
}(window));
|
||||
289
ParaView-5.0.1/VTK/Web/JavaScript/Lib/vtkweb.connect.js
Normal file
289
ParaView-5.0.1/VTK/Web/JavaScript/Lib/vtkweb.connect.js
Normal file
@ -0,0 +1,289 @@
|
||||
/**
|
||||
* vtkWeb JavaScript Library.
|
||||
*
|
||||
* This module allow the Web client to connect to a remote vtkWeb session.
|
||||
* The session must already exist and waiting for connections.
|
||||
*
|
||||
* This module registers itself as: 'vtkweb-connect'
|
||||
*
|
||||
* @class vtkWeb.connect
|
||||
*
|
||||
* {@img paraview/ParaViewWeb-simple.png
|
||||
* alt Focus on the communication between the client and the vtkWeb process}
|
||||
*/
|
||||
(function (GLOBAL, $) {
|
||||
|
||||
// Connections field used to store a map of the active sessions
|
||||
var connections = {}, module = {};
|
||||
|
||||
/*
|
||||
* Create a transport object appropriate to the protocol specified
|
||||
* in the given url.
|
||||
*/
|
||||
function getTransportObject(url) {
|
||||
var idx = url.indexOf(':'),
|
||||
protocol = url.substring(0, idx);
|
||||
if (protocol === 'ws' || protocol === 'wss') {
|
||||
return {
|
||||
'type': 'websocket',
|
||||
'url': url,
|
||||
};
|
||||
} else if (protocol === 'http' || protocol === 'https') {
|
||||
return {
|
||||
'type': 'longpoll',
|
||||
'url': url,
|
||||
request_timeout: 300000
|
||||
};
|
||||
} else {
|
||||
throw "Unknown protocol (" + protocol + ") for url (" + url + "). Unable to create transport object.";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @class vtkWeb.Session
|
||||
* vtkWeb Session object on which RPC method calls can be made.
|
||||
*
|
||||
* session.call("viewport.image.render", request).then( function (reply) {
|
||||
* // Do something with the reply
|
||||
* });
|
||||
*/
|
||||
/**
|
||||
* @member vtkWeb.Session
|
||||
* @method call
|
||||
* Returns a future of the RPC call.
|
||||
* @param {String} method
|
||||
* Full path method name.
|
||||
* @param {Object|String|Number} args
|
||||
* Arguments of the RPC call.
|
||||
*
|
||||
* @return {vtkWeb.Future} of the RPC call
|
||||
*/
|
||||
/**
|
||||
* @class vtkWeb.Future
|
||||
* Object on which can be attached a callback.
|
||||
*/
|
||||
/**
|
||||
* @member vtkWeb.Future
|
||||
* @method then
|
||||
* @param {Function} callback
|
||||
* Function to be called once the RPC called is done. The argument of the
|
||||
* function is the response of the RPC method.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Connect to a running vtkWeb session
|
||||
*
|
||||
* @member vtkWeb.connect
|
||||
*
|
||||
* @param {vtkWeb.Connection} connection
|
||||
* A connection object that should have been generated by the Launcher
|
||||
* part if any.
|
||||
*
|
||||
* connection = {
|
||||
* sessionURL: "http://localhost:8080/ws"
|
||||
* }
|
||||
*
|
||||
* get extended to once the readyCallback get called:
|
||||
*
|
||||
* connection = {
|
||||
* sessionURL: "http://localhost:8080/ws",
|
||||
* session: {vtkWeb.Session}
|
||||
* }
|
||||
*
|
||||
*
|
||||
* @param {Function} readyCallback
|
||||
* Callback function called when a connection that has been extended with
|
||||
* a valid {@link vtkWeb.Session}.
|
||||
*
|
||||
* @param {Function} closeCallback
|
||||
* Callback function called when the session end.
|
||||
*
|
||||
* vtkWeb.connect(
|
||||
* connection,
|
||||
* function(connection) {
|
||||
* // Now that we have a valid session let's add a viewport to
|
||||
* // see the 3D view of our vtkWeb pipeline.
|
||||
* var viewport = vtkWeb.createViewport(connection.session);
|
||||
* viewport.bind(".viewport-3d");
|
||||
* },
|
||||
* function(code,reason) {
|
||||
* if (code == ab.CONNECTION_UNSUPPORTED) {
|
||||
* alert("Connection not supported");
|
||||
* } else {
|
||||
* console.log(reason);
|
||||
* }
|
||||
* }
|
||||
* );
|
||||
*/
|
||||
function connect(connectionInfo, readyCallback, closeCallback) {
|
||||
var uri = connectionInfo.sessionURL,
|
||||
onReady = readyCallback,
|
||||
onClose = closeCallback,
|
||||
uriList = [].concat(uri),
|
||||
transports = [];
|
||||
|
||||
if(!connectionInfo.hasOwnProperty("secret")) {
|
||||
connectionInfo.secret = "vtkweb-secret"; // Default value
|
||||
}
|
||||
|
||||
for (var i = 0; i < uriList.length; i+=1) {
|
||||
var url = uriList[i],
|
||||
transport = null;
|
||||
try {
|
||||
transport = getTransportObject(url);
|
||||
transports.push(transport);
|
||||
} catch (transportCreateError) {
|
||||
console.error(transportCreateError);
|
||||
}
|
||||
}
|
||||
|
||||
connectionInfo.connection = new autobahn.Connection({
|
||||
transports: transports,
|
||||
realm: "vtkweb",
|
||||
authmethods: ["wampcra"],
|
||||
authid: "vtkweb",
|
||||
onchallenge: function(session, method, extra) {
|
||||
if (method === "wampcra") {
|
||||
var secretKey = autobahn.auth_cra.derive_key(connectionInfo.secret, "salt123");
|
||||
return autobahn.auth_cra.sign(secretKey, extra.challenge);
|
||||
} else {
|
||||
throw "don't know how to authenticate using '" + method + "'";
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
connectionInfo.connection.onopen = function(session, details) {
|
||||
try {
|
||||
connectionInfo.session = session;
|
||||
connections[connectionInfo.sessionURL] = connectionInfo;
|
||||
|
||||
if (onReady) {
|
||||
onReady(connectionInfo);
|
||||
}
|
||||
} catch(e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
connectionInfo.connection.onclose = function() {
|
||||
delete connections[connectionInfo.sessionURL];
|
||||
if (onClose) {
|
||||
onClose(arguments[0], arguments[1].reason);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
connectionInfo.connection.open();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a session that uses only http to make calls to the
|
||||
* server-side protocols.
|
||||
*
|
||||
* @member {object} vtkWeb.connect
|
||||
* A json object that only needs a 'sessionURL' string in to know where
|
||||
* to send method requests.
|
||||
*
|
||||
* @param connetionInfo
|
||||
*
|
||||
* @param {Function} readyCallback
|
||||
* Callback function called when a connection that has been extended with
|
||||
* a valid session that can be used to make server-side method calls.
|
||||
*
|
||||
*/
|
||||
function httpConnect(connectionInfo, readyCallback) {
|
||||
connectionInfo.session = {
|
||||
'call': function(methodName, args) {
|
||||
var dfd = $.Deferred();
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: connectionInfo.sessionURL + methodName,
|
||||
dataType: 'json',
|
||||
data: JSON.stringify({ 'args': args }),
|
||||
success: function(result) {
|
||||
dfd.resolve(result);
|
||||
},
|
||||
error: function(error) {
|
||||
dfd.reject(error);
|
||||
}
|
||||
});
|
||||
|
||||
return dfd.promise();
|
||||
}
|
||||
};
|
||||
|
||||
readyCallback(connectionInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return any existing session for a given connection or Wamp URL
|
||||
*
|
||||
* @member vtkWeb.connect
|
||||
*
|
||||
* @param {String} sessionURL
|
||||
* The sessionURL String.
|
||||
*
|
||||
* @return {vtkWeb.Connection} that contains a {@link vtkWeb.Session}
|
||||
*/
|
||||
function getConnection(sessionURL) {
|
||||
return connections[sessionURL];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all the available connections stored in an Object like follow:
|
||||
*
|
||||
* {
|
||||
* "ws://localhost:8080/proxy?sessionId=2345": connection
|
||||
* }
|
||||
*
|
||||
* {@link vtkWeb.Connection}
|
||||
*
|
||||
* @member vtkWeb.connect
|
||||
*/
|
||||
function getConnections() {
|
||||
return connections;
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Init vtkWeb module if needed
|
||||
// ----------------------------------------------------------------------
|
||||
if (GLOBAL.hasOwnProperty("vtkWeb")) {
|
||||
module = GLOBAL.vtkWeb || {};
|
||||
} else {
|
||||
GLOBAL.vtkWeb = module;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Export methods to the vtkWeb module
|
||||
// ----------------------------------------------------------------------
|
||||
module.connect = function (connection, ready, close) {
|
||||
connect(connection, ready, close);
|
||||
};
|
||||
module.getConnection = function (connection) {
|
||||
return getConnection(connection);
|
||||
};
|
||||
module.getConnections = function () {
|
||||
return getConnections();
|
||||
};
|
||||
module.httpConnect = function(connection, readyCallback) {
|
||||
return httpConnect(connection, readyCallback);
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Local module registration
|
||||
// ----------------------------------------------------------------------
|
||||
try {
|
||||
// Tests for presence of autobahn, then registers this module
|
||||
if (GLOBAL.autobahn !== undefined) {
|
||||
module.registerModule('vtkweb-connect');
|
||||
} else {
|
||||
console.error('Module failed to register, autobahn is missing');
|
||||
}
|
||||
} catch(err) {
|
||||
console.error('Caught exception while registering module: ' + err.message);
|
||||
}
|
||||
|
||||
}(window, jQuery));
|
||||
210
ParaView-5.0.1/VTK/Web/JavaScript/Lib/vtkweb.js
Normal file
210
ParaView-5.0.1/VTK/Web/JavaScript/Lib/vtkweb.js
Normal file
@ -0,0 +1,210 @@
|
||||
/**
|
||||
* vtkWeb JavaScript Library.
|
||||
*
|
||||
* This main module just gathers all the modules into a single namespace.
|
||||
*
|
||||
* This module registers itself as: 'vtkweb-base'
|
||||
*
|
||||
* @class vtkWeb
|
||||
*
|
||||
* @mixins vtkWeb.launcher
|
||||
* @mixins vtkWeb.connect
|
||||
* @mixins vtkWeb.viewport
|
||||
* @mixins vtkWeb.viewport.image
|
||||
* @mixins vtkWeb.viewport.webgl
|
||||
*
|
||||
* @singleton
|
||||
*/
|
||||
(function (GLOBAL, $) {
|
||||
|
||||
// VERSION field that store the current version of the library.
|
||||
// WampSessions field used to store a map of the active sessions
|
||||
// Default Viewport options values
|
||||
var VERSION = "2.0.0",
|
||||
fallBackStorage = {},
|
||||
isMobile = (function(a){
|
||||
return (/android.+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i).test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|e\-|e\/|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(di|rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|xda(\-|2|g)|yas\-|your|zeto|zte\-/i.test(a.substr(0,4));
|
||||
})(navigator.userAgent||navigator.vendor||window.opera), module = {}, registeredModules = [];
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
extractURLParameters = function() {
|
||||
var data = location.search.substr(1).split("&"), parameters = {};
|
||||
for(var i=0; i<data.length; i++) {
|
||||
var item = data[i].split("=");
|
||||
parameters[item[0]] = item[1];
|
||||
}
|
||||
return parameters;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
isSecured = function() {
|
||||
return location.protocol === 'https';
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
udpateConnectionFromURL = function(connection) {
|
||||
var params = extractURLParameters();
|
||||
for(var key in params) {
|
||||
connection[key] = decodeURIComponent(params[key]);
|
||||
}
|
||||
}
|
||||
|
||||
supportsLocalStorage = function() {
|
||||
try {
|
||||
return 'localStorage' in window && window['localStorage'] !== null;
|
||||
} catch(e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
storeApplicationDataObject = function(key, jsonObj) {
|
||||
var storage = fallBackStorage;
|
||||
if (supportsLocalStorage()) {
|
||||
storage = localStorage;
|
||||
}
|
||||
storage[key] = JSON.stringify(jsonObj);
|
||||
}
|
||||
|
||||
retrieveApplicationDataObject = function(key) {
|
||||
var storage = fallBackStorage;
|
||||
if (supportsLocalStorage()) {
|
||||
storage = localStorage;
|
||||
}
|
||||
var storedData = storage[key];
|
||||
if (storedData) {
|
||||
try {
|
||||
return JSON.parse(storedData);
|
||||
} catch(e) {
|
||||
console.error('Failed to parse stored data object as JSON: '+ storedData);
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
return {}; // if not supported, we could store in a map in vtkweb
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Init vtkWeb module if needed
|
||||
// ----------------------------------------------------------------------
|
||||
if (GLOBAL.hasOwnProperty("vtkWeb")) {
|
||||
module = GLOBAL.vtkWeb || {};
|
||||
} else {
|
||||
GLOBAL.vtkWeb = module;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Export internal methods to the vtkWeb module
|
||||
// ----------------------------------------------------------------------
|
||||
module.version = VERSION;
|
||||
module.isMobile = isMobile;
|
||||
module.extractURLParameters = extractURLParameters;
|
||||
module.udpateConnectionFromURL = udpateConnectionFromURL;
|
||||
module.supportsLocalStorage = supportsLocalStorage;
|
||||
module.storeApplicationDataObject = storeApplicationDataObject;
|
||||
module.retrieveApplicationDataObject = retrieveApplicationDataObject;
|
||||
module.properties = {
|
||||
'sessionManagerURL': location.protocol + "//" + location.hostname + ":" + location.port + "/paraview/",
|
||||
'sessionURL': (isSecured() ? "wss" : "ws") + "://" + location.hostname + ":" + location.port + "/ws"
|
||||
};
|
||||
module.NoOp = function() {};
|
||||
module.errorCallback = function(code, reason) {
|
||||
alert(reason);
|
||||
GLOBAL.close();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Module registration hooks.
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Javascript libraries can call this function to register themselves.
|
||||
*
|
||||
* @member vtkWeb
|
||||
* @method registerModule
|
||||
*
|
||||
* @param {String} The module name to use when registering a module.
|
||||
*
|
||||
*/
|
||||
module.registerModule = function(moduleName) {
|
||||
if (module.modulePresent(moduleName) === false) {
|
||||
registeredModules.push(moduleName);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Javascript libraries call this function to determine whether a
|
||||
* particular module is loaded.
|
||||
*
|
||||
* @member vtkWeb
|
||||
* @method modulePresent
|
||||
*
|
||||
* @param {String} The name of the module name to check.
|
||||
*
|
||||
* @return {Boolean} True if the module specified by the given name
|
||||
* is registered, false otherwise.
|
||||
*/
|
||||
module.modulePresent = function(moduleName) {
|
||||
for (var i = 0; i < registeredModules.length; ++i) {
|
||||
if (moduleName === registeredModules[i]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Javascript libraries call this function to determine whether an
|
||||
* entire list of modules is loaded.
|
||||
*
|
||||
* @member vtkWeb
|
||||
* @method allModulesPresent
|
||||
*
|
||||
* @param {Array} An array of module names to check.
|
||||
*
|
||||
* @return {Boolean} True if all modules names supplied are registered,
|
||||
* false otherwise.
|
||||
*/
|
||||
module.allModulesPresent = function(moduleNameList) {
|
||||
if (! moduleNameList instanceof Array) {
|
||||
throw "allModulesPresent() takes an array, passed " + typeof(moduleNameList);
|
||||
}
|
||||
|
||||
for (var i = 0; i < moduleNameList.length; ++i) {
|
||||
if (module.modulePresent(moduleNameList[i]) === false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Javascript libraries call this function to get a list of the
|
||||
* currently registered modules.
|
||||
*
|
||||
* @member vtkWeb
|
||||
* @method getRegisteredModules
|
||||
*
|
||||
* @return {Array} An array of the registered module names.
|
||||
*/
|
||||
module.getRegisteredModules = function() {
|
||||
return registeredModules;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Local module registration
|
||||
// ----------------------------------------------------------------------
|
||||
try {
|
||||
// Tests for presence of jQuery, then registers this module
|
||||
if ($ !== undefined) {
|
||||
module.registerModule('vtkweb-base');
|
||||
} else {
|
||||
console.error('Module failed to register, jQuery is missing: ' + err.message);
|
||||
}
|
||||
} catch(err) {
|
||||
console.error('Caught exception while registering module: ' + err.message);
|
||||
}
|
||||
|
||||
}(window, jQuery));
|
||||
250
ParaView-5.0.1/VTK/Web/JavaScript/Lib/vtkweb.launcher.js
Normal file
250
ParaView-5.0.1/VTK/Web/JavaScript/Lib/vtkweb.launcher.js
Normal file
@ -0,0 +1,250 @@
|
||||
/**
|
||||
* vtkWeb JavaScript Library.
|
||||
*
|
||||
* This module allow the Web client to start a remote vtkWeb session and
|
||||
* retreive all the connection information needed to properly connect to that
|
||||
* newly created session.
|
||||
*
|
||||
* @class vtkWeb.launcher
|
||||
*
|
||||
* {@img paraview/ParaViewWeb-multiuser.png alt Focus on the communication between the client and the front-end that manage the vtkWeb processes}
|
||||
*/
|
||||
(function (GLOBAL, $) {
|
||||
|
||||
// Internal field used to store all connection objects
|
||||
var Connections = [], module = {}, console = GLOBAL.console;
|
||||
|
||||
function generateSecretKey() {
|
||||
var text = "";
|
||||
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
|
||||
for( var i=0; i < 10; i++ )
|
||||
text += possible.charAt(Math.floor(Math.random() * possible.length));
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
/**
|
||||
* @class vtkWeb.Connection
|
||||
* This class provides all the informations needed to connect to the session
|
||||
* manager web service.
|
||||
*/
|
||||
/**
|
||||
* @member vtkWeb.Connection
|
||||
* @property {String} sessionManagerURL
|
||||
* The service URL that will respond to the REST request to start or stop
|
||||
* a visualization session.
|
||||
*
|
||||
* MANDATORY
|
||||
*/
|
||||
/**
|
||||
* @member vtkWeb.Connection
|
||||
* @property {String} name
|
||||
* The name given for the visualization.
|
||||
*
|
||||
* RECOMMENDED/OPTIONAL
|
||||
*/
|
||||
/**
|
||||
* @member vtkWeb.Connection
|
||||
* @property {String} application
|
||||
* The name of the application that should be started on the server side.
|
||||
*
|
||||
* MANDATORY
|
||||
*/
|
||||
/**
|
||||
* @member vtkWeb.Connection
|
||||
* @property {String|Number} __Any_Name__
|
||||
* Any property that we want to provide to the session that will be created.
|
||||
* Such property is not necessary used by the session manager but will be
|
||||
* returned if a connection information is requested from a session.
|
||||
*
|
||||
* OPTIONAL
|
||||
*/
|
||||
/**
|
||||
* @member vtkWeb.Connection
|
||||
* @property {String} secret
|
||||
* Password that should be used to protect remote session access.
|
||||
*
|
||||
* This property is used by the launcher to secure the process that it start
|
||||
* but it is also used by the client to authenticate itself against
|
||||
* the remote process.
|
||||
*
|
||||
* This can be provided by the client or by the server depending who
|
||||
* generate it. In both case, the client will use it for its authentication.
|
||||
* If missing, then the client will use the default secret key.
|
||||
*
|
||||
* OPTIONAL
|
||||
*/
|
||||
/**
|
||||
* @member vtkWeb.Connection
|
||||
* @property {Number} generate-secret
|
||||
* Property used to specify where the generation of the secret key should be
|
||||
* made.
|
||||
* 0: We use the default secret key. (No dynamic one)
|
||||
* 1: The JavaScript client generate the key and its the responsability of
|
||||
* the server to provide the generated key to the vtkWeb process.
|
||||
* 2: The launcher process generate that key when it start the vtkWeb
|
||||
* process. That given secret key must be returned to the client within
|
||||
* the connection object.
|
||||
*
|
||||
* OPTIONAL
|
||||
*/
|
||||
|
||||
//=========================================================================
|
||||
|
||||
/**
|
||||
* @member vtkWeb.Connection
|
||||
* @property {String} sessionURL
|
||||
* The websocket URL that should be used to connect to the running
|
||||
* visualization session.
|
||||
* This field is provided within the response.
|
||||
*/
|
||||
/**
|
||||
* @member vtkWeb.Connection
|
||||
* @property {String} id
|
||||
* The session identifier.
|
||||
* This field is provided within the response.
|
||||
*/
|
||||
/**
|
||||
* @member vtkWeb.Connection
|
||||
* @property {vtkWeb.Session} session
|
||||
* The session object will be automatically added to the connection once the
|
||||
* connection is properly established by calling:
|
||||
*
|
||||
* vtkWeb.connect(connection, success, error);
|
||||
*
|
||||
* This field is provided within the response.
|
||||
*/
|
||||
//=========================================================================
|
||||
|
||||
/**
|
||||
* Start a new vtkWeb process on the server side.
|
||||
* This method will make a JSON POST request to config.sessionManagerURL URL.
|
||||
*
|
||||
* @member vtkWeb.launcher
|
||||
*
|
||||
* @param {vtkWeb.ConnectionConfig} config
|
||||
* Session creation parameters. (sessionManagerURL, name, application).
|
||||
*
|
||||
* @param {Function} successCallback
|
||||
* The function will be called once the connection is successfully performed.
|
||||
* The argument of the callback will be a {@link vtkWeb.Connection}.
|
||||
*
|
||||
* @param {Function} errorCallback
|
||||
* The function will be called if anything bad happened and an explanation
|
||||
* message will be provided as argument.
|
||||
*/
|
||||
function start(config, successFunction, errorFunction) {
|
||||
if(!config.hasOwnProperty("secret") && config.hasOwnProperty("generate-secret") && config["generate-secret"] === 1) {
|
||||
config.secret = generateSecretKey();
|
||||
}
|
||||
var okCallback = successFunction,
|
||||
koCallback = errorFunction,
|
||||
arg = {
|
||||
url: config.sessionManagerURL,
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
data: (JSON.stringify(config)),
|
||||
success: function (reply) {
|
||||
Connections.push(reply);
|
||||
if (okCallback) {
|
||||
okCallback(reply);
|
||||
}
|
||||
},
|
||||
error: function (errMsg) {
|
||||
if (koCallback) {
|
||||
koCallback(errMsg);
|
||||
}
|
||||
}
|
||||
};
|
||||
return $.ajax(arg);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Query the Session Manager in order to retreive connection informations
|
||||
* based on a session id.
|
||||
*
|
||||
* @member vtkWeb.launcher
|
||||
*
|
||||
* @param {String} sessionManagerURL
|
||||
* Same as ConnectionConfig.sessionManagerURL value.
|
||||
*
|
||||
* @param {String} sessionId
|
||||
* The unique identifier of a session.
|
||||
*
|
||||
* @return {vtkWeb.Connection} if the session is found.
|
||||
*/
|
||||
function fetchConnection(sessionManagerURL, sessionId) {
|
||||
var config = {
|
||||
url: sessionManagerURL + '/' + sessionId,
|
||||
dataType: "json"
|
||||
};
|
||||
return $.ajax(config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop a remote running visualization session.
|
||||
*
|
||||
* @member vtkWeb.launcher
|
||||
*
|
||||
* @param {vtkWeb.ConnectionConfig} connection
|
||||
*/
|
||||
function stop(connection) {
|
||||
var config = {
|
||||
url: connection.sessionManagerURL + "/" + connection.id,
|
||||
type: "DELETE",
|
||||
dataType: "json",
|
||||
success: function (reply) {
|
||||
console.log(reply);
|
||||
},
|
||||
error: function (errMsg) {
|
||||
console.log("Error while trying to close service");
|
||||
}
|
||||
};
|
||||
return $.ajax(config);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Init vtkWeb module if needed
|
||||
// ----------------------------------------------------------------------
|
||||
if (GLOBAL.hasOwnProperty("vtkWeb")) {
|
||||
module = GLOBAL.vtkWeb || {};
|
||||
} else {
|
||||
GLOBAL.vtkWeb = module;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Export internal methods to the vtkWeb module
|
||||
// ----------------------------------------------------------------------
|
||||
module.start = function (config, successFunction, errorFunction) {
|
||||
return start(config, successFunction, errorFunction);
|
||||
};
|
||||
module.stop = function (connection) {
|
||||
return stop(connection);
|
||||
};
|
||||
module.fetchConnection = function (serviceUrl, sessionId) {
|
||||
return fetchConnection(serviceUrl, sessionId);
|
||||
};
|
||||
/**
|
||||
* Return all the session connections created in that JavaScript context.
|
||||
* @member vtkWeb.launcher
|
||||
* @return {vtkWeb.Connection[]}
|
||||
*/
|
||||
module.getConnections = function () {
|
||||
return Connections;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Local module registration
|
||||
// ----------------------------------------------------------------------
|
||||
try {
|
||||
// Tests for presence of jQuery, then registers this module
|
||||
if ($ !== undefined) {
|
||||
module.registerModule('vtkweb-launcher');
|
||||
}
|
||||
} catch(err) {
|
||||
console.error('jQuery is missing: ' + err.message);
|
||||
}
|
||||
|
||||
}(window, jQuery));
|
||||
109
ParaView-5.0.1/VTK/Web/JavaScript/Lib/vtkweb.simple.js
Normal file
109
ParaView-5.0.1/VTK/Web/JavaScript/Lib/vtkweb.simple.js
Normal file
@ -0,0 +1,109 @@
|
||||
/**
|
||||
* vtkWeb JavaScript Library.
|
||||
*
|
||||
* This module provide simpler connection paradigm for the Web client
|
||||
* to connect to a remote vtkWeb session.
|
||||
*
|
||||
* This module registers itself as: 'vtkweb-simple'
|
||||
*
|
||||
* @class vtkWeb.simple
|
||||
*/
|
||||
(function (GLOBAL, $) {
|
||||
|
||||
// Connections field used to store a map of the active sessions
|
||||
var module = {};
|
||||
|
||||
function autoConnect(connection, ready, close) {
|
||||
if(connection.hasOwnProperty('sessionURL')) {
|
||||
// Direct connect
|
||||
vtkWeb.connect(connection, ready, close);
|
||||
} else {
|
||||
// Launch process
|
||||
vtkWeb.start( connection, function(connection) {
|
||||
if(connection.error) {
|
||||
alert(connection.error);
|
||||
close("error", connection.error);
|
||||
} else {
|
||||
// The process successfuly started
|
||||
// => Just connect to the WebSocket
|
||||
vtkWeb.connect(connection, ready, close);
|
||||
}
|
||||
}, function(msg) {
|
||||
// No launcher found or error
|
||||
try {
|
||||
var launcherResponse = JSON.parse(msg.responseText);
|
||||
close("launcher error", launcherResponse);
|
||||
} catch (err) {
|
||||
console.log("No launcher found. Attempting to connect using the direct WS url.");
|
||||
connection.sessionURL = vtkWeb.properties.sessionURL;
|
||||
vtkWeb.connect(connection, ready, close);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Init vtkWeb module if needed
|
||||
// ----------------------------------------------------------------------
|
||||
if (GLOBAL.hasOwnProperty("vtkWeb")) {
|
||||
module = GLOBAL.vtkWeb || {};
|
||||
} else {
|
||||
GLOBAL.vtkWeb = module;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Export methods to the vtkWeb module
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Simple method that will automatically try to launch or connect
|
||||
* to an existing session based on URL parameters and failures.
|
||||
*
|
||||
* @member vtkWeb.simple
|
||||
* @method smartConnect
|
||||
*
|
||||
* @param {Object} base connection information
|
||||
* @param {Function} callback when success which expect
|
||||
* a full connection object as argument.
|
||||
* @param {Function} callback when failure occurs with "code" and "reason"
|
||||
* why the failure occured.
|
||||
*/
|
||||
module.smartConnect = function (connection, ready, close) {
|
||||
if(close === undefined) {
|
||||
close = module.errorCallback;
|
||||
}
|
||||
// Extend connection with URL parameters
|
||||
module.udpateConnectionFromURL(connection);
|
||||
|
||||
// Check if we should connect to an existing session
|
||||
if(connection.hasOwnProperty('session')) {
|
||||
var url = connection['sessionManagerURL'] + connection['session'];
|
||||
$.ajax({
|
||||
url: url,
|
||||
dataType: 'json'
|
||||
}).done(function(realConnection){
|
||||
autoConnect(realConnection, ready, close);
|
||||
}).fail(function(arg){
|
||||
alert("Unable to connect to the given session: " + connection['session']);
|
||||
close("error", "Unable to connect to the given session: " + connection['session']);
|
||||
});
|
||||
} else {
|
||||
autoConnect(connection, ready, close);
|
||||
}
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Local module registration
|
||||
// ----------------------------------------------------------------------
|
||||
try {
|
||||
// Tests for presence of autobahn, then registers this module
|
||||
if (module.allModulesPresent(['vtkweb-connect', 'vtkweb-launcher'])) {
|
||||
module.registerModule('vtkweb-simple');
|
||||
} else {
|
||||
console.error('Module failed to register, vtkweb-connect and vtkweb-launcher are missing');
|
||||
}
|
||||
} catch(err) {
|
||||
console.error('Caught exception while registering module: ' + err.message);
|
||||
}
|
||||
|
||||
}(window, jQuery));
|
||||
347
ParaView-5.0.1/VTK/Web/JavaScript/Lib/vtkweb.testing.js
Normal file
347
ParaView-5.0.1/VTK/Web/JavaScript/Lib/vtkweb.testing.js
Normal file
@ -0,0 +1,347 @@
|
||||
/**
|
||||
* vtkWeb JavaScript Library.
|
||||
*
|
||||
* This testing module is made to test vtkWeb components
|
||||
*
|
||||
* This module registers itself as: 'vtkweb-testing'
|
||||
*
|
||||
* @class vtkWeb.testing
|
||||
*
|
||||
* @singleton
|
||||
*/
|
||||
(function (GLOBAL, $) {
|
||||
|
||||
var parentModule = {}, module = {}, testToRun = 0;
|
||||
testSuite = {}, testOrder = [], outputLog = [], w = $(window),
|
||||
testTotal = 0, testRunned = 0, success = 0, failure = 0,
|
||||
testNameToRun = [],
|
||||
testLineTemplate = '<tr id="NAME"><td><input type="checkbox" value="NAME" checked/></td><td width="100%">NAME</td><td align="center" class="status">STATUS</td></tr>',
|
||||
tableHeader = '<thead><tr><th><input type="checkbox" value="select-all-test" title="Toggle all test selection" checked/></th><th width="100%">Test names</th><th>Status</th></tr>',
|
||||
outputLogHTML = '<div class="row-fluid log" style="display: none;"><div class="span12"><textarea style="width: 98%;height: 150px;"></textarea></div></div></thead>',
|
||||
controlHTML = '<table class="table table-striped"><thead><tr><th width="100%"></th><th><div class="run-tests vtk-icon-play"></div></th><th><div class="toggle-log vtk-icon-tools"></div></th><th class="summary" style="border-radius: 5px;">Results</th><th><span id="passedTestsSpan" class="badge badge-success">0</span></th><th><span id="failedTestsSpan" class="badge" style="background-color: red">0</span></th></tr></thead></table>',
|
||||
statusSuccess = '<div class="vtk-icon-ok-circled" style="color: green;"></div>',
|
||||
statusFailure = '<div class="vtk-icon-cancel-circled" style="color: red;"></div>',
|
||||
statusNotRunned = '<div class="vtk-icon-help-circled"></div>';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Init vtkWeb.testing module if needed
|
||||
// ----------------------------------------------------------------------
|
||||
if (GLOBAL.hasOwnProperty("vtkWeb")) {
|
||||
parentModule = GLOBAL.vtkWeb || {};
|
||||
} else {
|
||||
GLOBAL.vtkWeb = parentModule;
|
||||
}
|
||||
if (parentModule.hasOwnProperty("testing")) {
|
||||
module = GLOBAL.vtkWeb.testing || {};
|
||||
} else {
|
||||
GLOBAL.vtkWeb.testing = module;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Internal methods
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
function registerTest(name, func) {
|
||||
testOrder.push(name);
|
||||
testSuite[name] = {
|
||||
'name': name,
|
||||
'func': func,
|
||||
'active': true,
|
||||
'message': null,
|
||||
'success': false,
|
||||
'done': false
|
||||
};
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
function clearLog() {
|
||||
outputLog = [];
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
function logToString() {
|
||||
return outputLog.join('\n');
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
function clearResults() {
|
||||
outputLog = [];
|
||||
testTotal = 0;
|
||||
testRunned = 0;
|
||||
success = 0;
|
||||
failure = 0;
|
||||
for(var test in testSuite) {
|
||||
test.success = false;
|
||||
test.message = null;
|
||||
test.done = false;
|
||||
}
|
||||
w.trigger('vtk-test-clear');
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
function log(msg) {
|
||||
outputLog.push(msg);
|
||||
w.trigger('vtk-test-log-update');
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
function resultCallback(result) {
|
||||
var test = testSuite[result.name];
|
||||
|
||||
// Update test info
|
||||
test.done = true;
|
||||
test.message = result.message;
|
||||
test.success = result.success;
|
||||
|
||||
// Less test remaining
|
||||
++testRunned;
|
||||
if(result.success) {
|
||||
++success;
|
||||
} else {
|
||||
++failure;
|
||||
}
|
||||
|
||||
// Update log
|
||||
log((test.success?"+":"-") + result.name + ": " + test.message);
|
||||
|
||||
// Trigger event
|
||||
result.count = testRunned;
|
||||
result.total = testTotal;
|
||||
result.coutSuccess = success;
|
||||
result.countFailure = failure;
|
||||
result.type = 'vtk-test-complete';
|
||||
w.trigger(result);
|
||||
|
||||
if(testTotal === testRunned) {
|
||||
w.trigger('vtk-test-done');
|
||||
} else {
|
||||
runAnotherTest();
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
function testToString(testName) {
|
||||
return testLineTemplate.replace(/ID/g, testName).replace(/NAME/g, testName).replace('STATUS', statusNotRunned);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
function runAnotherTest() {
|
||||
var testName = testNameToRun.shift();
|
||||
var testFunction = testSuite[testName].func;
|
||||
testFunction(testName, resultCallback);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Export methods to the vtkWeb.testing module
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Register a set of methods as tests.
|
||||
*
|
||||
* @class vtkWeb.testing
|
||||
* @method registerTests
|
||||
* @param {Object} testSuiteToRegister
|
||||
* Should contains a set of methods that will be
|
||||
* executed.
|
||||
*/
|
||||
|
||||
module.registerTests = function(testSuiteToRegister) {
|
||||
for (var testName in testSuiteToRegister) {
|
||||
registerTest(testName, testSuiteToRegister[testName]);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Trigger the run of all the active test that have been
|
||||
* previously registered.
|
||||
*
|
||||
* @class vtkWeb.testing
|
||||
* @method runTests
|
||||
*/
|
||||
|
||||
module.runTests = function() {
|
||||
clearResults();
|
||||
log("Start testings...");
|
||||
|
||||
// Extract active tests list
|
||||
testNameToRun = [];
|
||||
for(var idx in testOrder) {
|
||||
if(testSuite[testOrder[idx]].active) {
|
||||
testNameToRun.push(testOrder[idx]);
|
||||
}
|
||||
}
|
||||
testTotal = testNameToRun.length;
|
||||
|
||||
// Start the tests running
|
||||
runAnotherTest();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Toggle test to be run.
|
||||
*
|
||||
* @class vtkWeb.testing
|
||||
* @method enableTest
|
||||
*/
|
||||
|
||||
module.enableTest = function(name, status) {
|
||||
testSuite[name].active = status;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Return test results summary.
|
||||
*
|
||||
* @class vtkWeb.testing
|
||||
* @method getCurrentTestResults
|
||||
*/
|
||||
|
||||
module.getCurrentTestResults = function() {
|
||||
return {
|
||||
'finished': (testTotal === testRunned),
|
||||
'testCount': testTotal,
|
||||
'successes': success,
|
||||
'failures': failure
|
||||
};
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Retrieve the test log, which contains all detailed error outputs from
|
||||
* the tests.
|
||||
*
|
||||
* @class vtkWeb.testing
|
||||
* @method getTestLog
|
||||
*/
|
||||
|
||||
module.getTestLog = logToString;
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Provide JQuery widgets
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Fill the selected container with test list and
|
||||
* action buttons to toggle and run them.
|
||||
*
|
||||
* @class jquery
|
||||
* @method vtkWebTestList
|
||||
*/
|
||||
$.fn.vtkWebTestList = function(options) {
|
||||
return this.each(function() {
|
||||
var me = $(this).empty(), buffer = [];
|
||||
|
||||
// Generate HTML
|
||||
buffer.push(controlHTML);
|
||||
buffer.push('<table class="table table-striped test-panel">');
|
||||
buffer.push(tableHeader);
|
||||
buffer.push('<tbody>');
|
||||
for(var idx in testOrder) {
|
||||
buffer.push(testToString(testOrder[idx]));
|
||||
}
|
||||
buffer.push('</tbody></table>');
|
||||
buffer.push(outputLogHTML);
|
||||
me[0].innerHTML = buffer.join('');
|
||||
|
||||
// Initialize listeners
|
||||
$('input', me).change(function(){
|
||||
var checkbox = $(this),
|
||||
checked = checkbox.is(":checked"),
|
||||
testName = checkbox.val();
|
||||
|
||||
if(testSuite.hasOwnProperty(testName)) {
|
||||
testSuite[testName].active = checked;
|
||||
} else {
|
||||
$('input', me).prop('checked', checked);
|
||||
for(var test in testSuite) {
|
||||
testSuite[test].active = checked;
|
||||
}
|
||||
}
|
||||
clearResults();
|
||||
});
|
||||
|
||||
$('.toggle-log', me).click(function(){
|
||||
var log = $('.log');
|
||||
var results = $('.test-panel');
|
||||
if(log.is(":visible")) {
|
||||
log.hide();
|
||||
results.show();
|
||||
} else {
|
||||
log.show();
|
||||
results.hide();
|
||||
}
|
||||
});
|
||||
|
||||
$('.run-tests', me).click(function(){
|
||||
module.runTests();
|
||||
});
|
||||
|
||||
// Bind events to UI updates
|
||||
w.bind('vtk-test-clear', function(){
|
||||
updateTextArea();
|
||||
updateResultSummary();
|
||||
$(".status").html(statusNotRunned);
|
||||
}).bind('vtk-test-complete', function(event){
|
||||
updateTextArea();
|
||||
updateResultSummary();
|
||||
updateStatus(event.name);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
function updateTextArea() {
|
||||
$('textarea')[0].innerHTML = logToString();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
function updateResultSummary() {
|
||||
$('#passedTestsSpan').html(success);
|
||||
$('#failedTestsSpan').html(failure);
|
||||
if(testTotal !== 0 && testTotal === testRunned) {
|
||||
if(success === testTotal) {
|
||||
$('.summary').css('background', 'green');
|
||||
} else {
|
||||
$('.summary').css('background', 'red');
|
||||
}
|
||||
} else {
|
||||
$('.summary').css('background', 'none');
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
function updateStatus(testName) {
|
||||
var test = testSuite[testName]
|
||||
$("#" + testName + " .status").html(test.success ? statusSuccess : statusFailure).attr('title', test.message);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Local module registration
|
||||
// ----------------------------------------------------------------------
|
||||
try {
|
||||
// Tests for presence of jQuery, then registers this module
|
||||
if ($ !== undefined) {
|
||||
parentModule.registerModule('vtkweb-testing');
|
||||
} else {
|
||||
console.error('Module failed to register, jQuery is missing.');
|
||||
}
|
||||
} catch(err) {
|
||||
console.error('Caught exception while registering module: ' + err.message);
|
||||
}
|
||||
|
||||
}(window, jQuery));
|
||||
346
ParaView-5.0.1/VTK/Web/JavaScript/Lib/vtkweb.viewport.image.js
Normal file
346
ParaView-5.0.1/VTK/Web/JavaScript/Lib/vtkweb.viewport.image.js
Normal file
@ -0,0 +1,346 @@
|
||||
/**
|
||||
* vtkWeb JavaScript Library.
|
||||
*
|
||||
* This module extend the vtkWeb viewport to add support for Image delivery
|
||||
* mechanism for rendering.
|
||||
*
|
||||
* @class vtkWeb.viewports.image
|
||||
*
|
||||
* Viewport Factory description:
|
||||
* - Key: image
|
||||
* - Stats:
|
||||
* - image-fps
|
||||
* - image-round-trip
|
||||
* - image-server-processing
|
||||
*/
|
||||
(function (GLOBAL, $) {
|
||||
var module = {},
|
||||
RENDERER_CSS = {
|
||||
"position": "absolute",
|
||||
"top": "0px",
|
||||
"left": "0px",
|
||||
"right": "0px",
|
||||
"bottom": "0px",
|
||||
"z-index" : "0"
|
||||
},
|
||||
DEFAULT_OPTIONS = {
|
||||
interactiveQuality: 30,
|
||||
stillQuality: 100
|
||||
},
|
||||
FACTORY_KEY = 'image',
|
||||
FACTORY = {
|
||||
'builder': createImageDeliveryRenderer,
|
||||
'options': DEFAULT_OPTIONS,
|
||||
'stats': {
|
||||
'image-fps': {
|
||||
label: 'Framerate',
|
||||
type: 'time',
|
||||
convert: function(value) {
|
||||
if(value === 0) {
|
||||
return 0;
|
||||
}
|
||||
return (1000 / value).toFixed(2);
|
||||
}
|
||||
},
|
||||
'image-round-trip': {
|
||||
label: 'Round trip (ms)',
|
||||
type: 'value',
|
||||
convert: NoOp
|
||||
},
|
||||
'image-server-processing': {
|
||||
label: 'Processing Time (ms)',
|
||||
type: 'value',
|
||||
convert: NoOp
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
function NoOp(a) {
|
||||
return a;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Image Delivery renderer - factory method
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
function createImageDeliveryRenderer(domElement) {
|
||||
var container = $(domElement),
|
||||
options = $.extend({}, DEFAULT_OPTIONS, container.data('config')),
|
||||
bgImage = new Image(),
|
||||
session = options.session,
|
||||
canvas = GLOBAL.document.createElement('canvas'),
|
||||
ctx2d = canvas.getContext('2d'),
|
||||
renderer = $(canvas).addClass(FACTORY_KEY).css(RENDERER_CSS).append(bgImage),
|
||||
force_render = false,
|
||||
statistics = null,
|
||||
lastMTime = 0,
|
||||
render_onidle_timeout = null,
|
||||
action_pending = false,
|
||||
button_state = {
|
||||
left : false,
|
||||
right: false,
|
||||
middle : false
|
||||
},
|
||||
quality = 100;
|
||||
|
||||
// ----
|
||||
/// Internal method that returns true if the mouse interaction event should be
|
||||
/// throttled.
|
||||
function eatMouseEvent(event) {
|
||||
var force_event = (button_state.left !== event.buttonLeft || button_state.right !== event.buttonRight || button_state.middle !== event.buttonMiddle);
|
||||
if (!force_event && !event.buttonLeft && !event.buttonRight && !event.buttonMiddle && !event.scroll) {
|
||||
return true;
|
||||
}
|
||||
if (!force_event && action_pending) {
|
||||
return true;
|
||||
}
|
||||
button_state.left = event.buttonLeft;
|
||||
button_state.right = event.buttonRight;
|
||||
button_state.middle = event.buttonMiddle;
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----
|
||||
// Internal function that requests a render on idle. Calling this
|
||||
// mutliple times will only result in the request being set once.
|
||||
function renderOnIdle() {
|
||||
if (render_onidle_timeout === null) {
|
||||
render_onidle_timeout = GLOBAL.setTimeout(render, 250);
|
||||
}
|
||||
}
|
||||
|
||||
// Setup internal API
|
||||
function render(fetch) {
|
||||
if (force_render === false) {
|
||||
if (render_onidle_timeout !== null) {
|
||||
// clear any renderOnIdle requests that are pending since we
|
||||
// are sending a render request.
|
||||
GLOBAL.clearTimeout(render_onidle_timeout);
|
||||
render_onidle_timeout = null;
|
||||
}
|
||||
force_render = true;
|
||||
|
||||
var renderCfg = {
|
||||
size: [ container.innerWidth(), container.innerHeight() ],
|
||||
view: Number(options.view),
|
||||
mtime: fetch ? 0 : lastMTime,
|
||||
quality: quality,
|
||||
localTime : new Date().getTime()
|
||||
};
|
||||
|
||||
container.trigger({
|
||||
type: 'stats',
|
||||
stat_id: 'image-fps',
|
||||
stat_value: 0 // start
|
||||
});
|
||||
|
||||
session.call("viewport.image.render", [renderCfg]).then(function (res) {
|
||||
options.view = Number(res.global_id);
|
||||
lastMTime = res.mtime;
|
||||
if(res.hasOwnProperty("image") && res.image !== null) {
|
||||
/**
|
||||
* @member vtkWeb.Viewport
|
||||
* @event start-loading
|
||||
*/
|
||||
|
||||
$(container).parent().trigger("start-loading");
|
||||
bgImage.width = res.size[0];
|
||||
bgImage.height = res.size[1];
|
||||
var previousSrc = bgImage.src;
|
||||
bgImage.src = "data:image/" + res.format + "," + res.image;
|
||||
|
||||
container.trigger({
|
||||
type: 'stats',
|
||||
stat_id: 'image-fps',
|
||||
stat_value: 1 // stop
|
||||
});
|
||||
|
||||
container.trigger({
|
||||
type: 'stats',
|
||||
stat_id: 'image-round-trip',
|
||||
stat_value: Number(new Date().getTime() - res.localTime) - res.workTime
|
||||
});
|
||||
|
||||
container.trigger({
|
||||
type: 'stats',
|
||||
stat_id: 'image-server-processing',
|
||||
stat_value: Number(res.workTime)
|
||||
});
|
||||
}
|
||||
renderStatistics();
|
||||
force_render = false;
|
||||
container.trigger('done');
|
||||
|
||||
// the image we received is not the latest, we should
|
||||
// request another render to try to get the latest image.
|
||||
if (res.stale === true) {
|
||||
renderOnIdle();
|
||||
} else {
|
||||
container.trigger({
|
||||
type: 'renderer-ready'
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// internal function to render stats.
|
||||
function renderStatistics() {
|
||||
if (statistics) {
|
||||
ctx2d.font = "bold 12px sans-serif";
|
||||
//ctx2d.fillStyle = "white";
|
||||
ctx2d.fillStyle = "black";
|
||||
ctx2d.fillRect(10, 10, 240, 100);
|
||||
//ctx2d.fillStyle = "black";
|
||||
ctx2d.fillStyle = "white";
|
||||
ctx2d.fillText("Frame Rate: " + statistics.frameRate().toFixed(2), 15, 25);
|
||||
ctx2d.fillText("Average Frame Rate: " + statistics.averageFrameRate().toFixed(2),
|
||||
15, 40);
|
||||
ctx2d.fillText("Round trip: " + statistics.roundTrip() + " ms - Max: " + statistics.maxRoundTrip() + " ms",
|
||||
15, 55);
|
||||
ctx2d.fillText("Server work time: " + statistics.serverWorkTime() + " ms - Max: " + statistics.maxServerWorkTime() + " ms",
|
||||
15, 70);
|
||||
ctx2d.fillText("Minimum Frame Rate: " + statistics.minFrameRate().toFixed(2),
|
||||
15, 85);
|
||||
ctx2d.fillText("Loading time: " + statistics.trueLoadTime(),
|
||||
15, 100);
|
||||
}
|
||||
}
|
||||
|
||||
// Choose if rendering is happening in Canvas or image
|
||||
bgImage.onload = function(){
|
||||
paint();
|
||||
};
|
||||
|
||||
// internal function used to draw update data on the canvas. When not
|
||||
// using canvas, this has no effect.
|
||||
function paint() {
|
||||
/**
|
||||
* @member vtkWeb.Viewport
|
||||
* @event stop-loading
|
||||
*/
|
||||
$(container).parent().trigger("stop-loading");
|
||||
ctx2d.canvas.width = $(container).width();
|
||||
ctx2d.canvas.height = $(container).height();
|
||||
ctx2d.drawImage(bgImage, 0, 0, bgImage.width, bgImage.height);
|
||||
renderStatistics();
|
||||
}
|
||||
|
||||
// Attach listener to container for mouse interaction and invalidateScene
|
||||
container.bind('invalidateScene', function() {
|
||||
if(renderer.hasClass('active')){
|
||||
render(true);
|
||||
}
|
||||
}).bind('resetViewId', function(e){
|
||||
options.view = -1;
|
||||
}).bind('captureRenderedImage', function(e){
|
||||
if(renderer.hasClass('active')){
|
||||
$(container).parent().trigger({
|
||||
type: 'captured-screenshot-ready',
|
||||
imageData: bgImage.src
|
||||
});
|
||||
}
|
||||
}).bind('render', function(e){
|
||||
if(renderer.hasClass('active')){
|
||||
var opts = e.options,
|
||||
previousQuality = quality,
|
||||
forceRender = false;
|
||||
|
||||
if(opts) {
|
||||
quality = opts.hasOwnProperty('quality') ? opts.quality : quality;
|
||||
options.view = opts.hasOwnProperty('view') ? opts.view : options.view;
|
||||
forceRender = opts.hasOwnProperty('forceRender');
|
||||
}
|
||||
|
||||
render(forceRender);
|
||||
|
||||
// Revert back to previous state
|
||||
quality = previousQuality;
|
||||
}
|
||||
}).bind('mouse', function(evt){
|
||||
if(renderer.hasClass('active')){
|
||||
// stop default event handling by the browser.
|
||||
evt.preventDefault();
|
||||
|
||||
// Update quality based on the type of the event
|
||||
if(evt.action === 'up' || evt.action === 'dblclick' || evt.action === 'scroll') {
|
||||
quality = options.stillQuality;
|
||||
} else {
|
||||
quality = options.interactiveQuality;
|
||||
}
|
||||
|
||||
var vtkWeb_event = {
|
||||
view: Number(options.view),
|
||||
action: evt.action,
|
||||
charCode: evt.charCode,
|
||||
altKey: evt.altKey,
|
||||
ctrlKey: evt.ctrlKey,
|
||||
shiftKey: evt.shiftKey,
|
||||
metaKey: evt.metaKey,
|
||||
buttonLeft: (evt.current_button === 1 ? true : false),
|
||||
buttonMiddle: (evt.current_button === 2 ? true : false),
|
||||
buttonRight: (evt.current_button === 3 ? true : false)
|
||||
},
|
||||
elem_position = $(evt.delegateTarget).offset(),
|
||||
pointer = {
|
||||
x : (evt.pageX - elem_position.left),
|
||||
y : (evt.pageY - elem_position.top)
|
||||
};
|
||||
|
||||
if(evt.action === 'scroll') {
|
||||
vtkWeb_event.scroll = evt.scroll;
|
||||
} else {
|
||||
vtkWeb_event.x = pointer.x / renderer.width();
|
||||
vtkWeb_event.y = 1.0 - (pointer.y / renderer.height());
|
||||
}
|
||||
|
||||
if (eatMouseEvent(vtkWeb_event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
action_pending = true;
|
||||
session.call("viewport.mouse.interaction", [vtkWeb_event]).then(function (res) {
|
||||
if (res) {
|
||||
action_pending = false;
|
||||
render();
|
||||
}
|
||||
}, function(error) {
|
||||
console.log("Call to viewport.mouse.interaction failed");
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
}).append(renderer);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Init vtkWeb module if needed
|
||||
// ----------------------------------------------------------------------
|
||||
if (GLOBAL.hasOwnProperty("vtkWeb")) {
|
||||
module = GLOBAL.vtkWeb || {};
|
||||
} else {
|
||||
GLOBAL.vtkWeb = module;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Extend the viewport factory
|
||||
// ----------------------------------------------------------------------
|
||||
if(!module.hasOwnProperty('ViewportFactory')) {
|
||||
module['ViewportFactory'] = {};
|
||||
}
|
||||
module.ViewportFactory[FACTORY_KEY] = FACTORY;
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Local module registration
|
||||
// ----------------------------------------------------------------------
|
||||
try {
|
||||
// Tests for presence of jQuery, then registers this module
|
||||
if ($ !== undefined) {
|
||||
module.registerModule('vtkweb-viewport-image');
|
||||
}
|
||||
} catch(err) {
|
||||
console.error('jQuery is missing: ' + err.message);
|
||||
}
|
||||
|
||||
}(window, jQuery));
|
||||
892
ParaView-5.0.1/VTK/Web/JavaScript/Lib/vtkweb.viewport.js
Normal file
892
ParaView-5.0.1/VTK/Web/JavaScript/Lib/vtkweb.viewport.js
Normal file
@ -0,0 +1,892 @@
|
||||
/**
|
||||
* vtkWeb JavaScript Library.
|
||||
*
|
||||
* This module allow the Web client to create viewport to vtkWeb views.
|
||||
* Those viewport are interactive windows that are used to render 2D/3D content
|
||||
* and response to user mouse interactions.
|
||||
*
|
||||
* This module registers itself as: 'vtkweb-viewport'
|
||||
*
|
||||
* @class vtkWeb.Viewport
|
||||
*/
|
||||
(function (GLOBAL, $) {
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Viewport constants
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
var DEFAULT_RENDERERS_CONTAINER_HTML = "<div class='renderers'></div>",
|
||||
DEFAULT_RENDERERS_CONTAINER_CSS = {
|
||||
"position": "absolute",
|
||||
"top": "0px",
|
||||
"left": "0px",
|
||||
"right": "0px",
|
||||
"bottom": "0px",
|
||||
"z-index" : "0",
|
||||
"overflow": "hidden"
|
||||
},
|
||||
|
||||
DEFAULT_MOUSE_LISTENER_HTML = "<div class='mouse-listener'></div>",
|
||||
DEFAULT_MOUSE_LISTENER_CSS = {
|
||||
"position": "absolute",
|
||||
"top": "0px",
|
||||
"left": "0px",
|
||||
"right": "0px",
|
||||
"bottom": "0px",
|
||||
"z-index" : "3"
|
||||
},
|
||||
|
||||
DEFAULT_STATISTIC_HTML = "<div class='statistics'></div>",
|
||||
DEFAULT_STATISTIC_CSS = {
|
||||
"position": "absolute",
|
||||
"top": "0px",
|
||||
"left": "0px",
|
||||
"right": "0px",
|
||||
"bottom": "0px",
|
||||
"z-index" : "2",
|
||||
"display" : "none"
|
||||
},
|
||||
|
||||
DEFAULT_OVERLAY_HTML = "<canvas class='overlay'></canvas>",
|
||||
DEFAULT_OVERLAY_CSS = {
|
||||
"position": "absolute",
|
||||
"top": "0px",
|
||||
"left": "0px",
|
||||
"right": "0px",
|
||||
"bottom": "0px",
|
||||
"z-index" : "1"
|
||||
},
|
||||
|
||||
module = {},
|
||||
|
||||
DEFAULT_VIEWPORT_OPTIONS = {
|
||||
session: null,
|
||||
view: -1,
|
||||
enableInteractions: true,
|
||||
renderer: 'image'
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Mouse interaction helper methods for viewport
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
function preventDefault(event) {
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
function attachMouseListener(mouseListenerContainer, renderersContainer, overlayContainer, viewport) {
|
||||
var current_button = null,
|
||||
area = [0,0,0,0],
|
||||
vp = viewport,
|
||||
overlayCtx2D = overlayContainer[0].getContext('2d');
|
||||
|
||||
// Draw rectangle in overlay
|
||||
function clearOverlay() {
|
||||
if(overlayCtx2D !== null) {
|
||||
overlayCtx2D.canvas.width = mouseListenerContainer.width();
|
||||
overlayCtx2D.canvas.height = mouseListenerContainer.height();
|
||||
overlayCtx2D.clearRect(0,0,overlayCtx2D.canvas.width,overlayCtx2D.canvas.height);
|
||||
}
|
||||
}
|
||||
|
||||
function redrawSelection() {
|
||||
clearOverlay();
|
||||
if(overlayCtx2D !== null) {
|
||||
overlayCtx2D.strokeStyle="#FFFFFF";
|
||||
var x1 = Math.min(area[0],area[2]);
|
||||
var y1 = Math.min(area[1],area[3]);
|
||||
var x2 = Math.max(area[0],area[2]);
|
||||
var y2 = Math.max(area[1],area[3]);
|
||||
var width = Math.abs(x2 - x1);
|
||||
var height = Math.abs(y2 - y1);
|
||||
overlayCtx2D.rect(x1, overlayContainer.height()-y2, width, height);
|
||||
overlayCtx2D.stroke();
|
||||
}
|
||||
}
|
||||
|
||||
function extractCoordinates(event, start, reorder) {
|
||||
var elem_position = $(event.delegateTarget).offset(),
|
||||
height = $(event.delegateTarget).height(),
|
||||
x = (event.pageX - elem_position.left),
|
||||
y = (event.pageY - elem_position.top),
|
||||
offset = start ? 0 : 2;
|
||||
area[0 + offset] = x;
|
||||
area[1 + offset] = height - y;
|
||||
|
||||
if(reorder) {
|
||||
// Re-order area
|
||||
var newArea = [
|
||||
Math.min(area[0], area[2]),
|
||||
Math.min(area[1], area[3]),
|
||||
Math.max(area[0], area[2]),
|
||||
Math.max(area[1], area[3])
|
||||
];
|
||||
area[0] = newArea[0];
|
||||
area[1] = newArea[1];
|
||||
area[2] = newArea[2];
|
||||
area[3] = newArea[3];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Internal method used to pre-process the interaction to standardise it
|
||||
// for a vtkWeb usage.
|
||||
function mouseInteraction(event) {
|
||||
if(event.hasOwnProperty("type")) {
|
||||
if(event.type === 'mouseup') {
|
||||
current_button = null;
|
||||
if (vp.getSelectionMode() === true) {
|
||||
clearOverlay();
|
||||
}
|
||||
renderersContainer.trigger($.extend(event, {
|
||||
type: 'mouse',
|
||||
action: 'up',
|
||||
current_button: current_button
|
||||
}));
|
||||
extractCoordinates(event, false, true);
|
||||
renderersContainer.trigger({
|
||||
type: 'endInteraction',
|
||||
area: area
|
||||
});
|
||||
} else if(event.type === 'mousedown') {
|
||||
current_button = event.which;
|
||||
// Override button if modifier is used
|
||||
// Middle: Alt - Right: Shift
|
||||
if(event.shiftKey) {
|
||||
current_button = 3;
|
||||
event.shiftKey = false;
|
||||
} else if(event.altKey) {
|
||||
current_button = 2;
|
||||
event.altKey = false;
|
||||
}
|
||||
extractCoordinates(event, true, false);
|
||||
renderersContainer.trigger('startInteraction');
|
||||
renderersContainer.trigger($.extend(event, {
|
||||
type: 'mouse',
|
||||
action: 'down',
|
||||
current_button: current_button
|
||||
}));
|
||||
|
||||
} else if(event.type === 'mousemove' && current_button != null) {
|
||||
if (vp.getSelectionMode() === true) {
|
||||
extractCoordinates(event, false, false);
|
||||
redrawSelection();
|
||||
}
|
||||
renderersContainer.trigger($.extend(event, {
|
||||
type: 'mouse',
|
||||
action: 'move',
|
||||
current_button: current_button
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Bind listener to UI container
|
||||
mouseListenerContainer.bind("contextmenu mouseover click", preventDefault);
|
||||
mouseListenerContainer.bind('mousedown mouseup mousemove', mouseInteraction);
|
||||
mouseListenerContainer.dblclick(function(event){
|
||||
renderersContainer.trigger($.extend(event, {
|
||||
type: 'mouse',
|
||||
action: 'dblclick',
|
||||
current_button: event.which
|
||||
}));
|
||||
});
|
||||
mouseListenerContainer.bind("DOMMouseScroll mousewheel",function(event){
|
||||
var scrollValue = (event.originalEvent.wheelDeltaY || -event.originalEvent.detail);
|
||||
renderersContainer.trigger($.extend(event, {
|
||||
type: 'mouse',
|
||||
action: 'scroll',
|
||||
current_button: current_button,
|
||||
scroll: scrollValue
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
function attachTouchListener(mouseListenerContainer, renderersContainer, viewport) {
|
||||
var current_button = null, posX, posY, defaultDragButton = 1,
|
||||
isZooming = false, isDragging = false, mouseAction = 'up', target;
|
||||
|
||||
function mobileTouchInteraction(evt) {
|
||||
evt.gesture.preventDefault();
|
||||
switch(evt.type) {
|
||||
case 'drag':
|
||||
if(isZooming) {
|
||||
return;
|
||||
}
|
||||
current_button = defaultDragButton;
|
||||
if(mouseAction === 'up') {
|
||||
mouseAction = "down";
|
||||
|
||||
target = evt.gesture.target;
|
||||
isDragging = true;
|
||||
} else {
|
||||
mouseAction = "move";
|
||||
}
|
||||
|
||||
posX = evt.gesture.touches[0].pageX;
|
||||
posY = evt.gesture.touches[0].pageY;
|
||||
break;
|
||||
case 'hold':
|
||||
if(defaultDragButton === 1) {
|
||||
defaultDragButton = 2;
|
||||
mouseListenerContainer.html("Pan mode").css('color','#FFFFFF');
|
||||
} else {
|
||||
defaultDragButton = 1;
|
||||
mouseListenerContainer.html("Rotation mode").css('color','#FFFFFF');
|
||||
}
|
||||
|
||||
break;
|
||||
case 'release':
|
||||
mouseListenerContainer.html('');
|
||||
current_button = 0;
|
||||
mouseAction = "up";
|
||||
isZooming = false;
|
||||
isDragging = false;
|
||||
break;
|
||||
case 'doubletap':
|
||||
viewport.resetCamera();
|
||||
return;
|
||||
case 'pinch':
|
||||
if(isDragging) {
|
||||
return;
|
||||
}
|
||||
current_button = 3;
|
||||
if(mouseAction === 'up') {
|
||||
mouseAction = 'down';
|
||||
posX = 0;
|
||||
posY = mouseListenerContainer.height();
|
||||
target = evt.gesture.target;
|
||||
isZooming = true;
|
||||
} else {
|
||||
mouseAction = 'move';
|
||||
posY = mouseListenerContainer.height() * (1+(evt.gesture.scale-1)/2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
//mouseListenerContainer.html(mouseAction + ' (' + posX + ', ' + posY + ') b:' + current_button + ' z: ' + isZooming ).css('color','#FFFFFF');
|
||||
|
||||
// Trigger event
|
||||
renderersContainer.trigger({
|
||||
type: 'mouse',
|
||||
action: mouseAction,
|
||||
current_button: current_button,
|
||||
charCode: '',
|
||||
altKey: false,
|
||||
ctrlKey: false,
|
||||
shiftKey: false,
|
||||
metaKey: false,
|
||||
delegateTarget: target,
|
||||
pageX: posX,
|
||||
pageY: posY
|
||||
});
|
||||
}
|
||||
|
||||
// Bind listener to UI container
|
||||
mouseListenerContainer.hammer({
|
||||
prevent_default : true,
|
||||
prevent_mouseevents : true,
|
||||
transform : true,
|
||||
transform_always_block : true,
|
||||
transform_min_scale : 0.03,
|
||||
transform_min_rotation : 2,
|
||||
drag : true,
|
||||
drag_max_touches : 1,
|
||||
drag_min_distance : 10,
|
||||
swipe : false,
|
||||
hold : true // To switch from rotation to pan
|
||||
}).on("doubletap pinch drag release hold", mobileTouchInteraction);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Viewport statistic manager
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
function createStatisticManager() {
|
||||
var statistics = {}, formatters = {};
|
||||
|
||||
// Fill stat formatters
|
||||
for(var factoryKey in vtkWeb.ViewportFactory) {
|
||||
var factory = vtkWeb.ViewportFactory[factoryKey];
|
||||
if(factory.hasOwnProperty('stats')) {
|
||||
for(var key in factory.stats) {
|
||||
formatters[key] = factory.stats[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function handleEvent(event) {
|
||||
var id = event.stat_id,
|
||||
value = event.stat_value,
|
||||
statObject = null;
|
||||
|
||||
if(!statistics.hasOwnProperty(id) && formatters.hasOwnProperty(id)) {
|
||||
if(formatters[id].type === 'time') {
|
||||
statObject = statistics[id] = createTimeValueRecord();
|
||||
} else if (formatters[id].type === 'value') {
|
||||
statObject = statistics[id] = createValueRecord();
|
||||
}
|
||||
} else {
|
||||
statObject = statistics[id];
|
||||
}
|
||||
|
||||
if(statObject != null) {
|
||||
statObject.record(value);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
function toHTML() {
|
||||
var buffer = createBuffer(), hasContent = false, key, formater, stat,
|
||||
min, max;
|
||||
|
||||
// Extract stat data
|
||||
buffer.append("<table class='viewport-stat'>");
|
||||
buffer.append("<tr class='stat-header'><td class='label'>Timed Quantity</td><td class='value'>Current</td><td class='min'>Min</td><td class='max'>Max</td><td class='avg'>Average</td></tr>");
|
||||
for(key in statistics) {
|
||||
if(formatters.hasOwnProperty(key) && statistics[key].valid) {
|
||||
formater = formatters[key];
|
||||
stat = statistics[key];
|
||||
hasContent = true;
|
||||
|
||||
// The functiion may swap the order
|
||||
min = formater.convert(stat.min);
|
||||
max = formater.convert(stat.max);
|
||||
|
||||
buffer.append("<tr><td class='label'>");
|
||||
buffer.append(formater.label);
|
||||
buffer.append("</td><td class='value'>");
|
||||
buffer.append(formater.convert(stat.value));
|
||||
buffer.append("</td><td class='min'>");
|
||||
buffer.append((min < max) ? min : max);
|
||||
buffer.append("</td><td class='max'>");
|
||||
buffer.append((min > max) ? min : max);
|
||||
buffer.append("</td><td class='avg'>");
|
||||
buffer.append(formater.convert(stat.getAverageValue()));
|
||||
buffer.append("</td></tr>");
|
||||
}
|
||||
}
|
||||
buffer.append("</table>");
|
||||
|
||||
return hasContent ? buffer.toString() : "";
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
return {
|
||||
eventHandler: handleEvent,
|
||||
toHTML: toHTML,
|
||||
reset: function() {
|
||||
statistics = {};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
function createBuffer() {
|
||||
var idx = -1, buffer = [];
|
||||
return {
|
||||
clear: function(){
|
||||
idx = -1;
|
||||
buffer = [];
|
||||
},
|
||||
append: function(str) {
|
||||
buffer[++idx] = str;
|
||||
return this;
|
||||
},
|
||||
toString: function() {
|
||||
return buffer.join('');
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
function createTimeValueRecord() {
|
||||
var lastTime, sum, count;
|
||||
|
||||
// Default values
|
||||
lastTime = 0;
|
||||
sum = 0;
|
||||
count = 0;
|
||||
|
||||
return {
|
||||
value: 0.0,
|
||||
valid: false,
|
||||
min: +1000000000.0,
|
||||
max: -1000000000.0,
|
||||
|
||||
record: function(v) {
|
||||
if(v === 0) {
|
||||
this.start();
|
||||
} else if (v === 1) {
|
||||
this.stop();
|
||||
}
|
||||
},
|
||||
|
||||
start: function() {
|
||||
lastTime = new Date().getTime();
|
||||
},
|
||||
|
||||
stop: function() {
|
||||
if(lastTime != 0) {
|
||||
this.valid = true;
|
||||
var time = new Date().getTime();
|
||||
this.value = time - lastTime;
|
||||
this.min = (this.min < this.value) ? this.min : this.value;
|
||||
this.max = (this.max > this.value) ? this.max : this.value;
|
||||
//
|
||||
sum += this.value;
|
||||
count++;
|
||||
}
|
||||
},
|
||||
|
||||
reset: function() {
|
||||
count = 0;
|
||||
sum = 0;
|
||||
lastTime = 0;
|
||||
this.value = 0;
|
||||
this.min = +1000000000.0;
|
||||
this.max = -1000000000.0;
|
||||
this.valid = false;
|
||||
},
|
||||
|
||||
getAverageValue: function() {
|
||||
if(count == 0) {
|
||||
return 0;
|
||||
}
|
||||
return Math.floor(sum / count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
function createValueRecord() {
|
||||
var sum = 0, count = 0;
|
||||
|
||||
return {
|
||||
value: 0.0,
|
||||
valid: false,
|
||||
min: +1000000000.0,
|
||||
max: -1000000000.0,
|
||||
|
||||
record: function(v) {
|
||||
this.valid = true;
|
||||
this.value = v;
|
||||
this.min = (this.min < this.value) ? this.min : this.value;
|
||||
this.max = (this.max > this.value) ? this.max : this.value;
|
||||
//
|
||||
sum += this.value;
|
||||
count++;
|
||||
},
|
||||
|
||||
reset: function() {
|
||||
count = 0;
|
||||
sum = 0;
|
||||
this.value = 0;
|
||||
this.min = +1000000000.0;
|
||||
this.max = -1000000000.0;
|
||||
this.valid = false;
|
||||
},
|
||||
|
||||
getAverageValue: function() {
|
||||
if(count === 0) {
|
||||
return 0;
|
||||
}
|
||||
return Math.floor(sum / count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Viewport container definition
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Create a new viewport for a vtkWeb View.
|
||||
* The options are explained below.
|
||||
*
|
||||
* @member vtkWeb.Viewport
|
||||
* @param {Object} options
|
||||
* Configure the viewport to create the way we want.
|
||||
*
|
||||
* options = {
|
||||
* session: sessionObject, // Object used to communicate with the remote server.
|
||||
* view: -1, // -1 for active view or use the proper viewId
|
||||
* enableInteractions: true, // True if mouse interaction should be forwarded to the server
|
||||
* renderer: 'image' // Type of renderer to be used. Can only be 'image' 'webgl' or 'vgl'.
|
||||
* // --- image renderer options
|
||||
* interactiveQuality: 30, // StillRender quality when interacting
|
||||
* stillQuality: 100, // StillRender quality when not interacting
|
||||
* // --- webgl/vgl renderer options
|
||||
* keepServerInSynch: false. // Push camera information to server if true
|
||||
* }
|
||||
*
|
||||
* @return {vtkWeb.Viewport}
|
||||
*/
|
||||
function createViewport(options) {
|
||||
// Make sure we have a valid autobahn session
|
||||
if (options.session === null) {
|
||||
throw "'session' must be provided within the option.";
|
||||
}
|
||||
|
||||
function onReadyInternal() {
|
||||
if(userReadyCallback.fn) {
|
||||
// Providing just a short delay before triggering the "image-not-state"
|
||||
// event provides a break in the action so that the browser can draw the
|
||||
// image we just copied to the src attribute.
|
||||
setTimeout(userReadyCallback.fn, 0);
|
||||
if(userReadyCallback.once) {
|
||||
userReadyCallback.fn = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create viewport
|
||||
var config = $.extend({}, DEFAULT_VIEWPORT_OPTIONS, options),
|
||||
session = options.session,
|
||||
rendererContainer = $(DEFAULT_RENDERERS_CONTAINER_HTML).css(DEFAULT_RENDERERS_CONTAINER_CSS),
|
||||
mouseListener = $(DEFAULT_MOUSE_LISTENER_HTML).css(DEFAULT_MOUSE_LISTENER_CSS),
|
||||
statContainer = $(DEFAULT_STATISTIC_HTML).css(DEFAULT_STATISTIC_CSS),
|
||||
overlayContainer = $(DEFAULT_OVERLAY_HTML).css(DEFAULT_OVERLAY_CSS),
|
||||
onDoneQueue = [],
|
||||
statisticManager = createStatisticManager(),
|
||||
inSelectionMode = false,
|
||||
userReadyCallback = { fn: null, once: false},
|
||||
viewport = {
|
||||
/**
|
||||
* Update the active renderer to be something else.
|
||||
* This allow the user to switch from Image Delivery to Geometry delivery
|
||||
* or even any other available renderer type available.
|
||||
*
|
||||
* The available renderers are indexed inside the following object vtkWeb.ViewportFactory.
|
||||
*
|
||||
* @member vtkWeb.Viewport
|
||||
* @param {String} rendererName
|
||||
* Key used to ID the renderer type.
|
||||
*/
|
||||
setActiveRenderer: function(rendererName) {
|
||||
$('.' + rendererName, rendererContainer).addClass('active').show().siblings().removeClass('active').hide();
|
||||
rendererContainer.trigger('active');
|
||||
statContainer[0].innerHTML = '';
|
||||
statisticManager.reset();
|
||||
},
|
||||
|
||||
/**
|
||||
* Method that should be called each time something in the scene as changed
|
||||
* and we want to update the viewport to reflect the latest state of the scene.
|
||||
*
|
||||
* @member vtkWeb.Viewport
|
||||
* @param {Function} ondone Function to call after rendering is complete.
|
||||
*/
|
||||
invalidateScene: function(onDone) {
|
||||
onDoneQueue.push(onDone);
|
||||
rendererContainer.trigger('invalidateScene');
|
||||
},
|
||||
|
||||
/**
|
||||
* Method that should be called when nothing has changed in the scene
|
||||
* but for some reason the viewport has been dirty.
|
||||
* (i.e. Toggeling the statistic information within the viewport)
|
||||
*
|
||||
* @member vtkWeb.Viewport
|
||||
* @param {Function} ondone Function to call after rendering is complete.
|
||||
*/
|
||||
render: function(onDone, args) {
|
||||
onDoneQueue.push(onDone);
|
||||
rendererContainer.trigger({type: 'render', options: args});
|
||||
},
|
||||
|
||||
/**
|
||||
* Reset the camera of the scene to make it fit in the screen as well
|
||||
* as invalidating the scene automatically.
|
||||
*
|
||||
* @member vtkWeb.Viewport
|
||||
* @param {Function} ondone Function to call after rendering is complete.
|
||||
*/
|
||||
resetCamera: function(onDone) {
|
||||
onDoneQueue.push(onDone);
|
||||
return session.call("viewport.camera.reset", [Number(config.view)]).then(function () {
|
||||
rendererContainer.trigger('invalidateScene');
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Update Orientation Axes Visibility for the given view
|
||||
*
|
||||
* @member vtkWeb.Viewport
|
||||
* @param {Boolean} show
|
||||
* Show: true / Hide: false
|
||||
* @param {Function} ondone Function to call after rendering is complete.
|
||||
*/
|
||||
updateOrientationAxesVisibility: function (show, onDone) {
|
||||
return session.call("viewport.axes.orientation.visibility.update", [Number(config.view), show]).then(function () {
|
||||
onDoneQueue.push(onDone);
|
||||
rendererContainer.trigger('invalidateScene');
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the Center Axes Visibility for the given view
|
||||
*
|
||||
* @member vtkWeb.Viewport
|
||||
* @param {Boolean} show
|
||||
* Show: true / Hide: false
|
||||
* @param {Function} ondone Function to call after rendering is complete.
|
||||
*/
|
||||
updateCenterAxesVisibility: function (show, onDone) {
|
||||
return session.call("viewport.axes.center.visibility.update", [Number(config.view), show]).then(function () {
|
||||
onDoneQueue.push(onDone);
|
||||
rendererContainer.trigger('invalidateScene');
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Reset view id.
|
||||
* This allow to invalidate the viewport and use the new active view
|
||||
*
|
||||
* @member vtkWeb.Viewport
|
||||
*/
|
||||
resetViewId: function () {
|
||||
rendererContainer.trigger('resetViewId');
|
||||
},
|
||||
|
||||
/**
|
||||
* Ask the concrete renderer to generate an image and trigger its own
|
||||
* event when the image is ready.
|
||||
*
|
||||
* @member vtkWeb.Viewport
|
||||
*/
|
||||
captureScreenImage: function () {
|
||||
rendererContainer.trigger('captureRenderedImage');
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
downloadTimestepData: function(shaList) {
|
||||
rendererContainer.trigger('downloadAllTimesteps');
|
||||
},
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
clearGeometryCache: function() {
|
||||
rendererContainer.trigger('clearCache');
|
||||
},
|
||||
|
||||
/*
|
||||
* Provide a function that will be called when
|
||||
*/
|
||||
onReady: function(readyCallback, once) {
|
||||
userReadyCallback.fn = readyCallback;
|
||||
userReadyCallback.once = once;
|
||||
},
|
||||
|
||||
/**
|
||||
* Attach viewport to a DOM element
|
||||
*
|
||||
* @member vtkWeb.Viewport
|
||||
* @param {String} selector
|
||||
* The will be used internally to get the jQuery associated element
|
||||
*
|
||||
* <div class="renderer"></div>
|
||||
* viewport.bind(".renderer");
|
||||
*
|
||||
* <div id="renderer"></div>
|
||||
* viewport.bind("#renderer");
|
||||
*
|
||||
* <html>
|
||||
* <body>
|
||||
* <!-- renderer -->
|
||||
* <div></div>
|
||||
* </body>
|
||||
* </html>
|
||||
* viewport.bind("body > div");
|
||||
*/
|
||||
bind: function (selector) {
|
||||
var container = $(selector);
|
||||
if (container.attr("__vtkWeb_viewport__") !== "true") {
|
||||
container.attr("__vtkWeb_viewport__", "true");
|
||||
container.append(rendererContainer).append(mouseListener).append(statContainer).append(overlayContainer);
|
||||
rendererContainer.trigger('invalidateScene');
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove viewport from DOM element
|
||||
*
|
||||
* @member vtkWeb.Viewport
|
||||
*/
|
||||
unbind: function () {
|
||||
var parentElement = rendererContainer.parent();
|
||||
if (parentElement) {
|
||||
parentElement.attr("__vtkWeb_viewport__", "false");
|
||||
rendererContainer.remove();
|
||||
mouseListener.remove();
|
||||
statContainer.remove();
|
||||
overlayContainer.remove();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Update statistic visibility
|
||||
*
|
||||
* @member vtkWeb.Viewport
|
||||
* @param {Boolean} visible
|
||||
*/
|
||||
showStatistics: function(isVisible) {
|
||||
if(isVisible) {
|
||||
statContainer.show();
|
||||
} else {
|
||||
statContainer.hide();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Clear current statistic values
|
||||
*
|
||||
* @member vtkWeb.Viewport
|
||||
*/
|
||||
resetStatistics: function() {
|
||||
statisticManager.reset();
|
||||
statContainer.empty();
|
||||
},
|
||||
|
||||
/**
|
||||
* Event triggered before a mouse down.
|
||||
*
|
||||
* @member vtkWeb.Viewport
|
||||
* @event startInteraction
|
||||
*/
|
||||
/**
|
||||
* Event triggered after a mouse up.
|
||||
*
|
||||
* @member vtkWeb.Viewport
|
||||
* @event endInteraction
|
||||
* @param area
|
||||
* Provide the area in pixel between the startInteraction and endInteraction.
|
||||
* This can be used for selection or zoom to box... [minX, minY, maxX, maxY]
|
||||
*/
|
||||
|
||||
/**
|
||||
* Toggle selection mode.
|
||||
*
|
||||
* When selection mode is active, the next interaction will
|
||||
* create a 2D rectangle that will be used to define an area to select.
|
||||
* This won't perform any selection but will provide another interaction
|
||||
* mode on the client side which will then trigger an event with
|
||||
* the given area. It is the responsibility of the user to properly
|
||||
* handle that event and eventually trigger the appropriate server
|
||||
* code to perform a selection or a zoom-to-box type of action.
|
||||
*
|
||||
* @member vtkWeb.Viewport
|
||||
* @return {Boolean} inSelectionMode state
|
||||
*/
|
||||
toggleSelectionMode: function() {
|
||||
inSelectionMode = !inSelectionMode;
|
||||
return inSelectionMode;
|
||||
},
|
||||
|
||||
/**
|
||||
* Return whether or not viewport is in selection mode.
|
||||
*
|
||||
* @return {Boolean} true if viewport is in selection mode, false otherwise.
|
||||
*/
|
||||
getSelectionMode: function() {
|
||||
return inSelectionMode;
|
||||
}
|
||||
};
|
||||
|
||||
// Attach config object to renderer parent
|
||||
rendererContainer.data('config', config);
|
||||
|
||||
// Attach onDone listener
|
||||
rendererContainer.bind('done', function(){
|
||||
while(onDoneQueue.length > 0) {
|
||||
var callback = onDoneQueue.pop();
|
||||
try {
|
||||
if(callback) {
|
||||
callback();
|
||||
}
|
||||
} catch(error) {
|
||||
console.log("On Done callback error:");
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Attach the on ready internal
|
||||
rendererContainer.bind('renderer-ready', onReadyInternal);
|
||||
|
||||
// Create any renderer type that is available
|
||||
for(var key in vtkWeb.ViewportFactory) {
|
||||
try {
|
||||
vtkWeb.ViewportFactory[key].builder(rendererContainer);
|
||||
} catch(error) {
|
||||
console.log("Error while trying to load renderer: " + key);
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
// Set default renderer
|
||||
viewport.setActiveRenderer(config.renderer);
|
||||
|
||||
// Attach mouse listener if requested
|
||||
if (config.enableInteractions) {
|
||||
attachMouseListener(mouseListener, rendererContainer, overlayContainer, viewport);
|
||||
try {
|
||||
attachTouchListener(mouseListener, rendererContainer, viewport);
|
||||
} catch(error) {
|
||||
console.log('Hammer is not properly initialized');
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
// Attach stat listener
|
||||
rendererContainer.bind('stats', function(event){
|
||||
statisticManager.eventHandler(event);
|
||||
statContainer[0].innerHTML = statisticManager.toHTML();
|
||||
});
|
||||
|
||||
return viewport;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Init vtkWeb module if needed
|
||||
// ----------------------------------------------------------------------
|
||||
if (GLOBAL.hasOwnProperty("vtkWeb")) {
|
||||
module = GLOBAL.vtkWeb || {};
|
||||
} else {
|
||||
GLOBAL.vtkWeb = module;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Export internal methods to the vtkWeb module
|
||||
// ----------------------------------------------------------------------
|
||||
module.createViewport = function (option) {
|
||||
return createViewport(option);
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Local module registration
|
||||
// ----------------------------------------------------------------------
|
||||
try {
|
||||
// Tests for presence of jQuery, then registers this module
|
||||
if ($ !== undefined) {
|
||||
module.registerModule('vtkweb-viewport');
|
||||
} else {
|
||||
console.error('Module failed to register, jQuery is missing');
|
||||
}
|
||||
} catch(err) {
|
||||
console.error('Caught exception while registering module: ' + err.message);
|
||||
}
|
||||
|
||||
}(window, jQuery));
|
||||
625
ParaView-5.0.1/VTK/Web/JavaScript/Lib/vtkweb.viewport.vgl.js
Normal file
625
ParaView-5.0.1/VTK/Web/JavaScript/Lib/vtkweb.viewport.vgl.js
Normal file
@ -0,0 +1,625 @@
|
||||
/**
|
||||
* vtkWeb JavaScript Library.
|
||||
*
|
||||
* This module extend the vtkWeb viewport to add support for WebGL rendering.
|
||||
*
|
||||
* @class vtkWeb.viewports.vgl
|
||||
*
|
||||
* Viewport Factory description:
|
||||
* - Key: vgl
|
||||
* - Stats:
|
||||
* - vgl-fps
|
||||
* - vgl-nb-objects
|
||||
* - vgl-fetch-scene
|
||||
* - vgl-fetch-object
|
||||
*/
|
||||
(function (GLOBAL, $) {
|
||||
var module = {},
|
||||
RENDERER_CSS = {
|
||||
"position": "absolute",
|
||||
"top" : "0px",
|
||||
"left" : "0px",
|
||||
"right" : "0px",
|
||||
"bottom" : "0px",
|
||||
"z-index" : "0"
|
||||
},
|
||||
RENDERER_CSS_2D = {
|
||||
"z-index" : "1"
|
||||
},
|
||||
RENDERER_CSS_3D = {
|
||||
"z-index" : "0"
|
||||
},
|
||||
DEFAULT_OPTIONS = {
|
||||
keepServerInSynch: false
|
||||
},
|
||||
FACTORY_KEY = 'vgl',
|
||||
FACTORY = {
|
||||
'builder': createVGLGeometryDeliveryRenderer,
|
||||
'options': DEFAULT_OPTIONS,
|
||||
'stats': {
|
||||
'vgl-fps': {
|
||||
label: 'Framerate',
|
||||
type: 'time',
|
||||
convert: function(value) {
|
||||
if(value === 0) {
|
||||
return 0;
|
||||
}
|
||||
return (1000 / value).toFixed(2);
|
||||
}
|
||||
},
|
||||
'vgl-nb-objects': {
|
||||
label: 'Number of 3D objects',
|
||||
type: 'value',
|
||||
convert: NoOp
|
||||
},
|
||||
'vgl-fetch-scene': {
|
||||
label: 'Fetch scene (ms)',
|
||||
type: 'time',
|
||||
convert: NoOp
|
||||
},
|
||||
'vgl-fetch-object': {
|
||||
label: 'Fetch object (ms)',
|
||||
type: 'time',
|
||||
convert: NoOp
|
||||
}
|
||||
}
|
||||
},
|
||||
DEFAULT_SHADERS = {},
|
||||
mvMatrixStack = [],
|
||||
PROGRESS_BAR_TEMPLATE =
|
||||
'<div class="download-progressbar-container">' +
|
||||
' <span class="progressbar-title">Download Progress</span>' +
|
||||
' <div class="progressbar-content-container">' +
|
||||
' <span class="progress-message-span">MESSAGE</span>' +
|
||||
' <div class="progress progress-meter-container">' +
|
||||
' <div class="progress-bar progress-bar-striped active progress-meter" role="progressbar" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100" style="width: 100%;">' +
|
||||
' </div>' +
|
||||
' </div>' +
|
||||
' </div>' +
|
||||
'</div>';
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
function NoOp(a) {
|
||||
return a;
|
||||
}
|
||||
|
||||
function getKey(object) {
|
||||
return object.id + '_' + object.md5 + '_' + object.part;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Geometry Delivery renderer - factory method
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
function createVGLGeometryDeliveryRenderer(domElement) {
|
||||
var m_container = $(domElement),
|
||||
m_options = $.extend({}, DEFAULT_OPTIONS, m_container.data('config')),
|
||||
m_session = m_options.session,
|
||||
m_divContainer = GLOBAL.document.createElement('div'),
|
||||
m_canvas2D = GLOBAL.document.createElement('canvas'),
|
||||
m_canvas3D = GLOBAL.document.createElement('canvas'),
|
||||
m_ctx2d = m_canvas2D.getContext('2d'),
|
||||
gl = m_canvas3D.getContext("webgl") || m_canvas3D.getContext("experimental-webgl"),
|
||||
m_rendererAttrs = $(m_divContainer).addClass(FACTORY_KEY).css(RENDERER_CSS).append($(m_canvas2D).css(RENDERER_CSS).css(RENDERER_CSS_2D)).append($(m_canvas3D).css(RENDERER_CSS).css(RENDERER_CSS_3D)),
|
||||
m_sceneJSON = null,
|
||||
m_sceneData = null,
|
||||
m_vglVtkReader = vgl.vtkReader(),
|
||||
m_viewer = null,
|
||||
m_interactorStyle,
|
||||
originalMouseDown = document.onmousedown,
|
||||
originalMouseUp = document.onmouseup,
|
||||
originalMouseMove = document.onmousemove,
|
||||
originalContextMenu = document.oncontextmenu,
|
||||
m_background = null;
|
||||
screenImage = null,
|
||||
m_vglActors = {},
|
||||
m_objectIndex = {},
|
||||
m_numberOfPartsDownloaded = 0,
|
||||
m_numberOfPartsToDownload = 0;
|
||||
|
||||
// Helper functions -------------------------------------------------
|
||||
|
||||
function fetchMissingObjects(fetchMethod, sceneJSON) {
|
||||
for(var idx in sceneJSON.Objects) {
|
||||
var currentObject = sceneJSON.Objects[idx];
|
||||
for(var part = 1; part <= currentObject.parts; part++) {
|
||||
var key = getKey({
|
||||
'id': currentObject.id,
|
||||
'md5': currentObject.md5,
|
||||
'part': part
|
||||
});
|
||||
if(!m_objectIndex.hasOwnProperty(key)) {
|
||||
fetchMethod(currentObject, part);
|
||||
} else {
|
||||
handleCompleteSceneObject(m_objectIndex[key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
function fetchScene() {
|
||||
m_container.trigger({
|
||||
type: 'stats',
|
||||
stat_id: 'vgl-fetch-scene',
|
||||
stat_value: 0
|
||||
});
|
||||
m_session.call("viewport.webgl.metadata", [Number(m_options.view)]).then(function(data) {
|
||||
if (m_sceneData === data) {
|
||||
updateScene();
|
||||
return;
|
||||
}
|
||||
m_sceneData = data;
|
||||
m_sceneJSON = JSON.parse(data);
|
||||
m_vglVtkReader.setVtkScene(m_sceneJSON);
|
||||
m_container.trigger({
|
||||
type: 'stats',
|
||||
stat_id: 'vgl-fetch-scene',
|
||||
stat_value: 1
|
||||
});
|
||||
updateScene();
|
||||
});
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
function handleDownloadProgressEvent(event) {
|
||||
var status = event.status;
|
||||
|
||||
function updateProgressBar(element, percentProgress) {
|
||||
var progressString = percentProgress + '%';
|
||||
element.attr('aria-valuenow', percentProgress)
|
||||
.css('width', progressString);
|
||||
//.html(progressString);
|
||||
}
|
||||
|
||||
if (status === 'create') {
|
||||
var initialMessage = "Downloading metadata for all timesteps",
|
||||
html = PROGRESS_BAR_TEMPLATE.replace(/MESSAGE/, initialMessage),
|
||||
progressElt = $(html);
|
||||
m_container.append(progressElt);
|
||||
} else if (status === 'update') {
|
||||
var progressType = event.progressType,
|
||||
pbElt = $('.progress-meter');
|
||||
if (progressType === 'retrieved-metadata') {
|
||||
$('.progress-message-span').text('Metadata retrieved, downloading objects');
|
||||
pbElt.removeClass('progress-bar-striped active');
|
||||
updateProgressBar(pbElt, 0);
|
||||
} else {
|
||||
var numPartsThisSha = event.numParts;
|
||||
m_numberOfPartsDownloaded += numPartsThisSha;
|
||||
var numberRemaining = m_numberOfPartsToDownload - m_numberOfPartsDownloaded;
|
||||
var percent = ((m_numberOfPartsDownloaded / m_numberOfPartsToDownload) * 100).toFixed(0);
|
||||
if (numberRemaining <= 0) {
|
||||
$('.download-progressbar-container').remove();
|
||||
} else {
|
||||
$('.progress-message-span').text('Downloading objects');
|
||||
updateProgressBar(pbElt, percent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
function downloadAllTimesteps() {
|
||||
m_container.trigger({
|
||||
type: 'downloadProgress',
|
||||
status: 'create'
|
||||
});
|
||||
|
||||
m_session.call('viewport.webgl.metadata.alltimesteps', []).then(function(result){
|
||||
if (result.hasOwnProperty('success') && result.success === true) {
|
||||
var metaDataList = result.metaDataList;
|
||||
|
||||
m_container.trigger({
|
||||
type: 'downloadProgress',
|
||||
status: 'update',
|
||||
progressType: 'retrieved-metadata'
|
||||
});
|
||||
|
||||
// For progress events, I want to first know how many items to retrieve
|
||||
m_numberOfPartsToDownload = 0;
|
||||
for (var sha in metaDataList) {
|
||||
if (metaDataList.hasOwnProperty(sha)) {
|
||||
m_numberOfPartsToDownload += metaDataList[sha].numParts;
|
||||
}
|
||||
}
|
||||
|
||||
m_numberOfPartsDownloaded = 0;
|
||||
|
||||
setTimeout(function() {
|
||||
|
||||
// Now go through and download the heavy data for anythin we don't already have
|
||||
for (var sha in metaDataList) {
|
||||
if (metaDataList.hasOwnProperty(sha)) {
|
||||
var numParts = metaDataList[sha].numParts,
|
||||
objId = metaDataList[sha].id,
|
||||
alreadyCached = true;
|
||||
// Before I go and fetch all the parts for this object, make sure
|
||||
// I don't already have them cached
|
||||
for (var i = 0; i < numParts; i+=1) {
|
||||
var key = getKey({
|
||||
'id': objId,
|
||||
'md5': sha,
|
||||
'part': i + 1
|
||||
});
|
||||
if(!m_objectIndex.hasOwnProperty(key)) {
|
||||
alreadyCached = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (alreadyCached === false) {
|
||||
fetchCachedObject(sha);
|
||||
} else {
|
||||
m_container.trigger({
|
||||
type: 'downloadProgress',
|
||||
status: 'update',
|
||||
numParts: numParts
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}, 500);
|
||||
}
|
||||
}, function(metaDataError) {
|
||||
console.log("Error retrieving metadata for all timesteps");
|
||||
console.log(metaDataError);
|
||||
});
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
function fetchCachedObject(sha) {
|
||||
var viewId = Number(m_options.view);
|
||||
|
||||
m_session.call('viewport.webgl.cached.data', [sha]).then(function(result) {
|
||||
if (result.success === false) {
|
||||
console.log("Fetching cached data for " + sha + " failed, reason:");
|
||||
consolelog(result.reason);
|
||||
return;
|
||||
}
|
||||
var dataObject = result.data;
|
||||
if (dataObject.hasOwnProperty('partsList')) {
|
||||
for (var dIdx = 0; dIdx < dataObject.partsList.length; dIdx += 1) {
|
||||
// Create a complete scene part object and cache it
|
||||
var newObject = {
|
||||
md5: dataObject.md5,
|
||||
part: dIdx + 1,
|
||||
vid: viewId,
|
||||
id: dataObject.id,
|
||||
data: dataObject.partsList[dIdx],
|
||||
hasTransparency: dataObject.transparency,
|
||||
layer: dataObject.layer
|
||||
};
|
||||
|
||||
var key = getKey(newObject);
|
||||
m_objectIndex[key] = newObject;
|
||||
|
||||
var actors = m_vglVtkReader.parseObject(newObject);
|
||||
m_vglActors[key] = actors;
|
||||
}
|
||||
|
||||
m_container.trigger({
|
||||
type: 'downloadProgress',
|
||||
status: 'update',
|
||||
numParts: dataObject.partsList.length
|
||||
});
|
||||
}
|
||||
}, function(err) {
|
||||
console.log('viewport.webgl.cached.data rpc method failed');
|
||||
console.log(err);
|
||||
});
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
function handleCompleteSceneObject(sceneObject) {
|
||||
var renderer = m_vglVtkReader.getRenderer(sceneObject.layer),
|
||||
key = getKey(sceneObject),
|
||||
actors = {};
|
||||
|
||||
// Parse the new object if its not parsed already
|
||||
// if parsed already then check if exists in current renderer
|
||||
if (key in m_vglActors) {
|
||||
actors = m_vglActors[key];
|
||||
// if exists in current renderer do nothing
|
||||
for (i = 0; i < actors.length; i++) {
|
||||
var actor = actors[i];
|
||||
if (!renderer.hasActor(actor)) {
|
||||
renderer.addActor(actor);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Object was not parsed so parse it, create actors, and add them to the renderer.
|
||||
actors = m_vglVtkReader.parseObject(sceneObject);
|
||||
m_vglActors[key] = actors;
|
||||
|
||||
for (i = 0; i < actors.length; i++) {
|
||||
renderer.addActor(actors[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Mark the actor as valid
|
||||
actors.invalid = false;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
function fetchObject(sceneObject, part) {
|
||||
try {
|
||||
var viewId = Number(m_options.view),
|
||||
newObject, renderer, actor, actors, key, i;
|
||||
|
||||
m_container.trigger({
|
||||
type: 'stats',
|
||||
stat_id: 'vgl-fetch-object',
|
||||
stat_value: 0
|
||||
});
|
||||
m_session.call("viewport.webgl.data", [viewId, sceneObject.id, part]).then(function(data) {
|
||||
try {
|
||||
m_container.trigger({
|
||||
type: 'stats',
|
||||
stat_id: 'vgl-fetch-object',
|
||||
stat_value: 1
|
||||
});
|
||||
|
||||
//add object to the reader
|
||||
newObject = {
|
||||
md5: sceneObject.md5,
|
||||
part: part,
|
||||
vid: viewId,
|
||||
id: sceneObject.id,
|
||||
data: data,
|
||||
hasTransparency: sceneObject.transparency,
|
||||
layer: sceneObject.layer
|
||||
};
|
||||
|
||||
// First, actually cache the object, because that was not happening
|
||||
var key = getKey(newObject);
|
||||
m_objectIndex[key] = newObject;
|
||||
|
||||
// Now add the object to the reader, etc...
|
||||
handleCompleteSceneObject(newObject);
|
||||
|
||||
// Redraw the scene
|
||||
drawScene(false);
|
||||
} catch(error) {
|
||||
console.log(error);
|
||||
}
|
||||
});
|
||||
} catch(error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
function render(saveScreenOnRender) {
|
||||
m_canvas3D.width = m_rendererAttrs.width();
|
||||
m_canvas3D.height = m_rendererAttrs.height();
|
||||
m_viewer = m_vglVtkReader.updateCanvas(m_canvas3D);
|
||||
drawScene(saveScreenOnRender);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
function drawScene(saveScreenOnRender) {
|
||||
var layer;
|
||||
|
||||
try {
|
||||
if (m_sceneJSON === null || typeof m_sceneJSON === 'undefined') {
|
||||
return;
|
||||
}
|
||||
|
||||
var width = m_rendererAttrs.width(),
|
||||
height = m_rendererAttrs.height(),
|
||||
nbObjects;
|
||||
|
||||
// Update frame rate
|
||||
m_container.trigger({
|
||||
type: 'stats',
|
||||
stat_id: 'vgl-fps',
|
||||
stat_value: 0
|
||||
});
|
||||
|
||||
m_viewer.render();
|
||||
|
||||
if (saveScreenOnRender === true) {
|
||||
screenImage = m_canvas3D.toDataURL();
|
||||
}
|
||||
|
||||
numObjects = m_vglVtkReader.numObjects();
|
||||
|
||||
// Update frame rate
|
||||
m_container.trigger({
|
||||
type: 'stats',
|
||||
stat_id: 'vgl-fps',
|
||||
stat_value: 1
|
||||
});
|
||||
|
||||
m_container.trigger({
|
||||
type: 'stats',
|
||||
stat_id: 'vgl-nb-objects',
|
||||
stat_value: numObjects
|
||||
});
|
||||
} catch(error) {
|
||||
console.log(error);
|
||||
}
|
||||
m_container.trigger('done');
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
function pushCameraState() {
|
||||
if(m_viewer !== null) {
|
||||
var cam = m_viewer.renderWindow().activeRenderer().camera(),
|
||||
fp_ = cam.focalPoint(),
|
||||
up_ = cam.viewUpDirection(),
|
||||
pos_ = cam.position(),
|
||||
fp = [fp_[0], fp_[1], fp_[2]],
|
||||
up = [up_[0], up_[1], up_[2]],
|
||||
pos = [pos_[0], pos_[1], pos_[2]];
|
||||
m_session.call("viewport.camera.update", [Number(m_options.view), fp, up, pos]);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
function updateScene() {
|
||||
var key;
|
||||
|
||||
try{
|
||||
if(m_sceneJSON === null || typeof(m_sceneJSON) === "undefined") {
|
||||
return;
|
||||
}
|
||||
|
||||
m_vglVtkReader.initScene();
|
||||
|
||||
// Mark all actors as invalid
|
||||
for (key in m_vglActors) {
|
||||
m_vglActors[key].invalid = true;
|
||||
}
|
||||
|
||||
// Fetch the object that we are missing
|
||||
fetchMissingObjects(fetchObject, m_sceneJSON);
|
||||
|
||||
// Draw scene
|
||||
drawScene(false);
|
||||
} catch(error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
function clearCache() {
|
||||
m_objectIndex = {};
|
||||
m_vglActors = {};
|
||||
m_container.trigger('invalidateScene');
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Add rendererAttrs into the DOM
|
||||
m_container.append(m_rendererAttrs);
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Add viewport listener
|
||||
m_container.bind('invalidateScene', function() {
|
||||
if(m_rendererAttrs.hasClass('active')){
|
||||
|
||||
if (m_vglVtkReader === null) {
|
||||
m_vglVtkReader = vgl.vtkReader();
|
||||
} else {
|
||||
m_vglVtkReader.deleteViewer();
|
||||
}
|
||||
|
||||
m_canvas3D.width = m_rendererAttrs.width();
|
||||
m_canvas3D.height = m_rendererAttrs.height();
|
||||
m_viewer = m_vglVtkReader.createViewer(m_canvas3D);
|
||||
m_viewer.renderWindow().activeRenderer().setResetScene(false);
|
||||
m_viewer.renderWindow().activeRenderer().setResetClippingRange(false);
|
||||
|
||||
// Bind mouse event handlers
|
||||
m_container.on('mouse', function(event) {
|
||||
if (m_viewer) {
|
||||
if (event.action === 'move') {
|
||||
m_viewer.handleMouseMove(event.originalEvent);
|
||||
}
|
||||
else if (event.action === 'up') {
|
||||
m_viewer.handleMouseUp(event.originalEvent);
|
||||
}
|
||||
else if (event.action === 'down') {
|
||||
m_viewer.handleMouseDown(event.originalEvent);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
fetchScene();
|
||||
}
|
||||
}).bind('render', function(){
|
||||
if(m_rendererAttrs.hasClass('active')){
|
||||
render(false);
|
||||
}
|
||||
}).bind('downloadAllTimesteps', function(event){
|
||||
if(m_rendererAttrs.hasClass('active')){
|
||||
downloadAllTimesteps();
|
||||
}
|
||||
}).bind('clearCache', function(event){
|
||||
if(m_rendererAttrs.hasClass('active')){
|
||||
clearCache();
|
||||
}
|
||||
}).bind('downloadProgress', function(event){
|
||||
if(m_rendererAttrs.hasClass('active')){
|
||||
handleDownloadProgressEvent(event);
|
||||
}
|
||||
}).bind('captureRenderedImage', function(e){
|
||||
if (m_rendererAttrs.hasClass('active')) {
|
||||
render(true);
|
||||
$(m_container).parent().trigger({
|
||||
type: 'captured-screenshot-ready',
|
||||
imageData: screenImage
|
||||
});
|
||||
}
|
||||
}).bind('resetViewId', function(e){
|
||||
m_options.view = -1;
|
||||
}).bind('mouse', function(event){
|
||||
if(m_rendererAttrs.hasClass('active')){
|
||||
event.preventDefault();
|
||||
pushCameraState();
|
||||
}
|
||||
|
||||
}).bind('active', function(){
|
||||
if(m_rendererAttrs.hasClass('active')){
|
||||
// Ready to render data
|
||||
fetchScene();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Init vtkWeb module if needed
|
||||
// ----------------------------------------------------------------------
|
||||
if (GLOBAL.hasOwnProperty("vtkWeb")) {
|
||||
module = GLOBAL.vtkWeb || {};
|
||||
} else {
|
||||
GLOBAL.vtkWeb = module;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Extend the viewport factory - ONLY IF WEBGL IS SUPPORTED
|
||||
// ----------------------------------------------------------------------
|
||||
try {
|
||||
if (GLOBAL.WebGLRenderingContext && typeof(vec3) != "undefined" && typeof(mat4) != "undefined") {
|
||||
var canvas = GLOBAL.document.createElement('canvas'),
|
||||
gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
|
||||
if(gl) {
|
||||
// WebGL is supported
|
||||
if(!module.hasOwnProperty('ViewportFactory')) {
|
||||
module['ViewportFactory'] = {};
|
||||
}
|
||||
module.ViewportFactory[FACTORY_KEY] = FACTORY;
|
||||
}
|
||||
}
|
||||
} catch(exception) {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Local module registration
|
||||
// ----------------------------------------------------------------------
|
||||
try {
|
||||
// Tests for presence of jQuery and glMatrix, then registers this module
|
||||
if ($ !== undefined && module.ViewportFactory[FACTORY_KEY] !== undefined) {
|
||||
module.registerModule('vtkweb-viewport-vgl');
|
||||
}
|
||||
} catch(err) {
|
||||
console.error('jQuery or glMatrix is missing or browser does not support WebGL: ' + err.message);
|
||||
}
|
||||
|
||||
}(window, jQuery));
|
||||
1804
ParaView-5.0.1/VTK/Web/JavaScript/Lib/vtkweb.viewport.webgl.js
Normal file
1804
ParaView-5.0.1/VTK/Web/JavaScript/Lib/vtkweb.viewport.webgl.js
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user