使用vtk.js加载vtu格式(UnstructuredGrid)的文件

创建日期:2024-11-02
更新日期:2024-11-03

1、下载并解压ParaView-5.13.1-Windows-Python3.10-msvc2017-AMD64.zip。

下载地址:Download ParaView

2、将ParaView bin目录添加到环境变量。

E:\temp\ParaView-5.13.1-Windows-Python3.10-msvc2017-AMD64\bin

3、安装ParaView对应的Python版本。

下载地址:Python Release Python 3.10.11 ~| Python.org

4、创建vue项目并安装依赖包。

npm create vite@latest
npm install @kitware/vtk.js

5、将 node_modules\@kitware\vtk.js\Utilities\DataGenerator\vtk-data-converter.py 复制到vtu所在的目录。并在from paraview import simple前面添加以下代码。

sys.path.append(
    "E:/temp/ParaView-5.13.1-Windows-Python3.10-msvc2017-AMD64/bin/Lib/site-packages"
)

点此下载修改好的文件。

6、编写convert.py脚本,将vtu转换为vtk.js能加载的格式。

from vtk_data_converter import convert
import json

def convert_model(dir, begin_index, end_index, out_folder, time_delta):
    series = []
    for i in range(begin_index, end_index):
        convert(f"{dir}/{i}step.vtu", f"./public/model/{out_folder}/", True, True)
        series.append({"url": f"{i}step.vtu", "timeStep": time_delta * i})
    index = {"series": series}
    index_file = f"./public/model/{out_folder}/index.json"
    file = open(index_file, "w")
    json.dump(index, file)
    file.close()

def start():
    convert_model("./public/model/raw/流线", 0, 160, "流线", 1)
    convert_model("./public/model/raw/烟粒子", 0, 250, "烟粒子", 1)

if __name__ == "__main__":
    start()

点此下载修改好的文件。

7、在App.vue中编写代码,加载处理好的文件。

<template>
  <div class="timeStep" ref="timeRef"></div>
</template>
<script setup lang="ts">
import { ref } from "vue";
import "@kitware/vtk.js/favicon";
import "@kitware/vtk.js/Rendering/Profiles/Geometry";
import "@kitware/vtk.js/IO/Core/DataAccessHelper/HtmlDataAccessHelper";
import "@kitware/vtk.js/IO/Core/DataAccessHelper/HttpDataAccessHelper";
import "@kitware/vtk.js/IO/Core/DataAccessHelper/JSZipDataAccessHelper";
import vtkFullScreenRenderWindow from "@kitware/vtk.js/Rendering/Misc/FullScreenRenderWindow";
import vtkActor from "@kitware/vtk.js/Rendering/Core/Actor";
// @ts-ignore
import vtkHttpDataSetSeriesReader from "@kitware/vtk.js/IO/Core/HttpDataSetSeriesReader";
import vtkMapper from "@kitware/vtk.js/Rendering/Core/Mapper";

const timeRef = ref<HTMLDivElement | undefined>(undefined);

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

renderer.getActiveCamera().setPosition(5, 5, 5);
renderer.getActiveCamera().setFocalPoint(0, -2, -2);

const reader = vtkHttpDataSetSeriesReader.newInstance({ fetchGzip: true });
reader.setUrl("/model/流线").then(() => {
  const timeSteps = reader.getTimeSteps();

  const updateTimeStep = (index: number) => {
    if (index < timeSteps.length) {
      setTimeout(() => {
        updateTimeStep(index + 1);
      }, 100);
    } else {
      return;
    }
    const newTimeStep = timeSteps[index];
    if (timeRef.value) {
      timeRef.value.textContent = `Current time step: ${index}`;
    }
    reader.setUpdateTimeStep(newTimeStep);
    renderer.resetCameraClippingRange();
    renderWindow.render();
  };

  let index = 0;

  updateTimeStep(index);
});

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

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

renderer.addActor(actor);
</script>
<style scoped>
.timeStep {
  position: absolute;
  left: 0;
  top: 0;
  color: #fff;
  z-index: 100;
}
</style>

8、(重要)由于vite返回的gz后缀的静态文件,会增加Conent-Encoding: gzip标头,导致浏览器自动解压gzip导致报错,需要编辑以下文件:node_modules\@kitware\vtk.js\IO\Core\DataAccessHelper\HttpDataAccessHelper.js,注释掉下面的三行。

            // if (options.compression) {
            //   if (array.dataType === 'string' || array.dataType === 'JSON') {
            //     array.buffer = strFromU8(decompressSync(new Uint8Array(array.buffer)));
            //   } else {
            //     array.buffer = decompressSync(new Uint8Array(array.buffer)).buffer;
            //   }
            // }

点此下载修改好的文件。

简介

一个来自三线小城市的程序员开发经验总结。