From 7912123a6ed7452a75ab907b290e3c28cd5d2d99 Mon Sep 17 00:00:00 2001 From: Tarek Sherif Date: Tue, 6 May 2014 17:05:24 -0400 Subject: [PATCH] v1.6.0 --- .../brainbrowser.surface-viewer.min.js | 29 ++++++++++++++++++ .../brainbrowser.volume-viewer.min.js | 29 ++++++++++++++++++ .../workers/deindex.worker.js | 29 ++++++++++++++++++ .../workers/freesurferasc.intensity.worker.js | 29 ++++++++++++++++++ .../workers/freesurferasc.worker.js | 29 ++++++++++++++++++ .../workers/mniobj.intensity.worker.js | 29 ++++++++++++++++++ .../workers/mniobj.worker.js | 29 ++++++++++++++++++ .../workers/wavefrontobj.worker.js | 29 ++++++++++++++++++ package.json | 2 +- release/brainbrowser-1.6.0.tar.gz | Bin 0 -> 18361 bytes 10 files changed, 233 insertions(+), 1 deletion(-) create mode 100644 build/brainbrowser-1.6.0/brainbrowser.surface-viewer.min.js create mode 100644 build/brainbrowser-1.6.0/brainbrowser.volume-viewer.min.js create mode 100644 build/brainbrowser-1.6.0/workers/deindex.worker.js create mode 100644 build/brainbrowser-1.6.0/workers/freesurferasc.intensity.worker.js create mode 100644 build/brainbrowser-1.6.0/workers/freesurferasc.worker.js create mode 100644 build/brainbrowser-1.6.0/workers/mniobj.intensity.worker.js create mode 100644 build/brainbrowser-1.6.0/workers/mniobj.worker.js create mode 100644 build/brainbrowser-1.6.0/workers/wavefrontobj.worker.js create mode 100644 release/brainbrowser-1.6.0.tar.gz diff --git a/build/brainbrowser-1.6.0/brainbrowser.surface-viewer.min.js b/build/brainbrowser-1.6.0/brainbrowser.surface-viewer.min.js new file mode 100644 index 00000000..f5c60150 --- /dev/null +++ b/build/brainbrowser-1.6.0/brainbrowser.surface-viewer.min.js @@ -0,0 +1,29 @@ +/* +* BrainBrowser: Web-based Neurological Visualization Tools +* (https://brainbrowser.cbrain.mcgill.ca) +* +* Copyright (C) 2011 +* The Royal Institution for the Advancement of Learning +* McGill University +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Affero General Public License as +* published by the Free Software Foundation, either version 3 of the +* License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Affero General Public License for more details. +* +* You should have received a copy of the GNU Affero General Public License +* along with this program. If not, see . +*/ + +/* +* BrainBrowser v1.6.0 +* +* Author: Tarek Sherif (http://tareksherif.ca/) +* Author: Nicolas Kassis +*/ +!function(){"use strict";var a="1.6.0";a=a.indexOf("BRAINBROWSER_VERSION")>0?"D.E.V":a,window.BrainBrowser={version:a},window.requestAnimationFrame=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(a){return window.setTimeout(a,1e3/60)},window.cancelAnimationFrame=window.cancelAnimationFrame||function(a){window.clearTimeout(a)}}(),function(){"use strict";BrainBrowser.createColorMap=function(a){function b(a,b,d,e){var f,g,h,i=document.createElement("canvas"),j=new Array(256);for($(i).attr("width",256),$(i).attr("height",d),f=0;256>f;f++)e?j[255-f]=f:j[f]=f;for(a=c.mapColors(j,{scale255:!0}),h=i.getContext("2d"),g=0;256>g;g++)h.fillStyle="rgb("+Math.floor(a[4*g])+", "+Math.floor(a[4*g+1])+", "+Math.floor(a[4*g+2])+")",h.fillRect(g,0,1,b);return i}var c={createCanvasWithScale:function(a,d,e){e=e||{};var f,g,h=c.colors,i=e.flip,j=d-a;return f=b(h,20,40,i),g=f.getContext("2d"),g.fillStyle="#FFA000",g.fillRect(.5,20,1,10),g.fillText(a.toPrecision(3),.5,40),g.fillRect(f.width/4,20,1,10),g.fillText((a+.25*j).toPrecision(3),.25*f.width,40),g.fillRect(f.width/2,20,1,10),g.fillText((a+.5*j).toPrecision(3),.5*f.width,40),g.fillRect(3*f.width/4,20,1,10),g.fillText((a+.75*j).toPrecision(3),.75*f.width,40),g.fillRect(f.width-.5,20,1,10),g.fillText(d.toPrecision(3),f.width-20,40),f},mapColors:function(a,b){b=b||{};var d,e,f,g,h=void 0===b.min?0:b.min,i=void 0===b.max?255:b.max,j=void 0===b.scale255?!1:b.scale255,k=void 0===b.brightness?0:b.brightness,l=void 0===b.contrast?1:b.contrast,m=void 0===b.alpha?1:b.alpha,n=b.destination||[],o=c.colors,p=o.length,q=i-h,r=(q+q/p)/p,s=j?255:1,t=[];for(m*=s,d=0,e=a.length;e>d;d++)g=a[d],f=h>=g?0:a[d]>i?p-1:Math.floor((g-h)/r),t=o[f]||[0,0,0],n[4*d+0]=s*(t[0]*l+k),n[4*d+1]=s*(t[1]*l+k),n[4*d+2]=s*(t[2]*l+k),n[4*d+3]=m;return n}};return function(){if(a){a=a.replace(/^\s+/,"").replace(/\s+$/,"");var b,d,e,f,g,h=a.split(/\n/),i=[];for(b=0,e=h.length;e>b;b++)if(g=h[b].replace(/^\s+/,"").replace(/\s+$/,"").split(/\s+/).slice(0,4),f=g.length,!(3>f)){for(d=0;f>d;d++)g[d]=parseFloat(g[d]);4>f&&g.push(1),i.push(g)}c.colors=i}}(),c}}(),function(){"use strict";var a=[];BrainBrowser.events={addEventListener:function(b,c){a[b]||(a[b]=[]),a[b].push(c)},triggerEvent:function(b){var c=Array.prototype.slice.call(arguments,1);a[b]&&a[b].forEach(function(a){setTimeout(function(){a.apply(null,c)},0)})}}}(),function(){"use strict";var a=BrainBrowser.loader={loadFromURL:function(b,c,d){d=d||{};var e,f=new XMLHttpRequest,g=d.result_type,h=b.split("/"),i=h[h.length-1];f.open("GET",b),"arraybuffer"===g&&(f.responseType="arraybuffer"),f.onreadystatechange=function(){if(4===f.readyState){if(e=f.status,!(e>=200&&300>e||304===e)){var g="error loading URL: "+b+"\nHTTP Response: "+f.status+"\nHTTP Status: "+f.statusText+"\nResponse was: \n"+f.response;throw BrainBrowser.events.triggerEvent("error",g),new Error(g)}a.checkCancel(d)||c(f.response,i,d)}},f.send()},loadFromFile:function(a,b,c){var d=a.files;if(0!==d.length){c=c||{};var e=c.result_type,f=new FileReader,g=a.value.split("\\"),h=g[g.length-1];f.file=d[0],f.onloadend=function(a){b(a.target.result,h,c)},f.onerror=function(){var a="error reading file: "+h;throw BrainBrowser.events.triggerEvent("error",a),new Error(a)},"arraybuffer"===e?f.readAsArrayBuffer(d[0]):f.readAsText(d[0])}},loadColorMapFromURL:function(a,b,c){BrainBrowser.loader.loadFromURL(a,function(a,c,d){b(BrainBrowser.createColorMap(a),c,d)},c)},loadColorMapFromFile:function(a,b,c){BrainBrowser.loader.loadFromFile(a,function(a,c,d){b(BrainBrowser.createColorMap(a),c,d)},c)},checkCancel:function(a){a=a||{},BrainBrowser.utils.isFunction(a)&&(a={test:a});var b=a.test,c=a.cleanup,d=!1;return b&&b()&&(d=!0,c&&c()),d}}}(),function(){"use strict";BrainBrowser.utils={canvasEnabled:function(){return!!document.createElement("canvas")},webglEnabled:function(){var a=document.createElement("canvas");try{return!(!a||!window.WebGLRenderingContext||!a.getContext("webgl")&&!a.getContext("experimental-webgl"))}catch(b){return!1}},webWorkersEnabled:function(){return!!window.Worker},webGLErrorMessage:function(){var a,b='BrainBrowser requires WebGL.
';return b+=window.WebGLRenderingContext?"Your browser seems to support it, but it is
disabled or unavailable.
":"Your browser does not seem to support it.
",b+='Test your browser\'s WebGL support here.',a=document.createElement("div"),a.id="webgl-error",a.innerHTML=b,a},isFunction:function(a){return a instanceof Function||"function"==typeof a},isNumeric:function(a){return!isNaN(parseFloat(a))},min:function(){var a=Array.prototype.slice.call(arguments);a=1===a.length&&Array.isArray(a[0])?a[0]:a;var b,c,d=a[0];for(b=1,c=a.length;c>b;b++)a[b]b;b++)a[b]>d&&(d=a[b]);return d},getOffset:function(a){for(var b=0,c=0;a.offsetParent;)b+=a.offsetTop,c+=a.offsetLeft,a=a.offsetParent;return{top:b,left:c}},checkConfig:function(a){if(!BrainBrowser.config)return!1;a=a||"";var b,c,d,e=BrainBrowser.config,f=a.split(".");for(c=0,d=f.length;d>c;c++){if(b=f[c],!e[b])return!1;e=e[b]}return!0}}}(),function(){"use strict";function a(a){if(!BrainBrowser.utils.checkConfig("surface_viewer.worker_dir"))return void a();var c,d={deindex:"deindex.worker.js"},e=BrainBrowser.config.surface_viewer,f=0;return BrainBrowser.utils.checkConfig("surface_viewer.model_types")&&Object.keys(e.model_types).forEach(function(a){d[a+"_model"]=e.model_types[a].worker}),BrainBrowser.utils.checkConfig("surface_viewer.intensity_data_types")&&Object.keys(e.intensity_data_types).forEach(function(a){d[a+"_intensity"]=e.intensity_data_types[a].worker}),c=Object.keys(d),0===c.length?void a():void(window.URL&&window.URL.createObjectURL?c.forEach(function(g){var h,i,j=e.worker_dir+"/"+d[g],k=new XMLHttpRequest;k.open("GET",j),k.onreadystatechange=function(){4===k.readyState&&(h=k.status,h>=200&&300>h||304===h?(i=new Blob([k.response],{type:"application/javascript"}),b.worker_urls[g]=window.URL.createObjectURL(i)):b.worker_urls[g]=j,++f===c.length&&a())},k.send()}):(c.forEach(function(a){b.worker_urls[a]=e.worker_dir+"/"+d[a]}),a()))}var b=BrainBrowser.SurfaceViewer={start:function(c,d){if(console.log("BrainBrowser Surface Viewer v"+BrainBrowser.version),!BrainBrowser.utils.webWorkersEnabled())return void alert("Can't find web workers. Exiting.");if(!BrainBrowser.utils.webglEnabled())return void alert("Can't get WebGL context. Exiting.");var e={},f={dom_element:document.getElementById(c),model:null,getAttribute:function(a){return e[a]},setAttribute:function(a,b){e[a]=b},getVertex:function(a){var b=f.model_data.vertices,c=3*a;return new THREE.Vector3(b[c],b[c+1],b[c+2])}};Object.keys(b.modules).forEach(function(a){b.modules[a](f)}),a(function(){d(f)})}};b.modules={},b.worker_urls={}}(),BrainBrowser.SurfaceViewer.parseIntensityData=function(a,b,c){"use strict";function d(){var b=new Worker(BrainBrowser.SurfaceViewer.worker_urls[f]);b.addEventListener("message",function(a){var d,e=a.data;for(d in e)e.hasOwnProperty(d)&&(g[d]=e[d]);c&&c(g),b.terminate()}),b.postMessage({cmd:"parse",data:a})}var e,f=b+"_intensity";if(!BrainBrowser.utils.checkConfig("surface_viewer.worker_dir"))throw e="error in SurfaceViewer configuration.\nBrainBrowser.config.surface_viewer.worker_dir not defined.",BrainBrowser.events.triggerEvent("error",e),new Error(e);if(!BrainBrowser.SurfaceViewer.worker_urls[f])throw e="error in SurfaceViewer configuration.\nIntensity data worker URL for "+b+" not defined.",BrainBrowser.events.triggerEvent("error",e),new Error(e);var g={};g.createColorArray=function(a,b,c,d,e,f,h,i){c=c.colors;var j,k,l,m,n=g.values,o=[],p=c.length,q=b-a,r=(q+q/p)/p;for(j=0,k=n.length;k>j;j++)m=n[j],l=a>=m?a>m&&!e?-1:0:m>b?e?p-1:-1:Math.floor((m-a)/r),d&&-1!==l?o.push.apply(o,c[p-1-l]):-1===l?4===f.length?o.push.apply(o,f):o.push(f[4*j],f[4*j+1],f[4*j+2],f[4*j+3]):o.push.apply(o,c[l]);i&&i(o)},a&&("string"==typeof a?d(a):a.values?(g.values=a.values.concat(),g.min=BrainBrowser.utils.min(g.values),g.max=BrainBrowser.utils.max(g.values)):(g.values=a,g.min=BrainBrowser.utils.min(a),g.max=BrainBrowser.utils.max(a)))},function(){"use strict";BrainBrowser.SurfaceViewer.utils={drawDot:function(a,b,c,d){var e=new THREE.SphereGeometry(2),f=new THREE.MeshBasicMaterial({color:16711680}),g=new THREE.Mesh(e,f);g.position.set(b,c,d),a.add(g)}}}(),BrainBrowser.SurfaceViewer.modules.color=function(a){"use strict";function b(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p;for(i=0,k=b.length;k>i;i++){for(d=b[i],l=d.getObjectByName("__wireframe__"),p=!!l,p&&(m=l.geometry.attributes.color.array),c=d.geometry,e=d.geometry.original_data.indices,f=c.attributes.color,g=f.array,h=0,j=e.length;j>h;h+=3)n=4*h,o=2*n,g[n]=a[4*e[h]],g[n+1]=a[4*e[h]+1],g[n+2]=a[4*e[h]+2],g[n+3]=1,g[n+4]=a[4*e[h+1]],g[n+5]=a[4*e[h+1]+1],g[n+6]=a[4*e[h+1]+2],g[n+7]=1,g[n+8]=a[4*e[h+2]],g[n+9]=a[4*e[h+2]+1],g[n+10]=a[4*e[h+2]+2],g[n+11]=1,p&&(m[o]=g[n],m[o+1]=g[n+1],m[o+2]=g[n+2],m[o+3]=g[n+3],m[o+4]=g[n+4],m[o+5]=g[n+5],m[o+6]=g[n+6],m[o+7]=g[n+7],m[o+8]=g[n+4],m[o+9]=g[n+5],m[o+10]=g[n+6],m[o+11]=g[n+7],m[o+12]=g[n+8],m[o+13]=g[n+9],m[o+14]=g[n+10],m[o+15]=g[n+11],m[o+16]=g[n+8],m[o+17]=g[n+9],m[o+18]=g[n+10],m[o+19]=g[n+11],m[o+20]=g[n],m[o+21]=g[n+1],m[o+22]=g[n+2],m[o+23]=g[n+3]);f.needsUpdate=!0,p&&(l.geometry.attributes.color.needsUpdate=!0)}}function c(a){var b,c,d,e,f,g,h=a[0];for(b=0,d=a[0].length/4;d>b;b++)for(c=1,e=a.length;e>c;c++)f=h[4*b+3],g=a[c][4*b+3],h[4*b]=h[4*b]*f+a[c][4*b]*g,h[4*b+1]=h[4*b+1]*f+a[c][4*b+1]*g,h[4*b+2]=h[4*b+2]*f+a[c][4*b+2]*g,h[4*b+3]=f+g;return h}function d(a,b){var d,e,f=b.length,g=new Array(f);for(d=0;f>d;d++)e=b[d],g[d]=a.mapColors(e.values,{min:e.range_min,max:e.range_max,alpha:e.alpha});return c(g)}var e=null;a.updateColors=function(c,f){function g(d){var e;e=c.apply_to_shape?[a.model.getObjectByName(c.apply_to_shape,!0)]:a.model.children,b(d,e),BrainBrowser.events.triggerEvent("updatecolors",c,j,k,n),i&&i()}f=f||{};var h=f.blend,i=f.complete,j=c.range_min,k=c.range_max,l=a.getAttribute("flip_colors"),m=a.getAttribute("clamp_colors"),n=a.color_map;clearTimeout(e),e=setTimeout(function(){h?g(d(n,c,0,1)):c.createColorArray(j,k,n,l,m,a.model_data.colors,a.model_data,g)},0)},a.setIntensityRange=function(b,c,d){d=d||{};var e=a.model_data.intensity_data;e.range_min=b,e.range_max=c,a.updateColors(e,{complete:d.complete}),BrainBrowser.events.triggerEvent("rangechange",e)},a.blend=function(b){var c,d=a.blend_data,e=d.length;for(d[0].alpha=b,d[1].alpha=1-b,c=2;e>c;c++)d[c].alpha=0;a.updateColors(d,{blend:!0})}},BrainBrowser.SurfaceViewer.modules.loading=function(a){"use strict";function b(a,b,c){c=c||{};var d=c.format||"mniobj",g=c.parse||{};e(a,d,g,function(a){BrainBrowser.loader.checkCancel(c.cancel)||f(a,b,c)})}function c(b,c,d){d=d||{};var e=d.name||c,f=d.format||"mniobj",g=a.model_data,h=1===d.blend_index?d.blend_index:0,i=1-h,k={};a.getAttribute("fix_color_range")&&g.intensity_data&&(k={min:g.intensity_data.range_min,max:g.intensity_data.range_max}),a.blend_data=a.blend_data||[],j.parseIntensityData(b,f,function(b){var c,f;a.getAttribute("fix_color_range")&&void 0!==k.min&&void 0!==k.max?(c=k.min,f=k.max):(c=void 0===d.min?b.min:d.min,f=void 0===d.max?b.max:d.max),b.filename=e,b.apply_to_shape=d.shape,b.applied=!1,g.intensity_data=b,a.blend_data[h]=b,b.range_min=c,b.range_max=f,a.blend_data[i]&&a.blend_data[i].applied?(a.blend_data[i].range_min=BrainBrowser.utils.min(a.blend_data[i].values),a.blend_data[i].range_max=BrainBrowser.utils.max(a.blend_data[i].values),a.blend(.5),BrainBrowser.events.triggerEvent("loadintensitydata",a.blend_data),BrainBrowser.events.triggerEvent("blendcolormaps",b.range_min,b.range_max,b)):(BrainBrowser.events.triggerEvent("loadintensitydata",b),a.updateColors(b,{complete:d.complete})),b.applied=!0})}function d(b){var c=a.model_data;a.color_map=b,BrainBrowser.events.triggerEvent("loadcolormap",b),c&&c.intensity_data&&a.updateColors(c.intensity_data)}function e(a,b,c,d){var e,f=b+"_model";if(!BrainBrowser.utils.checkConfig("surface_viewer.worker_dir"))throw e="error in SurfaceViewer configuration.\nBrainBrowser.config.surface_viewer.worker_dir not defined.",BrainBrowser.events.triggerEvent("error",e),new Error(e);if(!j.worker_urls[f])throw e="error in SurfaceViewer configuration.\nModel worker URL for "+b+" not defined.",BrainBrowser.events.triggerEvent("error",e),new Error(e);var g,h=new Worker(j.worker_urls[f]);h.addEventListener("message",function(a){var f=a.data;if(f.error)throw e="error parsing model.\n"+f.error_message+"\nFile type: "+b+"\nOptions: "+JSON.stringify(c),BrainBrowser.events.triggerEvent("error",e),new Error(e);d&&(g=new Worker(j.worker_urls.deindex),g.addEventListener("message",function(a){d(a.data)}),g.postMessage(f)),h.terminate()}),h.postMessage({data:a,options:c})}function f(b,c,d){d=d||{};var e=d.render_depth,f=d.complete;g(b,c,e),BrainBrowser.events.triggerEvent("displaymodel",a.model),f&&f()}function g(b,c,d){var e,f,g,i,j=a.model,k=b.shapes,l="line"===b.type;if(a.model_data=b,k){for(g=0,i=k.length;i>g;g++)f=b.shapes[g],e=h(f,l),e.name=f.name||c,e.geometry.original_data={vertices:b.vertices,indices:f.indices,normals:b.normals,colors:b.colors},d&&(e.renderDepth=d),j.add(e);b.split&&(j.children[0].name="left",j.children[0].model_num=0,j.children[1].name="right",j.children[1].model_num=1)}}function h(a,b){var c,d,e=a.unindexed,f=a.wireframe,g=a.centroid,h=e.position,j=e.normal||[],k=e.color||[],l=new THREE.BufferGeometry;return l.dynamic=!0,l.attributes.position={itemSize:3,array:new Float32Array(h),numItems:h.length},j.length>0?l.attributes.normal={itemSize:3,array:new Float32Array(j)}:l.computeVertexNormals(),k.length>0&&(l.attributes.color={itemSize:4,array:new Float32Array(k)}),b?(c=new THREE.LineBasicMaterial({vertexColors:THREE.VertexColors}),d=new THREE.Line(l,c,THREE.LinePieces)):(c=new THREE.MeshPhongMaterial({color:16777215,ambient:16777215,specular:1052688,shininess:150,vertexColors:THREE.VertexColors}),d=new THREE.Mesh(l,c),d.add(i(d,f))),d.centroid=g,d.position.set(g.x,g.y,g.z),d}function i(a,b){var c,d,e=new THREE.BufferGeometry;return e.attributes.position={itemSize:3,array:b.position,numItems:b.position.length},e.attributes.color={itemSize:4,array:b.color},e.attributes.color.needsUpdate=!0,c=new THREE.LineBasicMaterial({vertexColors:THREE.VertexColors}),d=new THREE.Line(e,c,THREE.LinePieces),d.name="__wireframe__",d.visible=!1,a.wireframe_active=!1,d}var j=BrainBrowser.SurfaceViewer,k=BrainBrowser.loader;a.loadModelFromURL=function(a,c){k.loadFromURL(a,b,c)},a.loadModelFromFile=function(a,c){k.loadFromFile(a,b,c)},a.loadIntensityDataFromURL=function(a,b){k.loadFromURL(a,c,b)},a.loadIntensityDataFromFile=function(a,b){k.loadFromFile(a,c,b)},a.loadColorMapFromURL=function(a,b){k.loadColorMapFromURL(a,d,b)},a.loadColorMapFromFile=function(a,b){k.loadColorMapFromFile(a,d,b)}},BrainBrowser.SurfaceViewer.modules.rendering=function(a){"use strict";function b(e){var h,j,k=a.model;window.requestAnimationFrame(b),d=c||e,c=e,h=c-d,j=15e-5*h,a.autorotate.x&&(k.rotation.x+=j),a.autorotate.y&&(k.rotation.y+=j),a.autorotate.z&&(k.rotation.z+=j),i.render(f,g)}var c,d,e=new THREE.WebGLRenderer({preserveDrawingBuffer:!0}),f=new THREE.Scene,g=new THREE.PerspectiveCamera(30,a.dom_element.offsetWidth/a.dom_element.offsetHeight,1,1e4),h=new THREE.PointLight(16777215),i=e,j={},k=e.domElement;a.model=new THREE.Object3D,f.add(a.model),a.render=function(){var c=a.dom_element;e.setClearColor(0),e.setSize(c.offsetWidth,c.offsetHeight),c.appendChild(e.domElement),g.position.z=500,h.position.set(0,0,500),f.add(h),a.autorotate={},window.onresize=function(){i.setSize(c.offsetWidth,c.offsetHeight),g.aspect=c.offsetWidth/c.offsetHeight,g.updateProjectionMatrix()},window.onresize(),b()},a.canvasDataURL=function(){return e.domElement.toDataURL()},a.addEffect=function(b){var c;BrainBrowser.utils.isFunction(THREE[b])&&(c=new THREE[b](e),c.setSize(a.dom_element.offsetWidth,a.dom_element.offsetHeight),j[b]=c)},a.setEffect=function(a){i=j[a]?j[a]:e},a.setCameraPosition=function(a,b,c){g.position.set(a,b,c),h.position.set(a,b,c)},a.resetView=function(){var b,c,d,e,f=a.model,i=new THREE.Matrix4;for(i.getInverse(f.matrix),f.applyMatrix(i),g.position.set(0,0,500),h.position.set(0,0,500),d=0,e=a.model.children.length;e>d;d++)b=f.children[d],b.centroid?b.position.set(b.centroid.x,b.centroid.y,b.centroid.z):b.position.set(0,0,0),b.rotation.set(0,0,0),c=b.getObjectByName("__wireframe__")},a.zoom=function(a){var b=g.position,c=b.z/a;c>g.near&&c<.9*g.far&&(b.z=c,h.position.z=c)},a.setClearColor=function(a){e.setClearColor(a,1)},a.pick=function(b,c){b=b/a.dom_element.offsetWidth*2-1,c=-c/a.dom_element.offsetHeight*2+1;var d,e,f,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w=a.model,x=new THREE.Projector,y=new THREE.Raycaster,z=new THREE.Vector3(b,c,g.near),A=new THREE.Matrix4;if(x.unprojectVector(z,g),y.set(g.position,z.sub(g.position).normalize()),d=y.intersectObject(w,!0),d.length>0){for(e=d[0],h=e.object,j=e.indices,s=h.centroid,t=s.x,u=s.y,v=s.z,A.getInverse(h.matrixWorld),i=e.point.applyMatrix4(A),m=h.geometry.original_data.vertices,n=h.geometry.original_data.indices,k=o=n[j[0]],l=i.distanceTo(new THREE.Vector3(m[3*o]-t,m[3*o+1]-u,m[3*o+2]-v)),q=1,r=j.length;r>q;q++)o=n[j[q]],p=i.distanceTo(new THREE.Vector3(m[3*o]-t,m[3*o+1]-u,m[3*o+2]-v)),l>p&&(k=o,l=p);f={index:k,point:new THREE.Vector3(e.point.x,e.point.y,e.point.z),object:e.object}}else f=null;return f},function(){function b(a){var b,c,d=BrainBrowser.utils.getOffset(k);return void 0!==a.pageX?(b=a.pageX,c=a.pageY):(b=a.clientX+document.body.scrollLeft+document.documentElement.scrollLeft,c=a.clientY+document.body.scrollTop+document.documentElement.scrollTop),b-=d.left,c-=d.top,{x:b,y:c}}function c(a,c){c=c||1;var d,e,f=new THREE.Matrix4,i=b(a),j=i.x,k=i.y;if(null!==o)if(d=j-o,e=k-p,"rotate"===n){f.getInverse(m.matrix);var l=new THREE.Vector3(1,0,0).applyMatrix4(f).normalize();m.rotateOnAxis(l,e/150),f.getInverse(m.matrix),l=new THREE.Vector3(0,1,0).applyMatrix4(f).normalize(),m.rotateOnAxis(l,d/150)}else g.position.x-=d*c,h.position.x-=d*c,g.position.y+=e*c,h.position.y+=e*c;o=j,p=k}function d(c){var d,e=b(c.touches[0]),f=b(c.touches[1]),g=e.x-f.x,h=e.y-f.y,i=Math.sqrt(g*g+h*h);null!==q&&(d=i-q,a.zoom(1+.01*d)),q=i}function e(a){a.preventDefault(),a.stopPropagation(),c(a,.25)}function f(a){a.preventDefault(),a.stopPropagation(),"zoom"===n?d(a):c(a.touches[0],1)}function i(){document.removeEventListener("mousemove",e,!1),document.removeEventListener("mouseup",i,!1),o=null,p=null}function j(){document.removeEventListener("touchmove",f,!1),document.removeEventListener("touchend",j,!1),o=null,p=null,q=null}function l(b){var c=Math.max(-1,Math.min(1,b.wheelDelta||-b.detail));b.preventDefault(),b.stopPropagation(),a.zoom(1+.05*c)}var m=a.model,n="rotate",o=null,p=null,q=null;k.addEventListener("mousedown",function(a){document.addEventListener("mousemove",e,!1),document.addEventListener("mouseup",i,!1),n=1===a.which?"rotate":"translate"},!1),k.addEventListener("touchstart",function(a){document.addEventListener("touchmove",f,!1),document.addEventListener("touchend",j,!1),n=1===a.touches.length?"rotate":2===a.touches.length?"zoom":"translate"},!1),k.addEventListener("mousewheel",l,!1),k.addEventListener("DOMMouseScroll",l,!1),k.addEventListener("contextmenu",function(a){a.preventDefault(),a.stopPropagation()},!1)}()},BrainBrowser.SurfaceViewer.modules.views=function(a){"use strict";function b(a){return a*Math.PI/180}var c={medialView:function(){var c=a.model;a.model_data.split&&(c.getObjectByName("left").position.x-=100,c.getObjectByName("left").rotation.z-=b(90),c.getObjectByName("right").position.x+=100,c.getObjectByName("right").rotation.z+=b(90),c.rotation.x+=b(-90))},lateralView:function(){var c,d,e=a.model;a.model_data.split&&(c=e.getObjectByName("left"),d=e.getObjectByName("right"),c.position.x-=100,c.rotation.z+=b(-90),d.position.x+=100,d.rotation.z+=b(90),e.rotation.x+=b(90),e.rotation.y+=b(180))},inferiorView:function(){a.model.rotation.y+=b(180)},anteriorView:function(){a.resetView(),a.model.rotation.x+=b(-90),a.model.rotation.z+=b(180)},posteriorView:function(){a.resetView(),a.model.rotation.x+=b(-90)}};a.setTransparency=function(b,c){var d,e,f=a.model.getObjectByName(b);f&&(d=f.material,d.opacity=c,d.transparent=1===c?!1:!0,e=f.getObjectByName("__wireframe__"),e&&(e.material.opacity=d.opacity,e.material.transparent=d.transparent))},a.setWireframe=function(b){for(var c,d,e=a.model.children,f=0;f0;)a.model.remove(b[0]);a.resetView(),BrainBrowser.events.triggerEvent("clearscreen")},a.separateHalves=function(b){b=b||1,a.model_data.split&&(a.model.children[0].position.x-=b,a.model.children[1].position.x+=b)}}; \ No newline at end of file diff --git a/build/brainbrowser-1.6.0/brainbrowser.volume-viewer.min.js b/build/brainbrowser-1.6.0/brainbrowser.volume-viewer.min.js new file mode 100644 index 00000000..ca2338d7 --- /dev/null +++ b/build/brainbrowser-1.6.0/brainbrowser.volume-viewer.min.js @@ -0,0 +1,29 @@ +/* +* BrainBrowser: Web-based Neurological Visualization Tools +* (https://brainbrowser.cbrain.mcgill.ca) +* +* Copyright (C) 2011 +* The Royal Institution for the Advancement of Learning +* McGill University +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Affero General Public License as +* published by the Free Software Foundation, either version 3 of the +* License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Affero General Public License for more details. +* +* You should have received a copy of the GNU Affero General Public License +* along with this program. If not, see . +*/ + +/* +* BrainBrowser v1.6.0 +* +* Author: Tarek Sherif (http://tareksherif.ca/) +* Author: Nicolas Kassis +*/ +!function(){"use strict";var a="1.6.0";a=a.indexOf("BRAINBROWSER_VERSION")>0?"D.E.V":a,window.BrainBrowser={version:a},window.requestAnimationFrame=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(a){return window.setTimeout(a,1e3/60)},window.cancelAnimationFrame=window.cancelAnimationFrame||function(a){window.clearTimeout(a)}}(),function(){"use strict";BrainBrowser.createColorMap=function(a){function b(a,b,d,e){var f,g,h,i=document.createElement("canvas"),j=new Array(256);for($(i).attr("width",256),$(i).attr("height",d),f=0;256>f;f++)e?j[255-f]=f:j[f]=f;for(a=c.mapColors(j,{scale255:!0}),h=i.getContext("2d"),g=0;256>g;g++)h.fillStyle="rgb("+Math.floor(a[4*g])+", "+Math.floor(a[4*g+1])+", "+Math.floor(a[4*g+2])+")",h.fillRect(g,0,1,b);return i}var c={createCanvasWithScale:function(a,d,e){e=e||{};var f,g,h=c.colors,i=e.flip,j=d-a;return f=b(h,20,40,i),g=f.getContext("2d"),g.fillStyle="#FFA000",g.fillRect(.5,20,1,10),g.fillText(a.toPrecision(3),.5,40),g.fillRect(f.width/4,20,1,10),g.fillText((a+.25*j).toPrecision(3),.25*f.width,40),g.fillRect(f.width/2,20,1,10),g.fillText((a+.5*j).toPrecision(3),.5*f.width,40),g.fillRect(3*f.width/4,20,1,10),g.fillText((a+.75*j).toPrecision(3),.75*f.width,40),g.fillRect(f.width-.5,20,1,10),g.fillText(d.toPrecision(3),f.width-20,40),f},mapColors:function(a,b){b=b||{};var d,e,f,g,h=void 0===b.min?0:b.min,i=void 0===b.max?255:b.max,j=void 0===b.scale255?!1:b.scale255,k=void 0===b.brightness?0:b.brightness,l=void 0===b.contrast?1:b.contrast,m=void 0===b.alpha?1:b.alpha,n=b.destination||[],o=c.colors,p=o.length,q=i-h,r=(q+q/p)/p,s=j?255:1,t=[];for(m*=s,d=0,e=a.length;e>d;d++)g=a[d],f=h>=g?0:a[d]>i?p-1:Math.floor((g-h)/r),t=o[f]||[0,0,0],n[4*d+0]=s*(t[0]*l+k),n[4*d+1]=s*(t[1]*l+k),n[4*d+2]=s*(t[2]*l+k),n[4*d+3]=m;return n}};return function(){if(a){a=a.replace(/^\s+/,"").replace(/\s+$/,"");var b,d,e,f,g,h=a.split(/\n/),i=[];for(b=0,e=h.length;e>b;b++)if(g=h[b].replace(/^\s+/,"").replace(/\s+$/,"").split(/\s+/).slice(0,4),f=g.length,!(3>f)){for(d=0;f>d;d++)g[d]=parseFloat(g[d]);4>f&&g.push(1),i.push(g)}c.colors=i}}(),c}}(),function(){"use strict";var a=[];BrainBrowser.events={addEventListener:function(b,c){a[b]||(a[b]=[]),a[b].push(c)},triggerEvent:function(b){var c=Array.prototype.slice.call(arguments,1);a[b]&&a[b].forEach(function(a){setTimeout(function(){a.apply(null,c)},0)})}}}(),function(){"use strict";var a=BrainBrowser.loader={loadFromURL:function(b,c,d){d=d||{};var e,f=new XMLHttpRequest,g=d.result_type,h=b.split("/"),i=h[h.length-1];f.open("GET",b),"arraybuffer"===g&&(f.responseType="arraybuffer"),f.onreadystatechange=function(){if(4===f.readyState){if(e=f.status,!(e>=200&&300>e||304===e)){var g="error loading URL: "+b+"\nHTTP Response: "+f.status+"\nHTTP Status: "+f.statusText+"\nResponse was: \n"+f.response;throw BrainBrowser.events.triggerEvent("error",g),new Error(g)}a.checkCancel(d)||c(f.response,i,d)}},f.send()},loadFromFile:function(a,b,c){var d=a.files;if(0!==d.length){c=c||{};var e=c.result_type,f=new FileReader,g=a.value.split("\\"),h=g[g.length-1];f.file=d[0],f.onloadend=function(a){b(a.target.result,h,c)},f.onerror=function(){var a="error reading file: "+h;throw BrainBrowser.events.triggerEvent("error",a),new Error(a)},"arraybuffer"===e?f.readAsArrayBuffer(d[0]):f.readAsText(d[0])}},loadColorMapFromURL:function(a,b,c){BrainBrowser.loader.loadFromURL(a,function(a,c,d){b(BrainBrowser.createColorMap(a),c,d)},c)},loadColorMapFromFile:function(a,b,c){BrainBrowser.loader.loadFromFile(a,function(a,c,d){b(BrainBrowser.createColorMap(a),c,d)},c)},checkCancel:function(a){a=a||{},BrainBrowser.utils.isFunction(a)&&(a={test:a});var b=a.test,c=a.cleanup,d=!1;return b&&b()&&(d=!0,c&&c()),d}}}(),function(){"use strict";BrainBrowser.utils={canvasEnabled:function(){return!!document.createElement("canvas")},webglEnabled:function(){var a=document.createElement("canvas");try{return!(!a||!window.WebGLRenderingContext||!a.getContext("webgl")&&!a.getContext("experimental-webgl"))}catch(b){return!1}},webWorkersEnabled:function(){return!!window.Worker},webGLErrorMessage:function(){var a,b='BrainBrowser requires WebGL.
';return b+=window.WebGLRenderingContext?"Your browser seems to support it, but it is
disabled or unavailable.
":"Your browser does not seem to support it.
",b+='Test your browser\'s WebGL support here.',a=document.createElement("div"),a.id="webgl-error",a.innerHTML=b,a},isFunction:function(a){return a instanceof Function||"function"==typeof a},isNumeric:function(a){return!isNaN(parseFloat(a))},min:function(){var a=Array.prototype.slice.call(arguments);a=1===a.length&&Array.isArray(a[0])?a[0]:a;var b,c,d=a[0];for(b=1,c=a.length;c>b;b++)a[b]b;b++)a[b]>d&&(d=a[b]);return d},getOffset:function(a){for(var b=0,c=0;a.offsetParent;)b+=a.offsetTop,c+=a.offsetLeft,a=a.offsetParent;return{top:b,left:c}},checkConfig:function(a){if(!BrainBrowser.config)return!1;a=a||"";var b,c,d,e=BrainBrowser.config,f=a.split(".");for(c=0,d=f.length;d>c;c++){if(b=f[c],!e[b])return!1;e=e[b]}return!0}}}(),function(){"use strict";var a=BrainBrowser.VolumeViewer={};a.modules={},a.volume_loaders={},a.start=function(b,c){function d(b,c,d){var e=a.utils.axis_to_number[c],g=f.volumes[b],h=g.display[e];h.setSlice(d),h.updateCursor()}function e(){document.addEventListener("keydown",function(a){if(f.active_canvas){var b=f.active_canvas,c=a.which;if(!(37>c||c>40)){a.preventDefault(),a.stopPropagation();var d=f.active_cursor,e=b.getAttribute("data-volume-id"),g=b.getAttribute("data-axis-name");return{37:function(){d.x--},38:function(){d.y--},39:function(){d.x++},40:function(){d.y++}}[c](),f.setCursor(e,g,d),f.synced&&f.volumes.forEach(function(a,b){b!==e&&f.setCursor(b,g,d)}),!1}}},!1)}var f={dom_element:document.getElementById(b),volumes:[],synced:!1,panel_width:256,panel_height:256};Object.keys(a.modules).forEach(function(b){a.modules[b](f)}),console.log("BrainBrowser Volume Viewer v"+BrainBrowser.version);var g={};f.fetchSlice=function(b,c,e,h){g[b]=g[b]||{},clearTimeout(g[b][c]),g[b][c]=setTimeout(function(){var g,i=f.volumes[b],j=a.utils.axis_to_number[c];void 0!==e&&(i.position[c]=e),g=i.slice(c),g.vol_id=b,g.axis_number=j,g.min=i.min,g.max=i.max,d(b,c,g),BrainBrowser.events.triggerEvent("sliceupdate"),BrainBrowser.utils.isFunction(h)&&h(g)},0)},f.setPanelSize=function(a,b,c){c=c||{};var d,e,g,h=c.scale_image;h&&(d=f.panel_width,e=f.panel_height,g=Math.min(a/d,b/e)),f.panel_width=a>0?a:f.panel_width,f.panel_height=b>0?b:f.panel_height,f.volumes.forEach(function(d,e){d.display.forEach(function(d,i){d.setSize(f.panel_width,f.panel_height,c),h&&(d.zoom=d.zoom*g,d.image_center.x=a/2,d.image_center.y=b/2,f.setCursor(e,["xspace","yspace","zspace"][i],{x:d.image_center.x,y:d.image_center.y}))})}),h&&f.redrawVolumes()},e(),c(f)}}(),function(){"use strict";function a(a){var b={x:0,y:0};return a.addEventListener("mousemove",function(c){var d,e,f=BrainBrowser.utils.getOffset(a);void 0!==c.pageX?(d=c.pageX,e=c.pageY):(d=c.clientX+document.body.scrollLeft+document.documentElement.scrollLeft,e=c.clientY+document.body.scrollTop+document.documentElement.scrollTop),b.x=d-f.left,b.y=e-f.top},!1),b}var b={setSize:function(a,b){this.canvas.width=a,this.canvas.height=b},setSlice:function(a){this.slice=a,this.slice_image=this.slice.getImage(this.zoom)},updateCursor:function(){var a=this.volume,b=this.slice,c=this.getImageOrigin();this.cursor.x=a.position[b.width_space.name]*Math.abs(b.width_space.step)*this.zoom+c.x,this.cursor.y=(b.height_space.space_length-a.position[b.height_space.name])*Math.abs(b.height_space.step)*this.zoom+c.y},followCursor:function(a){var b=a.x-this.last_cursor.x,c=a.y-this.last_cursor.y;this.image_center.x+=b,this.image_center.y+=c,this.cursor.x+=b,this.cursor.y+=c,this.last_cursor.x=a.x,this.last_cursor.y=a.y},reset:function(){this.zoom=1,this.image_center.x=this.canvas.width/2,this.image_center.y=this.canvas.height/2},getImageOrigin:function(){return{x:this.image_center.x-this.slice_image.width/2,y:this.image_center.y-this.slice_image.height/2}},drawSlice:function(){var a,b=this.slice_image;b&&(a=this.getImageOrigin(),this.context.putImageData(b,a.x,a.y))},drawCursor:function(a){var b=this.context,c=this.zoom,d=8;a=a||"#FF0000",b.save(),b.strokeStyle=a,b.translate(this.cursor.x,this.cursor.y),b.scale(c,c),b.lineWidth=2,b.beginPath(),b.moveTo(0,-d),b.lineTo(0,-2),b.moveTo(0,2),b.lineTo(0,d),b.moveTo(-d,0),b.lineTo(-2,0),b.moveTo(2,0),b.lineTo(d,0),b.stroke(),b.restore()}};BrainBrowser.VolumeViewer.createPanel=function(c){c=c||{};var d={cursor:{x:0,y:0},last_cursor:{x:0,y:0},image_center:{x:0,y:0},zoom:1},e=Object.create(b);return Object.keys(d).forEach(function(a){e[a]=d[a]}),Object.keys(c).forEach(function(a){e[a]=c[a]}),e.canvas&&BrainBrowser.utils.isFunction(e.canvas.getContext)&&(e.context=e.canvas.getContext("2d"),e.mouse=a(e.canvas)),e}}(),function(){"use strict";function a(a,b,c,d,e,f){var g,h,i,j,k,l=[];for(f=f||1,g=0;b>g;g++)for(h=0;c>h;h++)for(j=d?b-g-1:g,k=e?c-h-1:h,i=0;f>i;i++)l[(h*b+g)*f+i]=a[(k*b+j)*f+i];return l}BrainBrowser.VolumeViewer.utils={axis_to_number:{xspace:0,yspace:1,zspace:2},nearestNeighbor:function(b,c,d){var e=b.data,f=b.width,g=b.height,h=document.createElement("canvas").getContext("2d"),i=4;if(f===c&&g===d)return b;0>c&&d>0&&(e=a(e,f,g,!0,!1,i)),c=Math.abs(c),d=Math.abs(d);for(var j=h.createImageData(c,d),k=j.data,l=f/c,m=g/d,n=0;d>n;n++)for(var o=0;c>o;o++)for(var p=Math.floor(o*l),q=Math.floor(n*m),r=0;i>r;r++)k[Math.floor(n*c+o)*i+r]=e[Math.floor(q*f+p)*i+r];return j},rotateUint16Array90Left:function(a,b,c){var d,e,f=new Uint16Array(b*c);for(d=0;b>d;d++)for(e=0;c>e;e++)f[d*c+e]=a[e*b+(b-d)];return f},rotateUint16Array90Right:function(a,b,c){var d,e,f=new Uint16Array(b*c);for(d=0;b>d;d++)for(e=0;c>e;e++)f[d*c+e]=a[(c-e)*b+d];return f}}}(),BrainBrowser.VolumeViewer.modules.loading=function(a){"use strict";function b(a,b){var c,d=h.volume_loaders[a.type];if(!d)throw c="Unsuported Volume Type",BrainBrowser.events.triggerEvent("error",c),new Error(c);d(a,b)}function c(c,d,e){b(d,function(b){var f=0;a.volumes[c]=b,b.display=g(a.dom_element,c,d),b.color_map=a.default_color_map,["xspace","yspace","zspace"].forEach(function(d){var g=b.position[d]=Math.floor(b.header[d].space_length/2);a.fetchSlice(c,d,g,function(){3===++f&&BrainBrowser.utils.isFunction(e)&&e(b)})})})}function d(b,c,d){b.cursor_color=c,a.default_color_map=b,BrainBrowser.utils.isFunction(d)&&d(b)}function e(b,c,d,e){c.cursor_color=d,a.setVolumeColorMap(b,c),BrainBrowser.utils.isFunction(e)&&e(a.volumes[b],c)}function f(a,b,c,d){var e=document.getElementById(c).innerHTML.replace(/\{\{VOLID\}\}/gm,b),f=document.createElement("div");f.innerHTML=e;var g,h,i,j=f.childNodes,k=f.getElementsByClassName(d)[0];for(g=0,h=a.childNodes.length;h>g;g++)i=a.childNodes[g],1===i.nodeType&&(k.appendChild(i),g--,h--);return j}function g(b,c,d){var e,g=document.createElement("div"),i=a.volumes[c],j=[],k=d.template||{};if(g.classList.add("volume-container"),["xspace","yspace","zspace"].forEach(function(b){var d=document.createElement("canvas");d.width=a.panel_width,d.height=a.panel_height,d.setAttribute("data-volume-id",c),d.setAttribute("data-axis-name",b),d.classList.add("slice-display"),d.style.backgroundColor="#000000",g.appendChild(d),j.push(h.createPanel({volume:i,axis:b,canvas:d,cursor:{x:d.width/2,y:d.height/2},image_center:{x:d.width/2,y:d.height/2}}))}),k.element_id&&k.viewer_insert_class&&(e=f(g,c,k.element_id,k.viewer_insert_class),"function"==typeof k.complete&&k.complete(i,e),Array.prototype.forEach.call(e,function(a){1===a.nodeType&&g.appendChild(a)})),a.volumeUIControls){var l=document.createElement("div");l.className="volume-viewer-controls volume-controls",a.volumeUIControls.defer_until_page_load?BrainBrowser.events.addEventListener("ready",function(){g.appendChild(l),a.volumeUIControls(l,i,c)}):(a.volumeUIControls(l,i,c),g.appendChild(l))}return function(){var b=null;["xspace","yspace","zspace"].forEach(function(d,e){function f(f){var g={x:l.x,y:l.y};f.target===b&&(f.shiftKey?(i.followCursor(g),a.synced&&a.volumes.forEach(function(a,b){b!==c&&a.display[e].followCursor(g)})):(a.setCursor(c,d,g),a.synced&&a.volumes.forEach(function(b,e){e!==c&&a.setCursor(e,d,g)}),i.cursor=a.active_cursor=g))}function g(){document.removeEventListener("mousemove",f,!1),document.removeEventListener("mouseup",g,!1),b=null}function h(b){var d=Math.max(-1,Math.min(1,b.wheelDelta||-b.detail));b.preventDefault(),b.stopPropagation(),i.zoom=Math.max(i.zoom+.05*d,.05),a.fetchSlice(c,["xspace","yspace","zspace"][e]),a.synced&&a.volumes.forEach(function(b,f){if(f!==c){var g=b.display[e];g.zoom=Math.max(g.zoom+.05*d,.05),a.fetchSlice(f,["xspace","yspace","zspace"][e])}})}var i=j[e],k=i.canvas,l=i.mouse;k.addEventListener("mousedown",function(h){b=h.target;var j={x:l.x,y:l.y};h.preventDefault(),h.stopPropagation(),h.shiftKey?(i.last_cursor.x=j.x,i.last_cursor.y=j.y,a.synced&&a.volumes.forEach(function(a,b){if(b!==c){var d=a.display[e];d.last_cursor.x=j.x,d.last_cursor.y=j.y}})):(a.setCursor(c,d,j),a.synced&&a.volumes.forEach(function(b,e){e!==c&&a.setCursor(e,d,j)}),i.cursor=a.active_cursor=j),a.active_canvas=h.target,document.addEventListener("mousemove",f,!1),document.addEventListener("mouseup",g,!1)},!1),k.addEventListener("mousewheel",h,!1),k.addEventListener("DOMMouseScroll",h,!1)})}(),b.appendChild(g),BrainBrowser.events.triggerEvent("volumeuiloaded",g,c),j}var h=BrainBrowser.VolumeViewer;a.loadVolumes=function(b){function d(d){c(d,g[d],function(){++j1?a.createOverlay(f,function(){BrainBrowser.utils.isFunction(i)&&i(),BrainBrowser.events.triggerEvent("volumesloaded")}):(BrainBrowser.utils.isFunction(i)&&i(),BrainBrowser.events.triggerEvent("volumesloaded")))})}b=b||{};var e,f=b.overlay&&"object"==typeof b.overlay?b.overlay:{},g=b.volumes,h=b.volumes.length,i=b.complete,j=0;for(e=0;h>e;e++)d(e)},a.loadVolumeColorMapFromURL=function(a,b,c,d){BrainBrowser.loader.loadColorMapFromURL(b,function(b){e(a,b,c,d)})},a.loadDefaultColorMapFromURL=function(a,b,c){BrainBrowser.loader.loadColorMapFromURL(a,function(a){d(a,b,c)})},a.loadVolumeColorMapFromFile=function(a,b,c,d){BrainBrowser.loader.loadColorMapFromFile(b,function(b){e(a,b,c,d)})},a.loadDefaultColorMapFromFile=function(a,b,c){BrainBrowser.loader.loadColorMapFromFile(a,function(a){d(a,b,c)})},a.setVolumeColorMap=function(b,c){a.volumes[b].color_map=c},a.loadVolume=function(b,d){c(a.volumes.length,b,d)},a.clearVolumes=function(){a.volumes=[],a.active_canvas=null,a.active_cursor=null,a.dom_element.innerHTML=""},a.createOverlay=function(b,c){b=b||{},a.loadVolume({volumes:a.volumes,type:"overlay",template:b.template},c)}},BrainBrowser.VolumeViewer.modules.rendering=function(a){"use strict";var b=BrainBrowser.VolumeViewer;a.draw=function(){var b,c,d,e=4,f=e/2;a.volumes.forEach(function(g){g.display.forEach(function(h){c=h.canvas,b=h.context,b.globalAlpha=255,b.clearRect(0,0,c.width,c.height),d=g.color_map||a.default_color_map,h.drawSlice(),h.drawCursor(d.cursor_color),c===a.active_canvas&&(b.save(),b.strokeStyle="#EC2121",b.lineWidth=e,b.strokeRect(f,f,c.width-e,c.height-e),b.restore())})})},a.render=function(){BrainBrowser.events.triggerEvent("rendering"),function b(){window.requestAnimationFrame(b),a.draw()}()},a.setCursor=function(c,d,e){var f,g,h=a.volumes[c],i=b.utils.axis_to_number[d],j=h.display[i],k=j.slice,l=j.getImageOrigin(),m=j.zoom;j.cursor.x=e.x,j.cursor.y=e.y,e?(f=Math.floor((e.x-l.x)/m/Math.abs(k.width_space.step)),g=Math.floor(k.height_space.space_length-(e.y-l.y)/m/Math.abs(k.height_space.step))):(f=null,g=null),a.fetchSlice(c,k.width_space.name,f),a.fetchSlice(c,k.height_space.name,g)},a.redrawVolumes=function(){a.volumes.forEach(function(b,c){a.fetchSlice(c,"xspace",b.position.xspace),a.fetchSlice(c,"yspace",b.position.yspace),a.fetchSlice(c,"zspace",b.position.zspace)})},a.resetDisplays=function(){a.volumes.forEach(function(a){a.display.forEach(function(a){a.reset()})})}},function(){"use strict";function a(a,b){var c,d;try{c=JSON.parse(a)}catch(e){throw d="server did not respond with valid JSON\nResponse was: \n"+a,BrainBrowser.events.triggerEvent("error",d),new Error(d)}BrainBrowser.utils.isFunction(b)&&b(c)}function b(a,b,d){var f=Object.create(e);f.position={},f.current_time=0,f.data=c(a,new Uint8Array(b)),f.header=f.data.header,f.min=0,f.max=255,BrainBrowser.utils.isFunction(d)&&d(f)}function c(a,b){var c=Object.create(f);c.header=a,c.order=a.order,4===c.order.length&&(c.order=c.order.slice(1),c.time=a.time),c.xspace=a.xspace,c.yspace=a.yspace,c.zspace=a.zspace,c.xspace.name="xspace",c.yspace.name="yspace",c.zspace.name="zspace",c.xspace.space_length=parseFloat(c.xspace.space_length),c.yspace.space_length=parseFloat(c.yspace.space_length),c.zspace.space_length=parseFloat(c.zspace.space_length),c.xspace.start=parseFloat(c.xspace.start),c.yspace.start=parseFloat(c.yspace.start),c.zspace.start=parseFloat(c.zspace.start),c.xspace.step=parseFloat(c.xspace.step),c.yspace.step=parseFloat(c.yspace.step),c.zspace.step=parseFloat(c.zspace.step),4===c.order.length&&(c.time.space_length=parseFloat(c.time.space_length),c.time.start=parseFloat(c.time.start),c.time.step=parseFloat(c.time.step));var d=c[c.order[0]],e=c[c.order[1]],g=c[c.order[2]];return d.height=parseFloat(e.space_length),d.height_space=e,d.width=parseFloat(g.space_length),d.width_space=g,e.height=parseFloat(g.space_length),e.height_space=g,e.width=parseFloat(d.space_length),e.width_space=d,g.height=parseFloat(e.space_length),g.height_space=e,g.width=parseFloat(d.space_length),g.width_space=d,d.offset=parseFloat(e.space_length)*parseFloat(g.space_length),e.offset=parseFloat(d.space_length),g.offset=parseFloat(d.space_length),d.slice_length=d.height*d.width,c.cached_slices={},c.data=b,c}var d=BrainBrowser.VolumeViewer,e={slice:function(a,b,c){b=b||this.position[a],c=c||this.current_time;var e=this.data.slice(a,b,c);return e.color_map=this.color_map,e.min=this.min,e.max=this.max,e.axis=a,e.getImage=function(a){a=a||1;var b=document.createElement("canvas").getContext("2d"),c=e.color_map,f=b.createImageData(e.width,e.height);c.mapColors(e.data,{min:e.min,max:e.max,scale255:!0,brightness:0,contrast:1,alpha:e.alpha,destination:f.data});var g=e.width_space.step,h=e.height_space.step;return d.utils.nearestNeighbor(f,Math.floor(e.width*g*a),Math.floor(e.height*h*a))},e},getVoxelCoords:function(){return{x:this.position.xspace,y:this.position.yspace,z:this.position.zspace}},setVoxelCoords:function(a,b,c){this.position.xspace=a,this.position.yspace=b,this.position.zspace=c},getWorldCoords:function(){return{x:this.data.xspace.start+this.position.xspace*this.data.xspace.step,y:this.data.yspace.start+this.position.yspace*this.data.yspace.step,z:this.data.zspace.start+this.position.zspace*this.data.zspace.step}},setWorldCoords:function(a,b,c){this.position.xspace=Math.floor((a-this.data.xspace.start)/this.data.xspace.step),this.position.yspace=Math.floor((b-this.data.yspace.start)/this.data.yspace.step),this.position.zspace=Math.floor((c-this.data.zspace.start)/this.data.zspace.step)}},f={slice:function(a,b,c){var e,f=this.cached_slices,g=this[this.order[0]];if(c=c||0,f[a]=f[a]||[],f[a][c]=f[a][c]||[],this[a].step<0&&(b=this[a].space_length-b),void 0!==f[a][c][b])return e=f[a][c][b],e.alpha=1,e.number=b,e;if(void 0===this.order)return!1;var h=0;this.time&&(h=c*g.height*g.width*parseFloat(g.space_length));var i=this[a].width_space.step,j=this[a].height_space.step;e={};var k,l,m,n,o,p,q,r,s,t;if(this.order[0]===a)if(l=this[a].height*this[a].width,m=this[a].height,n=this[a].width,o=1,p=n,q=l,k=new Uint16Array(l),i>0)if(j>0)for(r=0;l>r;r++)k[r]=this.data[h+q*b+r];else for(r=m;r>0;r--)for(s=0;n>s;s++)k[(m-r)*n+s]=this.data[h+q*b+r*n+s];else if(0>j)for(r=0;m>r;r++)for(s=0;n>s;s++)k[r*n+s]=this.data[h+q*b+r*n+n-s];else for(r=m;r>0;r--)for(s=0;n>s;s++)k[(m-r)*n+s]=this.data[h+q*b+r*n+n-s];else if(this.order[1]===a)if(m=this[a].height,l=this[a].height*this[a].width,n=this[a].width,o=1,p=g.slice_length,q=g.width,k=new Uint8Array(l),0>j)for(s=0;m>s;s++)for(t=0;n>t;t++)k[s*n+t]=this.data[h+b*q+p*t+s];else for(s=m;s>=0;s--)for(t=0;n>t;t++)k[(m-s)*n+t]=this.data[h+b*q+p*t+s];else for(m=this[a].height,l=this[a].height*this[a].width,n=this[a].width,o=g.slice_length,p=g.width,q=1,k=new Uint16Array(l),s=0;m>s;s++)for(t=0;n>t;t++)k[s*n+t]=this.data[h+b+g.width*s+t*g.slice_length];return e.width_space=this[a].width_space,e.height_space=this[a].height_space,e.width=n,e.height=m,"xspace"===a&&"yspace"===this.xspace.height_space.name&&(k=this.zspace.step<0?d.utils.rotateUint16Array90Right(k,e.width,e.height):d.utils.rotateUint16Array90Left(k,e.width,e.height),e.width_space=this[a].height_space,e.height_space=this[a].width_space,e.width=m,e.height=n),"yspace"===a&&"xspace"===this.yspace.height_space.name&&(k=this.zspace.step<0?d.utils.rotateUint16Array90Right(k,e.width,e.height):d.utils.rotateUint16Array90Left(k,e.width,e.height),e.width_space=this[a].height_space,e.height_space=this[a].width_space,e.width=m,e.height=n),"zspace"===a&&"xspace"===this.zspace.height_space.name&&(k=d.utils.rotateUint16Array90Left(k,e.width,e.height),e.width_space=this[a].width_space,e.height_space=this[a].height_space,e.width=m,e.height=n),e.data=k,e.width_space=e.width_space||this[a].width_space,e.height_space=e.height_space||this[a].height_space,e.width=e.width||n,e.height=e.height||m,f[a][c][b]=e,e}};d.volume_loaders.minc=function(c,d){var e;if(c.header_url&&c.raw_data_url)BrainBrowser.loader.loadFromURL(c.header_url,function(e){a(e,function(a){BrainBrowser.loader.loadFromURL(c.raw_data_url,function(c){b(a,c,d)},{result_type:"arraybuffer"})})});else{if(!c.header_file||!c.raw_data_file)throw e="invalid volume description.\nDescription must contain property pair 'header_url' and 'raw_data_url', or\n'header_file' and 'raw_data_file'.",BrainBrowser.events.triggerEvent("error",e),new Error(e);BrainBrowser.loader.loadFromFile(c.header_file,function(e){a(e,function(a){BrainBrowser.loader.loadFromFile(c.raw_data_file,function(c){b(a,c,d)},{result_type:"arraybuffer"})})})}}}(),function(){"use strict";function a(a,b){var c,d,e,f,g,h,i,j=a.length,k=b.data,l=b.width,m=b.height,n=[];if(j>1){for(c=0;m>c;c+=1)for(e=0;l>e;e+=1)for(d=0;j>d;d+=1)n[d]=n[d]||0,f=a[d],c. +*/ + +/* +* BrainBrowser v1.6.0 +* +* Author: Tarek Sherif (http://tareksherif.ca/) +* Author: Nicolas Kassis +*/ +!function(){"use strict";function a(a,c,d,e,f){a=a||[],c=c||[],d=d||[],e=e||[.7,.7,.7,1];var g,h,i,j,k,l,m,n,o,p,q,r,s,t=a.length,u=3*t,v=4*t,w=d.length>0,x={},y={};4===e.length&&(l=!0,i=e[0],j=e[1],k=e[2]);var z=new Float32Array(u),A=w?new Float32Array(u):new Float32Array,B=new Float32Array(v);for(f&&(g=new Float32Array(2*u),h=new Float32Array(2*v)),m=0,n=a.length;n>m;m++)b(x,c[3*a[m]],c[3*a[m]+1],c[3*a[m]+2]);for(y.x=x.minX+(x.maxX-x.minX)/2,y.y=x.minY+(x.maxY-x.minY)/2,y.z=x.minZ+(x.maxZ-x.minZ)/2,y.bounding_box=x,m=0,n=t;n>m;m+=3)p=3*m,q=4*m,z[p]=c[3*a[m]]-y.x,z[p+1]=c[3*a[m]+1]-y.y,z[p+2]=c[3*a[m]+2]-y.z,z[p+3]=c[3*a[m+1]]-y.x,z[p+4]=c[3*a[m+1]+1]-y.y,z[p+5]=c[3*a[m+1]+2]-y.z,z[p+6]=c[3*a[m+2]]-y.x,z[p+7]=c[3*a[m+2]+1]-y.y,z[p+8]=c[3*a[m+2]+2]-y.z,w&&(A[p]=d[3*a[m]],A[p+1]=d[3*a[m]+1],A[p+2]=d[3*a[m]+2],A[p+3]=d[3*a[m+1]],A[p+4]=d[3*a[m+1]+1],A[p+5]=d[3*a[m+1]+2],A[p+6]=d[3*a[m+2]],A[p+7]=d[3*a[m+2]+1],A[p+8]=d[3*a[m+2]+2]),l?(B[q]=i,B[q+1]=j,B[q+2]=k,B[q+3]=1,B[q+4]=i,B[q+5]=j,B[q+6]=k,B[q+7]=1,B[q+8]=i,B[q+9]=j,B[q+10]=k,B[q+11]=1):(B[q]=e[4*a[m]],B[q+1]=e[4*a[m]+1],B[q+2]=e[4*a[m]+2],B[q+3]=1,B[q+4]=e[4*a[m+1]],B[q+5]=e[4*a[m+1]+1],B[q+6]=e[4*a[m+1]+2],B[q+7]=1,B[q+8]=e[4*a[m+2]],B[q+9]=e[4*a[m+2]+1],B[q+10]=e[4*a[m+2]+2],B[q+11]=1),f&&(o=2*p,r=2*q,g[o]=z[p],g[o+1]=z[p+1],g[o+2]=z[p+2],g[o+3]=z[p+3],g[o+4]=z[p+4],g[o+5]=z[p+5],g[o+6]=z[p+3],g[o+7]=z[p+4],g[o+8]=z[p+5],g[o+9]=z[p+6],g[o+10]=z[p+7],g[o+11]=z[p+8],g[o+12]=z[p+6],g[o+13]=z[p+7],g[o+14]=z[p+8],g[o+15]=z[p],g[o+16]=z[p+1],g[o+17]=z[p+2],h[r]=B[q],h[r+1]=B[q+1],h[r+2]=B[q+2],h[r+3]=B[q+3],h[r+4]=B[q+4],h[r+5]=B[q+5],h[r+6]=B[q+6],h[r+7]=B[q+7],h[r+8]=B[q+4],h[r+9]=B[q+5],h[r+10]=B[q+6],h[r+11]=B[q+7],h[r+12]=B[q+8],h[r+13]=B[q+9],h[r+14]=B[q+10],h[r+15]=B[q+11],h[r+16]=B[q+8],h[r+17]=B[q+9],h[r+18]=B[q+10],h[r+19]=B[q+11],h[r+20]=B[q],h[r+21]=B[q+1],h[r+22]=B[q+2],h[r+23]=B[q+3]);return s={centroid:y,unindexed:{position:z,normal:A,color:B}},f&&(s.wireframe={position:g,color:h}),s}function b(a,b,c,d){(!a.minX||a.minX>b)&&(a.minX=b),(!a.maxX||a.maxXc)&&(a.minY=c),(!a.maxY||a.maxYd)&&(a.minZ=d),(!a.maxZ||a.maxZc;c++)e=h[c],f=a(h[c].indices,i,j,k,"line"!==g.type),e.centroid=f.centroid,e.unindexed=f.unindexed,e.wireframe=f.wireframe;self.postMessage(g)})}(); \ No newline at end of file diff --git a/build/brainbrowser-1.6.0/workers/freesurferasc.intensity.worker.js b/build/brainbrowser-1.6.0/workers/freesurferasc.intensity.worker.js new file mode 100644 index 00000000..7d700f40 --- /dev/null +++ b/build/brainbrowser-1.6.0/workers/freesurferasc.intensity.worker.js @@ -0,0 +1,29 @@ +/* +* BrainBrowser: Web-based Neurological Visualization Tools +* (https://brainbrowser.cbrain.mcgill.ca) +* +* Copyright (C) 2011 +* The Royal Institution for the Advancement of Learning +* McGill University +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Affero General Public License as +* published by the Free Software Foundation, either version 3 of the +* License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Affero General Public License for more details. +* +* You should have received a copy of the GNU Affero General Public License +* along with this program. If not, see . +*/ + +/* +* BrainBrowser v1.6.0 +* +* Author: Tarek Sherif (http://tareksherif.ca/) +* Author: Nicolas Kassis +*/ +!function(){"use strict";function a(a){var b,c,d,e,f,g,h={values:[]};for(a=a.replace(/^\s+/,"").replace(/\s+$/,""),b=a.split("\n"),c=parseFloat(b[0].split(/\s+/)[4]),h.values[0]=c,f=c,g=c,d=1,e=b.length;e>d;d++)c=parseFloat(b[d].split(/\s+/)[4]),h.values[d]=c,f=Math.min(f,c),g=Math.max(g,c);return h.min=f,h.max=g,h}self.addEventListener("message",function(b){var c=b.data,d=c.data;self.postMessage(a(d))})}(); \ No newline at end of file diff --git a/build/brainbrowser-1.6.0/workers/freesurferasc.worker.js b/build/brainbrowser-1.6.0/workers/freesurferasc.worker.js new file mode 100644 index 00000000..c7f43bb3 --- /dev/null +++ b/build/brainbrowser-1.6.0/workers/freesurferasc.worker.js @@ -0,0 +1,29 @@ +/* +* BrainBrowser: Web-based Neurological Visualization Tools +* (https://brainbrowser.cbrain.mcgill.ca) +* +* Copyright (C) 2011 +* The Royal Institution for the Advancement of Learning +* McGill University +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Affero General Public License as +* published by the Free Software Foundation, either version 3 of the +* License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Affero General Public License for more details. +* +* You should have received a copy of the GNU Affero General Public License +* along with this program. If not, see . +*/ + +/* +* BrainBrowser v1.6.0 +* +* Author: Tarek Sherif (http://tareksherif.ca/) +* Author: Nicolas Kassis +*/ +!function(){"use strict";function a(a){var b,c,d,e,f,g,h,i=[],j={};for(a=a.split("\n"),j.shapes=[],b={name:"undefined"|a.name,faces:[],indices:[]},j.shapes.push(b),c=a[1].split(/\s+/),d=parseInt(c[0],10),e=parseInt(c[1],10),h=2;d+2>h;h++)f=a[h].split(/\s+/),i.push(parseFloat(f[0])),i.push(parseFloat(f[1])),i.push(parseFloat(f[2]));for(h=d+2;d+e+2>h;h++)f=a[h].split(/\s+/),g=[],g.push(parseInt(f[0],10)),g.push(parseInt(f[1],10)),g.push(parseInt(f[2],10)),Array.prototype.push.apply(b.indices,g),b.faces.push(g);return j.type="polygon",j.vertices=i,j.colors=[.8,.8,.8,1],j}self.addEventListener("message",function(b){self.postMessage(a(b.data.data))})}(); \ No newline at end of file diff --git a/build/brainbrowser-1.6.0/workers/mniobj.intensity.worker.js b/build/brainbrowser-1.6.0/workers/mniobj.intensity.worker.js new file mode 100644 index 00000000..257f0f21 --- /dev/null +++ b/build/brainbrowser-1.6.0/workers/mniobj.intensity.worker.js @@ -0,0 +1,29 @@ +/* +* BrainBrowser: Web-based Neurological Visualization Tools +* (https://brainbrowser.cbrain.mcgill.ca) +* +* Copyright (C) 2011 +* The Royal Institution for the Advancement of Learning +* McGill University +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Affero General Public License as +* published by the Free Software Foundation, either version 3 of the +* License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Affero General Public License for more details. +* +* You should have received a copy of the GNU Affero General Public License +* along with this program. If not, see . +*/ + +/* +* BrainBrowser v1.6.0 +* +* Author: Tarek Sherif (http://tareksherif.ca/) +* Author: Nicolas Kassis +*/ +!function(){"use strict";function a(a){var b,c,d,e,f={};for(a=a.replace(/^\s+/,"").replace(/\s+$/,""),f.values=a.split(/\s+/),d=f.values[0],e=f.values[0],b=0,c=f.values.length;c>b;b++)f.values[b]=parseFloat(f.values[b]),d=Math.min(d,f.values[b]),e=Math.max(e,f.values[b]);return f.min=d,f.max=e,f}self.addEventListener("message",function(b){var c=b.data,d=c.data;self.postMessage(a(d))})}(); \ No newline at end of file diff --git a/build/brainbrowser-1.6.0/workers/mniobj.worker.js b/build/brainbrowser-1.6.0/workers/mniobj.worker.js new file mode 100644 index 00000000..d64e16b1 --- /dev/null +++ b/build/brainbrowser-1.6.0/workers/mniobj.worker.js @@ -0,0 +1,29 @@ +/* +* BrainBrowser: Web-based Neurological Visualization Tools +* (https://brainbrowser.cbrain.mcgill.ca) +* +* Copyright (C) 2011 +* The Royal Institution for the Advancement of Learning +* McGill University +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Affero General Public License as +* published by the Free Software Foundation, either version 3 of the +* License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Affero General Public License for more details. +* +* You should have received a copy of the GNU Affero General Public License +* along with this program. If not, see . +*/ + +/* +* BrainBrowser v1.6.0 +* +* Author: Tarek Sherif (http://tareksherif.ca/) +* Author: Nicolas Kassis +*/ +!function(){"use strict";function a(a,i){var j,k,l,m,n,o,p,q=a.replace(/\s+$/,"").replace(/^\s+/,""),r=[],s=i.split,t={},u=q.split(/\s+/).reverse(),v=u.pop();if(t.split=!1,t.type="P"===v?"polygon":"L"===v?"line":v,"polygon"===t.type)b(t,u),t.num_vertices=parseInt(u.pop(),10),c(t,u),d(t,u),t.nitems=parseInt(u.pop(),10);else{if("line"!==t.type)return t.error=!0,void(t.error_message='Invalid MNI Object class: must be "polygon" or "line"');b(t,u),t.num_vertices=parseInt(u.pop(),10),c(t,u),t.nitems=parseInt(u.pop(),10)}if(e(t,u),f(t,u),g(t,u),"polygon"===t.type)s&&(t.split=!0,h(t,u));else if("line"===t.type){for(o=t.indices,p=t.end_indices,n=t.nitems,j=0;n>j;j++){for(l=0===j?0:p[j-1],r.push(o[l]),m=p[j],k=l+1;m-1>k;k++)r.push(o[k]),r.push(o[k]);r.push(o[m-1])}t.indices=r}return t}function b(a,b){"polygon"===a.type?a.surface_properties={ambient:parseFloat(b.pop()),diffuse:parseFloat(b.pop()),specular_reflectance:parseFloat(b.pop()),specular_scattering:parseFloat(b.pop()),transparency:parseFloat(b.pop())}:"line"===a.type&&(a.surfaceProperties={width:b.pop()})}function c(a,b){var c,d,e=[],f=a.num_vertices;for(c=0;f>c;c++)for(d=0;3>d;d++)e.push(parseFloat(b.pop()));a.vertices=e}function d(a,b){var c,d,e=[],f=a.num_vertices;for(c=0;f>c;c++)for(d=0;3>d;d++)e.push(parseFloat(b.pop()));a.normals=e}function e(a,b){var c,d,e,f=[],g=parseInt(b.pop(),10);if(0===g)for(c=0;4>c;c++)f.push(parseFloat(b.pop()));else if(1===g)for(d=0,e=a.num_polygons;e>d;d++)for(c=0;4>c;c++)f.push(parseFloat(b.pop()));else{if(2!==g)throw new Error("color_flag not valid in that file");for(d=0,e=a.num_vertices;e>d;d++)for(c=0;4>c;c++)f.push(parseFloat(b.pop()))}a.color_flag=g,a.colors=f}function f(a,b){var c,d,e=[];for(c=0,d=a.nitems;d>c;c++)e.push(parseInt(b.pop(),10));a.end_indices=e}function g(a,b){var c,d,e,f=b.length,g=[];for(d=0,e=b.length;f>d;d++)c=parseInt(b.pop(),10),g.push(c);a.indices=g}function h(a){var b=a.indices.length;a.left={indices:a.indices.slice(0,b/2)},a.right={indices:a.indices.slice(b/2)}}self.addEventListener("message",function(b){var c=b.data,d=a(c.data,c.options)||{error:!0,error_message:"Error parsing data."},e={type:d.type,vertices:d.vertices,normals:d.normals,colors:d.colors,surface_properties:d.surface_properties,split:d.split,error:d.error,error_message:d.error_message};e.shapes=e.split?[{indices:d.left.indices},{indices:d.right.indices}]:[{indices:d.indices}],self.postMessage(e)})}(); \ No newline at end of file diff --git a/build/brainbrowser-1.6.0/workers/wavefrontobj.worker.js b/build/brainbrowser-1.6.0/workers/wavefrontobj.worker.js new file mode 100644 index 00000000..b0979304 --- /dev/null +++ b/build/brainbrowser-1.6.0/workers/wavefrontobj.worker.js @@ -0,0 +1,29 @@ +/* +* BrainBrowser: Web-based Neurological Visualization Tools +* (https://brainbrowser.cbrain.mcgill.ca) +* +* Copyright (C) 2011 +* The Royal Institution for the Advancement of Learning +* McGill University +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Affero General Public License as +* published by the Free Software Foundation, either version 3 of the +* License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Affero General Public License for more details. +* +* You should have received a copy of the GNU Affero General Public License +* along with this program. If not, see . +*/ + +/* +* BrainBrowser v1.6.0 +* +* Author: Tarek Sherif (http://tareksherif.ca/) +* Author: Nicolas Kassis +*/ +!function(){"use strict";function a(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o=[],p=[],q=[],r={};for(a=a.split("\n"),r.shapes=[],b={name:"undefined"|a.name,faces:[],indices:[],texture_indices:[],normal_indices:[]},r.shapes.push(b),i=0,l=a.length;l>i;i++)if(f=a[i].split(/\s+/),g=f[0],h=f.length,!g.match("#")||""===f)switch(g){case"o":case"g":b={name:f[1],faces:[],indices:[],texture_indices:[],normal_indices:[]},r.shapes.push(b);break;case"v":o.push(parseFloat(f[1])),o.push(parseFloat(f[2])),o.push(parseFloat(f[3]));break;case"vt":for(j=1;h>j;j++)p.push(parseFloat(f[j]));break;case"vn":q.push(parseFloat(f[1])),q.push(parseFloat(f[2])),q.push(parseFloat(f[3]));break;case"f":m=[],c=b.indices,d=b.texture_indices,e=b.normal_indices;var s=f[1].split("/");for(k=2;h-1>k;k++)m.push(parseInt(s[0],10)-1),c.push(parseInt(s[0],10)-1),d.push(parseInt(s[1],10)-1),s[2]&&e.push(parseInt(s[2],10)-1),n=f[k].split("/"),m.push(parseInt(n[0],10)-1),c.push(parseInt(n[0],10)-1),d.push(parseInt(n[1],10)-1),n[2]&&e.push(parseInt(n[2],10)-1),n=f[k+1].split("/"),m.push(parseInt(n[0],10)-1),c.push(parseInt(n[0],10)-1),d.push(parseInt(n[1],10)-1),n[2]&&e.push(parseInt(n[2],10)-1);b.faces.push(m)}return r.type="polygon",r.vertices=o,r.normals=q,r.colors=[.8,.8,.8,1],r.texture_coords=p,r}self.addEventListener("message",function(b){self.postMessage(a(b.data.data))})}(); \ No newline at end of file diff --git a/package.json b/package.json index 29fd2954..39e19f73 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "brainbrowser", - "version": "1.5.4", + "version": "1.6.0", "license": "GNU Affero GPL 3.0", "devDependencies": { "grunt": "~0.4.1", diff --git a/release/brainbrowser-1.6.0.tar.gz b/release/brainbrowser-1.6.0.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..f4c0c074c94986c0bb7ae9a1b9f1104c1eb63877 GIT binary patch literal 18361 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 U;0^-+Lm}}00C}VH3ji1a0F3gQfB*mh literal 0 HcmV?d00001