Hello everyone,
I upload two samples at the same time so that both can be rendered in the same canvas with different colours and the below code works very well for that.
But now I want to control their scalar opacity and blending modes with event listener which I have already created in the HTML section. If I load two samples and play with the Scalar opacity slider and blending modes, it nicely interacts with the second sample (second uploaded sample) but not with the first although both samples were rendered at the same time.
I tried putting renderWindow.render() inside/outside of for loop but it didn’t work at all and I also did not find any example which can help me to solve this problem.
var container = document.getElementById('viewContainer');
const openglRenderWindow = vtk.Rendering.OpenGL.vtkRenderWindow.newInstance();
const renderer = vtk.Rendering.Core.vtkRenderer.newInstance();
const renderWindow = vtk.Rendering.Core.vtkRenderWindow.newInstance();
const interactorStyle = vtk.Interaction.Style.vtkInteractorStyleTrackballCamera.newInstance();
const interactor = vtk.Rendering.Core.vtkRenderWindowInteractor.newInstance();
const vtkBoundingBox = vtk.Common.DataModel.vtkBoundingBox.newInstance();
const vtkColorMaps = vtk.Rendering.Core.vtkColorTransferFunction.vtkColorMaps;
const vtkColorTransferFunction = vtk.Rendering.Core.vtkColorTransferFunction;
const vtkConvolution2DPass = vtk.Rendering.OpenGL.vtkConvolution2DPass;
const vtkCamera = vtk.Rendering.Core.vtkCamera;
openglRenderWindow.setContainer(container);
renderWindow.addView(openglRenderWindow);
function updateBlendMode(event) {
const blendMode = parseInt(event.target.value, 10);
const ipScalarEls = document.querySelectorAll('.ipScalar');
volumeMapper.setBlendMode(blendMode);
volumeMapper.setIpScalarRange(0.0, 1.0);
// if average or additive blend mode
if (blendMode === 3 || blendMode === 4) {
// Show scalar ui
for (let i = 0; i < ipScalarEls.length; i += 1) {
const el = ipScalarEls[i];
el.style.display = 'table-row';
}
} else {
// Hide scalar ui
for (let i = 0; i < ipScalarEls.length; i += 1) {
const el = ipScalarEls[i];
el.style.display = 'none';
}
}
renderWindow.render();
}
function updateScalarMin(event) {
volumeMapper.setIpScalarRange(event.target.value, volumeMapper.getIpScalarRange()[1]);
renderWindow.render();
}
function updateScalarMax(event) {
volumeMapper.setIpScalarRange(volumeMapper.getIpScalarRange()[0], event.target.value);
renderWindow.render();
}
for (i = 0; i < imageData.length; i++){
mycolor = color_maps[i]
console.log(i)
volume_vtk = vtk.Rendering.Core.vtkVolume.newInstance();
volumeMapper = vtk.Rendering.Core.vtkVolumeMapper.newInstance();
volumeProperty = vtk.Rendering.Core.vtkVolumeProperty.newInstance();
ofun = vtk.Common.DataModel.vtkPiecewiseFunction.newInstance();
ctfun = vtk.Rendering.Core.vtkColorTransferFunction.newInstance();
dataRange = imageData[i].getPointData().getScalars().getRange();
dimensions = imageData[i].getDimensions()
console.log('volume dimensions', dimensions)
// Calculating Pixel range
ii_0 = parseInt(dataRange[0])
ii_mid = parseInt(dataRange[1] / 2)
ii_1 = parseInt(dataRange[1])
// Define PieceWise transfer function
ofun.removeAllPoints();
ofun.addPoint(ii_0, 0.0);
ofun.addPoint(ii_1, 1.0);
// ######################################################################
// Define Color transfer Function
ctfun.addRGBPoint(i, mycolor[i+1].rgb.r, mycolor[i+1].rgb.g, mycolor[i+1].rgb.b);
// ######################################################################
// Define Volume Property
volumeProperty.setRGBTransferFunction(0, ctfun);
volumeProperty.setScalarOpacity(0, ofun);
volumeProperty.setShade(true);
volumeProperty.setInterpolationTypeToLinear();
volumeProperty.setAmbient(0.7);
volumeProperty.setDiffuse(0.7);
volumeProperty.setSpecular(0.3);
volumeProperty.setSpecularPower(30.0);
volumeProperty.setOpacityMode(0, 20);
volumeProperty.setIndependentComponents(true);
volumeProperty.setUseGradientOpacity(0, true);
volumeProperty.setGradientOpacityMinimumValue(0, 3.5);
volumeProperty.setGradientOpacityMinimumOpacity(0, 0.0);
volumeProperty.setGradientOpacityMaximumValue(0, 20);
volumeProperty.setGradientOpacityMaximumOpacity(0, 1.0);
// volumeProperty.setScalarOpacityUnitDistance(0, asasa);
// Define VolumeMapper
volumeMapper.setInputData(imageData[i]);
volumeMapper.setSampleDistance(0.4);
// Define vtkVolume
volume_vtk.setMapper(volumeMapper);
volume_vtk.setProperty(volumeProperty);
renderer.addActor(volume_vtk);
renderer.resetCamera();
renderWindow.render();
}
// Add blending mode into the viewer
const el = document.querySelector('.blendMode');
el.addEventListener('change', updateBlendMode);
const scalarMinEl = document.querySelector('.scalarMin');
scalarMinEl.addEventListener('input', updateScalarMin);
const scalarMaxEl = document.querySelector('.scalarMax');
scalarMaxEl.addEventListener('input', updateScalarMax);
// Control Scalar Opacity
$( "#setScalarOpacityUnitDistance" ).change(function() {
newVal= this.value
volumeProperty.setScalarOpacityUnitDistance(0, newVal);
renderWindow.render();
console.log(newVal)
});
const camera = vtkCamera.newInstance();
renderer.getActiveCamera();
camera.setFreezeFocalPoint(true);
renderer.resetCamera();
camera.elevation(70);
renderWindow.addRenderer(renderer);
interactor.setView(openglRenderWindow);
interactor.initialize();
interactor.bindEvents(container);
interactor.setInteractorStyle(interactorStyle);
renderWindow.render()
}
In the below image, we can see two samples loaded at once, the first sample is shown with red colour and the second sample is shown in green colour.
After loading when I use a scalar opacity slider from 0 to 50. It only interacts with the green sample as the result can be seen below image. I want to know what am I doing wrong and how can I modify the scalar opacity slider so that it can interact both images at the same time.
Likewise, I also tried by changing the blend mode from composite to maximum intensity and again it only change the second green sample (as it disappeared) as can be seen in the below figure but it did not make disappear to the red sample. As for now, it only interacts with the latest or last uploaded sample not with the first sample.
Can anyone give me some suggestions to solve this problem?
Thank you!