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 ...
随机推荐
- Petri网
Petri网是一种适合于系统描述和分析的数学模型,主要描述异步和并发关系.(或者Petri网是对离散并行系统的数学表示,适用于描述异步的,并发的计算机系统模型.) Petri网模型自然,直观,简单易懂 ...
- 细思极恐-你真的会写java吗?
导语 自2013年毕业后,今年已经是我工作的第4个年头了,总在做java相关的工作,终于有时间坐下来,写一篇关于java写法的一篇文章,来探讨一下如果你真的是一个java程序员,那你真的会写java吗 ...
- Java hashCode() 和 equals()的若干问题解答<转载自skywang12345>
第1部分 equals() 的作用equals()的作用是用来判断两个对象是否相等.equals()定义在JDK的Object类中.通过判断两个对象的地址是否相等(即,是否是同一个对象)来区分它们是否 ...
- C#如何使用SplitContainer控件实现上下分隔
C#如何使用SplitContainer控件实现上下分隔 Orientation 属性设置为Horizontal 完美世界 http://www.23cat.com/Contents_51864.ht ...
- Java vs C++ (7)导入
用法 import VS include Java import java.util.regex.Pattern; package com.slim; (1)假设少了; 会warning: C++ ...
- [leetcode]Wildcard Matching @ Python
原题地址:https://oj.leetcode.com/problems/wildcard-matching/ 题意: Implement wildcard pattern matching wit ...
- shell脚本用crontab执行和手动执行结果不一致
加上 PATH=/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin 这行就好了, shell首部用 #!/usr/bin/env bash 这个移植性更 ...
- JavaScript 从闭包可以做什么开始,将有助于理解闭包
本文内容 函数内部访问全局变量 函数外部不能直接访问局部变量 函数外部访问局部变量 保护私有成员 持久性 模块化 抽象性 闭包是 JavaScript 的重要特性,非常强大,可用于执行复杂的计算,可并 ...
- ImageLoader初始化以及调用
1.首先在当前程序的Application中调用ImageLoader的初始化init()方法 [java] view plain copy private void initImageLoader( ...
- Office 超级录屏如何旋转视频90度之后保存
打开视频转换专家 添加视频后点击编辑,然后在旋转的地方设置旋转,应用 输出可以正常播放