zoukankan      html  css  js  c++  java
  • 第04章-VTK基础(4)

    【译者:这个系列教程是以Kitware公司出版的《VTK User’s Guide -11th edition》一书作的中文翻译(出版时间2010年,ISBN: 978-1-930934-23-8)。因为时间关系,我们不能保证每周都能更新本书内容。但尽量做到一周更新一篇到两篇内容。

    敬请期待^_^。欢迎转载。另请转载时注明本文出处,谢谢合作!

    同一时候,因为译者水平有限,出错之处在所难免,欢迎指出订正。】

    【本小节内容相应原书的第52页至第63页】

    4.6 控制3D Props

    VTK中的渲染窗体渲染的对象通常称之为“Prop”(“Prop”这个词来源于舞台剧,指的是出如今舞台上的东西)。VTK里有几种不同类型的Prop。包含vtkProp3D和vtkActor。

    当中vtkProp3D是一个抽象父类。表示的是三维场景中的对象。vtkActor是vtkProp3D的子类。用类似多边形(Polygon)和线(Lines)等基本数据来定义它的几何。

    指定vtkProp3D的位置

    我们已经知道了怎样绕着一个对象来移动相机;反过来,也能够保持相机不动,而对Prop进行变换。以下的方法能够用于定义一个vtkProp3D(及其子类)对象的位置。

    • SetPosition(x, y, z)—— 指定vtkProp3D对象在世界坐标系中的位置。
    • AddPosition(deltaX,deltaY, deltaZ) —— 用指定的X、Y、Z三个方向的增量来平移Prop。
    • RotateX(theta),RotateY(theta), RotateZ(theta) —— 分别用指定的角度绕X、Y、Z轴旋转Prop。
    • SetOrientation(x, y,z) —— 通过先绕Z轴。然后绕X轴,最后绕Y轴旋转,从而来确定Prop的方向。

    • AddOrientation(a1, a2,a3) —— 在当前Prop方向添加a1,a2, a3增量。

    • RotateWXYZ(theta, x,y, z) —— 绕x, y, z指定的向量旋转theta角度。

    • SetScale(sx, sy, sz)—— 分别沿X、Y、Z三个方向缩放sx,sy, sz比例。
    • SetOrigin(x, y, z) —— 指定Prop的原点,Prop的原点指的是Prop旋转或缩放时的基准点。

    以上这些方法联合使用,能够产生复杂的变换矩阵。

    最重要的一点是,以上方法使用时要注意它们的调用顺序。不同的顺序对Actor的位置有不同的影响。VTK里是用下面的顺序来应用这些变换的:

    1.移动Prop到原点。

    2.缩放。

    3.绕Y轴旋转。

    4.绕X轴旋转。

    5.绕Z轴旋转。

    6.从原点中移动回原来的位置。

    7.平移。

    第1步和第6步平移的大小各自是Origin的负值和正值。

    单纯的平移是由vtkProp3D的Position值来确定的。

    这些变换中最easy混淆的旋转操作。

    比如,将一个Prop先绕X旋转。再绕Y轴旋转,它的效果与先绕Y轴旋转,再绕X轴旋转的效果是全然不一样的(图4-4)。

    要了解很多其它关于Actor变换内容能够參考《VisualizationToolkit》一书。


    图4-4不同旋转顺序的效果。左边是先绕X轴旋转,再绕Y轴旋转的效果;右边是先绕Y轴旋转,再绕X轴旋转的效果

    接下来。我们会介绍各种类型的vtkProp3D。当中VTK里最经常使用的类是vtkActor。在“控制vtkActor2D”一节里会介绍一下2DProp (也就是vtkActor2D)。这个类主要应用于标注(Annotation)及其它的二维操作。

    Actors

    Actor是最常的vtkProp3D类型,像其它的vtkProp3D子类一样,vtkActor提供了一组渲染属性。如表面属性(如环境光、散射光和镜面光颜色),显示形式(Representation)(如表面模型或线框模型),纹理映射以及几何定义(即mapper)。

    定义几何。前面的样例我们已经知道。一个Actor的几何是通过SetMapper()方法指定的:

    vtkPolyDataMapper mapper
      mapper SetInputConnection [aFilter GetOutputPort]
    vtkActor anActor
      anActor SetMapper mapper

    在这个样例里,mapper的类型是vtkPolyDataMapper,也就是用类似点、线、多边形(Polygons)和三角形带(Triangle Strips)等几何图元进行渲染的。Mapper会结束可视化管线。在可视化子系统和图形子系统之间起到桥梁的作用。

    Actor的属性。Actor里有一个类型为vtkProperty的实例,主要是用来控制Actor的显示属性。经常使用的属性是Actor的颜色,我们会在后面的内容具体描写叙述。其它的重要属性有显示形式(点模型、线框模型或表面模型)、着色方法(平面着色或Gouraud着色)、Actor的不透明度(相对于透明度)以及环境光、散射光和镜面光颜色等相关參数。以下的脚本程序演示了怎样设置这些变量。

    vtkActor anActor
      anActor SetMapper mapper
      [anActor GetProperty] SetOpacity 0.25
      [anActor GetProperty] SetAmbient 0.25
      [anActor GetProperty] SetDiffuse 0.6
      [anActor GetProperty] SetSpecular 1.0
      [anActor GetProperty] SetSpecularPower 10.0

    注意,我们通过方法GetProperty()间接引用Actor的属性。或者,我们也能够先实例化一个vtkProperty对象。然后把它设置到Actor中。

    vtkProperty prop
      prop SetOpacity 0.25
      prop SetAmbient 0.5
      prop SetDiffuse 0.6
      prop SetSpecular 1.0
      prop SetSpecularPower 10.0
    vtkActor anActor
      anActor SetMapper mapper
      anActor SetProperty prop

    后一种方法的优点是,我们能够把多个Actor设置成同一种属性。

    Actor的颜色

    颜色可能是Actor里最重要的属性了。设置Actor的颜色最简单的方法莫过于调用SetColor()方法,该方法用RGB值来设置一个Actor的红、绿、蓝分量的颜色,每一个分量的取值范围从0到1。

    [anActor GetProperty] SetColor 0.1 0.2 0.4

    或者,我们也能够通过设置环境光颜色、散射光颜色和镜面光颜色来控制Actor的颜色。

    vtkActor anActor
    anActor SetMapper mapper
    [anActor GetProperty] SetAmbientColor .1 .1 .1
    [anActor GetProperty] SetDiffuseColor .1 .2 .4
    [anActor GetProperty] SetSpecularColor 1 1 1

    以上代码把环境光颜色设置成深灰色,散射光颜色设置成蓝色的阴影,镜面光颜色设置成白色。

    (注意:SetColor()方法就是用指定的RGB值来设置环境光颜色、散射光颜色和镜面光颜色。

    )

    重要:Actor的属性中关于颜色的设置仅仅有当Actor的Mapper没有标量数据(ScalarData)时才起作用。

    缺省情况下,Mapper输入的标量数据会对Actor进行着色,而Actor的颜色设置会被忽略。假设要忽略这些标量数据,能够用法ScalarVisibilityOff(),如以下的Tcl脚本所看到的:

    vtkPolyDataMapper planeMapper
      planeMapper SetInputConnection [CompPlaneGetOutputPort]
      planeMapper ScalarVisibilityOff
    vtkActor planeActor
    planeActor SetMapper planeMapper
      [planeActor GetProperty] SetRepresentationToWireframe
      [planeActor GetProperty] SetColor 0 0 0

    Actor的透明度。非常多情况下。调整Actor的透明度(或者不透明度)是非常实用的。比方,假设你想显示一个病人图像的内部器官,而器官的外面包括着皮肤。这时你能够调整皮肤的透明度,使得内部器官可见。

    能够使用vtkProperty::SetOpacity()方法,例如以下:

    vtkActor popActor
      popActor SetMapper popMapper
      [popActor GetProperty] SetOpacity 0.3
      [popActor GetProperty] SetColor .9 .9 .9

    要注意透明度的实现是使用渲染库里的α-Blending处理技术。这样的处理技术要求以正确的顺序来渲染多边形(Polygons)。实际上,这是非常难做到的,特别是当你有多个透明的Actor须要渲染时。要对多边形排序。应该把透明的Actor加到待渲染的Actor列表的最后。你也能够用vtkDepthSortPolyData这个Filter沿着视向量方向对多边形排序。

    关于这个Filter使用方法,能够參考VTK/Examples/VisualizationAlgorithm/Tcl/DepthSort.tcl这个样例。很多其它关于这方面的内容能够參考本章的“透明多边形几何”(Translucentpolygonal geometry)一节。

    其它的属性

    Actor还有其它一些重要的属性。你能够用方法VisibilityOn()/VisibilityOff()来控制Actor的可见与不可见。假设在拾取过程中,不想某个Actor被拾取,能够用法PickableOff()关闭拾取属性(关于拾取方面的内容。能够參考本章的“拾取”一节)。

    Actor有一个拾取事件(PickEvent),当它们被拾取时就会调用这个事件。另外,方法GetBounds()能够获取与坐标轴对齐的Actor的包围盒(BoundingBox)。

    Level-Of-DetailActors

    图形系统一个基本的问题是,交互时有时会变得非常慢。为了解决问题。VTK使用Level-of-detail技术。在与数据交互时。以低分辨率的显示形式(Representation)来表示Actor以求达到更快的渲染速度。

    在本章的“读取源对象”(Reader SourceObject)一节。我们已经使用了vtkLODActor类。

    基本上,最简单的方法就是用vtkLODActor实例来替代vtkActor实例。另外。你也能够控制Level-of-detail的显示形式(Representation)。

    vtkLODActor缺省的做法是利用原始的Mapper创建另外两个低分辨率的模型。第一个是从定义Mapper输入的点採样得到的点云。

    你能够控制点云里点的个数(缺省是150个点),例如以下所看到的。

    vtkLODActor dotActor
      dotActor SetMapper dotMapper
      dotActor SetNumberOfCloudPoints 1000

    Actor最低分辨率的模型就是一个包围盒。

    其它的level-of-detail也能够通过方法AddLODMapper()增加。因为复杂性问题。一般都没有必要增加。

    为了控制渲染时Actor所选的level-of-detail,你能够设置渲染窗体的期望渲染帧率

    vtkRenderWindow renWin
      renWin SetDesiredUpdateRate 5.0

    这样,就会以每秒5帧的速率进行渲染。vtkLODActor会自己主动地选择合适的Level-of-detail来达到请求的渲染速率。(注意:类似vtkRenderWindowInteractor等交互器,会自己主动地控制期望渲染帧率(DesiredUpdate Rate),一般的做法是。当鼠标松开时,会把帧率设置得非常低,而鼠标按下时。则会提高对应的帧率。

    这样就能保证相机运动时产生低分辨率/高帧率,而相机停止时产生高分辨率/低帧率的理想效果。

    假设你想了解很多其它关于Level-of-detail的控制方面的内容,能够參考本章的“vtkLODProp3D”一节。通过这个类,能够指定不同的Level。

    Assemblies

    Actors有时也会组合在一起形成层次结构。当当中的某个Actor运动时,会影响到其它Actor的位置。比如,一个机械手臂可能由上臂、前臂、手腕和末端等部分通过关节连接起来。当上臂绕着肩关节旋转时,我们希望的是其它部分也会跟着运动。这样的行为的实现就要用到Assembly,vtkAssembly是vtkActor的子类。以下的程序演示了怎样使用vtkAssembly(摘自VTK/Examples/Rendering/Tcl/assembly.tcl)。

    vtkSphereSource sphere
    vtkPolyDataMapper sphereMapper
        sphereMapper SetInputConnection [sphere GetOutputPort]
    vtkActor sphereActor
        sphereActor SetMapper sphereMapper
        sphereActor SetOrigin 2 1 3
        sphereActor RotateY 6
        sphereActor SetPosition 2.25 0 0
        [sphereActor GetProperty] SetColor 1 0 1
     
    vtkCubeSource cube
    vtkPolyDataMapper cubeMapper
        cubeMapper SetInputConnection [cube GetOutputPort]
    vtkActor cubeActor
        cubeActor SetMapper cubeMapper
        cubeActor SetPosition 0.0 .25 0
        [cubeActor GetProperty] SetColor 0 0 1
     
    vtkConeSource cone
    vtkPolyDataMapper coneMapper
        coneMapper SetInputConnection [cone GetOutputPort]
    vtkActor coneActor
        coneActor SetMapper coneMapper
        coneActor SetPosition 0 0 .25
        [coneActor GetProperty] SetColor 0 1 0
     
    #top part of the assembly
    vtkCylinderSource cylinder;
    vtkPolyDataMapper cylinderMapper
        cylinderMapper SetInputConnection [cylinder GetOutputPort]
        cylinderMapper SetResolveCoincidentTopologyToPolygonOffset
    vtkActor cylinderActor
        cylinderActor SetMapper cylinderMapper
        [cylinderActor GetProperty] SetColor 1 0 0
     
    #Create the assembly and add the 4 parts to it. Also set the origin, position
    #and orientation in space.
    vtkAssembly assembly
        assembly AddPart cylinderActor
        assembly AddPart sphereActor
        assembly AddPart cubeActor
        assembly AddPart coneActor
        assembly SetOrigin 5 10 15
        assembly AddPosition 5 0 0
        assembly RotateX 15
     
    #Create the Renderer, RenderWindow, and RenderWindowInteractor
    #
    vtkRenderer ren1
    vtkRenderWindow renWin
        renWin AddRenderer ren1
    vtkRenderWindowInteractor iren
        iren SetRenderWindow renWin
     
    #Add the actors to the renderer, set the background and size
    #
    ren1 AddActor assembly
    ren1 AddActor coneActor

    注意是怎样使用vtkAssembly里的方法AddPart()来建立层次结构的。仅仅要不是自我嵌套。Assembly能够组合成随意层次深度的结构。vtkAssembly是vtkProp3D的子类,但没有与之相关联的Property以及Mapper。因此,vtkAssembly层次结构里的结点必需要包括关于材料的属性(如颜色等)及其它相关的几何信息。

    一个Actor能够用于多个Assembly(注意以上样例中的coneActor是怎样作为一个单独的Actor以及作为Assembly里的一个节点的)。通过渲染器里的方法AddActor()仅仅要增加最顶层的Assembly,而低层次的Assembly不用增加。由于它们会递归增加到渲染器中。

    假设一个Actor增加到多个Assembly时(就像上面的样例),你能够会想到怎样去区分不同的Actor。(关于这一点,在类似“拾取”操作时是很重要的,由于你必需要区分一下究竟哪个vtkProp对象是处于选中的姿态。

    )我们会在后面的“拾取”一节,具体讨论这个问题,以及介绍类vtkAssemblyPath的使用方法。

    Volumes

    类vtkVolume主要用于体绘制,这个类与vtkActor很类似。

    vtkVolume从vtkProp3D继承了对Volume进行定位和定向的方法。vtkVolume内部也有一个与它本身相关联的Property对象,即vtkVolumeProperty。请參考第七章“体绘制”了解很多其它的关于vtkVolume的应用以及体绘制方面的内容。

    vtkLODProp3D

    类vtkLODProp3D与vtkLODActor(參考本章“Level-Of-DetailActors”一节)类似,也是使用不同的显示形式(Representation)来表示它本身。以求达到更佳的交互渲染速率。

    与vtkLODActor不同的是,vtkLODProp3D仅仅支持体绘制和面绘制。也就是说,你仅仅可以在体绘制应用程序中使用vtkLODProp3D类来获取理想的交互帧率。下面的样例演示了这个类的使用。

    vtkLODProp 3Dlod
      set level1 [lod AddLOD volumeMappervolumeProperty2 0.0]
      set level2 [lod AddLOD volumeMappervolumeProperty 0.0]
    setlevel3 [lod AddLOD probeMapper_hres probeProperty 0.0]
    setlevel4 [lod AddLOD probeMapper_lres probeProperty 0.0]
    setlevel5 [lod AddLOD outlineMapper outlineProperty 0.0]

    基本上。依据不同的渲染复杂度。会创建不同的Mapper,并把它设置到vtkLODProp3D里。AddLOD()方法能够接收Volume或几何类型的Mapper作为參数,可选的參数包含纹理映射、属性对象等。

    (依据提供的信息不同,该方法会有不同的函数签名(Signatures)。)AddLOD()方法的最后一个參数是渲染的预计时间。普通情况下都设置为0。即没有针对渲染的初始预计值。该方法返回一个整型的ID值,利用这个值就能够訪问相应的LOD(能够用来选择某一Level或者删除某一Level)。

    4.7 使用纹理

    纹理映射是生成逼真的可视化效果的强大的图形工具。二维纹理映射的基本思想是在渲染过程中,图像能够“贴”到渲染对象的表面上,因此能够创建出细节更加丰富的渲染效果。

    纹理映射时须要提供三类信息:待贴纹理图的面、纹理映射(在VTK里,事实上就是vtkImageData类型的数据,即2D图像)以及纹理坐标(控制纹理图在面上的位置)。

    以下的样例演示了怎样使用纹理映射(完整的程序代码见VTK/Examples/Rendering/Tcl/TPlane.tcl)。要注意纹理映射(类vtkTexture)是与Actor相联的,而纹理坐标则是由平面来定义(纹理坐标是由类vtkPlaneSource创建的)。


    图4-5平面纹理映射

    #Load in the texture map.
    vtkBMPReader bmpReader
      bmpReader SetFileName"$VTK_DATA_ROOT/Data/masonry.bmp"
    vtkTexture atext
      atext SetInputConnection [bmpReader GetOutputPort]
      atext InterpolateOn
     
    #Create a plane source and actor.
    vtkPlaneSource plane
    vtkPolyDataMapper  planeMapper
      planeMapper SetInputConnection [plane GetOutputPort]
    vtkActor planeActor
      planeActor SetMapper planeMapper
      planeActor SetTexture atext

    非常多时候。纹理坐标是获取不到的,由于这些纹理坐标不能在管线中生成。

    假设你须要生成纹理坐标,能够參考第五章“生成纹理坐标”一节。虽然一些老的图形卡在纹理贴图时会有所限制(比方要求所贴的纹理图必须是二维的,并且每维的大小必须小于1024),但VTK支持随意尺寸的纹理图。程序执行时。VTK会检索图形系统,确定这些图形系统的性能,然后会自己主动地对所设置的纹理图做採样,以求达到特定图形卡的要求。

    4.8 拾取

    拾取操作是可视化应用程序中常见的一种功能。拾取主要是用于选择数据和Actor或者获取底层的数据值。在显示位置(以像素为坐标值)中拾取时,就会调用vtkAbstractPicker的Pick()方法。依赖于所用的拾取类不同,拾取时返回的信息也不同,最简单的是返回一个x-y-z的全局坐标值。或者是单元(cell)的ID值,点的ID值,单元參数坐标(CellParametric Coordinates),所拾取的vtkProp实例,以及Assemblypath。拾取方法的原型是:

    Pick(selectionX,selectionY, selectionZ, Renderer)

    注意Pick()方法须要一个渲染器作为參数。

    与渲染器相关联的Actor都是拾取的候选对象。另外。selectionZ通常都设置为0.0,它是与Z-buffer相关的值。(一般,Pick()这种方法都不会直接去调用它,用户使用vtkRenderWindowInteractor进行交互时。由这个类来管理拾取操作。这样的情况下,用户仅仅要选择一个拾取实例。让这个实例来控制拾取过程就可以,后面的样例会演示怎样使用。

    VTK支持多种不同功能的拾取类型(请參考图19-16,列出了与拾取相关的类的继承图)。

    类vtkAbstractPicker是全部拾取类的基类,它定义了一些公用的API,同意用户通过方法GetPickPosition()来获取拾取位置(全局坐标下)。

    vtkAbstractPicker有两个直接子类。第一个是vtkWorldPointPicker,这是一种使用Z-buffer高速返回所拾取的位置的x-y-z全局坐标的类(基于硬件的)。但不会返回其它的信息(比方究竟拾取了哪一个vtkProp实例等)。类vtkAbstractPropPicker是从vtkAbstractPicker中直接派生的另外一个子类。

    它定义了能够用于拾取某个vtkProp实例的API。以下列出一些比較方便的用于获取vtkProp实例的方法。

    • GetProp() —— 返回拾取的vtkProp实例指针。

      假设拾取了某个对象,就返回指向该vtkProp对象的指针,否则返回NULL。

    • GetProp3D() —— 假设拾取的是vtkProp3D对象。则返回该vtkProp3D对象的指针。
    • GetActor2D() —— 假设拾取的是vtkActor2D对象。则返回该vtkActor2D对象的指针。
    • GetActor() —— 假设拾取的是vtkActor对象。则返回该vtkActor对象的指针。

    • GetVolume() —— 假设拾取的是vtkVolume对象。则返回该vtkVolume对象的指针。
    • GetAssembly() —— 假设拾取的是vtkAssembly对象,则返回该vtkAssembly对象的指针。
    • GetPropAssembly() —— 假设拾取的是vtkPropAssembly对象,则返回该vtkPropAssembly对象的指针。

    使用这些方法时须要特别注意,vtkAbstractPropPicker及其子类拾取时返回的是最顶层的Assembly路径(top level of theassembly path)。因此。假设有一个顶层类型是vtkAssembly的Assembly对象,其叶结点类型是vtkActor时,用法GetAssembly()返回的是指向vtkAssembly对象的指针。而用法GetActor()返回则是空指针。假设有一个包括Assembly、Actor及其它类型的Prop的复杂场景时。最安全的方法是使用GetProp()来确定所拾取的对象。再使用GetPath()方法。

    类vtkAbstractPropPicker有三个直接子类。各自是:vtkPropPicker、vtkAreaPicker及vtkPicker。

    vtkPropPicker使用硬件拾取的策略来确定所拾取的vtkProp实例,包含拾取点的世界坐标系下的位置坐标。vtkPropPicker通常比vtkAbstractPropPicker的其它子类的速度要快。可是它不能返回所拾取对象的具体信息。

    vtkAreaPicker及其基于硬件实现的子类vtkRenderedAreaPicker相同无法确定所拾取对象的具体信息,它们的作用是选择屏幕上的对象。vtkAreaPicker及其子类与其它的拾取类不同,前者能够确定哪些是位于屏幕上矩阵区域的像素的開始位置,而不只确定哪些是位于某个像素的后方。这些类都有方法AreaPick(x_min, y_min,x_max, y_max, Renderer),能够与标准的方法Pick(x,y,z,Renderer)一起使用。

    假设想获取很多其它的信息,比方确定位于某个区域后方的单元或点等信息,能够參考本节兴许内容的介绍。

    vtkPicker是一个基于软件实现的拾取类,详细实现是基于vtkProp对象的包围盒来拾取对象。

    该类在拾取时,会从相机的当前位置投射一条光线到拾取点,所投射的光线会与某个Prop3D对象的包围盒相交,当然,通过这样的方式有可能会有多个的Prop3D对象被拾取到。最后返回的是所投射的光线与对象的包围盒相交最多的Prop3D。

    而方法GetProp3Ds()能够返回与投射光线相交的全部的Prop3D对象。vtkPicker拾取速度相对较快,但无法获取单一的拾取。

    vtkPicker有两个子类,通过这两个子类能够获取所拾取对象很多其它具体的信息。比方。点的ID。单元的ID等。vtkPointPicker用于拾取单个点,返回其ID值和坐标值。拾取时,vtkPointPicker也是通过从相机当前位置投射一条光线至拾取点。然后将光线周围且位于容差(Tolerance)范围内的点投射至光线上,最后返回的是距离相机近期的点以及该点所相应的Actor对象。

    (注意:容差是用渲染窗体的对角线的长度作为分数的。)vtkPointPicker比vtkPicker拾取速度要慢。但比vtkCellPicker要快。由于引入的容差。所以vtkPointPicker能够返回单一的拾取对象。

    vtkCellPicker用于拾取某个单元,并返回交点的信息,比方,交点所相应的单元ID、全局坐标以及參数化单元坐标(Parametric cellcoordinates)。与vtkPointPicker类似,vtkCellPicker拾取时也是投射一条光线至拾取点,在一定的容差范围内确定光线是否与Actor底层的几何相交,最后返回的就是沿着光线最靠近相机的单元及其相应的对象。

    (注意:在确定光线是否与单元相交时会使用到容差,可能须要多次实验才干获得惬意的结果。)vtkCellPicker是全部拾取类中速度最慢的一个,可是所获取的信息也是最多的。

    通过指定容差。能够返回单一的拾取对象。

    VTK定义了与拾取操作相关的几个事件。拾取操作发生之前会调用StartPickEvent事件,拾取完毕后则调用EndPickEvent事件。

    当对象被拾取时会调用Picker类的PickEvent事件以及Actor类的PickEvent事件。

    注意:使用vtkWorldPointPicker类时,不会有PickEvent事件发生。

    vtkAssemblyPath

    在拾取包括不同类型的vtkProp对象的场景时,有必要理解类vtkAssemblyPath,特别是当场景中包括有vtkAssembly对象。

    vtkAssemblyPath简单地能够理解为包括vtkAssemblyNode的顺序列表,每一个结点含有一个指向vtkProp对象的指针以及一个可选的vtkMatrix4x4对象。列表的顺序很重要。列表的開始是根结点或者说是Assembly层次结构的顶层结点。列表的结尾表示Assembly层次结构的叶结点。结点的顺序会影响到与之关联的矩阵。每一个矩阵是列表里结点的Prop所相应的矩阵与前一个矩阵的级联。因此,对于某个给定的vtkAssemblyNode,所关联的vtkMatrix4x4表示的是该结点的vtkProp对象的位置和方向(如果vtkProp对象初始状态是没有经过变换的)。

    样例

    通常。拾取是由vtkRenderWindowInteractor自己主动管理的(见“使用VTK交互器”一节了解很多其它关于交互器的内容)。

    比方。当按下P键时,vtkRenderWindowInteractor会调用内部的vtkPropPicker实例运行拾取操作。接着,能够通过vtkRenderWindowInteractor訪问拾取器(Picker)或者其它信息。也能够给vtkRenderWindowInteractor指定一个从vtkAbstractPicker派生的拾取器。图4-6显示了对数据集拾取的结果,程序代码摘自VTK/Examples/Annotation/Tcl/annotationPick.tcl。


    图4-6 带标注信息的拾取操作

    vtkCellPicker picker
        picker AddObserver EndPickEvent annotatePick
     
    #Create a text mapper and actor to display the results of picking.
    vtkTextMapper textMapper
    settprop [textMapper GetTextProperty]
        $tprop SetFontFamilyToArial
        $tprop SetFontSize 10
        $tprop BoldOn
        $tprop ShadowOn
        $tprop SetColor 1 0 0
    vtkActor2D textActor
        textActor VisibilityOff
        textActor SetMapper textMapper
     
    #Create the Renderer, RenderWindow, and RenderWindowInteractor
    #
    vtkRenderer ren1
    vtkRenderWindow renWin
        renWin AddRenderer ren1
    vtkRenderWindowInteractor iren
        iren SetRenderWindow renWin
        iren SetPicker picker
     
    #Create a Tcl procedure to create the text for the text mapper used to
    #display the results of picking.
    proc annotatePick {} {
        if { [picker GetCellId] < 0 } {
           textActor VisibilityOff
     
        } else {
           set selPt [picker GetSelectionPoint]
           set x [lindex $selPt 0]
           set y [lindex $selPt 1]
           set pickPos [picker GetPickPosition]
           set xp [lindex $pickPos 0]
           set yp [lindex $pickPos 1]
           set zp [lindex $pickPos 2]
     
           textMapper SetInput "($xp, $yp,$zp)"
           textActor SetPosition $x $y
           textActor VisibilityOn
        }
     
        renWin Render
    }
     
    #Pick the cell at this location.
    picker Pick 85 126 0 ren1

    这个样例使用vtkTextMapper在屏幕上绘制拾取点的世界坐标值。(參考“文本标注”一节了解很多其它信息)。注意到在这个样例中,我们注冊了EndPickEvent事件,拾取操作完毕后,就会调用annotatePick()过程。

    4.9 vtkCoordinate和坐标系统

    VTK支持多种不同类型的坐标系统。类vtkCoordinate管理这些坐标系统之间的变换。支持的坐标系统有:

    • DISPLAY —— X-Y坐标值定义在渲染窗体中,以像素为单位(注意vtkRenderWindow是vtkWindow的子类)。原点在窗体的左下角(这一点对于以下的二维坐标系统都是如此)。
    • NORMALIZED DISPLAY —— 窗体的X-Y坐标取值归一化。即(0,1)。

    • VIEWPORT —— X-Y坐标值定义在视口(Viewport)或者渲染器(Renderer,vtkRenderer是vtkViewport的子类)里。
    • NORMALIZED VIEWPORT ——视口里的X-Y坐标取值归一化,即(0, 1)。
    • VIEW —— X-Y-Z坐标值(取值范围为(-1,1))定义在相机坐标系统,Z表示深度。
    • WORLD —— X-Y-Z为全局坐标值。
    • USERDEFINED —— X-Y-Z定义在用户自己定义的空间里。

      用户必须为自己定义的坐标系统提供空间变换方法。

      请參考类vtkCoordinate了解很多其它信息。

    类vtkCoordinate能够用于坐标系统之间的变换,也能够用于连接各个坐标系统以形成“相对”或者“偏移”等坐标值。请參考下一节内容了解vtkCoordinate的使用方法。

    4.10 控制vtkActor2D

    vtkActor2D与vtkActor非常多功能都类似。除了vtkActor2D是在层叠(overlay)平面上绘制的以及没有与之相关联的4×4的变换矩阵。与vtkActor类似,vtkActor2D涉及到一个mapper(即vtkMapper2D)和属性对象(即vtkProperty2D)。使用vtkActor2D时。比較困难的部分是怎样定位它的对象。

    定位vtkActor2D对象时会用到类vtkCoordinate(请參考上一部分“vtkCoordinate和坐标系统”一节)。以下的样例演示了怎样使用vtkCoordinate对象。

    vtkActor2D bannerActor
      bannerActor SetMapper banner
      [bannerActor GetProperty] SetColor 0 1 0
      [bannerActor GetPositionCoordinate]SetCoordinateSystemToNormalizedDisplay
      [bannerActor GetPositionCoordinate] SetValue0.5 0.5

    在这个样例中。訪问了坐标对象以及定义了它的坐标系统,然后设置了该坐标系统下合适的坐标值。

    这个样例中。使用了归一化显示坐标系统(Normalized DisplayCoordinate System)。因此坐标范围定义为0到1。坐标值(0.5,0.5)就设置vtkActor2D对象在渲染窗体的中间位置。

    vtkActor2D也提供了一个方便的接口。SetDisplayPosition()能够设置坐标系统为DISPLAY,而且利用传入的參数(以像素为单位)设置vtkActor2D对象在渲染窗体中的位置。下一节的内容将会演示怎样使用这种方法。


  • 相关阅读:
    frida
    ES中filter 和map的使用
    阿里巴巴15 款开发者工具
    小程序的开发记录
    微信3.1小程序商城源码C# ASP.NET 多用户微商城 saas模式
    js中for,for in,forEach,for of的使用
    Vuejs学习笔记
    vue.js/element-ui/webpack 开发记录
    ESXi开启虚拟化
    shell把字符串中的字母去掉,只保留数字
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/5234459.html
Copyright © 2011-2022 走看看