1
0

2 Achegas 09773cd20e ... b5b5116caf

Autor SHA1 Mensaxe Data
  Raghav Arora b5b5116caf Added Wave with correct loading order %!s(int64=6) %!d(string=hai) anos
  Raghav Arora 8e35563596 Added Zoom Selection %!s(int64=6) %!d(string=hai) anos
Modificáronse 3 ficheiros con 390 adicións e 283 borrados
  1. 24 0
      nova/static/css/custom.css
  2. 290 279
      nova/static/js/wave/volumeRaycaster.js
  3. 76 4
      nova/templates/dataset/wave.html

+ 24 - 0
nova/static/css/custom.css

@@ -393,3 +393,27 @@ a:hover {
   width: 20px;
   height: 20px;
 }
+
+#zoom-controls {
+  position: relative;
+}
+
+#zoom-controls>div {
+  display: inline-block;
+  margin-left:40px;
+}
+
+#xy-zoom-control, #yz-zoom-control {
+    overflow: hidden;
+    position: relative;
+    width: 150px;
+    height: 150px;
+    border: 1px solid #ddd;
+}
+
+#xy-zoom-selection, #yz-zoom-selection {
+    position: absolute;
+    width: 150px;
+    height: 150px;
+    border: 1px solid blue;
+}

+ 290 - 279
nova/static/js/wave/volumeRaycaster.js

