VTK. js Неверный или отсутствующий ввод после renderer.resetCamera () - PullRequest
0 голосов
/ 26 апреля 2020

Я изучаю vtk. js и пытаюсь манипулировать файлом vti с помощью объектной архитектуры, но у меня есть некоторые проблемы с камерой. Когда я пытаюсь визуализировать трехмерный вид моего файла vti, он работает отлично, но когда я пробую вид срезов, он работает, но каждый раз, когда я изменяю прозрачность или срезы с помощью мыши, это вызывает у меня массу ошибок в консоли: «Неверный или отсутствует input 'and' No input 'в myfilename. js: отформатирован: 207.

Я знаю, что это как-то связано с тем, что я не объявляю свой рендерер и окно рендеринга в одном блоке как мои операции нарезки, но это работает для моего трехмерного изображения, поэтому я не понимаю.

Спасибо за ваше время.

import vtkFullScreenWindow from 'vtk.js/Sources/Rendering/Misc/FullScreenRenderWindow';


import vtkActor from 'vtk.js/Sources/Rendering/Core/Actor';
import vtkMapper from 'vtk.js/Sources/Rendering/Core/Mapper';

import vtkHttpDataSetReader from 'vtk.js/Sources/IO/Core/HttpDataSetReader';

import vtkColorTransferFunction from 'vtk.js/Sources/Rendering/Core/ColorTransferFunction';
import vtkColorMaps from 'vtk.js/Sources/Rendering/Core/ColorTransferFunction/ColorMaps';
import vtkPiecewiseFunction from 'vtk.js/Sources/Common/DataModel/PiecewiseFunction';


import vtkVolume from 'vtk.js/Sources/Rendering/Core/Volume';
import vtkVolumeMapper from 'vtk.js/Sources/Rendering/Core/VolumeMapper';
import vtkOutlineFilter   from 'vtk.js/Sources/Filters/General/OutlineFilter'


import vtkImageSlice from 'vtk.js/Sources/Rendering/Core/ImageSlice'
import vtkImageMapper from 'vtk.js/Sources/Rendering/Core/ImageMapper'

import vtkInteractorStyleImage from 'vtk.js/Sources/Interaction/Style/InteractorStyleImage'
import ImageConstants from 'vtk.js/Sources/Rendering/Core/ImageMapper/Constants'


import { AttributeTypes } from 'vtk.js/Sources/Common/DataModel/DataSetAttributes/Constants';
import { FieldDataTypes } from 'vtk.js/Sources/Common/DataModel/DataSet/Constants';

const { SlicingMode } = ImageConstants;

import controlPanel from './controller.html';
import {render} from "vtk.js/Sources/Widgets/Core/WidgetManager/vdom";
var mapPreset = require('../node_modules/vtk.js/Sources/Rendering/Core/ColorTransferFunction/ColorMaps.json')


class ThreeDViewer{
    constructor() {
        this.actor = vtkVolume.newInstance();
        this.mapper = vtkVolumeMapper.newInstance();

        this.actor.setMapper(this.mapper);
        console.log('3dViewer initialised.');
    }
}

class SliceViewer{
    constructor() {
        this.actor = vtkImageSlice.newInstance();
        this.mapper = vtkImageMapper.newInstance();
        this.istyle = vtkInteractorStyleImage.newInstance();

        this.mapper.setSliceAtFocalPoint(true);
        this.mapper.setSlicingMode(SlicingMode.Z);

        this.actor.setMapper(this.mapper);

        this.actor.getProperty().setColorWindow(255);
        this.actor.getProperty().setColorLevel(127);


        this.istyle.setInteractionMode('IMAGE_SLICING');

        console.log('SliceViewer initialised.');
    }
}

class filterManager{
    constructor() {
        this.filter = vtkOutlineFilter.newInstance();
        this.actor = vtkActor.newInstance();
        this.mapper = vtkMapper.newInstance();
        console.log('FilterManager initialised.');

        this.actor.setMapper(this.mapper);
        this.mapper.setInputConnection(this.filter.getOutputPort());
        console.log('FilterManager set up. Ready to use.');
    }
}

class ReaderManager{
    constructor(dataUrl) {
        this.url = url;
        this.reader = vtkHttpDataSetReader.newInstance({ fetchGzip: true });
    }

    loadData() {
        return new Promise((resolve) => {
            this.reader.setUrl(this.url)
                .then(() => this.reader.loadData())
                .then(() => resolve("DATA LOADED"));
        })

    }
}


class Visualizer{

