From e8a96bbcc2dc9a4dc38854c157ab211e036871e6 Mon Sep 17 00:00:00 2001 From: Alexander Huth Date: Thu, 17 Oct 2024 12:52:07 -0700 Subject: [PATCH] working clipping --- cortex/webgl/resources/js/dataset.js | 12 ++++++ cortex/webgl/resources/js/mriview.js | 48 ++++++++++++++++++++++++ cortex/webgl/resources/js/shaderlib.js | 49 +++++++++++++++++++++++++ cortex/webgl/resources/js/sliceplane.js | 37 ++++++++++++++++++- 4 files changed, 145 insertions(+), 1 deletion(-) diff --git a/cortex/webgl/resources/js/dataset.js b/cortex/webgl/resources/js/dataset.js index dd156b905..c44263ec7 100644 --- a/cortex/webgl/resources/js/dataset.js +++ b/cortex/webgl/resources/js/dataset.js @@ -83,6 +83,18 @@ var dataset = (function(module) { this.uniforms = { framemix: { type:'f', value:0}, dataAlpha: { type:'f', value:1.0}, + + slicexn: { type:'v3', value:new THREE.Vector3( 0,0,0 )}, + sliceyn: { type:'v3', value:new THREE.Vector3( 0,0,0 )}, + slicezn: { type:'v3', value:new THREE.Vector3( 0,0,0 )}, + + slicexc: { type:'v3', value:new THREE.Vector3( 0,0,0 )}, + sliceyc: { type:'v3', value:new THREE.Vector3( 0,0,0 )}, + slicezc: { type:'v3', value:new THREE.Vector3( 0,0,0 )}, + + doslicex: { type:'i', value:false}, + doslicey: { type:'i', value:false}, + doslicez: { type:'i', value:false}, } if (!this.vertex) { diff --git a/cortex/webgl/resources/js/mriview.js b/cortex/webgl/resources/js/mriview.js index 75e5baa64..ff536df6c 100644 --- a/cortex/webgl/resources/js/mriview.js +++ b/cortex/webgl/resources/js/mriview.js @@ -49,6 +49,9 @@ var mriview = (function(module) { y: new sliceplane.Plane(this, 1), z: new sliceplane.Plane(this, 2), }; + this._clipx = false; + this._clipy = false; + this._clipz = false; this.ui = new jsplot.Menu(); this.ui.addEventListener("update", this.schedule.bind(this)); @@ -1164,6 +1167,18 @@ var mriview = (function(module) { rotate_z: {action:[this.sliceplanes.z, 'setAngle', -89, 89]} }); + var sliceplane_clip = sliceplane_ui.addFolder("clip", true); + sliceplane_clip.add({ + clip_x: {action:[this, "setClippingX"]}, + flip_x: {action:[this.sliceplanes.x, "setFlip"]}, + clip_y: {action:[this, "setClippingY"]}, + flip_y: {action:[this.sliceplanes.y, "setFlip"]}, + clip_z: {action:[this, "setClippingZ"]}, + flip_z: {action:[this.sliceplanes.z, "setFlip"]}, + }) + + // + if ($(this.object).find("#colormap_category").length > 0) { $(this.object).find("#colormap").ddslick({ width:296, height:350, onSelected: function() { @@ -1294,6 +1309,39 @@ var mriview = (function(module) { this.sliceplanes.z.setVisible(!this.sliceplanes.z._visible); viewer.schedule(); }; + module.Viewer.prototype.setClippingX = function(val) { + if (val === undefined) + return this._clipx; + + this._clipx = val; + + if (this.active !== undefined) { + this.active.uniforms.doslicex.value = this._clipx; + } + this.schedule(); + } + module.Viewer.prototype.setClippingY = function(val) { + if (val === undefined) + return this._clipy; + + this._clipy = val; + + if (this.active !== undefined) { + this.active.uniforms.doslicey.value = this._clipy; + } + this.schedule(); + } + module.Viewer.prototype.setClippingZ = function(val) { + if (val === undefined) + return this._clipz; + + this._clipz = val; + + if (this.active !== undefined) { + this.active.uniforms.doslicez.value = this._clipz; + } + this.schedule(); + } return module; }(mriview || {})); diff --git a/cortex/webgl/resources/js/shaderlib.js b/cortex/webgl/resources/js/shaderlib.js index aa8904f91..fbf4da2d1 100644 --- a/cortex/webgl/resources/js/shaderlib.js +++ b/cortex/webgl/resources/js/shaderlib.js @@ -363,6 +363,18 @@ var Shaderlib = (function() { "uniform int bumpyflat;", "float f_bumpyflat = float(bumpyflat);", + "uniform vec3 slicexn;", + "uniform vec3 sliceyn;", + "uniform vec3 slicezn;", + + "uniform vec3 slicexc;", + "uniform vec3 sliceyc;", + "uniform vec3 slicezc;", + + "uniform bool doslicex;", + "uniform bool doslicey;", + "uniform bool doslicez;", + "attribute vec4 wm;", "attribute vec3 wmnorm;", "attribute vec4 auxdat;", @@ -379,6 +391,8 @@ var Shaderlib = (function() { "varying float vCurv;", "varying float vMedial;", "varying float vThickmix;", + "varying float vSliced;", + "varying vec3 vWorldPosition;", // "varying float vDrop;", "varying vec3 vPos_x[2];", @@ -421,6 +435,8 @@ var Shaderlib = (function() { "vMedial = auxdat.x;", "vCurv = auxdat.y;", + //"vSliced = float(mpos.y > slicey) * float(doslicey);", + "vec3 pos, norm;", "mixfunc(mpos, mnorm, pos, norm);", @@ -444,6 +460,10 @@ var Shaderlib = (function() { "gl_Position = projectionMatrix * modelViewMatrix * vec4( pos, 1.0 );", + "vWorldPosition = pos;", + + //"vSliced = float( ((dot(pos - sliceyc, sliceyn) > 0.0) && bool(doslicey)) || ((dot(pos - slicexc, slicexn) > 0.0) && bool(doslicex)) );", + "}" ].join("\n"); @@ -477,6 +497,18 @@ var Shaderlib = (function() { "uniform vec2 dshape[2];", "uniform sampler2D data[4];", + "uniform vec3 slicexn;", + "uniform vec3 sliceyn;", + "uniform vec3 slicezn;", + + "uniform vec3 slicexc;", + "uniform vec3 sliceyc;", + "uniform vec3 slicezc;", + + "uniform bool doslicex;", + "uniform bool doslicey;", + "uniform bool doslicez;", + // "uniform float hatchAlpha;", // "uniform vec3 hatchColor;", // "uniform sampler2D hatch;", @@ -489,6 +521,8 @@ var Shaderlib = (function() { "varying float vCurv;", "varying float vMedial;", "varying float vThickmix;", + "varying float vSliced;", + "varying vec3 vWorldPosition;", utils.standard_frag_vars, utils.rand, @@ -501,6 +535,21 @@ var Shaderlib = (function() { //Curvature Underlay "float ctmp = clamp(vCurv / smoothness, -0.5, 0.5);", // use limits here too "float curv = clamp(ctmp * contrast + brightness, 0.0, 1.0);", + //"if (vSliced > 0.5) discard;", + + "bool clipx = dot(vWorldPosition - slicexc, slicexn) > 0.0;", + "bool clipy = dot(vWorldPosition - sliceyc, sliceyn) > 0.0;", + "bool clipz = dot(vWorldPosition - slicezc, slicezn) > 0.0;", + + "if (clipx && doslicex && !doslicey && !doslicez) discard;", + "if (clipy && !doslicex && doslicey && !doslicez) discard;", + "if (clipz && !doslicex && !doslicey && doslicez) discard;", + "if (clipx && clipy && doslicex && doslicey && !doslicez) discard;", + "if (clipx && clipz && doslicex && !doslicey && doslicez) discard;", + "if (clipy && clipz && !doslicex && doslicey && doslicez) discard;", + "if (clipx && clipy && clipz && doslicex && doslicey && doslicez) discard;", + //"if( ((dot(vWorldPosition - sliceyc, sliceyn) > 0.0) && bool(doslicey)) && ((dot(vWorldPosition - slicexc, slicexn) > 0.0) && bool(doslicex)) && ((dot(vWorldPosition - slicezc, slicezn) > 0.0) && bool(doslicez)) ) discard;", + "vec4 cColor = vec4(vec3(curv), 1.0);", "vec3 coord_x, coord_y;", diff --git a/cortex/webgl/resources/js/sliceplane.js b/cortex/webgl/resources/js/sliceplane.js index d18af74cc..aba5a06b2 100644 --- a/cortex/webgl/resources/js/sliceplane.js +++ b/cortex/webgl/resources/js/sliceplane.js @@ -56,6 +56,8 @@ var sliceplane = (function(module) { this.mesh = new THREE.Mesh(this.geometry, this.shader); this.mesh.doubleSided = true; + this.flip_clip = 1; // 1 or -1 + this.object.add(this.mesh); //this.scene.add(this.mesh); this.scene.add(this.object); @@ -127,6 +129,9 @@ var sliceplane = (function(module) { imat.multiplyVector3(this.geometry.vertices[2].set(shape[0]-0.5,-0.5,slice)); imat.multiplyVector3(this.geometry.vertices[3].set(shape[0]-0.5,shape[1]-0.5,slice)); } + this.center = new THREE.Vector3().add(this.geometry.vertices[0]).add(this.geometry.vertices[1]).add(this.geometry.vertices[2]).add(this.geometry.vertices[3]).divideScalar(4); + + this.updateClipping(); this.geometry.computeBoundingSphere(); var center = this.geometry.boundingSphere.center; @@ -184,6 +189,8 @@ var sliceplane = (function(module) { this.mesh.rotation.set(0,0,0); this.mesh.rotateOnAxis(axis, angle / 180 * Math.PI); + + this.updateClipping(); } module.Plane.prototype.setVisible = function(val) { if (val === undefined) @@ -191,8 +198,36 @@ var sliceplane = (function(module) { this._visible = val; - if (this.mesh !== undefined) + if (this.mesh !== undefined) { this.mesh.visible = this._visible; + this.updateClipping(); + } + + } + module.Plane.prototype.updateClipping = function() { + this.normal = this.geometry.faces[0].normal.clone().applyEuler(this.mesh.rotation).multiplyScalar(this.flip_clip); + + if (this.dir == 0){ + this.viewer.active.uniforms.slicexn.value.copy(this.normal); + this.viewer.active.uniforms.slicexc.value.copy(this.center); + } else if (this.dir == 1){ + this.viewer.active.uniforms.sliceyn.value.copy(this.normal); + this.viewer.active.uniforms.sliceyc.value.copy(this.center); + } else if (this.dir == 2){ + this.viewer.active.uniforms.slicezn.value.copy(this.normal); + this.viewer.active.uniforms.slicezc.value.copy(this.center); + } + } + module.Plane.prototype.setFlip = function(val) { + if (val === undefined) { + return this.flip_clip == -1; + } + if (val) { + this.flip_clip = -1; + } else { + this.flip_clip = 1; + } + this.updateClipping(); } module.MIP = function(viewer) {