VTK中获取STL模型点的坐标以及对其进行变换
VTK是一个基于面向对象的开源三维绘图软件包,和其它的的三维绘图引擎如OSG、OGRE不同之处在于,VTK可视化对象主要是各种数据,更加注重对数据分析处理后的可视化,可视化的内容是人们无法直接感受到的东西,如地质构造、地层分布、矿床分布、三维空间应力场的状态变化等等,而OSG、OGRE是基于场景的可视化,更强调视觉感官的感受,所以OSG主要应用于虚拟现实领域,而VTK主要应用于科学计算可视化领域。

VTK的可视化设计是基于管线流的设计模式,将要处理的数据作为流动介质在管线中流动,不同的阶段对数据有不同的处理方式,VTK的可视化管线如图所示:

Sources: 数据生成的源头,数据来源主要包括从磁盘读取数据文件,如VTK所支持的各种格式文件生成数据源对象,这种源对象被称为读源对象,或者利用数学方法生成源对象,如利用多个四边形构建一个圆柱体,这种对象被称为程序源对象。
Filters: 对源对象进行处理,生成新的数据集输出。
Mappers: 映射器对象主要作用是将可视化模型生成的数据转换到图形模型进行绘制,或者以磁盘文件的形式进行输出。
渲染对象(vtkRenderer)和渲染窗口(vtkRenderWindow): 渲染对象和渲染窗口分别对应于用于显示图形的视口和窗口。每个渲染窗口可以容纳一个或多个渲染对象。即一个渲染窗口中可以存在多个视口,它们既可以并列也可以分层排放。
如下图所示,用vtkSTLReader读入一个边长为50mm的立方体模型(注意模型不在原点--导出STL文件时选择了自定义的坐标系)。如果是ASCII格式的STL文件可以直接用文本编辑器打开查看立方体各顶点的坐标,在VTK中如何获得这些顶点的坐标位置呢?vtkProp3D类里面有几个函数:GetPosition、GetOrigin、GetCenter不过这些都没办法获取立方体顶点的坐标。不管立方体在坐标系中处于什么位置,只要没调用SetPosition设置新位置,GetPosition都会返回(0, 0, 0)。

import vtk # Create the reader and read a data file.
sr = vtk.vtkSTLReader()
sr.SetFileName("cube.stl")
sr.Update() stlMapper = vtk.vtkPolyDataMapper()
stlMapper.SetInputConnection(sr.GetOutputPort()) stlActor = vtk.vtkLODActor()
stlActor.SetMapper(stlMapper)
#stlActor.SetPosition(-50, 0, 0) p = [0, 0, 0]
polydata = sr.GetOutput()
for i in range(polydata.GetNumberOfPoints()):
polydata.GetPoint(i, p);
print p # Create the Renderer, RenderWindow, and RenderWindowInteractor
ren = vtk.vtkRenderer()
renWin = vtk.vtkRenderWindow()
renWin.AddRenderer(ren)
iren = vtk.vtkRenderWindowInteractor()
iren.SetRenderWindow(renWin) # Add the actors to the render; set the background and size
ren.AddActor(stlActor)
ren.SetBackground(0.1, 0.1, 0.1)
renWin.SetSize(500, 500) # create coordinate axes in the render window
axes = vtk.vtkAxesActor()
axes.SetTotalLength(100, 100, 100) # Set the total length of the axes in 3 dimensions
# Set the type of the shaft to a cylinder:0, line:1, or user defined geometry.
axes.SetShaftType(0)
axes.SetCylinderRadius(0.02)
axes.SetAxisLabels(0)
ren.AddActor(axes) style = vtk.vtkInteractorStyleTrackballCamera()
style.SetDefaultRenderer(ren)
iren.SetInteractorStyle(style) iren.Initialize()
renWin.Render()
iren.Start()
运行后得到如下结果,即立方体8个顶点的实际坐标:
[50.0, 0.0, 100.0]
[50.0, 100.0, 100.0]
[50.0, 0.0, 0.0]
[50.0, 100.0, 0.0]
[150.0, 0.0, 100.0]
[150.0, 0.0, 0.0]
[150.0, 100.0, 100.0]
[150.0, 100.0, 0.0]
如果将注释"#stlActor.SetPosition(-50, 0, 0)"取消,再运行会得到同样的结果。可以发现SetPosition这种操作并不会影响顶点的实际位置,只能控制场景中的演员的位置。vtkActor.SetPosition() simply effects where your actor is rendered, but do not modify any coordinates of the underlying polydata physically. 即VTK中的变换可分为对实际数据的变换和对演员的变换,具体可以参考PPT:Introduction to VTK: Transforms