    constructor(mode, showfilter, mapColorPreset, opacity, dataURL){
        this.mode = mode;
        this.showFilter = showfilter;
        this.mapColorPreset = mapColorPreset;
        this.opacity = opacity;

        this.threeDViewer = new ThreeDViewer();
        this.sliceViewer = new SliceViewer();
        this.filterManager = new filterManager();
        this.readerManager = new ReaderManager(dataURL);

        this.fullScreenRenderer = vtkFullScreenWindow.newInstance();
        this.renderer = this.fullScreenRenderer.getRenderer();
        this.renderWindow = this.fullScreenRenderer.getRenderWindow();

        console.log('Visualizer initialised.');

        this.updateMode(this.mode);
        console.log('Visualizer mode set up.');

        this.updateOpacity();
        console.log('Visualizer opacity set up.');
        console.log(this.showProperties());
        this.updateFilter();
        console.log('Visualizer filter set up.');

        this.updateMapColorPreset();
        console.log('Visualizer map preset set up.');

    }

    showProperties(){
        return 'Visualizer for: ' + this.readerManager.url
            + ' in mode ' + this.mode
            + '. Color preset: ' + this.mapColorPreset
            + '. Opacity: ' + this.opacity
            + '. Filter: ' + this.showFilter;
    }

    updateMode(mode) {



        switch(mode){
            case '3d':
                this.threeDViewer.mapper.setInputConnection(this.readerManager.reader.getOutputPort());
                this.filterManager.filter.setInputConnection(this.readerManager.reader.getOutputPort());

                this.readerManager.loadData()
                    .then(() => {
                        this.renderer.addVolume(this.threeDViewer.actor);

                        this.showRenderer();
                    });

                break;
            case 'Slicing':


                this.sliceViewer.mapper.setInputConnection(this.readerManager.reader.getOutputPort());

                this.readerManager.loadData()
                    .then(() => {
                        this.renderer.addActor(this.sliceViewer.actor);

                        this.showRenderer();
                    });

                break;

                default:
                console.log('This mode doesn`\'t exist');
        }
    }

    showRenderer(){
        console.log('try render');

        this.renderer.resetCamera();
        console.log('Reset camera. Done.');

        this.renderWindow.render();
        console.log('Rendering Data. Done.');
    }

    updateOpacity(){
        const piecewisefun = vtkPiecewiseFunction.newInstance();

        for (let i = 0; i <= 8; i++){
            piecewisefun.addPoint(i * 32, i / 8 + this.opacity);
        }

        this.threeDViewer.actor.getProperty().setScalarOpacity(0, piecewisefun);
    }

    updateFilter(){
        if (this.showFilter){
            this.renderer.addActor(this.filterManager.actor);
        }else{
            this.renderer.removeActor(this.filterManager.actor);
        }
    }

    updateMapColorPreset(){
        if (this.mapColorPreset == '') {
            const lookupTable = vtkColorTransferFunction.newInstance();

            lookupTable.removeAllPoints();

            this.threeDViewer.actor.getProperty().setRGBTransferFunction(0, lookupTable);
        } else {
            const lookupTable = vtkColorTransferFunction.newInstance();

            lookupTable.applyColorMap(vtkColorMaps.getPresetByName(this.mapColorPreset));
            lookupTable.setMappingRange(0, 256);
            lookupTable.updateRange()

            this.threeDViewer.actor.getProperty().setRGBTransferFunction(0, lookupTable);
        }
    }
}

//Main
const url  = 'https://kitware.github.io/vtk-js/data/volume/LIDC2.vti';
let visualizationManager = new Visualizer('Slicing', 'true', '', '0', url);

visualizationManager.fullScreenRenderer.addController(controlPanel);
const opacitySelector = document.querySelector('#opacity');
const filterSelector = document.querySelector('#filter');
const colorSelector = document.querySelector('#colorTransfers');

//Adding all mapPreset for vtkColorTransferFunction to HTML selector
mapPreset = JSON.parse(JSON.stringify(mapPreset));

for (let i=0; i<mapPreset.length; i++){

    if (mapPreset[i].RGBPoints != null){
        const opt = document.createElement('option');

        opt.appendChild(document.createTextNode(mapPreset[i].Name));
        opt.value = mapPreset[i].Name;

        console.log('Adding: ' + opt.value);

        colorSelector.appendChild(opt);
    }else{
        console.log('Removing: ' + mapPreset[i].Name);
    }
}

opacitySelector.addEventListener('change', (e) => {
    const newOpacityValue = Number(e.target.value) / 1000;
    console.log('newOpacityValue :' + newOpacityValue);

    visualizationManager.opacity = newOpacityValue;
    visualizationManager.updateOpacity();

    visualizationManager.showRenderer();
});

filterSelector.addEventListener('change', (e) => {
    const newFilterValue = Boolean(e.target.checked);
    console.log(Boolean(e.target.checked));

    visualizationManager.showFilter = newFilterValue;
    visualizationManager.updateFilter();

    visualizationManager.showRenderer();
});

colorSelector.addEventListener('change', (e) => {
    const newColorValue = String(e.target.value);
    console.log('newColorValue :', newColorValue);

    visualizationManager.mapColorPreset = newColorValue;
    visualizationManager.updateMapColorPreset();

    visualizationManager.showRenderer();
});
...