Kitware / vtk-js

Visualization Toolkit for the Web
https://kitware.github.io/vtk-js/
BSD 3-Clause "New" or "Revised" License
1.23k stars 371 forks source link

Angular 8 + vtk.js #1313

Closed aminechir closed 3 years ago

aminechir commented 4 years ago

Hi,

I am using vtkjs in Angular web projects.

In the old versions of Angular, we had access to the webpack.config.js file to edit it and I could then add the rules of vtk.js.

The problem is that in the latest versions, Angular encapsulates webpack in its code (through the angular.json file) and it is now very difficult to edit the webpack of an Angular project.

So I can't do npm install vtk.js.

For the moment to work around the problem, I import the vtk.js library precompiled in app.module.ts. Thus, I can't use 'import ... from vtk.js ...' and I have to update the vtk.js versions by downloading the new release each time

Have people here already been confronted with this problem? Thanks

dannyrb commented 4 years ago

I was under the impression that this was an issue with Angular 7, but not Angular 8. Are you able to use angular-builders?

aminechir commented 4 years ago

I will try with the new version of the angular builders.

doczoidberg commented 4 years ago

@aminechir did you have succes? what did you do?

aminechir commented 3 years ago

Hi,

With the new approach for using vtk.js, with @kitware/vtk.js, we can easily use vtk.js into an angular app. I can close this issue @doczoidberg

Thanks you

Maybe you can add a small example in the vtk.js website for angular apps, as examples you have for react and vue ? @jourdain For those interested in angular example, here are the steps to reproduce a small one:

  1. Install the angular-cli with npm install @angular/cli
  2. Create and initialize your project with ng new my-vtk-app
  3. Replace the content of the file app.component.ts with the following contents:
import { Component, ElementRef, ViewChild } from '@angular/core';
import vtkConeSource from '@kitware/vtk.js/Filters/Sources/ConeSource';
import '@kitware/vtk.js/Rendering/Profiles/Geometry';
import vtkActor from '@kitware/vtk.js/Rendering/Core/Actor';
import vtkInteractorStyleTrackballCamera from '@kitware/vtk.js/Interaction/Style/InteractorStyleTrackballCamera';
import vtkOpenGLRenderWindow from '@kitware/vtk.js/Rendering/OpenGL/RenderWindow';
import vtkRenderWindow from '@kitware/vtk.js/Rendering/Core/RenderWindow';
import vtkRenderWindowInteractor from '@kitware/vtk.js/Rendering/Core/RenderWindowInteractor';
import vtkRenderer from '@kitware/vtk.js/Rendering/Core/Renderer';
import vtkMapper from '@kitware/vtk.js/Rendering/Core/Mapper';

@Component({
  selector: 'app-root',
  template: `
  <div>
    <div #vtkContainerRef>
    </div>
    <table
        style="
          position: 'absolute';
          top: '25px';
          left: '25px';
          background: 'white';
          padding: '12px'"
      >
        <tbody>
          <tr>
            <td>
              <select
                value={{representation}}
                style="width: '100%'"
                (input)=setRepresentation($event.target.value)
              >
                <option value="0">Points</option>
                <option value="1">Wireframe</option>
                <option value="2">Surface</option>
              </select>
            </td>
          </tr>
          <tr>
            <td>
              <input
                type="range"
                min="4"
                max="80"
                value={{resolution}}
                (input)=setConeResolution($event.target.value)
              />
            </td>
          </tr>
        </tbody>
      </table>
  </div>`
})
export class AppComponent {

  coneSource: vtkConeSource;
  actor: vtkActor;
  mapper: vtkMapper;
  renderWindow: vtkRenderWindow;
  interactor: vtkRenderWindowInteractor;
  openglRenderWindow: any;
  resolution: number = 10;
  representation: number = 2;

  @ViewChild('vtkContainerRef') element: ElementRef;

  setRepresentation(representation) {
    this.actor.getProperty().setRepresentation(Number(representation));
    this.renderWindow.render();
  }

  setConeResolution(coneResolution) {
    this.coneSource.setResolution(coneResolution);
    this.renderWindow.render();
  }

  ngAfterViewInit() {

    this.renderWindow = vtkRenderWindow.newInstance();
    this.openglRenderWindow = vtkOpenGLRenderWindow.newInstance();
    this.renderWindow.addView(this.openglRenderWindow);

    const container: HTMLElement = this.element.nativeElement;
    this.openglRenderWindow.setContainer(container);
    this.openglRenderWindow.setSize(window.innerWidth,window.innerHeight);

    this.interactor = vtkRenderWindowInteractor.newInstance();
    this.interactor.setView(this.openglRenderWindow);
    this.interactor.initialize();
    this.interactor.bindEvents(container);
    this.interactor.setInteractorStyle(vtkInteractorStyleTrackballCamera.newInstance());

    this.mapper = vtkMapper.newInstance();
    this.actor = vtkActor.newInstance();
    this.actor.getProperty().setRepresentation(this.representation);

    this.actor.setMapper(this.mapper);
    const renderer = vtkRenderer.newInstance();

    this.coneSource = vtkConeSource.newInstance({ resolution: this.resolution });
    this.mapper.setInputConnection(this.coneSource.getOutputPort());
    renderer.addActor(this.actor);

    this.renderWindow.addRenderer(renderer);
    this.renderWindow.render();
  }

}