@kitware/vtk.js 22.2.0 → 22.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Rendering/OpenGL/RenderWindow.js +6 -0
- package/Rendering/SceneGraph/RenderWindowViewNode.js +5 -0
- package/Rendering/WebGPU/BindGroup.js +5 -4
- package/Rendering/WebGPU/Buffer.js +6 -3
- package/Rendering/WebGPU/BufferManager.js +3 -1
- package/Rendering/WebGPU/Device.js +1 -1
- package/Rendering/WebGPU/FullScreenQuad.js +1 -1
- package/Rendering/WebGPU/Glyph3DMapper.js +5 -4
- package/Rendering/WebGPU/HardwareSelectionPass.js +11 -7
- package/Rendering/WebGPU/HardwareSelector.js +7 -2
- package/Rendering/WebGPU/ImageMapper.js +16 -14
- package/Rendering/WebGPU/MapperHelper.js +7 -6
- package/Rendering/WebGPU/OpaquePass.js +11 -7
- package/Rendering/WebGPU/OrderIndependentTranslucentPass.js +17 -11
- package/Rendering/WebGPU/Pipeline.js +6 -5
- package/Rendering/WebGPU/PolyDataMapper.js +11 -9
- package/Rendering/WebGPU/RenderEncoder.js +12 -3
- package/Rendering/WebGPU/RenderWindow.js +10 -1
- package/Rendering/WebGPU/Renderer.js +10 -7
- package/Rendering/WebGPU/Sampler.js +4 -3
- package/Rendering/WebGPU/ShaderDescription.js +4 -4
- package/Rendering/WebGPU/SphereMapper.js +3 -3
- package/Rendering/WebGPU/StickMapper.js +4 -4
- package/Rendering/WebGPU/StorageBuffer.js +6 -5
- package/Rendering/WebGPU/Texture.js +13 -7
- package/Rendering/WebGPU/TextureView.js +10 -21
- package/Rendering/WebGPU/UniformBuffer.js +6 -5
- package/Rendering/WebGPU/VertexInput.js +1 -1
- package/Rendering/WebGPU/VolumePass.js +30 -22
- package/Rendering/WebGPU/VolumePassFSQ.js +18 -18
- package/Widgets/Core/WidgetManager.js +211 -71
- package/Widgets/Widgets3D/SplineWidget/behavior.js +9 -6
- package/package.json +5 -6
|
@@ -9,7 +9,7 @@ import vtkWebGPUSampler from './Sampler.js';
|
|
|
9
9
|
import vtkWebGPUTypes from './Types.js';
|
|
10
10
|
import { BlendMode } from '../Core/VolumeMapper/Constants.js';
|
|
11
11
|
|
|
12
|
-
var volFragTemplate = "\n//VTK::Renderer::Dec\n\n//VTK::Mapper::Dec\n\n//VTK::TCoord::Dec\n\n//VTK::Volume::TraverseDec\n\n//VTK::RenderEncoder::Dec\n\n//VTK::IOStructs::Dec\n\nfn getTextureValue(vTex: texture_3d<f32>, tpos: vec4<f32>) -> f32\n{\n // todo multicomponent support\n return textureSampleLevel(vTex, clampSampler, tpos.xyz, 0.0).r;\n}\n\nfn getGradient(vTex: texture_3d<f32>, tpos: vec4<f32>, vNum: i32, scalar: f32) -> vec4<f32>\n{\n var result: vec4<f32>;\n\n var tstep: vec4<f32> = volumeSSBO.values[vNum].tstep;\n result.x = getTextureValue(vTex, tpos + vec4<f32>(tstep.x, 0.0, 0.0, 1.0)) - scalar;\n result.y = getTextureValue(vTex, tpos + vec4<f32>(0.0, tstep.y, 0.0, 1.0)) - scalar;\n result.z = getTextureValue(vTex, tpos + vec4<f32>(0.0, 0.0, tstep.z, 1.0)) - scalar;\n\n // divide by spacing\n result = result / volumeSSBO.values[vNum].spacing;\n\n var grad: f32 = length(result.xyz);\n\n // // rotate to View Coords, needed for lighting and shading\n // result.xyz =\n // result.x * vPlaneNormal0 +\n // result.y * vPlaneNormal2 +\n // result.z * vPlaneNormal4;\n\n if (grad > 0.0)\n {\n result = result * (1.0 / grad);\n }\n\n result.w = grad;\n\n return result;\n}\n\nfn processVolume(vTex: texture_3d<f32>, vNum: i32, cNum: i32, posSC: vec4<f32>, tfunRows: f32) -> vec4<f32>\n{\n var outColor: vec4<f32> = vec4<f32>(0.0, 0.0, 0.0, 0.0);\n\n // convert to tcoords and reject if outside the volume\n var tpos: vec4<f32> = volumeSSBO.values[vNum].SCTCMatrix*posSC;\n if (tpos.x < 0.0 || tpos.y < 0.0 || tpos.z < 0.0 ||\n tpos.x > 1.0 || tpos.y > 1.0 || tpos.z > 1.0) { return outColor; }\n\n var scalar: f32 = getTextureValue(vTex, tpos);\n\n var coord: vec2<f32> =\n vec2<f32>(scalar * componentSSBO.values[cNum].cScale + componentSSBO.values[cNum].cShift,\n (0.5 + 2.0 * f32(vNum)) / tfunRows);\n var color: vec4<f32> = textureSampleLevel(tfunTexture, clampSampler, coord, 0.0);\n\n var gofactor: f32 = 1.0;\n if (componentSSBO.values[cNum].gomin < 1.0)\n {\n var normal: vec4<f32> = getGradient(vTex, tpos, vNum, scalar);\n gofactor = clamp(normal.a*componentSSBO.values[cNum].goScale + componentSSBO.values[cNum].goShift,\n componentSSBO.values[cNum].gomin, componentSSBO.values[cNum].gomax);\n }\n\n coord.x = (scalar * componentSSBO.values[cNum].oScale + componentSSBO.values[cNum].oShift);\n var opacity: f32 = textureSampleLevel(ofunTexture, clampSampler, coord, 0.0).r;\n\n outColor = vec4<f32>(color.rgb, gofactor * opacity);\n\n//VTK::Volume::Process\n\n return outColor;\n}\n\n// adjust the start and end point of a raycast such that it intersects the unit cube.\n// This function is used to take a raycast starting point and step vector\n// and numSteps and return the startijng and ending steps for intersecting the\n// unit cube. Recall for a 3D texture, the unit cube is the range of texture coordsinates\n// that have valid values. So this funtion can be used to take a ray in texture coordinates\n// and bound it to intersecting the texture.\n//\nfn adjustBounds(tpos: vec4<f32>, tstep: vec4<f32>, numSteps: f32) -> vec2<f32>\n{\n var result: vec2<f32> = vec2<f32>(0.0, numSteps);\n var tpos2: vec4<f32> = tpos + tstep*numSteps;\n\n // move tpos to the start of the volume\n var adjust: f32 =\n min(\n max(tpos.x/tstep.x, (tpos.x - 1.0)/tstep.x),\n min(\n max((tpos.y - 1.0)/tstep.y, tpos.y/tstep.y),\n max((tpos.z - 1.0)/tstep.z, tpos.z/tstep.z)));\n if (adjust < 0.0)\n {\n result.x = result.x - adjust;\n }\n\n // adjust length to the end\n adjust =\n max(\n min(tpos2.x/tstep.x, (tpos2.x - 1.0)/tstep.x),\n max(\n min((tpos2.y - 1.0)/tstep.y, tpos2.y/tstep.y),\n min((tpos2.z - 1.0)/tstep.z, tpos2.z/tstep.z)));\n if (adjust > 0.0)\n {\n result.y = result.y - adjust;\n }\n\n return result;\n}\n\nfn getSimpleColor(scalar: f32, vNum: i32, cNum: i32) -> vec4<f32>\n{\n // how many rows (tfuns) do we have in our tfunTexture\n var tfunRows: f32 = f32(textureDimensions(tfunTexture).y);\n\n var coord: vec2<f32> =\n vec2<f32>(scalar * componentSSBO.values[cNum].cScale + componentSSBO.values[cNum].cShift,\n (0.5 + 2.0 * f32(vNum)) / tfunRows);\n var color: vec4<f32> = textureSampleLevel(tfunTexture, clampSampler, coord, 0.0);\n coord.x = (scalar * componentSSBO.values[cNum].oScale + componentSSBO.values[cNum].oShift);\n var opacity: f32 = textureSampleLevel(ofunTexture, clampSampler, coord, 0.0).r;\n return vec4<f32>(color.rgb, opacity);\n}\n\nfn traverseMax(vTex: texture_3d<f32>, vNum: i32, cNum: i32, rayLengthSC: f32, minPosSC: vec4<f32>, rayStepSC: vec4<f32>)\n{\n // convert to tcoords and reject if outside the volume\n var numSteps: f32 = rayLengthSC/mapperUBO.SampleDistance;\n var tpos: vec4<f32> = volumeSSBO.values[vNum].SCTCMatrix*minPosSC;\n var tpos2: vec4<f32> = volumeSSBO.values[vNum].SCTCMatrix*(minPosSC + rayStepSC);\n var tstep: vec4<f32> = tpos2 - tpos;\n\n var rayBounds: vec2<f32> = adjustBounds(tpos, tstep, numSteps);\n\n // did we hit anything\n if (rayBounds.x >= rayBounds.y)\n {\n traverseVals[vNum] = vec4<f32>(0.0,0.0,0.0,0.0);\n return;\n }\n\n tpos = tpos + tstep*rayBounds.x;\n var curDist: f32 = rayBounds.x;\n var maxVal: f32 = -1.0e37;\n loop\n {\n var scalar: f32 = getTextureValue(vTex, tpos);\n if (scalar > maxVal)\n {\n maxVal = scalar;\n }\n\n // increment position\n curDist = curDist + 1.0;\n tpos = tpos + tstep;\n\n // check if we have reached a terminating condition\n if (curDist > rayBounds.y) { break; }\n }\n\n // process to get the color and opacity\n traverseVals[vNum] = getSimpleColor(maxVal, vNum, cNum);\n}\n\nfn traverseMin(vTex: texture_3d<f32>, vNum: i32, cNum: i32, rayLengthSC: f32, minPosSC: vec4<f32>, rayStepSC: vec4<f32>)\n{\n // convert to tcoords and reject if outside the volume\n var numSteps: f32 = rayLengthSC/mapperUBO.SampleDistance;\n var tpos: vec4<f32> = volumeSSBO.values[vNum].SCTCMatrix*minPosSC;\n var tpos2: vec4<f32> = volumeSSBO.values[vNum].SCTCMatrix*(minPosSC + rayStepSC);\n var tstep: vec4<f32> = tpos2 - tpos;\n\n var rayBounds: vec2<f32> = adjustBounds(tpos, tstep, numSteps);\n\n // did we hit anything\n if (rayBounds.x >= rayBounds.y)\n {\n traverseVals[vNum] = vec4<f32>(0.0,0.0,0.0,0.0);\n return;\n }\n\n tpos = tpos + tstep*rayBounds.x;\n var curDist: f32 = rayBounds.x;\n var minVal: f32 = 1.0e37;\n loop\n {\n var scalar: f32 = getTextureValue(vTex, tpos);\n if (scalar < minVal)\n {\n minVal = scalar;\n }\n\n // increment position\n curDist = curDist + 1.0;\n tpos = tpos + tstep;\n\n // check if we have reached a terminating condition\n if (curDist > rayBounds.y) { break; }\n }\n\n // process to get the color and opacity\n traverseVals[vNum] = getSimpleColor(minVal, vNum, cNum);\n}\n\nfn traverseAverage(vTex: texture_3d<f32>, vNum: i32, cNum: i32, rayLengthSC: f32, minPosSC: vec4<f32>, rayStepSC: vec4<f32>)\n{\n // convert to tcoords and reject if outside the volume\n var numSteps: f32 = rayLengthSC/mapperUBO.SampleDistance;\n var tpos: vec4<f32> = volumeSSBO.values[vNum].SCTCMatrix*minPosSC;\n var tpos2: vec4<f32> = volumeSSBO.values[vNum].SCTCMatrix*(minPosSC + rayStepSC);\n var tstep: vec4<f32> = tpos2 - tpos;\n\n var rayBounds: vec2<f32> = adjustBounds(tpos, tstep, numSteps);\n\n // did we hit anything\n if (rayBounds.x >= rayBounds.y)\n {\n traverseVals[vNum] = vec4<f32>(0.0,0.0,0.0,0.0);\n return;\n }\n\n let ipRange: vec4<f32> = volumeSSBO.values[vNum].ipScalarRange;\n tpos = tpos + tstep*rayBounds.x;\n var curDist: f32 = rayBounds.x;\n var avgVal: f32 = 0.0;\n var sampleCount: f32 = 0.0;\n loop\n {\n var sample: f32 = getTextureValue(vTex, tpos);\n // right now leave filtering off until WebGL changes get merged\n // if (ipRange.z == 0.0 || sample >= ipRange.x && sample <= ipRange.y)\n // {\n avgVal = avgVal + sample;\n sampleCount = sampleCount + 1.0;\n // }\n\n // increment position\n curDist = curDist + 1.0;\n tpos = tpos + tstep;\n\n // check if we have reached a terminating condition\n if (curDist > rayBounds.y) { break; }\n }\n\n if (sampleCount <= 0.0)\n {\n traverseVals[vNum] = vec4<f32>(0.0,0.0,0.0,0.0);\n }\n\n // process to get the color and opacity\n traverseVals[vNum] = getSimpleColor(avgVal/sampleCount, vNum, cNum);\n}\n\nfn traverseAdditive(vTex: texture_3d<f32>, vNum: i32, cNum: i32, rayLengthSC: f32, minPosSC: vec4<f32>, rayStepSC: vec4<f32>)\n{\n // convert to tcoords and reject if outside the volume\n var numSteps: f32 = rayLengthSC/mapperUBO.SampleDistance;\n var tpos: vec4<f32> = volumeSSBO.values[vNum].SCTCMatrix*minPosSC;\n var tpos2: vec4<f32> = volumeSSBO.values[vNum].SCTCMatrix*(minPosSC + rayStepSC);\n var tstep: vec4<f32> = tpos2 - tpos;\n\n var rayBounds: vec2<f32> = adjustBounds(tpos, tstep, numSteps);\n\n // did we hit anything\n if (rayBounds.x >= rayBounds.y)\n {\n traverseVals[vNum] = vec4<f32>(0.0,0.0,0.0,0.0);\n return;\n }\n\n let ipRange: vec4<f32> = volumeSSBO.values[vNum].ipScalarRange;\n tpos = tpos + tstep*rayBounds.x;\n var curDist: f32 = rayBounds.x;\n var sumVal: f32 = 0.0;\n loop\n {\n var sample: f32 = getTextureValue(vTex, tpos);\n // right now leave filtering off until WebGL changes get merged\n // if (ipRange.z == 0.0 || sample >= ipRange.x && sample <= ipRange.y)\n // {\n sumVal = sumVal + sample;\n // }\n\n // increment position\n curDist = curDist + 1.0;\n tpos = tpos + tstep;\n\n // check if we have reached a terminating condition\n if (curDist > rayBounds.y) { break; }\n }\n\n // process to get the color and opacity\n traverseVals[vNum] = getSimpleColor(sumVal, vNum, cNum);\n}\n\nfn composite(rayLengthSC: f32, minPosSC: vec4<f32>, rayStepSC: vec4<f32>) -> vec4<f32>\n{\n // initial ray position is at the beginning\n var rayPosSC: vec4<f32> = minPosSC;\n\n // how many rows (tfuns) do we have in our tfunTexture\n var tfunRows: f32 = f32(textureDimensions(tfunTexture).y);\n\n var curDist: f32 = 0.0;\n var computedColor: vec4<f32> = vec4<f32>(0.0, 0.0, 0.0, 0.0);\n var sampleColor: vec4<f32>;\n//VTK::Volume::TraverseCalls\n\n loop\n {\n // for each volume, sample and accumulate color\n//VTK::Volume::CompositeCalls\n\n // increment position\n curDist = curDist + mapperUBO.SampleDistance;\n rayPosSC = rayPosSC + rayStepSC;\n\n // check if we have reached a terminating condition\n if (curDist > rayLengthSC) { break; }\n if (computedColor.a > 0.98) { break; }\n }\n return computedColor;\n}\n\n[[stage(fragment)]]\nfn main(\n//VTK::IOStructs::Input\n)\n//VTK::IOStructs::Output\n{\n var output: fragmentOutput;\n\n var rayMax: f32 = textureSampleLevel(maxTexture, clampSampler, input.tcoordVS, 0.0).r;\n var rayMin: f32 = textureSampleLevel(minTexture, clampSampler, input.tcoordVS, 0.0).r;\n\n // discard empty rays\n if (rayMax <= rayMin) { discard; }\n else\n {\n // compute start and end ray positions in view coordinates\n var minPosSC: vec4<f32> = rendererUBO.PCSCMatrix*vec4<f32>(2.0 * input.tcoordVS.x - 1.0, 1.0 - 2.0 * input.tcoordVS.y, rayMax, 1.0);\n minPosSC = minPosSC * (1.0 / minPosSC.w);\n var maxPosSC: vec4<f32> = rendererUBO.PCSCMatrix*vec4<f32>(2.0 * input.tcoordVS.x - 1.0, 1.0 - 2.0 * input.tcoordVS.y, rayMin, 1.0);\n maxPosSC = maxPosSC * (1.0 / maxPosSC.w);\n\n var rayLengthSC: f32 = distance(minPosSC.xyz, maxPosSC.xyz);\n var rayStepSC: vec4<f32> = (maxPosSC - minPosSC)*(mapperUBO.SampleDistance/rayLengthSC);\n rayStepSC.w = 0.0;\n\n var computedColor: vec4<f32>;\n\n//VTK::Volume::Loop\n\n//VTK::RenderEncoder::Impl\n }\n\n return output;\n}\n";
|
|
12
|
+
var volFragTemplate = "\n//VTK::Renderer::Dec\n\n//VTK::Mapper::Dec\n\n//VTK::TCoord::Dec\n\n//VTK::Volume::TraverseDec\n\n//VTK::RenderEncoder::Dec\n\n//VTK::IOStructs::Dec\n\nfn getTextureValue(vTex: texture_3d<f32>, tpos: vec4<f32>) -> f32\n{\n // todo multicomponent support\n return textureSampleLevel(vTex, clampSampler, tpos.xyz, 0.0).r;\n}\n\nfn getGradient(vTex: texture_3d<f32>, tpos: vec4<f32>, vNum: i32, scalar: f32) -> vec4<f32>\n{\n var result: vec4<f32>;\n\n var tstep: vec4<f32> = volumeSSBO.values[vNum].tstep;\n result.x = getTextureValue(vTex, tpos + vec4<f32>(tstep.x, 0.0, 0.0, 1.0)) - scalar;\n result.y = getTextureValue(vTex, tpos + vec4<f32>(0.0, tstep.y, 0.0, 1.0)) - scalar;\n result.z = getTextureValue(vTex, tpos + vec4<f32>(0.0, 0.0, tstep.z, 1.0)) - scalar;\n\n // divide by spacing\n result = result / volumeSSBO.values[vNum].spacing;\n\n var grad: f32 = length(result.xyz);\n\n // // rotate to View Coords, needed for lighting and shading\n // result.xyz =\n // result.x * vPlaneNormal0 +\n // result.y * vPlaneNormal2 +\n // result.z * vPlaneNormal4;\n\n if (grad > 0.0)\n {\n result = result * (1.0 / grad);\n }\n\n result.w = grad;\n\n return result;\n}\n\nfn processVolume(vTex: texture_3d<f32>, vNum: i32, cNum: i32, posSC: vec4<f32>, tfunRows: f32) -> vec4<f32>\n{\n var outColor: vec4<f32> = vec4<f32>(0.0, 0.0, 0.0, 0.0);\n\n // convert to tcoords and reject if outside the volume\n var tpos: vec4<f32> = volumeSSBO.values[vNum].SCTCMatrix*posSC;\n if (tpos.x < 0.0 || tpos.y < 0.0 || tpos.z < 0.0 ||\n tpos.x > 1.0 || tpos.y > 1.0 || tpos.z > 1.0) { return outColor; }\n\n var scalar: f32 = getTextureValue(vTex, tpos);\n\n var coord: vec2<f32> =\n vec2<f32>(scalar * componentSSBO.values[cNum].cScale + componentSSBO.values[cNum].cShift,\n (0.5 + 2.0 * f32(vNum)) / tfunRows);\n var color: vec4<f32> = textureSampleLevel(tfunTexture, clampSampler, coord, 0.0);\n\n var gofactor: f32 = 1.0;\n if (componentSSBO.values[cNum].gomin < 1.0)\n {\n var normal: vec4<f32> = getGradient(vTex, tpos, vNum, scalar);\n gofactor = clamp(normal.a*componentSSBO.values[cNum].goScale + componentSSBO.values[cNum].goShift,\n componentSSBO.values[cNum].gomin, componentSSBO.values[cNum].gomax);\n }\n\n coord.x = (scalar * componentSSBO.values[cNum].oScale + componentSSBO.values[cNum].oShift);\n var opacity: f32 = textureSampleLevel(ofunTexture, clampSampler, coord, 0.0).r;\n\n outColor = vec4<f32>(color.rgb, gofactor * opacity);\n\n//VTK::Volume::Process\n\n return outColor;\n}\n\n// adjust the start and end point of a raycast such that it intersects the unit cube.\n// This function is used to take a raycast starting point and step vector\n// and numSteps and return the startijng and ending steps for intersecting the\n// unit cube. Recall for a 3D texture, the unit cube is the range of texture coordsinates\n// that have valid values. So this funtion can be used to take a ray in texture coordinates\n// and bound it to intersecting the texture.\n//\nfn adjustBounds(tpos: vec4<f32>, tstep: vec4<f32>, numSteps: f32) -> vec2<f32>\n{\n var result: vec2<f32> = vec2<f32>(0.0, numSteps);\n var tpos2: vec4<f32> = tpos + tstep*numSteps;\n\n // move tpos to the start of the volume\n var adjust: f32 =\n min(\n max(tpos.x/tstep.x, (tpos.x - 1.0)/tstep.x),\n min(\n max((tpos.y - 1.0)/tstep.y, tpos.y/tstep.y),\n max((tpos.z - 1.0)/tstep.z, tpos.z/tstep.z)));\n if (adjust < 0.0)\n {\n result.x = result.x - adjust;\n }\n\n // adjust length to the end\n adjust =\n max(\n min(tpos2.x/tstep.x, (tpos2.x - 1.0)/tstep.x),\n max(\n min((tpos2.y - 1.0)/tstep.y, tpos2.y/tstep.y),\n min((tpos2.z - 1.0)/tstep.z, tpos2.z/tstep.z)));\n if (adjust > 0.0)\n {\n result.y = result.y - adjust;\n }\n\n return result;\n}\n\nfn getSimpleColor(scalar: f32, vNum: i32, cNum: i32) -> vec4<f32>\n{\n // how many rows (tfuns) do we have in our tfunTexture\n var tfunRows: f32 = f32(textureDimensions(tfunTexture).y);\n\n var coord: vec2<f32> =\n vec2<f32>(scalar * componentSSBO.values[cNum].cScale + componentSSBO.values[cNum].cShift,\n (0.5 + 2.0 * f32(vNum)) / tfunRows);\n var color: vec4<f32> = textureSampleLevel(tfunTexture, clampSampler, coord, 0.0);\n coord.x = (scalar * componentSSBO.values[cNum].oScale + componentSSBO.values[cNum].oShift);\n var opacity: f32 = textureSampleLevel(ofunTexture, clampSampler, coord, 0.0).r;\n return vec4<f32>(color.rgb, opacity);\n}\n\nfn traverseMax(vTex: texture_3d<f32>, vNum: i32, cNum: i32, rayLengthSC: f32, minPosSC: vec4<f32>, rayStepSC: vec4<f32>)\n{\n // convert to tcoords and reject if outside the volume\n var numSteps: f32 = rayLengthSC/mapperUBO.SampleDistance;\n var tpos: vec4<f32> = volumeSSBO.values[vNum].SCTCMatrix*minPosSC;\n var tpos2: vec4<f32> = volumeSSBO.values[vNum].SCTCMatrix*(minPosSC + rayStepSC);\n var tstep: vec4<f32> = tpos2 - tpos;\n\n var rayBounds: vec2<f32> = adjustBounds(tpos, tstep, numSteps);\n\n // did we hit anything\n if (rayBounds.x >= rayBounds.y)\n {\n traverseVals[vNum] = vec4<f32>(0.0,0.0,0.0,0.0);\n return;\n }\n\n tpos = tpos + tstep*rayBounds.x;\n var curDist: f32 = rayBounds.x;\n var maxVal: f32 = -1.0e37;\n loop\n {\n var scalar: f32 = getTextureValue(vTex, tpos);\n if (scalar > maxVal)\n {\n maxVal = scalar;\n }\n\n // increment position\n curDist = curDist + 1.0;\n tpos = tpos + tstep;\n\n // check if we have reached a terminating condition\n if (curDist > rayBounds.y) { break; }\n }\n\n // process to get the color and opacity\n traverseVals[vNum] = getSimpleColor(maxVal, vNum, cNum);\n}\n\nfn traverseMin(vTex: texture_3d<f32>, vNum: i32, cNum: i32, rayLengthSC: f32, minPosSC: vec4<f32>, rayStepSC: vec4<f32>)\n{\n // convert to tcoords and reject if outside the volume\n var numSteps: f32 = rayLengthSC/mapperUBO.SampleDistance;\n var tpos: vec4<f32> = volumeSSBO.values[vNum].SCTCMatrix*minPosSC;\n var tpos2: vec4<f32> = volumeSSBO.values[vNum].SCTCMatrix*(minPosSC + rayStepSC);\n var tstep: vec4<f32> = tpos2 - tpos;\n\n var rayBounds: vec2<f32> = adjustBounds(tpos, tstep, numSteps);\n\n // did we hit anything\n if (rayBounds.x >= rayBounds.y)\n {\n traverseVals[vNum] = vec4<f32>(0.0,0.0,0.0,0.0);\n return;\n }\n\n tpos = tpos + tstep*rayBounds.x;\n var curDist: f32 = rayBounds.x;\n var minVal: f32 = 1.0e37;\n loop\n {\n var scalar: f32 = getTextureValue(vTex, tpos);\n if (scalar < minVal)\n {\n minVal = scalar;\n }\n\n // increment position\n curDist = curDist + 1.0;\n tpos = tpos + tstep;\n\n // check if we have reached a terminating condition\n if (curDist > rayBounds.y) { break; }\n }\n\n // process to get the color and opacity\n traverseVals[vNum] = getSimpleColor(minVal, vNum, cNum);\n}\n\nfn traverseAverage(vTex: texture_3d<f32>, vNum: i32, cNum: i32, rayLengthSC: f32, minPosSC: vec4<f32>, rayStepSC: vec4<f32>)\n{\n // convert to tcoords and reject if outside the volume\n var numSteps: f32 = rayLengthSC/mapperUBO.SampleDistance;\n var tpos: vec4<f32> = volumeSSBO.values[vNum].SCTCMatrix*minPosSC;\n var tpos2: vec4<f32> = volumeSSBO.values[vNum].SCTCMatrix*(minPosSC + rayStepSC);\n var tstep: vec4<f32> = tpos2 - tpos;\n\n var rayBounds: vec2<f32> = adjustBounds(tpos, tstep, numSteps);\n\n // did we hit anything\n if (rayBounds.x >= rayBounds.y)\n {\n traverseVals[vNum] = vec4<f32>(0.0,0.0,0.0,0.0);\n return;\n }\n\n let ipRange: vec4<f32> = volumeSSBO.values[vNum].ipScalarRange;\n tpos = tpos + tstep*rayBounds.x;\n var curDist: f32 = rayBounds.x;\n var avgVal: f32 = 0.0;\n var sampleCount: f32 = 0.0;\n loop\n {\n var sample: f32 = getTextureValue(vTex, tpos);\n // right now leave filtering off until WebGL changes get merged\n // if (ipRange.z == 0.0 || sample >= ipRange.x && sample <= ipRange.y)\n // {\n avgVal = avgVal + sample;\n sampleCount = sampleCount + 1.0;\n // }\n\n // increment position\n curDist = curDist + 1.0;\n tpos = tpos + tstep;\n\n // check if we have reached a terminating condition\n if (curDist > rayBounds.y) { break; }\n }\n\n if (sampleCount <= 0.0)\n {\n traverseVals[vNum] = vec4<f32>(0.0,0.0,0.0,0.0);\n }\n\n // process to get the color and opacity\n traverseVals[vNum] = getSimpleColor(avgVal/sampleCount, vNum, cNum);\n}\n\nfn traverseAdditive(vTex: texture_3d<f32>, vNum: i32, cNum: i32, rayLengthSC: f32, minPosSC: vec4<f32>, rayStepSC: vec4<f32>)\n{\n // convert to tcoords and reject if outside the volume\n var numSteps: f32 = rayLengthSC/mapperUBO.SampleDistance;\n var tpos: vec4<f32> = volumeSSBO.values[vNum].SCTCMatrix*minPosSC;\n var tpos2: vec4<f32> = volumeSSBO.values[vNum].SCTCMatrix*(minPosSC + rayStepSC);\n var tstep: vec4<f32> = tpos2 - tpos;\n\n var rayBounds: vec2<f32> = adjustBounds(tpos, tstep, numSteps);\n\n // did we hit anything\n if (rayBounds.x >= rayBounds.y)\n {\n traverseVals[vNum] = vec4<f32>(0.0,0.0,0.0,0.0);\n return;\n }\n\n let ipRange: vec4<f32> = volumeSSBO.values[vNum].ipScalarRange;\n tpos = tpos + tstep*rayBounds.x;\n var curDist: f32 = rayBounds.x;\n var sumVal: f32 = 0.0;\n loop\n {\n var sample: f32 = getTextureValue(vTex, tpos);\n // right now leave filtering off until WebGL changes get merged\n // if (ipRange.z == 0.0 || sample >= ipRange.x && sample <= ipRange.y)\n // {\n sumVal = sumVal + sample;\n // }\n\n // increment position\n curDist = curDist + 1.0;\n tpos = tpos + tstep;\n\n // check if we have reached a terminating condition\n if (curDist > rayBounds.y) { break; }\n }\n\n // process to get the color and opacity\n traverseVals[vNum] = getSimpleColor(sumVal, vNum, cNum);\n}\n\nfn composite(rayLengthSC: f32, minPosSC: vec4<f32>, rayStepSC: vec4<f32>) -> vec4<f32>\n{\n // initial ray position is at the beginning\n var rayPosSC: vec4<f32> = minPosSC;\n\n // how many rows (tfuns) do we have in our tfunTexture\n var tfunRows: f32 = f32(textureDimensions(tfunTexture).y);\n\n var curDist: f32 = 0.0;\n var computedColor: vec4<f32> = vec4<f32>(0.0, 0.0, 0.0, 0.0);\n var sampleColor: vec4<f32>;\n//VTK::Volume::TraverseCalls\n\n loop\n {\n // for each volume, sample and accumulate color\n//VTK::Volume::CompositeCalls\n\n // increment position\n curDist = curDist + mapperUBO.SampleDistance;\n rayPosSC = rayPosSC + rayStepSC;\n\n // check if we have reached a terminating condition\n if (curDist > rayLengthSC) { break; }\n if (computedColor.a > 0.98) { break; }\n }\n return computedColor;\n}\n\n@stage(fragment)\nfn main(\n//VTK::IOStructs::Input\n)\n//VTK::IOStructs::Output\n{\n var output: fragmentOutput;\n\n var rayMax: f32 = textureSampleLevel(maxTexture, clampSampler, input.tcoordVS, 0.0).r;\n var rayMin: f32 = textureSampleLevel(minTexture, clampSampler, input.tcoordVS, 0.0).r;\n\n // discard empty rays\n if (rayMax <= rayMin) { discard; }\n else\n {\n // compute start and end ray positions in view coordinates\n var minPosSC: vec4<f32> = rendererUBO.PCSCMatrix*vec4<f32>(2.0 * input.tcoordVS.x - 1.0, 1.0 - 2.0 * input.tcoordVS.y, rayMax, 1.0);\n minPosSC = minPosSC * (1.0 / minPosSC.w);\n var maxPosSC: vec4<f32> = rendererUBO.PCSCMatrix*vec4<f32>(2.0 * input.tcoordVS.x - 1.0, 1.0 - 2.0 * input.tcoordVS.y, rayMin, 1.0);\n maxPosSC = maxPosSC * (1.0 / maxPosSC.w);\n\n var rayLengthSC: f32 = distance(minPosSC.xyz, maxPosSC.xyz);\n var rayStepSC: vec4<f32> = (maxPosSC - minPosSC)*(mapperUBO.SampleDistance/rayLengthSC);\n rayStepSC.w = 0.0;\n\n var computedColor: vec4<f32>;\n\n//VTK::Volume::Loop\n\n//VTK::RenderEncoder::Impl\n }\n\n return output;\n}\n";
|
|
13
13
|
var tmpMat4 = new Float64Array(16);
|
|
14
14
|
var tmp2Mat4 = new Float64Array(16); // ----------------------------------------------------------------------------
|
|
15
15
|
// vtkWebGPUVolumePassFSQ methods
|
|
@@ -21,12 +21,12 @@ function vtkWebGPUVolumePassFSQ(publicAPI, model) {
|
|
|
21
21
|
|
|
22
22
|
publicAPI.replaceShaderPosition = function (hash, pipeline, vertexInput) {
|
|
23
23
|
var vDesc = pipeline.getShaderDescription('vertex');
|
|
24
|
-
vDesc.addBuiltinOutput('vec4<f32>', '
|
|
24
|
+
vDesc.addBuiltinOutput('vec4<f32>', '@builtin(position) Position');
|
|
25
25
|
var code = vDesc.getCode();
|
|
26
26
|
code = vtkWebGPUShaderCache.substitute(code, '//VTK::Position::Impl', ['output.tcoordVS = vec2<f32>(vertexBC.x * 0.5 + 0.5, 1.0 - vertexBC.y * 0.5 - 0.5);', 'output.Position = vec4<f32>(vertexBC, 1.0);']).result;
|
|
27
27
|
vDesc.setCode(code);
|
|
28
28
|
var fDesc = pipeline.getShaderDescription('fragment');
|
|
29
|
-
fDesc.addBuiltinInput('vec4<f32>', '
|
|
29
|
+
fDesc.addBuiltinInput('vec4<f32>', '@builtin(position) fragPos');
|
|
30
30
|
};
|
|
31
31
|
|
|
32
32
|
model.shaderReplacements.set('replaceShaderPosition', publicAPI.replaceShaderPosition);
|
|
@@ -189,8 +189,7 @@ function vtkWebGPUVolumePassFSQ(publicAPI, model) {
|
|
|
189
189
|
format: 'rgba8unorm'
|
|
190
190
|
};
|
|
191
191
|
var newTex = device.getTextureManager().getTexture(treq);
|
|
192
|
-
var tview = newTex.createView();
|
|
193
|
-
tview.setName('tfunTexture');
|
|
192
|
+
var tview = newTex.createView('tfunTexture');
|
|
194
193
|
model.textureViews[2] = tview;
|
|
195
194
|
}
|
|
196
195
|
{
|
|
@@ -204,9 +203,7 @@ function vtkWebGPUVolumePassFSQ(publicAPI, model) {
|
|
|
204
203
|
|
|
205
204
|
var _newTex = device.getTextureManager().getTexture(_treq);
|
|
206
205
|
|
|
207
|
-
var _tview = _newTex.createView();
|
|
208
|
-
|
|
209
|
-
_tview.setName('ofunTexture');
|
|
206
|
+
var _tview = _newTex.createView('ofunTexture');
|
|
210
207
|
|
|
211
208
|
model.textureViews[3] = _tview;
|
|
212
209
|
}
|
|
@@ -446,8 +443,7 @@ function vtkWebGPUVolumePassFSQ(publicAPI, model) {
|
|
|
446
443
|
var newTex = device.getTextureManager().getTexture(treq);
|
|
447
444
|
|
|
448
445
|
if (!model.textureViews[vidx + 4] || model.textureViews[vidx + 4].getTexture() !== newTex) {
|
|
449
|
-
var tview = newTex.createView();
|
|
450
|
-
tview.setName("volTexture".concat(vidx));
|
|
446
|
+
var tview = newTex.createView("volTexture".concat(vidx));
|
|
451
447
|
model.textureViews[vidx + 4] = tview;
|
|
452
448
|
}
|
|
453
449
|
} // clear any old leftovers
|
|
@@ -498,8 +494,9 @@ function vtkWebGPUVolumePassFSQ(publicAPI, model) {
|
|
|
498
494
|
publicAPI.updateBuffers(device);
|
|
499
495
|
|
|
500
496
|
if (!model.clampSampler) {
|
|
501
|
-
model.clampSampler = vtkWebGPUSampler.newInstance(
|
|
502
|
-
|
|
497
|
+
model.clampSampler = vtkWebGPUSampler.newInstance({
|
|
498
|
+
label: 'clampSampler'
|
|
499
|
+
});
|
|
503
500
|
model.clampSampler.create(device, {
|
|
504
501
|
minFilter: 'linear',
|
|
505
502
|
magFilter: 'linear'
|
|
@@ -534,13 +531,16 @@ function extend(publicAPI, model) {
|
|
|
534
531
|
|
|
535
532
|
vtkWebGPUFullScreenQuad.extend(publicAPI, model, initialValues);
|
|
536
533
|
model.fragmentShaderTemplate = volFragTemplate;
|
|
537
|
-
model.UBO = vtkWebGPUUniformBuffer.newInstance(
|
|
538
|
-
|
|
534
|
+
model.UBO = vtkWebGPUUniformBuffer.newInstance({
|
|
535
|
+
label: 'mapperUBO'
|
|
536
|
+
});
|
|
539
537
|
model.UBO.addEntry('SampleDistance', 'f32');
|
|
540
|
-
model.SSBO = vtkWebGPUStorageBuffer.newInstance(
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
model.componentSSBO.
|
|
538
|
+
model.SSBO = vtkWebGPUStorageBuffer.newInstance({
|
|
539
|
+
label: 'volumeSSBO'
|
|
540
|
+
});
|
|
541
|
+
model.componentSSBO = vtkWebGPUStorageBuffer.newInstance({
|
|
542
|
+
label: 'componentSSBO'
|
|
543
|
+
});
|
|
544
544
|
model.lutBuildTime = {};
|
|
545
545
|
macro.obj(model.lutBuildTime, {
|
|
546
546
|
mtime: 0
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import _asyncToGenerator from '@babel/runtime/helpers/asyncToGenerator';
|
|
1
2
|
import _slicedToArray from '@babel/runtime/helpers/slicedToArray';
|
|
3
|
+
import _regeneratorRuntime from '@babel/runtime/regenerator';
|
|
2
4
|
import { r as radiansFromDegrees } from '../../Common/Core/Math/index.js';
|
|
3
5
|
import { FieldAssociations } from '../../Common/DataModel/DataSet/Constants.js';
|
|
4
6
|
import macro from '../../macros.js';
|
|
@@ -10,7 +12,8 @@ import { diff } from './WidgetManager/vdom.js';
|
|
|
10
12
|
var ViewTypes = WidgetManagerConst.ViewTypes,
|
|
11
13
|
RenderingTypes = WidgetManagerConst.RenderingTypes,
|
|
12
14
|
CaptureOn = WidgetManagerConst.CaptureOn;
|
|
13
|
-
var vtkErrorMacro = macro.vtkErrorMacro
|
|
15
|
+
var vtkErrorMacro = macro.vtkErrorMacro,
|
|
16
|
+
vtkWarningMacro = macro.vtkWarningMacro;
|
|
14
17
|
var createSvgElement = vtkSVGRepresentation.createSvgElement,
|
|
15
18
|
createSvgDomElement = vtkSVGRepresentation.createSvgDomElement;
|
|
16
19
|
var viewIdCount = 1; // ----------------------------------------------------------------------------
|
|
@@ -267,17 +270,48 @@ function vtkWidgetManager(publicAPI, model) {
|
|
|
267
270
|
model.widgets.forEach(updateWidgetForRender);
|
|
268
271
|
}
|
|
269
272
|
|
|
270
|
-
function captureBuffers(
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
273
|
+
function captureBuffers(_x, _x2, _x3, _x4) {
|
|
274
|
+
return _captureBuffers.apply(this, arguments);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
function _captureBuffers() {
|
|
278
|
+
_captureBuffers = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3(x1, y1, x2, y2) {
|
|
279
|
+
return _regeneratorRuntime.wrap(function _callee3$(_context3) {
|
|
280
|
+
while (1) {
|
|
281
|
+
switch (_context3.prev = _context3.next) {
|
|
282
|
+
case 0:
|
|
283
|
+
if (!model._captureInProgress) {
|
|
284
|
+
_context3.next = 2;
|
|
285
|
+
break;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
return _context3.abrupt("return");
|
|
289
|
+
|
|
290
|
+
case 2:
|
|
291
|
+
model._captureInProgress = true;
|
|
292
|
+
renderPickingBuffer();
|
|
293
|
+
model._capturedBuffers = null;
|
|
294
|
+
_context3.next = 7;
|
|
295
|
+
return model.selector.getSourceDataAsync(model.renderer, x1, y1, x2, y2);
|
|
296
|
+
|
|
297
|
+
case 7:
|
|
298
|
+
model._capturedBuffers = _context3.sent;
|
|
299
|
+
model.previousSelectedData = null;
|
|
300
|
+
renderFrontBuffer();
|
|
301
|
+
model._captureInProgress = false;
|
|
302
|
+
|
|
303
|
+
case 11:
|
|
304
|
+
case "end":
|
|
305
|
+
return _context3.stop();
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}, _callee3);
|
|
309
|
+
}));
|
|
310
|
+
return _captureBuffers.apply(this, arguments);
|
|
276
311
|
}
|
|
277
312
|
|
|
278
313
|
publicAPI.enablePicking = function () {
|
|
279
314
|
model.pickingEnabled = true;
|
|
280
|
-
model.pickingAvailable = true;
|
|
281
315
|
publicAPI.renderWidgets();
|
|
282
316
|
};
|
|
283
317
|
|
|
@@ -288,7 +322,7 @@ function vtkWidgetManager(publicAPI, model) {
|
|
|
288
322
|
w = _model$apiSpecificRen4[0],
|
|
289
323
|
h = _model$apiSpecificRen4[1];
|
|
290
324
|
|
|
291
|
-
|
|
325
|
+
captureBuffers(0, 0, w, h);
|
|
292
326
|
}
|
|
293
327
|
|
|
294
328
|
renderFrontBuffer();
|
|
@@ -297,7 +331,6 @@ function vtkWidgetManager(publicAPI, model) {
|
|
|
297
331
|
|
|
298
332
|
publicAPI.disablePicking = function () {
|
|
299
333
|
model.pickingEnabled = false;
|
|
300
|
-
model.pickingAvailable = false;
|
|
301
334
|
};
|
|
302
335
|
|
|
303
336
|
publicAPI.setRenderer = function (renderer) {
|
|
@@ -307,9 +340,8 @@ function vtkWidgetManager(publicAPI, model) {
|
|
|
307
340
|
subscriptions.pop().unsubscribe();
|
|
308
341
|
}
|
|
309
342
|
|
|
310
|
-
model.selector = model.apiSpecificRenderWindow.
|
|
343
|
+
model.selector = model.apiSpecificRenderWindow.createSelector();
|
|
311
344
|
model.selector.setFieldAssociation(FieldAssociations.FIELD_ASSOCIATION_POINTS);
|
|
312
|
-
model.selector.attach(model.apiSpecificRenderWindow, model.renderer);
|
|
313
345
|
subscriptions.push(model.interactor.onRenderEvent(updateSvg));
|
|
314
346
|
subscriptions.push(model.apiSpecificRenderWindow.onModified(setSvgSize));
|
|
315
347
|
setSvgSize();
|
|
@@ -323,61 +355,90 @@ function vtkWidgetManager(publicAPI, model) {
|
|
|
323
355
|
model.isAnimating = false;
|
|
324
356
|
publicAPI.renderWidgets();
|
|
325
357
|
}));
|
|
326
|
-
subscriptions.push(model.interactor.onMouseMove(function (
|
|
327
|
-
var
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
return
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
358
|
+
subscriptions.push(model.interactor.onMouseMove( /*#__PURE__*/function () {
|
|
359
|
+
var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(_ref) {
|
|
360
|
+
var position, _yield$publicAPI$getS, requestCount, selectedState, representation, widget, i, w;
|
|
361
|
+
|
|
362
|
+
return _regeneratorRuntime.wrap(function _callee$(_context) {
|
|
363
|
+
while (1) {
|
|
364
|
+
switch (_context.prev = _context.next) {
|
|
365
|
+
case 0:
|
|
366
|
+
position = _ref.position;
|
|
367
|
+
|
|
368
|
+
if (!(model.isAnimating || !model.pickingEnabled || model._selectionInProgress)) {
|
|
369
|
+
_context.next = 3;
|
|
370
|
+
break;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
return _context.abrupt("return");
|
|
374
|
+
|
|
375
|
+
case 3:
|
|
376
|
+
model._selectionInProgress = true;
|
|
377
|
+
_context.next = 6;
|
|
378
|
+
return publicAPI.getSelectedDataForXY(position.x, position.y);
|
|
379
|
+
|
|
380
|
+
case 6:
|
|
381
|
+
_yield$publicAPI$getS = _context.sent;
|
|
382
|
+
requestCount = _yield$publicAPI$getS.requestCount;
|
|
383
|
+
selectedState = _yield$publicAPI$getS.selectedState;
|
|
384
|
+
representation = _yield$publicAPI$getS.representation;
|
|
385
|
+
widget = _yield$publicAPI$getS.widget;
|
|
386
|
+
model._selectionInProgress = false;
|
|
387
|
+
|
|
388
|
+
if (!requestCount) {
|
|
389
|
+
_context.next = 14;
|
|
390
|
+
break;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
return _context.abrupt("return");
|
|
394
|
+
|
|
395
|
+
case 14:
|
|
396
|
+
// Default cursor behavior
|
|
397
|
+
model.apiSpecificRenderWindow.setCursor(widget ? 'pointer' : 'default');
|
|
398
|
+
|
|
399
|
+
if (model.widgetInFocus === widget && widget.hasFocus()) {
|
|
400
|
+
widget.activateHandle({
|
|
401
|
+
selectedState: selectedState,
|
|
402
|
+
representation: representation
|
|
403
|
+
}); // Ken FIXME
|
|
404
|
+
|
|
405
|
+
model.interactor.render();
|
|
406
|
+
model.interactor.render();
|
|
407
|
+
} else {
|
|
408
|
+
for (i = 0; i < model.widgets.length; i++) {
|
|
409
|
+
w = model.widgets[i];
|
|
410
|
+
|
|
411
|
+
if (w === widget && w.getNestedPickable()) {
|
|
412
|
+
w.activateHandle({
|
|
413
|
+
selectedState: selectedState,
|
|
414
|
+
representation: representation
|
|
415
|
+
});
|
|
416
|
+
model.activeWidget = w;
|
|
417
|
+
} else {
|
|
418
|
+
w.deactivateAllHandles();
|
|
419
|
+
}
|
|
420
|
+
} // Ken FIXME
|
|
421
|
+
|
|
422
|
+
|
|
423
|
+
model.interactor.render();
|
|
424
|
+
model.interactor.render();
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
case 16:
|
|
428
|
+
case "end":
|
|
429
|
+
return _context.stop();
|
|
430
|
+
}
|
|
369
431
|
}
|
|
370
|
-
}
|
|
432
|
+
}, _callee);
|
|
433
|
+
}));
|
|
371
434
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
}));
|
|
435
|
+
return function (_x5) {
|
|
436
|
+
return _ref2.apply(this, arguments);
|
|
437
|
+
};
|
|
438
|
+
}()));
|
|
377
439
|
publicAPI.modified();
|
|
378
440
|
|
|
379
441
|
if (model.pickingEnabled) {
|
|
380
|
-
// also sets pickingAvailable
|
|
381
442
|
publicAPI.enablePicking();
|
|
382
443
|
}
|
|
383
444
|
|
|
@@ -453,7 +514,93 @@ function vtkWidgetManager(publicAPI, model) {
|
|
|
453
514
|
}
|
|
454
515
|
};
|
|
455
516
|
|
|
517
|
+
publicAPI.getSelectedDataForXY = /*#__PURE__*/function () {
|
|
518
|
+
var _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(x, y) {
|
|
519
|
+
var i, widget, hoveredSVGReps, selection, capturedRegion;
|
|
520
|
+
return _regeneratorRuntime.wrap(function _callee2$(_context2) {
|
|
521
|
+
while (1) {
|
|
522
|
+
switch (_context2.prev = _context2.next) {
|
|
523
|
+
case 0:
|
|
524
|
+
model.selections = null;
|
|
525
|
+
|
|
526
|
+
if (!model.pickingEnabled) {
|
|
527
|
+
_context2.next = 24;
|
|
528
|
+
break;
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
i = 0;
|
|
532
|
+
|
|
533
|
+
case 3:
|
|
534
|
+
if (!(i < model.widgets.length)) {
|
|
535
|
+
_context2.next = 16;
|
|
536
|
+
break;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
widget = model.widgets[i];
|
|
540
|
+
hoveredSVGReps = widget.getRepresentations().filter(function (r) {
|
|
541
|
+
return r.isA('vtkSVGRepresentation') && r.getHover() != null;
|
|
542
|
+
});
|
|
543
|
+
|
|
544
|
+
if (!hoveredSVGReps.length) {
|
|
545
|
+
_context2.next = 13;
|
|
546
|
+
break;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
selection = vtkSelectionNode.newInstance();
|
|
550
|
+
selection.getProperties().compositeID = hoveredSVGReps[0].getHover();
|
|
551
|
+
selection.getProperties().widget = widget;
|
|
552
|
+
selection.getProperties().representation = hoveredSVGReps[0];
|
|
553
|
+
model.selections = [selection];
|
|
554
|
+
return _context2.abrupt("return", publicAPI.getSelectedData());
|
|
555
|
+
|
|
556
|
+
case 13:
|
|
557
|
+
++i;
|
|
558
|
+
_context2.next = 3;
|
|
559
|
+
break;
|
|
560
|
+
|
|
561
|
+
case 16:
|
|
562
|
+
if (!(!model._capturedBuffers || model.captureOn === CaptureOn.MOUSE_MOVE)) {
|
|
563
|
+
_context2.next = 19;
|
|
564
|
+
break;
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
_context2.next = 19;
|
|
568
|
+
return captureBuffers(x, y, x, y);
|
|
569
|
+
|
|
570
|
+
case 19:
|
|
571
|
+
// or do we need a pixel that is outside the last capture?
|
|
572
|
+
capturedRegion = model._capturedBuffers.area;
|
|
573
|
+
|
|
574
|
+
if (!(x < capturedRegion[0] || x > capturedRegion[2] || y < capturedRegion[1] || y > capturedRegion[3])) {
|
|
575
|
+
_context2.next = 23;
|
|
576
|
+
break;
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
_context2.next = 23;
|
|
580
|
+
return captureBuffers(x, y, x, y);
|
|
581
|
+
|
|
582
|
+
case 23:
|
|
583
|
+
model.selections = model._capturedBuffers.generateSelection(x, y, x, y);
|
|
584
|
+
|
|
585
|
+
case 24:
|
|
586
|
+
return _context2.abrupt("return", publicAPI.getSelectedData());
|
|
587
|
+
|
|
588
|
+
case 25:
|
|
589
|
+
case "end":
|
|
590
|
+
return _context2.stop();
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
}, _callee2);
|
|
594
|
+
}));
|
|
595
|
+
|
|
596
|
+
return function (_x6, _x7) {
|
|
597
|
+
return _ref3.apply(this, arguments);
|
|
598
|
+
};
|
|
599
|
+
}();
|
|
600
|
+
|
|
456
601
|
publicAPI.updateSelectionFromXY = function (x, y) {
|
|
602
|
+
vtkWarningMacro('updateSelectionFromXY is deprecated, please use getSelectedDataForXY');
|
|
603
|
+
|
|
457
604
|
if (model.pickingEnabled) {
|
|
458
605
|
// First pick SVG representation
|
|
459
606
|
for (var i = 0; i < model.widgets.length; ++i) {
|
|
@@ -473,20 +620,14 @@ function vtkWidgetManager(publicAPI, model) {
|
|
|
473
620
|
} // Then pick regular representations.
|
|
474
621
|
|
|
475
622
|
|
|
476
|
-
var pickingAvailable = model.pickingAvailable;
|
|
477
|
-
|
|
478
623
|
if (model.captureOn === CaptureOn.MOUSE_MOVE) {
|
|
479
|
-
|
|
480
|
-
renderFrontBuffer();
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
if (pickingAvailable) {
|
|
484
|
-
model.selections = model.selector.generateSelection(x, y, x, y);
|
|
624
|
+
captureBuffers(x, y, x, y);
|
|
485
625
|
}
|
|
486
626
|
}
|
|
487
627
|
};
|
|
488
628
|
|
|
489
629
|
publicAPI.updateSelectionFromMouseEvent = function (event) {
|
|
630
|
+
vtkWarningMacro('updateSelectionFromMouseEvent is deprecated, please use getSelectedDataForXY');
|
|
490
631
|
var pageX = event.pageX,
|
|
491
632
|
pageY = event.pageY;
|
|
492
633
|
|
|
@@ -603,7 +744,6 @@ var DEFAULT_VALUES = {
|
|
|
603
744
|
widgets: [],
|
|
604
745
|
renderer: null,
|
|
605
746
|
viewType: ViewTypes.DEFAULT,
|
|
606
|
-
pickingAvailable: false,
|
|
607
747
|
isAnimating: false,
|
|
608
748
|
pickingEnabled: true,
|
|
609
749
|
selections: null,
|
|
@@ -48,13 +48,16 @@ function widgetBehavior(publicAPI, model) {
|
|
|
48
48
|
return handles.reduce(function (_ref, handle) {
|
|
49
49
|
var closestHandle = _ref.closestHandle,
|
|
50
50
|
closestDistance = _ref.closestDistance;
|
|
51
|
-
var distance = vec3.squaredDistance(model.moveHandle.getOrigin(), handle.getOrigin());
|
|
52
51
|
|
|
53
|
-
if (handle !== model.moveHandle) {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
52
|
+
if (handle !== model.moveHandle && model.moveHandle.getOrigin() && handle.getOrigin()) {
|
|
53
|
+
var distance = vec3.squaredDistance(model.moveHandle.getOrigin(), handle.getOrigin());
|
|
54
|
+
|
|
55
|
+
if (distance < closestDistance) {
|
|
56
|
+
return {
|
|
57
|
+
closestHandle: handle,
|
|
58
|
+
closestDistance: distance
|
|
59
|
+
};
|
|
60
|
+
}
|
|
58
61
|
}
|
|
59
62
|
|
|
60
63
|
return {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kitware/vtk.js",
|
|
3
|
-
"version": "22.
|
|
3
|
+
"version": "22.3.0",
|
|
4
4
|
"description": "Visualization Toolkit for the Web",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"3d",
|
|
@@ -38,7 +38,6 @@
|
|
|
38
38
|
"globalthis": "1.0.2",
|
|
39
39
|
"jszip": "3.7.1",
|
|
40
40
|
"pako": "2.0.4",
|
|
41
|
-
"patch-package": "6.4.7",
|
|
42
41
|
"seedrandom": "3.0.5",
|
|
43
42
|
"shader-loader": "1.3.1",
|
|
44
43
|
"shelljs": "0.8.5",
|
|
@@ -98,6 +97,7 @@
|
|
|
98
97
|
"lodash": "4.17.21",
|
|
99
98
|
"magic-string": "0.25.7",
|
|
100
99
|
"moment": "2.29.1",
|
|
100
|
+
"patch-package": "6.4.7",
|
|
101
101
|
"pixelmatch": "5.2.1",
|
|
102
102
|
"postcss-loader": "6.2.1",
|
|
103
103
|
"prettier": "2.5.1",
|
|
@@ -112,10 +112,9 @@
|
|
|
112
112
|
"rollup-plugin-string": "3.0.0",
|
|
113
113
|
"rollup-plugin-svgo": "1.1.0",
|
|
114
114
|
"rollup-plugin-web-worker-loader": "1.6.1",
|
|
115
|
-
"semantic-release": "
|
|
115
|
+
"semantic-release": "19.0.2",
|
|
116
116
|
"string-replace-loader": "3.1.0",
|
|
117
117
|
"style-loader": "3.3.1",
|
|
118
|
-
"tap-spec": "5.0.0",
|
|
119
118
|
"tape": "5.4.0",
|
|
120
119
|
"tape-catch": "1.0.6",
|
|
121
120
|
"webpack": "5.65.0",
|
|
@@ -145,7 +144,7 @@
|
|
|
145
144
|
"dev:esm": "npm run build:esm -- -w",
|
|
146
145
|
"dev:umd": "webpack --watch --config webpack.dev.js --progress",
|
|
147
146
|
"build": "npm run build:release",
|
|
148
|
-
"build:esm": "rollup -c rollup.config.js",
|
|
147
|
+
"build:esm": "npm run patch-build-deps && rollup -c rollup.config.js",
|
|
149
148
|
"build:umd": "webpack --config webpack.prod.js --progress",
|
|
150
149
|
"build:release": "npm run lint && concurrently \"cross-env NOLINT=1 npm run build:esm\" \"cross-env NOLINT=1 npm run build:umd\"",
|
|
151
150
|
"release:create-packages": "node ./Utilities/ci/build-npm-package.js",
|
|
@@ -158,7 +157,7 @@
|
|
|
158
157
|
"commit": "git cz",
|
|
159
158
|
"semantic-release": "semantic-release",
|
|
160
159
|
"prepare": "node ./Utilities/prepare.js",
|
|
161
|
-
"
|
|
160
|
+
"patch-build-deps": "patch-package --patch-dir ./Utilities/build/patches"
|
|
162
161
|
},
|
|
163
162
|
"config": {
|
|
164
163
|
"commitizen": {
|