@@ -601,139 +601,137 @@ Core.prototype.init = function() {
     // 2D
     if(this._mode == "2d") {
         /*
-	    this._tex1 = THREE.ImageUtils.loadTexture( this._slicemaps_paths[0] );
-	    this._tex1.minFilter = THREE.LinearFilter;
-	    this._tex2 = THREE.ImageUtils.loadTexture( this._slicemaps_paths[1] );
-	    this._tex2.minFilter = THREE.LinearFilter;
-	    this._cm = THREE.ImageUtils.loadTexture( "http://katrin.kit.edu/static/colormaps/cm_BrBG.png" );
-	    this._cm.minFilter = THREE.LinearFilter;
-
-	    this._material2D = new THREE.ShaderMaterial({
-		vertexShader: this._shaders["secondPass2DCustom"].vertexShader,
-		fragmentShader: ejs.render(
-		    this._shaders["secondPass2DCustom"].fragmentShader,
-		    {"maxTexturesNumber": this.getMaxTexturesNumber()}
-		),
-		uniforms: {
-		    uSetViewMode: {type: "i", value: 0},
-		    texture1: {type: 't', value: this._tex1},
-		    texture2: {type: 't', value: this._tex2},
-		    colourmap: {type: 't', value: this._cm},
-		    uZoom: {type:'v4', value: new THREE.Vector4(0.0, 1.0, 0.0, 1.0)},
-		    //uZoom: {type:'v4', value: new THREE.Vector4(0.1875, 0.28125, 0.20117, 0.29492)},
-		    resolution: {type: 'v2',value: new THREE.Vector2(this._render_size[0], this._render_size[1])}
-		}
-	    });
-	    var geometry = new THREE.PlaneBufferGeometry( 10, 10 );
-	    this._meshFirstPass = new THREE.Mesh( geometry, this._material2D );
-	    this._sceneFirstPass = new THREE.Scene();
-	    this._sceneFirstPass.add(this._meshFirstPass);
+        this._tex1 = THREE.ImageUtils.loadTexture( this._slicemaps_paths[0] );
+        this._tex1.minFilter = THREE.LinearFilter;
+        this._tex2 = THREE.ImageUtils.loadTexture( this._slicemaps_paths[1] );
+        this._tex2.minFilter = THREE.LinearFilter;
+        this._cm = THREE.ImageUtils.loadTexture( "http://katrin.kit.edu/static/colormaps/cm_BrBG.png" );
+        this._cm.minFilter = THREE.LinearFilter;
+
+        this._material2D = new THREE.ShaderMaterial({
+        vertexShader: this._shaders["secondPass2DCustom"].vertexShader,
+        fragmentShader: ejs.render(
+            this._shaders["secondPass2DCustom"].fragmentShader,
+            {"maxTexturesNumber": this.getMaxTexturesNumber()}
+        ),
+        uniforms: {
+            uSetViewMode: {type: "i", value: 0},
+            texture1: {type: 't', value: this._tex1},
+            texture2: {type: 't', value: this._tex2},
+            colourmap: {type: 't', value: this._cm},
+            uZoom: {type:'v4', value: new THREE.Vector4(0.0, 1.0, 0.0, 1.0)},
+            //uZoom: {type:'v4', value: new THREE.Vector4(0.1875, 0.28125, 0.20117, 0.29492)},
+            resolution: {type: 'v2',value: new THREE.Vector2(this._render_size[0], this._render_size[1])}
+        }
+        });
+        var geometry = new THREE.PlaneBufferGeometry( 10, 10 );
+        this._meshFirstPass = new THREE.Mesh( geometry, this._material2D );
+        this._sceneFirstPass = new THREE.Scene();
+        this._sceneFirstPass.add(this._meshFirstPass);
         */
-	    //var sprite = new THREE.Mesh( geometry,material );
-	    //scene.add( sprite );
-	    //sprite.position.z = -1;//Move it back so we can see it
+        //var sprite = new THREE.Mesh( geometry,material );
+        //scene.add( sprite );
+        //sprite.position.z = -1;//Move it back so we can see it
 
     } else {
-	    this._materialFirstPass = new THREE.ShaderMaterial( {
-		vertexShader: this._shaders.firstPass.vertexShader,
-		fragmentShader: this._shaders.firstPass.fragmentShader,
-		side: THREE.FrontSide,
+        this._materialFirstPass = new THREE.ShaderMaterial( {
+        vertexShader: this._shaders.firstPass.vertexShader,
+        fragmentShader: this._shaders.firstPass.fragmentShader,
+        side: THREE.FrontSide,
         //side: THREE.BackSide,
-		transparent: true
-	    } );
+        transparent: true
+        } );
 
         // TODO: Load colourmap, but should be from local
         //var cm = THREE.ImageUtils.loadTexture( "http://katrin.kit.edu/vis/colormap/cm_jet.png" );
         //cm.minFilter = THREE.LinearFilter;
-
-	    this._materialSecondPass = new THREE.ShaderMaterial( {
-		vertexShader: this._shaders[this._shader_name].vertexShader,
-		fragmentShader: ejs.render( this._shaders[this._shader_name].fragmentShader, {
-		  "maxTexturesNumber": me.getMaxTexturesNumber()}),
-		uniforms: {
+        this._materialSecondPass = new THREE.ShaderMaterial( {
+        vertexShader: this._shaders[this._shader_name].vertexShader,
+        fragmentShader: ejs.render( this._shaders[this._shader_name].fragmentShader, {
+            "maxTexturesNumber": me.getMaxTexturesNumber()}),
+        uniforms: {
             uRatio : { type: "f", value: this.zFactor},
-		    uBackCoord: { type: "t",  value: this._rtTexture },
-		    uSliceMaps: { type: "tv", value: this._slicemaps_textures },
-		    uLightPos: {type:"v3", value: new THREE.Vector3() },
-		    uSetViewMode: {type:"i", value: 0 },
+            uBackCoord: { type: "t",  value: this._rtTexture },
+            uSliceMaps: { type: "tv", value: this._slicemaps_textures },
+            uLightPos: {type:"v3", value: new THREE.Vector3() },
+            uSetViewMode: {type:"i", value: 0 },
             //uColormap : {type:'t',value:cm },
-		    uSteps: { type: "i", value: this._steps },
-		    uSlicemapWidth: { type: "f", value: this._slicemaps_width },
-		    uNumberOfSlices: { type: "f", value:  (parseFloat(this.getSlicesRange()[1]) + 1.0) },
-		    uSlicesOverX: { type: "f", value: this._slicemap_row_col[0] },
-		    uSlicesOverY: { type: "f", value: this._slicemap_row_col[1] },
-		    uOpacityVal: { type: "f", value: this._opacity_factor },
-		    darkness: { type: "f", value: this._color_factor },
-
-		    l: { type: "f", value: this.l },
-		    s: { type: "f", value: this.s },
-		    hMin: { type: "f", value: this.hMin },
-		    hMax: { type: "f", value: this.hMax },
-
-		    minSos: { type: "f", value: this.minSos },
-		    maxSos: { type: "f", value: this.maxSos },
-		    minAtten: { type: "f", value: this.minAtten },
-		    maxAtten: { type: "f", value: this.maxAtten },
-		    minRefl: { type: "f", value: this.minRefl },
-		    maxRefl: { type: "f", value: this.maxRefl },
-
-		   uTransferFunction: { type: "t",  value: this._transfer_function },
-		   uColorVal: { type: "f", value: this._color_factor },
-		   uAbsorptionModeIndex: { type: "f", value: this._absorption_mode_index },
-		   uMinGrayVal: { type: "f", value: this._gray_value[0] },
-		   uMaxGrayVal: { type: "f", value: this._gray_value[1] },
-           uIndexOfImage: { type: "f", value: this._indexOfImage }
-		},
-		//side: THREE.FrontSide,
+            uSteps: { type: "i", value: this._steps },
+            uSlicemapWidth: { type: "f", value: this._slicemaps_width },
+            uNumberOfSlices: { type: "f", value:  (parseFloat(this.getSlicesRange()[1]) + 1.0) },
+            uSlicesOverX: { type: "f", value: this._slicemap_row_col[0] },
+            uSlicesOverY: { type: "f", value: this._slicemap_row_col[1] },
+            uOpacityVal: { type: "f", value: this._opacity_factor },
+            darkness: { type: "f", value: this._color_factor },
+
+            l: { type: "f", value: this.l },
+            s: { type: "f", value: this.s },
+            hMin: { type: "f", value: this.hMin },
+            hMax: { type: "f", value: this.hMax },
+            minSos: { type: "f", value: this.minSos },
+            maxSos: { type: "f", value: this.maxSos },
+            minAtten: { type: "f", value: this.minAtten },
+            maxAtten: { type: "f", value: this.maxAtten },
+            minRefl: { type: "f", value: this.minRefl },
+            maxRefl: { type: "f", value: this.maxRefl },
+
+            uTransferFunction: { type: "t",  value: this._transfer_function },
+            uColorVal: { type: "f", value: this._color_factor },
+            uAbsorptionModeIndex: { type: "f", value: this._absorption_mode_index },
+            uMinGrayVal: { type: "f", value: this._gray_value[0] },
+            uMaxGrayVal: { type: "f", value: this._gray_value[1] },
+            uIndexOfImage: { type: "f", value: this._indexOfImage }
+        },
+        //side: THREE.FrontSide,
         side: THREE.BackSide,
-		transparent: true
-	    });
-
-	    this._sceneFirstPass = new THREE.Scene();
-	    this._sceneSecondPass = new THREE.Scene();
-
-	    // Created mesh for both passes using geometry helper
-	    this._initGeometry( this.getGeometryDimensions(), this.getVolumeSizeNormalized() );
-	    this._meshFirstPass = new THREE.Mesh( this._geometry, this._materialFirstPass );
-	    this._meshSecondPass = new THREE.Mesh( this._geometry, this._materialSecondPass );
-
-	    //this._axes = buildAxes(0.5);
-	    this._sceneFirstPass.add(this._meshFirstPass);
-	    this._sceneSecondPass.add(this._meshSecondPass);
-	    //this._sceneSecondPass.add(this._axes);
-
-
-	    var mesh = new THREE.Mesh(
-		new THREE.BoxGeometry( 1, 1, 1 ),
-		new THREE.MeshNormalMaterial()
-	    );
-	    this._wireframe = new THREE.BoxHelper( mesh );
-	    this._wireframe.material.color.set( 0xe3e3e3 );
-	    this._sceneSecondPass.add( this._wireframe );
-
-	    var sphere = new THREE.SphereGeometry( 0.1 );
-	    this._light1 = new THREE.PointLight( 0xff0040, 2, 50 );
-	    this._light1.add( new THREE.Mesh( sphere, new THREE.MeshBasicMaterial( { color: 0xff0040 } ) ) );
-	    this._light1.position.set(1, 0, 0);
-	    //this._sceneSecondPass.add( this._light1 );
-	    //this._sceneSecondPass.add( new THREE.DirectionalLightHelper(this._light1, 0.2) );
-
-	    // parent
-		this._parent = new THREE.Object3D();
-		this._sceneSecondPass.add( this._parent );
-	    // pivot
-		this._pivot = new THREE.Object3D();
-		this._parent.add( this._pivot );
+        transparent: true
+        });
+
+        this._sceneFirstPass = new THREE.Scene();
+        this._sceneSecondPass = new THREE.Scene();
+
+        // Created mesh for both passes using geometry helper
+        this._initGeometry( this.getGeometryDimensions(), this.getVolumeSizeNormalized() );
+        this._meshFirstPass = new THREE.Mesh( this._geometry, this._materialFirstPass );
+        this._meshSecondPass = new THREE.Mesh( this._geometry, this._materialSecondPass );
+
+        //this._axes = buildAxes(0.5);
+        this._sceneFirstPass.add(this._meshFirstPass);
+        this._sceneSecondPass.add(this._meshSecondPass);
+        //this._sceneSecondPass.add(this._axes);
+
+
+        var mesh = new THREE.Mesh(
+            new THREE.BoxGeometry( 1, 1, 1 ),
+            new THREE.MeshNormalMaterial()
+        );
+        this._wireframe = new THREE.BoxHelper( mesh );
+        this._wireframe.material.color.set( 0xe3e3e3 );
+        this._sceneSecondPass.add( this._wireframe );
+
+        var sphere = new THREE.SphereGeometry( 0.1 );
+        this._light1 = new THREE.PointLight( 0xff0040, 2, 50 );
+        this._light1.add( new THREE.Mesh( sphere, new THREE.MeshBasicMaterial( { color: 0xff0040 } ) ) );
+        this._light1.position.set(1, 0, 0);
+        //this._sceneSecondPass.add( this._light1 );
+        //this._sceneSecondPass.add( new THREE.DirectionalLightHelper(this._light1, 0.2) );
+
+        // parent
+        this._parent = new THREE.Object3D();
+        this._sceneSecondPass.add( this._parent );
+        // pivot
+        this._pivot = new THREE.Object3D();
+        this._parent.add( this._pivot );
     }
 
-	// mesh
-	//mesh1 = new THREE.Mesh( geometry, material1 );
-	//mesh2 = new THREE.Mesh( geometry, material2 );
-	//this._light1.position.x = 2;
+    // mesh
+    //mesh1 = new THREE.Mesh( geometry, material1 );
+    //mesh2 = new THREE.Mesh( geometry, material2 );
+    //this._light1.position.x = 2;
     //mesh2.scale.multiplyScalar( 0.5 );
-	//this._parent.add( mesh1 );
+    //this._parent.add( mesh1 );
 
-	//this._pivot.add( this._light1 );
+    //this._pivot.add( this._light1 );
 
     /*
     var mesh2 = new THREE.Mesh(
@@ -842,74 +840,93 @@ Core.prototype._secondPassSetUniformValue = function(key, value) {
 };
 
 
-	Core.prototype._setSlicemapsTextures = function(images) {
-	    var textures = [];
-            var loader = new THREE.TextureLoader();
-            loader.crossOrigin = '';
-            for(var i=0; i<images.length; i++) {
-                this_img = images[i];
-                loader.load(this_img.src, function (texture) {
-                    texture.magFilter = THREE.LinearFilter;
-		    texture.minFilter = THREE.LinearFilter;
-                    texture.wrapS = texture.wrapT = THREE.ClampToEdgeWrapping;
-		    texture.generateMipmaps = false;
-		    texture.flipY = false;
-		    texture.needsUpdate = true;
-                    textures.push(texture);
-	        }, function (err) { console.log("error");} );
-            }
-	    this._slicemaps_textures = textures;
-	};
-
-
-	Core.prototype.setTransferFunctionByImage = function(image) {
-	    this._transfer_function_as_image = image;
-	    var texture = new THREE.Texture(image);
-	    texture.magFilter = THREE.LinearFilter;
-	    texture.minFilter = THREE.LinearFilter;
-	    texture.wrapS = texture.wrapT =  THREE.ClampToEdgeWrapping;
-	    texture.generateMipmaps = false;
-	    texture.flipY = true;
-	    texture.needsUpdate = true;
-
-	    if(this._mode == "3d") {
-		this._secondPassSetUniformValue("uTransferFunction", texture);
-	    }
-	    this.onChangeTransferFunction.call(image);
-	};
+Core.prototype._setSlicemapsTextures = function(images) {
+    var allPromises = [];
+    var me = this;
+    var textures = [];
+    var loader = new THREE.TextureLoader();
+    loader.crossOrigin = '';
+
+    images.forEach( function( image ) {
+        allPromises.push( new Promise( function( resolve, reject ) {
+
+            loader.load(image.src, function (texture) {
+                texture.magFilter = THREE.LinearFilter;
+                texture.minFilter = THREE.LinearFilter;
+                texture.wrapS = texture.wrapT = THREE.ClampToEdgeWrapping;
+                texture.generateMipmaps = false;
+                texture.flipY = false;
+                texture.needsUpdate = true;
+                //textures.push(texture);
+                resolve( texture );
+            },
+            function( xhr ) {
+               // Progress callback of TextureLoader
+               // ...
+            },
+            function (err) {
+                console.log(err);
+                console.log("error");
+            });
+        }));
+    });
+    Promise.all( allPromises )
+        .then( function( promises ) {
+            // All textures are now loaded, and this array
+            // contains all the materials that you created
+            me._secondPassSetUniformValue("uSliceMaps", promises);
+        }, function( error ) {
+            console.error( "Could not load all textures:", error );
+        });
+    //this._slicemaps_textures = textures;
+};
 
 
-	Core.prototype.setTransferFunctionByColors = function(colors) {
-	    this._transfer_function_colors = colors;
+Core.prototype.setTransferFunctionByImage = function(image) {
+    this._transfer_function_as_image = image;
+    var texture = new THREE.Texture(image);
+    texture.magFilter = THREE.LinearFilter;
+    texture.minFilter = THREE.LinearFilter;
+    texture.wrapS = texture.wrapT =  THREE.ClampToEdgeWrapping;
+    texture.generateMipmaps = false;
+    texture.flipY = true;
+    texture.needsUpdate = true;
+    if(this._mode == "3d") {
+    this._secondPassSetUniformValue("uTransferFunction", texture);
+    }
+    this.onChangeTransferFunction.call(image);
+};
 
-	    var canvas = document.createElement('canvas');
-	    canvas.width  = 512;
-	    canvas.height = 2;
 
-	    var ctx = canvas.getContext('2d');
+Core.prototype.setTransferFunctionByColors = function(colors) {
+    this._transfer_function_colors = colors;
+    var canvas = document.createElement('canvas');
+    canvas.width  = 512;
+    canvas.height = 2;
+    var ctx = canvas.getContext('2d');
 
-	    var grd = ctx.createLinearGradient(0, 0, canvas.width -1 , canvas.height - 1);
+    var grd = ctx.createLinearGradient(0, 0, canvas.width -1 , canvas.height - 1);
 
-	    for(var i=0; i<colors.length; i++) {
-		grd.addColorStop(colors[i].pos, colors[i].color);
-	    }
+    for(var i=0; i<colors.length; i++) {
+        grd.addColorStop(colors[i].pos, colors[i].color);
+    }
 
-	    ctx.fillStyle = grd;
-	    ctx.fillRect(0,0,canvas.width ,canvas.height);
-	    var image = new Image();
-	    image.src = canvas.toDataURL();
-	    image.style.width = 20 + " px";
-	    image.style.height = 512 + " px";
+    ctx.fillStyle = grd;
+    ctx.fillRect(0,0,canvas.width ,canvas.height);
+    var image = new Image();
+    image.src = canvas.toDataURL();
+    image.style.width = 20 + " px";
+    image.style.height = 512 + " px";
 
-	    var transferTexture = this.setTransferFunctionByImage(image);
+    var transferTexture = this.setTransferFunctionByImage(image);
 
-	    this.onChangeTransferFunction.call(image);
-	};
+    this.onChangeTransferFunction.call(image);
+};
 
 
-	Core.prototype.getTransferFunctionAsImage = function() {
-	    return this._transfer_function_as_image;
-	};
+Core.prototype.getTransferFunctionAsImage = function() {
+    return this._transfer_function_as_image;
+};
 
 
 Core.prototype.getBase64 = function() {
@@ -934,46 +951,46 @@ Core.prototype.setMode = function(conf) {
 
 
     if(this._mode == "3d") {
-	    this._materialSecondPass = new THREE.ShaderMaterial( {
-		vertexShader: this._shaders[this._shader_name].vertexShader,
-		fragmentShader: ejs.render(
-		    this._shaders[this._shader_name].fragmentShader,
-		    {"maxTexturesNumber": this.getMaxTexturesNumber()}
-		),
-		//attributes: {
-		//    vertColor: {type: 'c', value: [] }
-		//},
-		uniforms: {
-            uRatio : { type: "f", value: this.zFactor},
-		    uBackCoord: { type: "t",  value: this._rtTexture },
-		    uSliceMaps: { type: "tv", value: this._slicemaps_textures },
-		    uLightPos: {type:"v3", value: new THREE.Vector3() },
-		    uSetViewMode: {type:"i", value: 0 },
-		    uNumberOfSlices: { type: "f", value: (parseFloat(this.getSlicesRange()[1]) + 1.0) },
-		    uSlicemapWidth: { type: "f", value: this._slicemaps_width},
-		    uSlicesOverX: { type: "f", value: this._slicemap_row_col[0] },
-		    uSlicesOverY: { type: "f", value: this._slicemap_row_col[1] },
-		    uOpacityVal: { type: "f", value: this._opacity_factor },
-		    darkness: { type: "f", value: this._color_factor },
-		    l: { type: "f", value: this.l },
-		    s: { type: "f", value: this.s },
-		    hMin: { type: "f", value: this.hMin },
-		    hMax: { type: "f", value: this.hMax },
-		    minSos: { type: "f", value: this.minSos },
-		    maxSos: { type: "f", value: this.maxSos },
-		    minAtten: { type: "f", value: this.minAtten },
-		    maxAtten: { type: "f", value: this.maxAtten },
-		    minRefl: { type: "f", value: this.minRefl },
-		    maxRefl: { type: "f", value: this.maxRefl }
-		},
-		side: THREE.BackSide,
-		transparent: true
-	    });
-
-	    this._meshSecondPass = new THREE.Mesh( this._geometry, this._materialSecondPass );
-
-	    this._sceneSecondPass = new THREE.Scene();
-	    this._sceneSecondPass.add( this._meshSecondPass );
+        this._materialSecondPass = new THREE.ShaderMaterial( {
+            vertexShader: this._shaders[this._shader_name].vertexShader,
+            fragmentShader: ejs.render(
+                this._shaders[this._shader_name].fragmentShader,
+                {"maxTexturesNumber": this.getMaxTexturesNumber()}
+            ),
+            //attributes: {
+            //    vertColor: {type: 'c', value: [] }
+            //},
+            uniforms: {
+                uRatio : { type: "f", value: this.zFactor},
+                uBackCoord: { type: "t",  value: this._rtTexture },
+                uSliceMaps: { type: "tv", value: this._slicemaps_textures },
+                uLightPos: {type:"v3", value: new THREE.Vector3() },
+                uSetViewMode: {type:"i", value: 0 },
+                uNumberOfSlices: { type: "f", value: (parseFloat(this.getSlicesRange()[1]) + 1.0) },
+                uSlicemapWidth: { type: "f", value: this._slicemaps_width},
+                uSlicesOverX: { type: "f", value: this._slicemap_row_col[0] },
+                uSlicesOverY: { type: "f", value: this._slicemap_row_col[1] },
+                uOpacityVal: { type: "f", value: this._opacity_factor },
+                darkness: { type: "f", value: this._color_factor },
+                l: { type: "f", value: this.l },
+                s: { type: "f", value: this.s },
+                hMin: { type: "f", value: this.hMin },
+                hMax: { type: "f", value: this.hMax },
+                minSos: { type: "f", value: this.minSos },
+                maxSos: { type: "f", value: this.maxSos },
+                minAtten: { type: "f", value: this.minAtten },
+                maxAtten: { type: "f", value: this.maxAtten },
+                minRefl: { type: "f", value: this.minRefl },
+                maxRefl: { type: "f", value: this.maxRefl }
+            },
+            side: THREE.BackSide,
+            transparent: true
+        });
+
+        this._meshSecondPass = new THREE.Mesh( this._geometry, this._materialSecondPass );
+
+        this._sceneSecondPass = new THREE.Scene();
+        this._sceneSecondPass.add( this._meshSecondPass );
     }
 }
 
@@ -1008,61 +1025,62 @@ Core.prototype.setShaderName = function(value) {
     if(this._mode == "3d") {
 
 
-      this._materialSecondPass = new THREE.ShaderMaterial( {
-		vertexShader: this._shaders[this._shader_name].vertexShader,
-		fragmentShader: ejs.render( this._shaders[this._shader_name].fragmentShader, {
-		  "maxTexturesNumber": this.getMaxTexturesNumber()}),
-		uniforms: {
-      uRatio : { type: "f", value: this.zFactor},
-      uBackCoord: { type: "t",  value: this._rtTexture },
-      uSliceMaps: { type: "tv", value: this._slicemaps_textures },
-      uLightPos: {type:"v3", value: new THREE.Vector3() },
-      uSetViewMode: {type:"i", value: 0 },
-
-      uSteps: { type: "i", value: this._steps },
-      uSlicemapWidth: { type: "f", value: this._slicemaps_width },
-      uNumberOfSlices: { type: "f", value:  (parseFloat(this.getSlicesRange()[1]) + 1.0) },
-      uSlicesOverX: { type: "f", value: this._slicemap_row_col[0] },
-      uSlicesOverY: { type: "f", value: this._slicemap_row_col[1] },
-      uOpacityVal: { type: "f", value: this._opacity_factor },
-      darkness: { type: "f", value: this._color_factor },
-
-      l: { type: "f", value: this.l },
-      s: { type: "f", value: this.s },
-      hMin: { type: "f", value: this.hMin },
-      hMax: { type: "f", value: this.hMax },
-
-      minSos: { type: "f", value: this.minSos },
-      maxSos: { type: "f", value: this.maxSos },
-      minAtten: { type: "f", value: this.minAtten },
-      maxAtten: { type: "f", value: this.maxAtten },
-      minRefl: { type: "f", value: this.minRefl },
-      maxRefl: { type: "f", value: this.maxRefl },
-
-     uTransferFunction: { type: "t",  value: this._transfer_function },
-     uColorVal: { type: "f", value: this._color_factor },
-     uAbsorptionModeIndex: { type: "f", value: this._absorption_mode_index },
-     uMinGrayVal: { type: "f", value: this._gray_value[0] },
-     uMaxGrayVal: { type: "f", value: this._gray_value[1] },
-     uIndexOfImage: { type: "f", value: this._indexOfImage },
-
-    uSosThresholdBot: { type: "f", value: this._sosThresholdBot },
-    uSosThresholdTop: { type: "f", value: this._sosThresholdTop },
-    uAttenThresholdBot: { type: "f", value: this._attenThresholdBot },
-    uAttenThresholdTop: { type: "f", value: this._attenThresholdTop },
-		},
-		//side: THREE.FrontSide,
-        side: THREE.BackSide,
-		transparent: true
-	    });
-
-
-	    this._meshSecondPass = new THREE.Mesh( this._geometry, this._materialSecondPass );
-
-	    this._sceneSecondPass = new THREE.Scene();
-	    this._sceneSecondPass.add( this._meshSecondPass );
-
-      this.addWireframe();
+        this._materialSecondPass = new THREE.ShaderMaterial( {
+            vertexShader: this._shaders[this._shader_name].vertexShader,
+            fragmentShader: ejs.render( this._shaders[this._shader_name].fragmentShader, {
+                "maxTexturesNumber": this.getMaxTexturesNumber()
+            }),
+            uniforms: {
+                uRatio : { type: "f", value: this.zFactor},
+                uBackCoord: { type: "t",  value: this._rtTexture },
+                uSliceMaps: { type: "tv", value: this._slicemaps_textures },
+                uLightPos: {type:"v3", value: new THREE.Vector3() },
+                uSetViewMode: {type:"i", value: 0 },
+
+                uSteps: { type: "i", value: this._steps },
+                uSlicemapWidth: { type: "f", value: this._slicemaps_width },
+                uNumberOfSlices: { type: "f", value:  (parseFloat(this.getSlicesRange()[1]) + 1.0) },
+                uSlicesOverX: { type: "f", value: this._slicemap_row_col[0] },
+                uSlicesOverY: { type: "f", value: this._slicemap_row_col[1] },
+                uOpacityVal: { type: "f", value: this._opacity_factor },
+                darkness: { type: "f", value: this._color_factor },
+
+                l: { type: "f", value: this.l },
+                s: { type: "f", value: this.s },
+                hMin: { type: "f", value: this.hMin },
+                hMax: { type: "f", value: this.hMax },
+
+                minSos: { type: "f", value: this.minSos },
+                maxSos: { type: "f", value: this.maxSos },
+                minAtten: { type: "f", value: this.minAtten },
+                maxAtten: { type: "f", value: this.maxAtten },
+                minRefl: { type: "f", value: this.minRefl },
+                maxRefl: { type: "f", value: this.maxRefl },
+
+                uTransferFunction: { type: "t",  value: this._transfer_function },
+                uColorVal: { type: "f", value: this._color_factor },
+                uAbsorptionModeIndex: { type: "f", value: this._absorption_mode_index },
+                uMinGrayVal: { type: "f", value: this._gray_value[0] },
+                uMaxGrayVal: { type: "f", value: this._gray_value[1] },
+                uIndexOfImage: { type: "f", value: this._indexOfImage },
+
+                uSosThresholdBot: { type: "f", value: this._sosThresholdBot },
+                uSosThresholdTop: { type: "f", value: this._sosThresholdTop },
+                uAttenThresholdBot: { type: "f", value: this._attenThresholdBot },
+                uAttenThresholdTop: { type: "f", value: this._attenThresholdTop },
+            },
+            //side: THREE.FrontSide,
+            side: THREE.BackSide,
+            transparent: true
+        });
+
+
+        this._meshSecondPass = new THREE.Mesh( this._geometry, this._materialSecondPass );
+
+        this._sceneSecondPass = new THREE.Scene();
+        this._sceneSecondPass.add( this._meshSecondPass );
+
+        this.addWireframe();
 
     }
 }
@@ -1147,7 +1165,6 @@ Core.prototype.setSlicemapsImages = function(images, imagesPaths) {
     this._slicemaps_images = images;
     this._slicemaps_paths = imagesPaths != undefined ? imagesPaths : this._slicemaps_paths;
     this._setSlicemapsTextures(images);
-
     if(this._mode == "3d") {
         this._secondPassSetUniformValue("uSliceMaps", this._slicemaps_textures);
     }
@@ -5124,7 +5141,6 @@ window.VRC.Core.prototype._shaders.secondPassStevenTri = {
 
         me.uploadSlicemapsImages = function(imagesPaths, userOnLoadImage, userOnLoadImages, userOnError) {
 
-
             var downloadImages = function(imagesPaths, onLoadImage, onLoadImages, onError) {
                 var downloadedImages = [];
                 var downloadedImagesNumber = 0;
@@ -5158,7 +5174,6 @@ window.VRC.Core.prototype._shaders.secondPassStevenTri = {
                 };
 
             };
-
             downloadImages(imagesPaths,
                 function(image) {
                     // downloaded one of the images
@@ -5168,7 +5183,7 @@ window.VRC.Core.prototype._shaders.secondPassStevenTri = {
                 function(images) {
                     // downloaded all images
                     me.setSlicemapsImages(images, imagesPaths);
-                    // me.start();
+                    me.start();
 
                     me._onLoadSlicemaps.call(images);
 
@@ -5791,6 +5806,7 @@ window.VRC.Core.prototype._shaders.secondPassStevenTri = {
 
             if(config['slicemaps_paths'] != undefined) {
                 me.uploadSlicemapsImages(
+
                     config['slicemaps_paths'],
                     function(image) {
                         if(onLoadImage != undefined) onLoadImage(image);
@@ -5799,16 +5815,11 @@ window.VRC.Core.prototype._shaders.secondPassStevenTri = {
                         if(config['slices_range'] != undefined) {
                             me.setSlicesRange( config['slices_range'][0], config['slices_range'][1] );
                         }
-                        //
-
-
-
                         me.stop();
                         if(onLoadImages != undefined) onLoadImages(images);
 
                         me.start();
                     }
-
                 );
             }
 

+ 76 - 4
nova/templates/dataset/wave.html

@@ -14,6 +14,20 @@
           <div class="col-sm-2"><input type="text" class="slider-range-input" id="gray-threshold-max-input" /></div>
         </div>
       </div>
+      <div class="wave-control" id="zoom-controls">
+        <p>Zoom Control</p>
+        <div>
+          <div id="xy-zoom-control"><div id="xy-zoom-selection"></div></div>
+          <p><small>x-y plane</small></p>
+        </div>
+        <div>
+          <div id="yz-zoom-control"><div id="yz-zoom-selection"></div></div>
+          <p><small>y-z plane</small></p>
+        </div>
+      </div>
+      <div class="wave-control">
+        <button type="button" class="btn btn-dark" id="res-zoom-button-selection">Zoom to Selected Volume</button>
+      </div>
       <div class="wave-control">
         <p>X axis slicing</p>
         <div class="col-sm-12">
@@ -39,7 +53,7 @@
         </div>
       </div>
       <div class="wave-control">
-        <button type="button" class="btn btn-dark" id="res-zoom-button">Zoom to Sliced Volume</button>
+        <button type="button" class="btn btn-dark" id="res-zoom-button-slice">Zoom to Sliced Volume</button>
       </div>
     </div>
   </div>
@@ -256,7 +270,11 @@
                 $("#slider-Z").dragslider("option", "values", $values);
                 $vrc.setGeometryMaxZ($(this).val()/100);
             });
-            $("#res-zoom-button").click( function() {
+            function zoomToVolume($v) {
+                $gray = [$("#gray-threshold-min-input").val(), $("#gray-threshold-max-input").val()];
+                window.location.href='/wave?user='+user_name+'&dataset='+dataset_name+'&collection='+collection_name+'&vol='+$v+'&gt='+$gray;
+            }
+            $("#res-zoom-button-slice").click( function() {
                 $x = $("#x-min-input").val();
                 $y = $("#y-min-input").val();
                 $z = $("#z-min-input").val();
@@ -269,8 +287,62 @@
                 $adj_y = Math.round($current_y + $y*$current_dim/100);
                 $adj_z = Math.round($current_z + $z*$current_dim/100);
                 $vol = [$adj_x, $adj_y, $adj_z, $adj_size];
-                $gray = [$("#gray-threshold-min-input").val(), $("#gray-threshold-max-input").val()];
-                window.location.href='/wave?user='+user_name+'&dataset='+dataset_name+'&collection='+collection_name+'&vol='+$vol+'&gt='+$gray;
+                zoomToVolume($vol);
+            });
+            $("#res-zoom-button-selection").click( function() {
+                $W = $("#xy-zoom-selection").parent().width();
+                $x = Math.round(100*parseInt($("#xy-zoom-selection").css("left"), 10)/$W);
+                $y = Math.round(100*parseInt($("#xy-zoom-selection").css("top"), 10)/$W);
+                $z = Math.round(100*parseInt($("#yz-zoom-selection").css("top"), 10)/$W);
+                $size = Math.round(100*$("#yz-zoom-selection").width()/$W);
+                $vol = [$x, $y, $z, $size];
+                zoomToVolume($vol);
+            });
+            $("#xy-zoom-selection").resizable({
+                aspectRatio: 1,
+                containment: "parent",
+                create: function (event, ui ){
+                    $(this).css({
+                        'left': $current_x*$(this).parent().width()/100,
+                        'top': $current_y*$(this).parent().height()/100,
+                        'width': $current_dim*$(this).parent().width()/100,
+                        'height': $current_dim*$(this).parent().height()/100
+                    });
+                },
+                resize: function (event, ui ){
+                    h = ui.size.height;
+                    t = ui.position.top;
+                    $("#yz-zoom-selection").css({'height':h, 'width': h,'left': t});
+                }
+            }).draggable({
+                containment: "parent",
+                drag: function (event, ui) {
+                    t = ui.position.top;
+                    $("#yz-zoom-selection").css({'left': t});
+                }
+            });
+            $("#yz-zoom-selection").resizable({
+                aspectRatio: 1,
+                containment: "parent",
+                create: function (event, ui ){
+                    $(this).css({
+                        'left': $current_y*$(this).parent().width()/100,
+                        'top': $current_z*$(this).parent().height()/100,
+                        'width': $current_dim*$(this).parent().width()/100,
+                        'height': $current_dim*$(this).parent().height()/100
+                    });
+                },
+                resize: function (event, ui ){
+                    w = ui.size.width;
+                    l = ui.position.left;
+                    $("#xy-zoom-selection").css({'height':w, 'width': w,'top':l});
+                }
+            }).draggable({
+                containment: "parent",
+                drag: function (event, ui) {
+                    l = ui.position.left;
+                    $("#xy-zoom-selection").css({'top': l});
+                }
             });
          });
   </script>