The article shows how to create a simple vtk render window project and show it in the web browser. We need emscripten tool and the visualization toolkit installed.
emscripten : https://emscripten.org/docs/getting_started/downloads.html
VTK: https://vtk.org/

Build the VTK source to get JS library before our coding.

This example uses C plus plus programming language to create and show a cone in the 3D world.

CMakeLists.txt

project(wasmTester)

if (VTK_VERSION VERSION_LESS "8.9") #"9.0.3"
    find_package( VTK REQUIRED )
else ()
    find_package( VTK COMPONENTS vtkCommonCore vtkRenderingCore
        vtkInteractionStyle vtkRenderingOpenGL2 vtkFiltersSources
        vtkRenderingFreeType IOGeometry )
endif()

include_directories(
    ${CMAKE_CURRENT_BINARY_DIR}
    ${CMAKE_CURRENT_SOURCE_DIR}
)

if(EMSCRIPTEN)
  set(emscripten_options)
  list(APPEND emscripten_options
    "--bind"
    "-O3"
    "-g"
    "-DLOG_OFF"
    "SHELL:-s USE_SDL=2"
    "SHELL:-s EXPORTED_RUNTIME_METHODS=['allocate,stringToUTF8,UTF8ToString,FS,intArrayFromString']"
    "SHELL:-s EXTRA_EXPORTED_RUNTIME_METHODS=['ALLOC_NORMAL']"
    "SHELL:-s -fdebug-compilation-dir=."
    "SHELL:-s EXPORT_NAME=tester"
    "SHELL:-s ALLOW_MEMORY_GROWTH=1"
    "SHELL:-s DEMANGLE_SUPPORT=1"
    "SHELL:-s EMULATE_FUNCTION_POINTER_CASTS=0"
    "SHELL:-s ERROR_ON_UNDEFINED_SYMBOLS=0"
    "SHELL:-s MODULARIZE=1"
    "SHELL:-s WASM=1"
    "SHELL:-s --no-heap-copy"
    "SHELL:-s INITIAL_MEMORY=200MB"
    "SHELL:-s MAXIMUM_MEMORY=512MB"
    "SHELL:-s ASSERTIONS=2"
    "SHELL:-s TOTAL_MEMORY=512MB"
    "SHELL:-s DISABLE_EXCEPTION_CATCHING=0"
  )
    message("Configuring data directory for wasm..........")
endif()

set( cpps 
    main.cpp
    )

add_executable(${PROJECT_NAME} ${cpps})

if (VTK_VERSION VERSION_LESS "8.9")
  # old system
  include(${VTK_USE_FILE})
else ()
  # vtk_module_autoinit is needed
  message("autoinit module for higher version vtk")
  vtk_module_autoinit(
    TARGETS ${PROJECT_NAME}
    MODULES ${VTK_LIBRARIES}
    )
endif ()

target_compile_options(${PROJECT_NAME}
  PUBLIC
    ${emscripten_options}
)

target_link_options(${PROJECT_NAME}
  PUBLIC
    ${emscripten_options}
)

target_link_libraries( ${PROJECT_NAME} ${VTK_LIBRARIES} ${LINK_FLAGS} )

# -----------------------------------------------------------------------------
# Copy HTML to build directory
# -----------------------------------------------------------------------------

add_custom_command(
  TARGET ${PROJECT_NAME}
  POST_BUILD
  COMMAND
    ${CMAKE_COMMAND} -E copy_if_different
      "${CMAKE_CURRENT_SOURCE_DIR}/index.html"
      $<TARGET_FILE_DIR:wasmTester>
)

main.cpp

#include <iostream>
#include <vtkSmartPointer.h>
#include <vtkSphereSource.h>
#include <vtkActor.h>
#include <vtkConeSource.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkPolyDataMapper.h>
#include <vtkRenderWindowInteractor.h>

#ifdef __EMSCRIPTEN__
#include "vtkSDL2OpenGLRenderWindow.h"
#include "vtkSDL2RenderWindowInteractor.h"
#endif // __EMSCRIPTEN__


#define vtkSPtr vtkSmartPointer
#define vtkSPtrNew(Var, Type) vtkSPtr<Type> Var = vtkSPtr<Type>::New();

using namespace std;

int main()
{
    vtkSPtrNew( cone, vtkConeSource );
    vtkSPtrNew( mapper, vtkPolyDataMapper );
    mapper->SetInputConnection( cone->GetOutputPort() );

    vtkSPtrNew( actor, vtkActor );
    actor->SetMapper( mapper );

    vtkSPtrNew( renderer, vtkRenderer );
    renderer->AddActor(actor);
    renderer->SetBackground( 0, 0, 0 );

#ifdef __EMSCRIPTEN__
    vtkSPtrNew(renderWindow, vtkSDL2OpenGLRenderWindow);
#else
    vtkSPtrNew(renderWindow, vtkRenderWindow);
#endif
    renderWindow->AddRenderer( renderer );

#ifdef __EMSCRIPTEN__
    vtkSPtrNew(renderWindowInteractor, vtkSDL2RenderWindowInteractor);
#else
    vtkSPtrNew(renderWindowInteractor, vtkRenderWindowInteractor);
#endif
    renderWindowInteractor->SetRenderWindow( renderWindow );

    renderer->ResetCamera();
    renderWindow->Render();
    renderWindowInteractor->Start();
    return 0;
}

index.html

<html>
   <head>
      <!-- Load WebAssembly module -->
      <script type="text/javascript" src="wasmTester.js"></script>
   </head>
   <body>
      <canvas id="canvas" style="position: absolute; left: 0; top: 0; width:100%; height:100%"></canvas>

      <script>
        var Module = {
            canvas: (function() {
                var canvas = document.getElementById('canvas');
                canvas.addEventListener(
                "webglcontextlost",
                function(e) {
                    console.error('WebGL context lost. You will need to reload the page.');
                    e.preventDefault();
                },
                false
                );
                return canvas;
            })(),
            onRuntimeInitialized:  function() {
                console.log('initialized');
            },
        };

        var app = tester(Module);
        console.log('App created');
      </script>
   </body>
</html>

After cmake and make, we can set up a simple http service to watch the result.

python3 -m http.server 4000

The code files tree:

Categories: VTK

0 0 votes
Article Rating
Subscribe
Notify of
guest

4 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
logan
logan
1 year ago

how can I generate wasm file with js file? I used emcmake, but it didn’t generate them..

nghiaphamsg
nghiaphamsg
4 months ago

Thank you for your useful shares.
I’m trying to integrate vtk-wasm into a Reactjs project but getting a lot of errors. Can you make a sample?

Tex To PDF
: convert the Latex file which suffix is tex to a PDF file

X
4
0
Would love your thoughts, please comment.x
()
x