在vtk.js学习笔记(1)中搭建好了vtk.js的开发环境,并绘制了一个圆锥,这篇笔记将通过绘制一个带深度信息的纹理图继续学习vtk.js,实际效果如下图所示。
1、通过vtkElevationReader实现带深度信息的纹理映射
import vtkTexture from 'vtk.js/Sources/Rendering/Core/Texture'; import vtkElevationReader from 'vtk.js/Sources/IO/Misc/ElevationReader'; import vtkMapper from 'vtk.js/Sources/Rendering/Core/Mapper'; import vtkActor from 'vtk.js/Sources/Rendering/Core/Actor'; import vtkFullScreenRenderWindow from 'vtk.js/Sources/Rendering/Misc/FullScreenRenderWindow'; const img = new Image(); img.onload = function() { const texture = vtkTexture.newInstance(); texture.setInterpolate(true); texture.setImage(img); actor.addTexture(texture); }; img.src = `./img/dem.jpg`; const reader = vtkElevationReader.newInstance({ xSpacing: 0.01568, ySpacing: 0.01568, zScaling: 0.06666, }); reader.setUrl(`./img/dem.csv`); const mapper = vtkMapper.newInstance(); mapper.setInputConnection(reader.getOutputPort()); const actor = vtkActor.newInstance(); actor.setMapper(mapper); const fullScreenRenderer = vtkFullScreenRenderWindow.newInstance({ background: [0, 0, 0] }); const renderer = fullScreenRenderer.getRenderer(); renderer.addActor(actor); renderer.resetCamera(); const renderWindow = fullScreenRenderer.getRenderWindow(); renderWindow.render();
webpack.config.js内容如下:
const path = require('path'); const vtkRules = require('vtk.js/Utilities/config/dependency.js').webpack.v2.rules; const entry = path.join(__dirname, './src/index.js'); const sourcePath = path.join(__dirname, './src'); // 也可用path.resolve(__dirname,'dist') const outputPath = path.join(__dirname, './dist'); module.exports = { mode: 'development', // 入口文件的配置项 entry, // 控制台报错信息 devtool: 'inline-source-map', // 出口文件的配置项 output:{ // 输出的路径 path: outputPath, // 输出的文件名称 filename: 'bundle.js' }, // 模块:例如解读CSS,图片如何转换,压缩 module: { rules: [ { test: entry, loader: 'expose-loader?app' }, { test: /\.html$/, loader: 'html-loader' }, ].concat(vtkRules) }, // 插件,用于生产模版和各项功能 plugins:[], // 配置webpack开发服务功能 devServer:{}, resolve: { modules: [ path.resolve(__dirname, 'node_modules'), sourcePath ] } }
上面第一个module没有“s”,resolve中的是“modules”!
package.json内容如下:
{ "name": "vtkjs", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "webpack", "build:release": "webpack -p", "start": "webpack-dev-server --content-base ./dist", "commit": "git cz", "semantic-release": "semantic-release" }, "author": "", "license": "ISC", "dependencies": { "vtk.js": "^6.4.22" }, "devDependencies": { "kw-web-suite": "^6.0.2" } }
运行npm run build命令,cd到dist文件夹下,运行http-server(需先npm install http-server或用webpack dev-server),打开http://127.0.0.1:8080/,黑屏。
2、原因分析及改进
img.onload及reader.setUrl中使用回调函数,当renderWindow.render()执行完成后图片及深度信息才加载完毕,而未被窗口渲染,因此应在img.onload()和reader.setUrl().then()中添加窗口渲染并将fullScreenRenderer、renderer和renderWindow的声明前移,修改如下。
import vtkTexture from 'vtk.js/Sources/Rendering/Core/Texture'; import vtkElevationReader from 'vtk.js/Sources/IO/Misc/ElevationReader'; import vtkMapper from 'vtk.js/Sources/Rendering/Core/Mapper'; import vtkActor from 'vtk.js/Sources/Rendering/Core/Actor'; import vtkFullScreenRenderWindow from 'vtk.js/Sources/Rendering/Misc/FullScreenRenderWindow'; const fullScreenRenderer = vtkFullScreenRenderWindow.newInstance({ background: [0, 0, 0] }); const renderer = fullScreenRenderer.getRenderer(); const renderWindow = fullScreenRenderer.getRenderWindow(); const img = new Image(); img.onload = function() { const texture = vtkTexture.newInstance(); texture.setInterpolate(true); texture.setImage(img); actor.addTexture(texture); renderWindow.render(); }; img.src = `./img/dem.jpg`; const reader = vtkElevationReader.newInstance({ xSpacing: 0.01568, ySpacing: 0.01568, zScaling: 0.06666, }); reader.setUrl(`./img/dem.csv`) .then(function() { renderer.resetCamera(); renderWindow.render(); }); const mapper = vtkMapper.newInstance(); mapper.setInputConnection(reader.getOutputPort()); const actor = vtkActor.newInstance(); actor.setMapper(mapper); renderer.addActor(actor); renderer.resetCamera(); renderWindow.render();
3、在浏览器console中查看及修改
当试图在浏览器console中修改actor信息时,报错如下。
解决办法是在index.js文件的最后附加以下代码,即可在console中查看或修改相应的属性。
global.reader = reader; global.mapper = mapper; global.actor = actor; global.renderer = renderer; global.renderWindow = renderWindow;
完整程序见我的github,具体步骤为:
step1 新建文件夹,cmd输入git clone [email protected]:orangecsy/vtkjs-exercise.git,cd 2进入文件夹2;
step2 cmd输入npm run build;
step3 cd dist进入dist文件夹,cmd中输入http-server(需先npm install http-server)或使用webpack配置开发服务器;
step4 浏览器中输入http://127.0.0.1:8080/,即为结果。