Hi,
I managed to get the volume viewer functionality of adding the controller widget to work in full screen render mode. However, I experience difficulty making it work with a generic render window (so not full screen). In the html a div is created with id ‘container’, this container is used in the javascript to render the window in that div.
<div id="container" class="rounded shadow-lg" ></div>
<script type="text/javascript">
const {renderer, renderWindow } = window.createVTKWindow("#container", file);
window.renderer = renderer;
window.renderWindow = renderWindow;
</script>
</div>
In the javascript I tried the following:
function createVTKWindow(name, url) {
const container = document.querySelector(`container id from div`);
const background = userParams.background
? options.background.split(',').map((s) => Number(s))
: [1, 1, 1];
const containerStyle = userParams.containerStyle;
const genericRenderWindow = vtkGenericRenderWindow.newInstance({
background,
containerStyle,
});
genericRenderWindow.setContainer(container);
const renderer = genericRenderWindow.getRenderer();
const renderWindow = genericRenderWindow.getRenderWindow();
const camera = renderer.getActiveCamera()
renderer.setActiveCamera(window.camera);
fetch(url)
.then(resp => resp.blob())
.then(blob => {
onDownloaded(container, renderer, renderWindow, blob, function() {
$("#loader").remove();
});
})
.catch(() => {
console.log('Error retrieving data..')
$("#loader").remove();
});
return {
renderer: renderer,
renderWindow: renderWindow
};
window.createVTKWindow = createVTKWindow;
function onDownloaded(container, renderer, renderWindow, bin, completion = null) {
const reader = new FileReader();
reader.onload = function onLoad(e) {
const vtiReader = vtkXMLImageDataReader.newInstance();
vtiReader.parseAsArrayBuffer(reader.result);
// --- Set up the cone actor ---
const source = vtiReader.getOutputData(0);
const mapper = vtkVolumeMapper.newInstance();
const actor = vtkVolume.newInstance();
const dataArray = source.getPointData().getScalars() || source.getPointData().getArrays()[0];
const dataRange = dataArray.getRange();
const lookupTable = vtkColorTransferFunction.newInstance();
const piecewiseFunction = vtkPiecewiseFunction.newInstance();
// /* Pipeline handling */
actor.setMapper(mapper);
mapper.setInputData(source);
renderer.addActor(actor);
const sampleDistance =
0.7 *
Math.sqrt(
source
.getSpacing()
.map((v) => v * v)
.reduce((a, b) => a + b, 0)
);
mapper.setSampleDistance(sampleDistance);
// set the actor properties
actor.getProperty().setRGBTransferFunction(0, lookupTable);
actor.getProperty().setScalarOpacity(0, piecewiseFunction);
actor.getProperty().setInterpolationTypeToLinear();
actor
.getProperty()
.setScalarOpacityUnitDistance(
0,
vtkBoundingBox.getDiagonalLength(source.getBounds()) /
Math.max(...source.getDimensions())
);
actor.getProperty().setGradientOpacityMinimumValue(0, 0);
actor
.getProperty()
.setGradientOpacityMaximumValue(0, (dataRange[1] - dataRange[0]) * 0.05);
actor.getProperty().setShade(true);
actor.getProperty().setUseGradientOpacity(0, true);
actor.getProperty().setGradientOpacityMinimumOpacity(0, 0.0);
actor.getProperty().setGradientOpacityMaximumOpacity(0, 1.0);
actor.getProperty().setAmbient(0.2);
actor.getProperty().setDiffuse(0.7);
actor.getProperty().setSpecular(0.3);
actor.getProperty().setSpecularPower(8.0);
const controllerWidget = vtkVolumeController.newInstance({
size: [200, 100],
rescaleColorMap: true,
expanded: true,
});
const isBackgroundDark = background[0] + background[1] + background[2] < 1.5;
controllerWidget.setContainer(container);
controllerWidget.setupContent(renderWindow, actor, isBackgroundDark);
controllerWidget.setSize(200, 100);
controllerWidget.render();
fpsMonitor.update();
// --- Add actor to scene ---
renderer.resetCamera();
renderWindow.render();
if (completion) completion();
};
reader.readAsArrayBuffer(new File([bin], "data"));
}
window.onDownloaded = onDownloaded;
What results from this is a rendered window within the specified div. However, the window remains black and keeps on loading. How do I make the Volume Controller work with a generic render window? Can someone help? Thanks in advance!