vtk file in DATASET UNSTRUCTURED_GRID format

Hi all has anyone ever used vtk Js in Vue with vtk files in DATASET UNSTRUCTURED_GRID format? I can’t get it to set up a viewer.

This is my code can you help me improve it and make it able to display any vtk or vtu format please.

<template>
	<div class="flex flex-col items-center justify-start h-screen">
		<!-- Header Section with Inputs -->
		<div
			class="flex flex-row items-center space-x-4 mb-4 p-4 bg-gray-100 shadow-md z-10">
			<!-- Container for the table with select and range input -->
			<div class="bg-white p-4 shadow-md">
				<table class="w-full">
					<tbody>
						<tr>
							<td>
								<select
									class="w-full border border-gray-300 p-2 rounded-md"
									:value="representation"
									@change="
										(event: Event) =>
											setRepresentation(
												(event.target as HTMLSelectElement).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"
									class="w-full mt-4"
									:value="coneResolution"
									@input="
										(event: Event) =>
											setConeResolution(
												(event.target as HTMLInputElement).value,
											)
									" />
							</td>
						</tr>
					</tbody>
				</table>
			</div>

			<!-- File input -->
			<div>
				<input
					type="file"
					@change="onFileChange"
					accept=".vtk, .vtu"
					class="p-2 border border-gray-300 rounded-md text-base" />
			</div>
		</div>

		<!-- VTK container with fixed size -->
		<div ref="vtkContainer"></div>
	</div>
</template>

<script setup lang="ts">
import { onMounted, ref } from "vue";
import "@kitware/vtk.js/favicon";
import "@kitware/vtk.js/Rendering/Profiles/Geometry";
import vtkActor from "@kitware/vtk.js/Rendering/Core/Actor";
import vtkFullScreenRenderWindow from "@kitware/vtk.js/Rendering/Misc/FullScreenRenderWindow";
import vtkMapper from "@kitware/vtk.js/Rendering/Core/Mapper";
import vtkPolyDataReader from "@kitware/vtk.js/IO/Legacy/PolyDataReader";
import vtkXMLPolyDataReader from "@kitware/vtk.js/IO/XML/XMLPolyDataReader"; // Import per vtu

const coneResolution = ref(6);
const representation = ref(2);
let actor: any = null;
let mapper = null;

function setConeResolution(res: any) {
	coneResolution.value = Number(res);
	if (actor) {
		actor.getProperty().setPointSize(coneResolution.value);
		render();
	}
}

function setRepresentation(rep: any) {
	representation.value = Number(rep);
	if (actor) {
		switch (representation.value) {
			case 0:
				actor.getProperty().setRepresentationToPoints();
				break;
			case 1:
				actor.getProperty().setRepresentationToWireframe();
				break;
			case 2:
				actor.getProperty().setRepresentationToSurface();
				break;
			default:
				break;
		}
		render();
	}
}

const fullScreenRenderer = vtkFullScreenRenderWindow.newInstance();
const renderer = fullScreenRenderer.getRenderer();
const renderWindow = fullScreenRenderer.getRenderWindow();
const resetCamera = renderer.resetCamera;
const render = renderWindow.render;

// Funzione per gestire il caricamento del file
const onFileChange = (event: Event) => {
	const input = event.target as HTMLInputElement;
	if (input.files && input.files.length > 0) {
		const file = input.files[0];
		const fileReader = new FileReader();

		fileReader.onload = () => {
			const vtkData = fileReader.result as ArrayBuffer;
			try {
				let reader;
				// Determina il tipo di reader in base all'estensione del file
				if (file.name.endsWith(".vtu")) {
					reader = vtkXMLPolyDataReader.newInstance();
					reader.parseAsArrayBuffer(vtkData);
				} else {
					// Per i file .vtk, utilizza vtkPolyDataReader
					reader = vtkPolyDataReader.newInstance();
					reader.parseAsText(vtkData);
				}

				const polydata = reader.getOutputData(0);

				if (!polydata) {
					console.error(
						"Nessun dato di poligono caricato. Controlla il file VTK.",
					);
					return;
				}

				mapper = vtkMapper.newInstance();
				actor = vtkActor.newInstance();

				actor.setMapper(mapper);
				mapper.setInputData(polydata);

				renderer.removeAllActors();
				renderer.addActor(actor);
				resetCamera();
				render();
			} catch (error) {
				console.error("Errore durante il parsing del file VTK:", error);
			}
		};
		fileReader.readAsText(file);
	}
};

onMounted(() => {
	// Logica iniziale, se necessaria
});
</script>

<style scoped></style>

Indeed, VTK.js supports only vtkImageData and vtkPolyData.

The idea behind that limitation is that unstructured grids are typically large and therefore do not make sense to be loaded with a light client.

If you need to visualize large dataset, you might want to consider a remote rendering solution (-> trame). If you still want client-side rendering, you can extract the surface of your unstructured grid for visualization in VTK.js. Alternatively, you can consider VTK.wasm.
Last but not least, adding unstructured grid support in VTK.js is doable, it’s a bit of work though.

And how would you add unstructured grid support in VTK.js, even if it’s a bit laborious could you tell me how to do it?

You would need to create a vtkUnstructuredGrid class similar to vtkPolyData (easy).
You would also need to create vtkXMLUnstructuredGridReader similar to vtkXMLPolyDataReader (easy).
And finally, you would need to write an Unstructured Grid mapper (not easy).
You would need to take example on the Unstructured Grid mapper in VTK C++.