import '@kitware/vtk.js/favicon';
import '@kitware/vtk.js/Rendering/Profiles/Geometry';
import macro from '@kitware/vtk.js/macros'; import vtkFullScreenRenderWindow from '@kitware/vtk.js/Rendering/Misc/FullScreenRenderWindow';
import vtkActor from '@kitware/vtk.js/Rendering/Core/Actor'; import vtkCalculator from '@kitware/vtk.js/Filters/General/Calculator'; import vtkDataSet from '@kitware/vtk.js/Common/DataModel/DataSet'; import vtkLookupTable from '@kitware/vtk.js/Common/Core/LookupTable'; import vtkMapper from '@kitware/vtk.js/Rendering/Core/Mapper'; import vtkPlaneSource from '@kitware/vtk.js/Filters/Sources/PlaneSource'; import vtkPoints from '@kitware/vtk.js/Common/Core/Points'; import vtkPolyData from '@kitware/vtk.js/Common/DataModel/PolyData'; import vtkWarpScalar from '@kitware/vtk.js/Filters/General/WarpScalar';
import controlPanel from './controlPanel.html';
const { ColorMode, ScalarMode } = vtkMapper; const { FieldDataTypes } = vtkDataSet; const { vtkErrorMacro } = macro;
let formulaIdx = 0; const FORMULA = [ '((x[0] - 0.5) * (x[0] - 0.5)) + ((x[1] - 0.5) * (x[1] - 0.5)) + 0.125', '0.25 * Math.sin(Math.sqrt(((x[0] - 0.5) * (x[0] - 0.5)) + ((x[1] - 0.5) * (x[1] - 0.5)))*50)', ];
const fullScreenRenderer = vtkFullScreenRenderWindow.newInstance({ background: [0.9, 0.9, 0.9], }); const renderer = fullScreenRenderer.getRenderer(); const renderWindow = fullScreenRenderer.getRenderWindow();
const lookupTable = vtkLookupTable.newInstance({ hueRange: [0.666, 0] });
const planeSource = vtkPlaneSource.newInstance({ xResolution: 25, yResolution: 25, }); const planeMapper = vtkMapper.newInstance({ interpolateScalarsBeforeMapping: true, colorMode: ColorMode.DEFAULT, scalarMode: ScalarMode.DEFAULT, useLookupTableScalarRange: true, lookupTable, }); const planeActor = vtkActor.newInstance(); planeActor.getProperty().setEdgeVisibility(true);
const simpleFilter = vtkCalculator.newInstance(); simpleFilter.setFormulaSimple( FieldDataTypes.POINT, [], 'z', (x) => (x[0] - 0.5) * (x[0] - 0.5) + (x[1] - 0.5) * (x[1] - 0.5) + 0.125 );
const warpScalar = vtkWarpScalar.newInstance(); const warpMapper = vtkMapper.newInstance({ interpolateScalarsBeforeMapping: true, useLookupTableScalarRange: true, lookupTable, }); const warpActor = vtkActor.newInstance();
simpleFilter.setInputConnection(planeSource.getOutputPort());
warpScalar.setInputConnection(simpleFilter.getOutputPort()); warpScalar.setInputArrayToProcess(0, 'z', 'PointData', 'Scalars');
planeMapper.setInputConnection(simpleFilter.getOutputPort()); planeActor.setMapper(planeMapper);
warpMapper.setInputConnection(warpScalar.getOutputPort()); warpActor.setMapper(warpMapper);
renderer.addActor(planeActor); renderer.addActor(warpActor);
renderer.resetCamera(); renderWindow.render();
fullScreenRenderer.addController(controlPanel);
function updateScalarRange() { const min = Number(document.querySelector('.min').value); const max = Number(document.querySelector('.max').value); if (!Number.isNaN(min) && !Number.isNaN(max)) { lookupTable.setMappingRange(min, max); renderWindow.render(); } }
function applyFormula() { const el = document.querySelector('.formula'); let fn = null; try { fn = new Function('x,y', `return ${el.value}`); } catch (exc) { if (!('name' in exc && exc.name === 'SyntaxError')) { vtkErrorMacro(`Unexpected exception ${exc}`); el.style.background = '#fbb'; return; } } if (fn) { el.style.background = '#fff'; const formulaObj = simpleFilter.createSimpleFormulaObject( FieldDataTypes.POINT, [], 'z', fn );
planeSource.update(); const arraySpec = formulaObj.getArrays(planeSource.getOutputData()); const testData = vtkPolyData.newInstance(); const testPts = vtkPoints.newInstance({ name: 'coords', numberOfComponents: 3, size: 3, values: [0, 0, 0], }); testData.setPoints(testPts); const testOut = vtkPolyData.newInstance(); testOut.shallowCopy(testData); const testArrays = simpleFilter.prepareArrays(arraySpec, testData, testOut); try { formulaObj.evaluate(testArrays.arraysIn, testArrays.arraysOut);
simpleFilter.setFormula(formulaObj);
simpleFilter.update();
const [min, max] = simpleFilter .getOutputData() .getPointData() .getScalars() .getRange(); document.querySelector('.min').value = min; document.querySelector('.max').value = max; lookupTable.setMappingRange(min, max);
renderWindow.render(); return; } catch (exc) { vtkErrorMacro(`Unexpected exception ${exc}`); } } el.style.background = '#ffb'; }
['xResolution', 'yResolution'].forEach((propertyName) => { document.querySelector(`.${propertyName}`).addEventListener('input', (e) => { const value = Number(e.target.value); planeSource.set({ [propertyName]: value }); renderWindow.render(); }); });
['scaleFactor'].forEach((propertyName) => { document.querySelector(`.${propertyName}`).addEventListener('input', (e) => { const value = Number(e.target.value); warpScalar.set({ [propertyName]: value }); renderWindow.render(); }); });
document.querySelector('.visibility').addEventListener('change', (e) => { planeActor.setVisibility(!!e.target.checked); renderWindow.render(); });
document.querySelector('.formula').addEventListener('input', applyFormula);
['min', 'max'].forEach((selector) => { document .querySelector(`.${selector}`) .addEventListener('input', updateScalarRange); });
document.querySelector('.next').addEventListener('click', (e) => { formulaIdx = (formulaIdx + 1) % FORMULA.length; document.querySelector('.formula').value = FORMULA[formulaIdx]; applyFormula(); renderWindow.render(); });
applyFormula();
global.setLoggerFunction = macro.setLoggerFunction; global.planeSource = planeSource; global.planeMapper = planeMapper; global.planeActor = planeActor; global.simpleFilter = simpleFilter; global.warpMapper = warpMapper; global.warpActor = warpActor; global.renderer = renderer; global.renderWindow = renderWindow; global.lookupTable = lookupTable;
|