ETC

vtkRenderWindow를 div에 연결하기 - Vue

leonhong 2022. 5. 24. 18:18

 vtkRenderWindow를 HTML에 출력하려고 하면 가장 좋은 태그는 div 일 것입니다. 그런데 div에 연결하는것이 조금 복잡합니다. 

 아래의 그림이 div를 vtkRenderWindow에 연결하는 구조도입니다. 

 HTML의 div 태그는 먼저 vtkOpenGLRenderWindow의 setContainer 함수를 통해 설정됩니다. 그 후에 vtkRenderWindow의 addView 함수를 통해서 VTK 구조와 연결됩니다.

 PC기반의 VTK를 사용할때에 비하면 vtkRenderWindow와 vtkOpenGLRenderWindow가 함께 존재해서 햇갈리기는 하지만, vtk.js는 이렇게 쓴다고 하니 적응해야죠 ㅠㅠ.

 

 

아래는 div에 vtk.js를 연결한 코드입니다.(Vue3 Composition API를 활용한 예제)

<template>
  <div>
    <div style="width:300px; height:300px; background-color:#C00" ref="vtkContainer" />
  </div>
</template>

<script>
import { ref, onMounted, onBeforeUnmount, watchEffect } from 'vue';

import '@kitware/vtk.js/Rendering/Profiles/Geometry';

import vtkOpenGLRenderWindow from '@kitware/vtk.js/Rendering/OpenGL/RenderWindow';
import vtkRenderWindow from '@kitware/vtk.js/Rendering/Core/RenderWindow';
import vtkRenderer from '@kitware/vtk.js/Rendering/Core/Renderer';
import vtkRenderWindowInteractor from '@kitware/vtk.js/Rendering/Core/RenderWindowInteractor';
import vtkInteractorStyleTrackballCamera from '@kitware/vtk.js/Interaction/Style/InteractorStyleTrackballCamera';

import vtkActor           from '@kitware/vtk.js/Rendering/Core/Actor';
import vtkMapper          from '@kitware/vtk.js/Rendering/Core/Mapper';
import vtkConeSource      from '@kitware/vtk.js/Filters/Sources/ConeSource';

export default {
  name: 'HelloWorld',

  setup() {
    const vtkContainer = ref(null);
    const context = ref(null);

    watchEffect(() => {
      if (context.value) {
        const { renderWindow } = context.value;
        renderWindow.render();
      }
    });

    onMounted(() => {

      if (!context.value) {
        // Renderer와 RenderWindow 생성하여 연결
        const renderer = vtkRenderer.newInstance({ background: [0.2, 0.3, 0.4] });
        const renderWindow = vtkRenderWindow.newInstance();
        renderWindow.addRenderer(renderer);

        // div 요소에 RenderWindow를 적용하기 위해
        // 중간 매개인 OpenGLRenderWindow 생성하여 연결
        const openGLRenderWindow = vtkOpenGLRenderWindow.newInstance();
        renderWindow.addView(openGLRenderWindow);

        // div 요소에 RenderWindow 적용하기
        // Vue3 Conposition API 방식에서는 div 요소를 가져오려면 ref 이름을 맞춰주면 된다.
        openGLRenderWindow.setContainer(vtkContainer.value)
        const { width, height } = vtkContainer.value.getBoundingClientRect();
        openGLRenderWindow.setSize(width, height);

        // Interactor Renderer에 설정
        const interactor = vtkRenderWindowInteractor.newInstance();
        interactor.setView(openGLRenderWindow);
        interactor.initialize();
        interactor.bindEvents(vtkContainer.value);

        interactor.setInteractorStyle(vtkInteractorStyleTrackballCamera.newInstance());

        // Src - Mapper - Actor 생성후 Renderer에 추가
        const coneSource = vtkConeSource.newInstance({ height: 1.0 });

        const mapper = vtkMapper.newInstance();
        mapper.setInputConnection(coneSource.getOutputPort());

        const actor = vtkActor.newInstance();
        actor.setMapper(mapper);

        renderer.addActor(actor);
        renderer.resetCamera();
        renderWindow.render();

        context.value = {
          renderer,
          renderWindow,  
          openGLRenderWindow,        
          coneSource,
          actor,
          mapper,
          interactor,
        };
      }
    });

    onBeforeUnmount(() => {
      if (context.value) {
        const { renderer, renderWindow, openGLRenderWindow, coneSource, 
          actor, mapper, interactor } = context.value;
        actor.delete();
        mapper.delete();
        coneSource.delete();
        interactor.delete();
        renderer.delete();
        openGLRenderWindow.delete();
        renderWindow.delete();
        context.value = null;
      }
    });

    return {
      vtkContainer,
    };
  }
}
</script>

출력결과는 다음과 같습니다. 

 

div 요소에 vtk 연결

 

'ETC' 카테고리의 다른 글

HTML 비디오 테스트  (0) 2024.07.18
수학 관련 용어  (0) 2023.04.26
BCI 관련 자료들  (0) 2021.12.20
Simple Volume Rendering App - React  (0) 2021.12.11
Volume Rendering - React  (0) 2021.12.05