为了对原始数据进行处理可以添加filter,如下面代码,将原始STL模型中的顶点向X轴负方向平移50mm
transform = vtk.vtkTransform()
transform.Translate(-50, 0, 0)
transformFilter = vtk.vtkTransformPolyDataFilter()
transformFilter.SetInputConnection(sr.GetOutputPort())
transformFilter.SetTransform(transform)
transformFilter.Update()
再次查询立方体的顶点,坐标如下:
[0.0, 100.0, 100.0]
[0.0, 0.0, 0.0]
[0.0, 100.0, 0.0]
[100.0, 0.0, 100.0]
[100.0, 0.0, 0.0]
[100.0, 100.0, 100.0]
[100.0, 100.0, 0.0]
另外需要注意的是可视化管道使用惰性计算策略(lazy evaluation scheme): 直到需要数据(或被强制)时,可视化管道才会产生数据,产生的数据是最新的。对数据的需求由Update()方法提出,这一方法可以显示调用,也可以由图形流水线中演员对象(Actor)的Render()方法自动调用。对数据的需求会逆着流水线的方向传递,如果某一部分的数据过时(通过检查时间标签),可视化流水线中的过滤器会重新执行,最新生成的数据沿着流水线传递给演员(Actor)。
在上面的代码中如果实例化vtkSTLReader后,直接调用GetNumberOfPoints方法获取STL模型顶点的数目,会返回0,尽管这个模型包含了8个顶点。出现这样的原因是因为GetNumberOfPoints()方法没有被要求执行,而使用Update()方法强制了流水线的执行,因此会返回8。
参考:
VTK/Examples/Cxx/PolyData/PolyDataGetPoint
Visualization Toolkit ( VTK ) Tutorial
Introduction to VTK: Transforms
how to get the world coordinate of a Prop?
what's the difference between actor 's position and sphere 's center ?
VTK中获取STL模型点的坐标以及对其进行变换的更多相关文章
- jQuery中获取相对文档的坐标的方法是什么?
offset(),获取匹配元素在当前视口的相对偏移.返回的对象包含两个整型属性:top 和 left,以像素计.此方法只对可见元素有效. position()获取匹配元素相对定位父级的偏移.没有定位父 ...
- VTK中导入并显示STL、3DS文件
VTK(visualization toolkit)是一个开源的免费软件系统,主要用于三维计算机图形学.图像处理和科学计算可视化.VTK是在三维函数库OpenGL 的基础上采用面向对象的设计方法发展起 ...
- 《Entity Framework 6 Recipes》中文翻译系列 (40) ------ 第七章 使用对象服务之从跟踪器中获取实体与从命令行生成模型(想解决EF第一次查询慢的,请阅读)
翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 7-5 从跟踪器中获取实体 问题 你想创建一个扩展方法,从跟踪器中获取实体,用于数 ...
- ionic中获取坐标方法
ionic中获取坐标的方法 1.首相需要执行命令: cordova plugin add cordova-plugin-geolocation2.然后块级注入配置bower文件引入ngCordova ...
- 37 VTK中的坐标系系统
0 引言 在利用PCL的交互功能解决尺寸关联几何的指定问题时,涉及到一些显示上的操作.目前的需求是:将投影到注释平面上的点云,以与屏幕平齐的方式,显示在屏幕正中,这样方便用户进行操作.但是,在运用se ...
- 机器学习数据集,主数据集不能通过,人脸数据集介绍,从r包中获取数据集,中国河流数据集
机器学习数据集,主数据集不能通过,人脸数据集介绍,从r包中获取数据集,中国河流数据集 选自Microsoft www.tz365.Cn 作者:Lee Scott 机器之心编译 参与:李亚洲.吴攀. ...
- VTK中的装配体(vtkAssembly)
Actors有时也会组合在一起形成层次结构,当其中的某个Actor运动时,会影响到其他Actor的位置.例如,一个机械手臂可能由上臂.前臂.手腕和末端等部分通过关节连接起来.当上臂绕着肩关节旋转时,我 ...
- 整理下PC和移动获取点击、移动坐标的代码和坑
一.PC PC是通过鼠标点击和移动,相对比较简单,比如onmousedown.onmouseup.onmousemove.onmouseout鼠标按键按下.按键起来.鼠标在元素上移动.鼠标从元素上离开 ...
- android 中获取当前焦点所在屏幕中的位置 view.getLocationOnScreen(location)
final int[] location = new int[2]; view.getLocationOnScreen(location); final int[] location = new in ...
随机推荐
- Docker配置国内加速器加速镜像下载的方法
在搭建hyperledger fabric的开发环境的时候,用docker去下载镜像,好慢好慢,慢到下了一个下午没有下载完成,最后还是失败了.最后去网上找了一下,发现有配置国内加速器加速镜像下载的方法 ...
- ArrayBlockingQueue, LinkedBlockingQueue, ConcurrentLinkedQueue, RingBuffer
1. ArrayBlockingQueue, LinkedBlockingQueue, ConcurrentLinkedQueue ArrayBlockingQueue, LinkedBlocking ...
- 混合开发 Hybird Ionic Angular Cordova web 跨平台 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- Unicode与JavaScript详解 [很好的文章转]
上个月,我做了一次分享,详细介绍了Unicode字符集,以及JavaScript语言对它的支持.下面就是这次分享的讲稿. 一.Unicode是什么? Unicode源于一个很简单的想法:将全世界所有的 ...
- 最小二乘法多项式曲线拟合原理与实现 zz
概念 最小二乘法多项式曲线拟合,根据给定的m个点,并不要求这条曲线精确地经过这些点,而是曲线y=f(x)的近似曲线y= φ(x). 原理 [原理部分由个人根据互联网上的资料进行总结,希望对大家能有用] ...
- python3 验证码图片切割
切割前图片 切割后四个图片 代码 #coding:utf8 import os from PIL import Image,ImageDraw,ImageFile import numpy impor ...
- python2.7 调用 .net的webservice asmx
首先安装pip install suds 或下载:https://pypi.org/project/suds-jurko/0.6/#files 这个是最新版本 由于不支持python3.6, 所以只能 ...
- ICTCLAS中的HMM人名识别
http://www.hankcs.com/nlp/segment/ictclas-the-hmm-name-recognition.html 本文主要从代码的角度分析标注过程中的细节,理论谁都能说, ...
- Java-JUC(三):原子性变量与CAS算法
原子性 并发程序正确地执行,必须要保证原子性.可见性以及有序性.只要有一个没有被保证,就有可能会导致程序运行不正确. 原子性:一个操作或多个操作要么全部执行完成且执行过程不被中断,要么就不执行. 可见 ...
- docker service ps打印出来的错误信息被截断了怎么办?
[解决方法] 用Format属性: 这个其实解决不了截断的问题,不过可以显示更少的列,看起来更清楚. Formatting The formatting options (--format) pr ...