在vtk.js学习笔记(1)中搭建好了vtk.js的开发环境,并绘制了一个圆锥。这篇笔记将通过绘制一个带深度信息的纹理图继续学习vtk.js,实际效果如下图所示。

demopic

1、通过vtkElevationReader实现带深度信息的纹理映射

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{  
"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的声明前移,修改如下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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信息时,报错如下。
errpic
解决办法是在index.js文件的最后附加以下代码,即可在console中查看或修改相应的属性。

1
2
3
4
5
global.reader = reader;  
global.mapper = mapper;
global.actor = actor;
global.renderer = renderer;
global.renderWindow = renderWindow;

完整程序见我的github,具体步骤为:
step1 新建文件夹,cmd输入git clone git@github.com: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/,即为结果。