vtk用户指南 第五章 可视化技术

        在前一章中介绍了一些渲染和交互数据的基本工具。在本章中,我们将向您展示各种可视化技术。这些技术(作为过滤器实现)根据它们操作的数据类型进行组织。一些过滤器是通用的,可以应用于任何类型的数据——那些接受vtkDataSet类(或任何子类)输入的过滤器。许多过滤器更专门于它们接受的输入类型(例如,vtkPolyData)。有一类过滤器——那些接受vtkImageData类型输入的过滤器(或其过时的子类vtkStructuredPoints)——在本章中没有提到。相反,这种类型的过滤器将在下一章(第103页的“图像处理和可视化”)中描述。

        在你阅读本章的时候,请记住两件事。首先,过滤器生成各种输出类型,输出类型不一定与输入类型相同。其次,结合使用过滤器来创建复杂的数据处理管道。通常有使用模式,或者使用过滤器的常见组合。在下面的示例中,您可能希望注意这些组合。

5.1可视化vtkDataSet(和子类)

        在本节中,我们将向您展示如何对vtkDataSet类型的数据对象执行一些常见的可视化操作。回想一下,vtkDataSet是所有具体类型可视化数据的超类(参见图3-2)。因此,这里描述的方法适用于所有不同的数据类型。(换句话说,所有以vtkDataSet为输入的过滤器也将接受vtkPolyData, vtkImageData, vtkStructuredGrid, vtklineargrid和vtkUnstructuredGrid。)数据属性数据属性是与数据集结构相关的信息(如第25页“可视化管道”中所述)。在VTK中,属性数据与点(点属性数据)和单元(单元属性数据)相关联。属性数据与数据集结构一起由许多VTK过滤器处理,以生成新的结构和属性。对属性数据的一般介绍超出了本节的范围,但是一个简单的示例将演示其基本思想。(欲了解更多信息,请参阅第362页和图16-1中的“字段和属性数据”。)

        数据属性是简单的vtkdataarray,它可以被标记为标量、向量、张量、法线、纹理坐标、全局id(用于标识冗余元素)或系谱id(用于跟踪管道中的元素历史)。vtkDataSet的点和单元可以有自己独立的数据属性。数据属性可以与vtkDataSet的点或单元相关联。与vtkDataSet相关联的每个vtkDataArray都是vtkDataArray的具体子类,例如vtkFloatArray或vtkIntArray。这些数据数组可以被认为是命名为本机类型的连续线性内存块。在这个线性块中,数据数组被认为由子数组或“元组”组成。创建属性数据意味着实例化所需类型的数据数组、指定元组大小、插入数据并将其与数据集关联,如下面的Tcl脚本所示。这种关联可能具有将数据标记为标量、向量、张量、纹理坐标或法线的副作用。例如:

vtkFloatArray scalars
    scalars InsertTuple1 0 1.0
    scalars InsertTuple1 1 1.2
    ...etc...
vtkDoubleArray vectors
    vectors SetNumberOfComponents 3
    vectors InsertTuple3 0 0.0 0.0 1.0
    vectors InsertTuple3 1 1.2 0.3 1.1
    ...etc...
vtkIntArray justAnArray
    justAnArray SetNumberOfComponents 2
    justAnArray SetNumberOfTuples $numberOfPoints
    justAnArray SetName “Solution Attributes”
    justAnArray SetTuple2 0 1 2
    justAnArray SetTuple2 1 3 4
    ...etc...
vtkPolyData polyData;#A concrete type of vtkDataSet
    [polyData GetPointData] SetScalars scalars
    [polyData GetCellData] SetVectors vectors
    [polyData GetPointData] AddArray justAnArray

        这里我们创建了三个类型分别为float、double和int的数组。第一个数组(标量)被实例化,默认情况下其元组大小为1。InsertTuple1()方法用于将数据放入数组中(所有名为Insert___()的方法都根据需要分配内存来保存数据)。下一个数据数组(向量)创建的元组大小为3,因为向量被定义为具有三个组件,并且InsertTuple3用于向数组中添加数据。最后,我们创建一个元组大小为2的通用数组,并使用SetNumberOfTuples()分配内存。然后使用SetTuple2()来添加数据;此方法假定内存已经分配,因此比类似的Insert__()方法更快。注意,当我们将数据数组与数据集的点数据或单元数据相关联时(使用setscalar()和SetVectors()方法),就会对标量、向量等进行标记。请记住,点属性的数量(例如,本例中标量的数量)必须等于数据集中的点的数量,单元格属性的数量(例如,向量的数量)必须与数据集中的单元格数量相匹配。

        类似地,要访问属性数据,请使用这些方法

set scalars [[polyData GetPointData] GetScalars]
set vectors [[polyData GetCellData] GetVectors]

        您会发现许多过滤器专门处理属性数据。例如,vtkElevationFilter根据它们在指定方向上的高度生成标量值。其他过滤器与数据集的结构一起工作,通常忽略或通过过滤器传递属性数据(例如,vtkDecimatePro)。最后,一些过滤器使用(部分)属性数据和结构来生成它们的输出。vtkMarchingCubes就是一个例子。它使用输入标量与数据集结构相结合来生成轮廓原语(即三角形,线或点)。其他类型的属性数据,如向量,在轮廓过程中被插值并发送到过滤器的输出。

        关于属性数据的另一个重要问题是,某些过滤器将只处理一种类型的属性(点数据与单元格数据),忽略或将其他属性数据类型传递给它们的输出。您可能会发现您的输入数据是一种属性类型,而您希望使用不处理该类型的过滤器来处理它,或者您只是希望从一种属性类型转换为另一种属性类型。有两个过滤器可以帮助您:vtkPointDataToCellData和vtkCellDataToPointData,它们转换为点和单元格数据属性。这里有一个使用它们的例子(来自Tcl脚本VTK/Examples/ datamanmanipulation /Tcl/pointToCellData.tcl)。

vtkUnstructuredGridReader reader
 reader SetFileName "$VTK_DATA_ROOT/Data/blow.vtk"
 reader SetScalarsName "thickness9"
 reader SetVectorsName "displacement9"
vtkPointDataToCellData p2c
 p2c SetInputConnection [reader GetOutputPort]
 p2c PassPointDataOn
vtkWarpVector warp
 warp SetInputConnection [p2c GetOutputPort]
vtkThreshold thresh
 thresh SetInputConnection [warp GetOutputPort]
 thresh ThresholdBetween 0.25 0.75
 thresh SetAttributeModeToUseCellData

        这个例子很有趣,因为它演示了属性数据类型(vtkPointDataToCellData)之间的转换,以及可以处理单元格数据或点数据(vtkThreshold)的过滤器的使用。方法PassPointDataOn()指示vtkPointDataToCellData创建单元格数据,并将输入点数据传递给其输出。SetAttributeModeToUseCellData()方法配置vtkThreshold过滤器,以使用单元格数据执行阈值操作。

        点和单元数据之间的转换,反之亦然,使用平均算法执行。通过将与给定单元格使用的点相关联的点数据的值求平均值,将点数据转换为单元格数据。通过计算与使用给定点的单元格相关联的单元格数据的平均值,将单元格数据转换为点数据。

颜色映射

        可能最常用的可视化技术是通过标量值或颜色映射为对象着色。这种技术背后的思想很简单:通过查找表映射标量值以获得颜色,在呈现期间应用颜色以修改点或单元格的外观。在继续本节之前,请确保您了解如何控制角色的颜色(请参阅第54页的“角色颜色”)。

        在VTK中,颜色映射通常由标量控制,我们假设您已经创建或从数据文件中读取,以及查找表,这是由vtkMapper实例用于执行颜色映射。通过使用ColorByArrayComponent()方法,也可以使用任何数据数组来执行着色。如果没有指定,一个默认的查找表是由映射器创建的,但你可以创建你自己的(取自VTK/Examples/Rendering/Tcl/rainbow)。tcl -见图5-1) 

vtkLookupTable lut
lut SetNumberOfColors 64
lut SetHueRange 0.0 0.667
lut Build
 for {set i 0} {$i<16} {incr i 1} {
 eval lut SetTableValue [expr $i*16] $red 1
 eval lut SetTableValue [expr $i*16+1] $green 1
 eval lut SetTableValue [expr $i*16+2] $blue 1
 eval lut SetTableValue [expr $i*16+3] $black 1
 }
vtkPolyDataMapper planeMapper
 planeMapper SetLookupTable lut
 planeMapper SetInputConnection [plane GetOutputPort]
 planeMapper SetScalarRange 0.197813 0.710419
vtkActor planeActor
 planeActor SetMapper planeMapper

        如本例所示,可以用两种不同的方式操作查找表。首先,您可以指定一个HSVA(色调-饱和度-值- alpha透明度)渐变,该渐变用于在HSVA空间中使用线性插值来生成表中的颜色(Build()方法实际上生成表)。其次,您可以在表中的特定位置手动插入颜色。注意,表格中的颜色数量是可以设置的。在本例中,我们使用HSVA渐变生成表格,然后用SetTableValue()方法替换表格中的颜色。

        映射器的SetScalarRange()方法控制标量如何映射到表中。大于最大值的标量值被固定到最大值。小于最小值的标量值被固定到最小值。使用标量范围,您可以通过映射更多颜色来“扩展”标量数据的区域。

        有时标量数据实际上是彩色的,不需要通过查找表进行映射。映射器提供了几种方法来控制映射行为。

        •SetColorModeToDefault()调用默认映射器行为。默认行为将数据类型unsigned char的3个分量标量作为颜色,并且不执行映射;所有其他类型的标量都通过查找表进行映射。

        •SetColorModeToMapScalars()通过查找表映射所有标量,无论类型如何。如果标量在每个元组中有多个组件,则使用标量的第0个组件执行映射。vtkMapper的另一个重要功能是控制哪些属性数据(即,点或单元标量,或一般数据数组)用于对象着色。下面的方法可以控制这种行为。请注意,这些方法给出了截然不同的结果:在呈现过程中,点属性数据是跨呈现原语插值的,而单元格属性数据则为单元格涂上常量。

        •SetScalarModeToDefault()调用默认映射器行为。默认行为使用点标量为对象上色,除非它们不可用,在这种情况下,如果单元格标量可用,则使用它们。

        •SetScalarModeToUsePointData()总是使用点数据来为对象上色。如果没有点标量数据可用,则对象颜色不受标量数据的影响。•SetScalarModeToUseCellData()总是使用单元格数据给对象上色。如果没有可用的单元格标量数据,则对象颜色不受标量数据的影响。

        •SetScalarModeToUsePointFieldData()表示既不使用点标量也不使用单元标量,而是使用点属性数据中的数据数组。此方法应与ColorByArrayComponent()一起使用,以指定要使用的数据数组和组件作为标量。

        •SetScalarModeToUseCellFieldData()表明既不使用点标量也不使用单元格标量,而是在单元格字段数据中找到的数据数组。此方法应与ColorByArrayComponent()一起使用,以指定要使用的数据数组和组件作为标量。通常情况下,默认行为运行良好,除非单元格和点标量数据都可用。在这种情况下,您可能需要显式地指出是使用点标量还是单元标量来为对象上色。

轮廓线

另一种常见的可视化技术是生成轮廓。
等高线是标量值恒定的线或面。在VTK中,过滤器vtkContourFilter用于执行轮廓,如下面的Tcl示例所示,来自VTK/Examples/
VisualizationAlgorithms / Tcl / VisQuad。tcl-refer来
图5 - 2。

# Create 5 surfaces in range specified
vtkContourFilter contours
    contours SetInputConnection [sample \
GetOutputPort]
    contours GenerateValues 5 0.0 1.2
vtkPolyDataMapper contMapper
    contMapper SetInputConnection [contours GetOutputPort]
    contMapper SetScalarRange 0.0 1.2
vtkActor contActor
    contActor SetMapper contMapper

您可以通过两种方式指定轮廓值。最简单的方法是使用SetValue()方法指定轮廓数及其值(可以指定多个值)。

contours SetValue 0 0.5

        上面的示例演示了第二种方法:通过generatevalvalues()方法。使用此方法,您可以指定标量范围和要在该范围内生成的轮廓数(包括结束值)。

        请注意,VTK中有几个对象执行特定数据集类型的轮廓(并且更快)。例如vtkSynchronizedTemplates2D和vtkSynchronizedTemplates3D。你不需要实例化这些直接如果你使用vtkContourFilter;过滤器将自动为您的数据集类型选择最佳轮廓函数

Glyphing

        字形是一种可视化技术,通过使用符号或字形来表示数据(图5-3)。这些符号可以是简单的,也可以是复杂的,从显示矢量数据的定向锥体,到复杂的多变量符号,如Chernoff脸(人脸的符号表示,其表情由数据值控制)。在VTK中,vtkGlyph3D类允许您创建可以缩放,着色和沿方向定向的字形。字形被复制到输入数据集的每个点。字形本身是使用到过滤器的第二个输入连接来定义的。(它接受vtkPolyData类型的数据集)。下面的脚本演示了vtkGlyph3D的使用(Tcl脚本取自VTK/Examples/VisualizationAlgorithms/Tcl/ spikeF.tcl)。

vtkPolyDataReader fran
 fran SetFileName "$VTK_DATA_ROOT/Data/fran_cut.vtk"
vtkPolyDataNormals normals
 normals SetInputConnection [fran GetOutputPort]
 normals FlipNormalsOn
vtkPolyDataMapper franMapper
 franMapper SetInputConnection [normals GetOutputPort]
vtkActor franActor
 franActor SetMapper franMapper
[franActor GetProperty] SetColor 1.0 0.49 0.25
vtkMaskPoints ptMask
 ptMask SetInputConnection [normals GetOutputPort]
 ptMask SetOnRatio 10
 ptMask RandomModeOn
# In this case we are using a cone as a glyph. We transform the cone so
# its base is at 0,0,0. This is the point where glyph rotation occurs.
vtkConeSource cone
 cone SetResolution 6
vtkTransform transform
 transform Translate 0.5 0.0 0.0
vtkTransformPolyDataFilter transformF
 transformF SetInputConnection [cone GetOutputPort]
 transformF SetTransform transform
vtkGlyph3D glyph
 glyph SetInputConnection [ptMask GetOutputPort]
 glyph SetSourceConnection [transformF GetOutputPort]
 glyph SetVectorModeToUseNormal
 glyph SetScaleModeToScaleByVector
 glyph SetScaleFactor 0.004
vtkPolyDataMapper spikeMapper
 spikeMapper SetInputConnection [glyph GetOutputPort]
vtkActor spikeActor
 spikeActor SetMapper spikeMapper
 eval [spikeActor GetProperty] SetColor 0.0 0.79 0.34

        该脚本的目的是使用小的定向锥体来指示表面法线的方向。输入数据集(来自Cyberware激光数字化系统)被读取和显示。接下来,使用过滤器vtkMaskPoints从Cyberware数据中对点(以及相关的点属性数据)进行子采样。这将作为vtkGlyph3D实例的输入。一个vtkConeSource被用作字形实例的源。注意,圆锥体被平移了(使用vtkTransformPolyDataFilter),这样它的基础就在原点(0,0,0)上(因为vtkGlyph3D围绕原点旋转源对象)。

        vtkGlyph3D对象字形被配置为使用点属性法线作为方向向量。(或者,使用SetVectorModeToUseVector()来使用矢量数据而不是法线。)在给定的比例因子下,它还通过矢量值的大小来缩放锥体。(你可以使用SetScaleModeToScaleByScalar()和SetScaleModeToDataScalingOff()方法来缩放符号或关闭数据缩放。)

        也可以使用标量或矢量数据或按比例因子为符号上色。您还可以创建符号表,并使用标量或矢量数据将其索引到表中。有关更多信息,请参阅在线文档。

流线

        流线可以被认为是一个无质量粒子在矢量场(如速度场)中的路径。流线用来表示向量场的结构。通常创建多个流线来探索领域中有趣的特性(图5-4)。流线是通过数值积分计算的(对速度乘积进行积分),因此只是实际流线的近似值。

        创建流线需要指定一个起点(如果有多个流线,则需要指定多个起点)、一个集成方向(沿流方向,或与流方向相反,或两个方向),以及控制其传播的其他参数。下面的脚本展示了如何创建单个流线。流线被一个半径与速度大小成反比的管子包裹着。这表明哪里流动慢(肥管),哪里流动快(细管)。这个Tcl脚本是从
VTK / / VisualizationAlgorithms / Tcl / officeTube.tcl例子。

# Read structured grid data
vtkStructuredGridReader reader
 reader SetFileName "$VTK_DATA_ROOT/Data/office.binary.vtk"
 reader Update #force a read to occur
# Create source for streamtubes
vtkRungeKutta4 integ
vtkStreamTracer streamer
 streamer SetInputConnection [reader GetOutputPort]
 streamer SetStartPosition 0.1 2.1 0.5
 streamer SetMaximumPropagation 500
streamer SetMaximumPropagationUnitToTimeUnit
 streamer SetInitialIntegrationStep 0.05
streamer SetInitialIntegrationStepUnitToCellLengthUnit
streamer SetIntegrationDirectionToBoth
streamer SetIntegrator integ
vtkTubeFilter streamTube
 streamTube SetInputConnection [streamer GetOutputPort]
streamTube SetInputArrayToProcess 1 0 0 \
vtkDataObject::FIELD_ASSOCIATION_POINTS vectors
 streamTube SetRadius 0.02
 streamTube SetNumberOfSides 12
 streamTube SetVaryRadiusToVaryRadiusByVector
vtkPolyDataMapper mapStreamTube
 mapStreamTube SetInputConnection [streamTube GetOutputPort]
 eval mapStreamTube SetScalarRange \
 [[[[reader GetOutput] GetPointData] GetScalars] \
GetRange] #this is why we did an Update
vtkActor streamTubeActor
 streamTubeActor SetMapper mapStreamTube
[streamTubeActor GetProperty] BackfaceCullingOn

        在这个例子中,我们通过指定世界坐标(0.1,2.1,0.5)来选择起点。还可以通过使用celllid、cell subId和参数坐标来指定起始位置。MaximumPropagation实例变量控制流线的最大长度(以MaximumPropagationUnit实例变量指定的单位测量,在本例中是time)。如果你想要更高的精度(以更多的计算时间为代价),设置InitialIntegrationStep实例变量如图5-4流线包裹着一根管子。能够更小的值。(在这种情况下,这是根据单元格的长度指定的;可以通过设置InitialIntegrationStepUnit来选择时间或距离。)精度也可以通过选择vtkInitialValueProblemSolver的不同子类来控制,例如vtkRungeKutta2或vtkRungeKutta45(允许自适应控制步长)。默认情况下,流跟踪程序类使用vtkRungeKutta2来执行数值积分。您还可以使用以下方法控制集成的方向。

        •SetIntegrationDirectionToBoth()

        •SetIntegrationDirectionToForward()

        •SetIntegrationDirectionToBackward()

        •SetIntegrationDirectionToBoth()线通常很难看到和创建有用的图像。在本例中,我们用管过滤器包装行。管过滤器配置成与速度大小成反比地改变管的半径(即,如果流场不可压缩,则保持通量关系)。SetVaryRadiusToVaryRadiusByVector()启用这个功能。你也可以改变半径的标量值(SetVaryRadiusToVaryRadiusByScalar())或关闭可变半径(SetVaryRadiusToVaryRadiusOff())。注意,当缩放其半径时,必须告诉管过滤器使用哪个数组。在本例中,使用SetInputArrayToProcess()选择名称为“vectors”的数组。

        如前所述,我们经常希望同时生成许多流线。这样做的一种方法是使用setsourcececonnection()方法来指定vtkDataSet的实例,其点用于种子流线。下面是一个使用它的例子(来自VTK/Examples/ VisualizationAlgorithms/Tcl/officeTubes.tcl)。

vtkPointSource seeds
 seeds SetRadius 0.15
seeds SetCenter 0.1 2.1 0.5
 seeds SetNumberOfPoints 6
vtkRungeKutta4 integ
vtkStreamTracer streamer
 streamer SetInputConnection [reader GetOutputPort]
 streamer SetSourceConnection [seeds GetOutput]
 streamer SetMaximumPropagationTime 500
streamer SetMaximumPropagationUnitToTimeUnit
streamer SetInitialIntegrationStep 0.05
streamer SetInitialIntegrationStepUnitToCellLengthUnit
streamer SetIntegrationDirectionToBoth
streamer SetIntegrator integ

注意,示例使用源对象vtkPointSource来创建点的球形云,然后将其设置为流的源。对于每个点(在输入数据集中),将计算一个流线。

流面

        高级用户可能希望使用VTK的流表面功能。流表面由两部分生成。首先,使用一个耙或一系列有序点来生成一系列流线。然后,使用vtkruledsurfaceffilter从流线创建一个表面。这是非常重要的,(因此流线)被仔细排序,因为vtkRuledSurfaceFilter假设这些线彼此相邻,并且在指定的距离(DistanceFactor)内左右相邻。否则,表面撕裂或可获得较差的效果。下面的脚本演示了如何创建流表面(取自Tcl脚本VTK/Examples/ VisualizationAlgorithms/Tcl/streamSurface)。如图5-5所示)。

vtkLineSource rake
 rake SetPoint1 15 -5 32
 rake SetPoint2 15 5 32
 rake SetResolution 21
vtkPolyDataMapper rakeMapper
 rakeMapper SetInputConnection [rake
GetOutputPort]
vtkActor rakeActor
 rakeActor SetMapper rakeMapper
vtkRungeKutta4 integ
vtkStreamTracer sl
 sl SetInputConnection [pl3d GetOutputPort]
 sl SetSourceConnection [rake GetOutputPort]
 sl SetIntegrator integ
 sl SetMaximumPropagation 0.1
sl SetMaximumPropagationUnitToTimeUnit
 sl SetInitialIntegrationStep 0.1
sl SetInitialIntegrationStepUnitToCellLengthUnit
 sl SetIntegrationDirectionToBackward
vtkRuledSurfaceFilter scalarSurface
 scalarSurface SetInputConnection [sl GetOutputPort]
 scalarSurface SetOffset 0
 scalarSurface SetOnRatio 2
 scalarSurface PassLinesOn
 scalarSurface SetRuledModeToPointWalk
 scalarSurface SetDistanceFactor 30
vtkPolyDataMapper mapper
 mapper SetInputConnection [scalarSurface GetOutputPort]
 eval mapper SetScalarRange [[pl3d GetOutput] GetScalarRange]
vtkActor actor
 actor SetMapper mapper 

vtkRuledSurfaceFilter的一个很好的特性是,如果提供多条线作为过滤器的输入(SetOnRatio()方法),则能够关闭条带。这有助于理解表面的结构。

切割

        在VTK中切割或切片数据集需要使用任何类型的隐式函数通过数据集创建“横截面”。例如,我们可以用平面对数据集进行切片,以创建平面切割。切割面在切割时插入数据,然后可以使用任何标准的可视化技术将其可视化。切割的结果总是vtkPolyData类型。(切割n维图5-5流面。纵坐标单元导致(n-1)维输出原语。例如,切割一个四面体会产生一个三角形或四边形。)

        在下面的Tcl示例中,燃烧室(结构化网格)用平面切割,如图5-6所示。示例取自Tcl脚本VTK/Graphics/ Testing/Tcl/probe.tcl。

vtkPlane plane
 eval plane SetOrigin [[pl3d GetOutput]
GetCenter]
 plane SetNormal -0.287 0 0.9579
vtkCutter planeCut
 planeCut SetInputConnection [pl3d GetOutputPort]
 planeCut SetCutFunction plane
vtkPolyDataMapper cutMapper
 cutMapper SetInputConnection [planeCut GetOutputPort]
 eval cutMapper SetScalarRange \
 [[[[pl3d GetOutput] GetPointData] GetScalars] GetRange]
vtkActor cutActor
 cutActor SetMapper cutMapper

        vtkCutter要求你指定一个隐式函数来进行切割。此外,您可能希望使用SetValue()或GenerateValues()方法指定一个或多个切割值。这些值指定用于执行切割的隐式函数的值。(通常切割值为零,意味着切割表面精确地在隐函数上。小于或大于零的值是隐式曲面下方和上方的隐式曲面。切割值也可以被认为是
到隐式曲面的“距离”,这只对vtkPlane严格成立。)

合并数据

        到目前为止,我们已经看到了简单的线性可视化管道。然而,管道可以分支、合并,甚至有循环。数据块也有可能从管道的一段移动到另一段。在本节和下一节中,我们将介绍两个过滤器,它们允许您从其他数据集构建数据集。我们将从vtkMergeFilter开始。

        vtkMergeFilter将来自多个数据集的数据块合并为一个新的数据集。例如,您可以从一个数据集获取结构(拓扑和几何),从第二个数据集获取标量,从第三个数据集获取向量,并将它们组合成一个数据集。这里有一个使用它的例子(来自Tcl脚本VTK/Examples/VisualizationAlgorithms/Tcl/imageWarp.tcl)。(请忽略那些你不认识的过滤器,专注于使用vtkMergeFilter。我们将在106页的“基于标量值的Warp”中更详细地描述脚本的细节。)

vtkBMPReader reader
 reader SetFileName $VTK_DATA_ROOT/Data/masonry.bmp
vtkImageLuminance luminance
 luminance SetInputConnection [reader GetOutputPort]
vtkImageDataGeometryFilter geometry
 geometry SetInputConnection [luminance GetOutputPort]
vtkWarpScalar warp
 warp SetInputConnection [geometry GetOutputPort]
warp SetScaleFactor -0.1
# use merge to put back scalars from image file
vtkMergeFilter merge
 merge SetGeometryConnection [warp GetOutputPort]
 merge SetScalarsConnection [reader GetOutputPort]
vtkDataSetMapper mapper
 mapper SetInputConnection [merge GetOutputPort]
 mapper SetScalarRange 0 255
 mapper ImmediateModeRenderingOff
vtkActor actor
 actor SetMapper mapper

        这里发生的是来自vtkWarpScalar(碰巧是vtkPolyData类型)的数据集(或几何)与来自vtkBMPReader的标量数据相结合。由于必须(在成像管道中)从标量数据中单独处理几何图形,因此管道已经分裂并重新连接。
        合并数据时,在组成点属性数据的数据数组中找到的元组的数量必须等于点的数量。对于单元格数据也是如此        

 数据追加式

        像vtkMergeFilter一样,vtkAppendFilter(及其专门的表兄vtkAppendPolyData)通过附加数据集构建新的数据集。附加过滤器接受一个输入列表,每个输入必须是相同的类型。在追加操作期间,只将所有输入数据集共有的数据属性追加在一起。下一节的示例将展示其应用程序的一个很好的示例。

探查

        探测是用一个数据集对另一个数据集进行采样的过程。在VTK中,您可以使用任何数据集作为探针几何,其中点数据属性从另一个数据集映射到。例如,下面的Tcl脚本(取自
VTK/Examples/VisualizationAlgorithms/Tcl/ probeComb.tcl)创建用于采样结构化网格数据集的三个平面(作为探针几何)。然后使用vtkContourFilter对平面进行处理以生成等高线。

# Create pipeline
vtkPLOT3DReader pl3d
 pl3d SetXYZFileName "$VTK_DATA_ROOT/Data/combxyz.bin"
 pl3d SetQFileName "$VTK_DATA_ROOT/Data/combq.bin"
 pl3d SetScalarFunctionNumber 100
 pl3d SetVectorFunctionNumber 202
 pl3d Update;#force data read
# Create the probes. Transform them into right place.
vtkPlaneSource plane
 plane SetResolution 50 50
vtkTransform transP1
 transP1 Translate 3.7 0.0 28.37
 transP1 Scale 5 5 5
 transP1 RotateY 90
vtkTransformPolyDataFilter tpd1
 tpd1 SetInputConnection [plane GetOutputPort]
 tpd1 SetTransform transP1
vtkOutlineFilter outTpd1
 outTpd1 SetInputConnection [tpd1 GetOutputPort]
vtkPolyDataMapper mapTpd1
 mapTpd1 SetInputConnection [outTpd1 GetOutputPort]
vtkActor tpd1Actor
 tpd1Actor SetMapper mapTpd1
 [tpd1Actor GetProperty] SetColor 0 0 0
vtkTransform transP2
 transP2 Translate 9.2 0.0 31.20
 transP2 Scale 5 5 5
 transP2 RotateY 90
vtkTransformPolyDataFilter tpd2
 tpd2 SetInputConnection [plane GetOutputPort]
 tpd2 SetTransform transP2
vtkOutlineFilter outTpd2
 outTpd2 SetInputConnection [tpd2 GetOutputPort]
vtkPolyDataMapper mapTpd2
 mapTpd2 SetInputConnection [outTpd2 GetOutputPort]
vtkActor tpd2Actor
 tpd2Actor SetMapper mapTpd2
 [tpd2Actor GetProperty] SetColor 0 0 0
vtkTransform transP3
 transP3 Translate 13.27 0.0 33.30
 transP3 Scale 5 5 5
 transP3 RotateY 90
vtkTransformPolyDataFilter tpd3
 tpd3 SetInputConnection [plane GetOutputPort]
 tpd3 SetTransform transP3
vtkOutlineFilter outTpd3
 outTpd3 SetInputConnection [tpd3 GetOutputPort]
vtkPolyDataMapper mapTpd3
 mapTpd3 SetInputConnection [outTpd3 GetOutputPort]
vtkActor tpd3Actor
 tpd3Actor SetMapper mapTpd3
 [tpd3Actor GetProperty] SetColor 0 0 0
vtkAppendPolyData appendF
 appendF AddInputConnection [tpd1 GetOutputPort]
 appendF AddInputConnection [tpd2 GetOutputPort]
 appendF AddInputConnection [tpd3 GetOutputPort]
vtkProbeFilter probe
 probe SetInputConnection [appendF GetOutputPort]
 probe SetSourceConnection [pl3d GetOutputPort]
vtkContourFilter contour
 contour SetInputConnection [probe GetOutputPort]
 eval contour GenerateValues 50 [[pl3d GetOutput]\
GetScalarRange]
vtkPolyDataMapper contourMapper
 contourMapper SetInputConnection [contour GetOutputPort]
 eval contourMapper SetScalarRange [[pl3d GetOutput]\
GetScalarRange]
vtkActor planeActor
 planeActor SetMapper contourMapper

        注意,探测是使用vtkProbeFilter的SetInputConnection()方法设置的,要探测的数据集是使用SetSourceConnection()方法设置的。

        探测的另一个有用的应用是对数据重新采样。例如,如果你有一个非结构化网格,并希望使用特定于vtkImageData的工具将其可视化(如体积渲染-参见第139页的“体积渲染”),你可以使用vtkProbeFilter对非结构化网格进行采样,然后将体积可视化。还可以用直线(或曲线)探测数据,并使用输出执行x-y绘图。

        最后一点:切割和探测可以得到类似的结果,尽管分辨率不同。类似于第98页“切割”中描述的例子,vtkProbeFilter可以与vtkPlaneSource一起使用,从结构化网格中生成具有数据属性的平面。然而,切割创建的表面的分辨率取决于输入数据的分辨率。探测创建的表面(和其他几何形状)具有独立于输入数据的分辨率。探测数据时必须小心,避免过采样或过采样。欠采样会导致可视化误差,过采样会消耗过多的计算时间。

用另一个标量给等值面上色

        常见的可视化任务是生成等值面,然后用另一个标量为其上色。虽然您可以使用探针来完成此操作,但是当等值面的数据集包含您希望为等值面的着色的数据时,还有一种更有效的方法。这是因为vtkContourFilter(生成等值面)在生成过程中将所有数据插值到等值面。然后在映射过程中使用插值后的数据为等值面上色。这里有一个来自VTK/的例子
例子/ VisualizationAlgorithms / Tcl / ColorIsosurface.tcl。

vtkPLOT3DReader pl3d
 pl3d SetXYZFileName "$VTK_DATA_ROOT/Data/combxyz.bin"
 pl3d SetQFileName "$VTK_DATA_ROOT/Data/combq.bin"
 pl3d SetScalarFunctionNumber 100
 pl3d SetVectorFunctionNumber 202
 pl3d AddFunction 153
 pl3d Update
vtkContourFilter iso
 iso SetInputConnection [pl3d GetOutputPort]
 iso SetValue 0 .24
vtkPolyDataNormals normals
 normals SetInputConnection [iso GetOutputPort]
 normals SetFeatureAngle 45
vtkPolyDataMapper isoMapper
 isoMapper SetInputConnection [normals GetOutputPort]
 isoMapper ScalarVisibilityOn
 isoMapper SetScalarRange 0 1500
 isoMapper SetScalarModeToUsePointFieldData
 isoMapper ColorByArrayComponent "VelocityMagnitude" 0
vtkLODActor isoActor
 isoActor SetMapper isoMapper
 isoActor SetNumberOfCloudPoints 1000

        首先,使用vtkPLOT3DReader读取数据集。这里我们添加了一个要读取的函数(函数号153),我们知道它被命名为“Velocity Magnitude”。生成一个等值面,它还插入所有输入数据数组,包括速度大小数据。然后,我们通过调用SetScalarModeToUsePointFieldData()方法,并使用ColorByArrayComponent()方法指定用于着色的数据数组,从而使用速度大小来对轮廓进行着色。

提取网格子集

        可视化数据通常很大,处理这样的数据在执行时间和内存需求方面可能相当昂贵。因此,提取数据片段的能力非常重要。

        很多时候,只有数据的一个子集包含有意义的信息,或者可以在不显著损失准确性的情况下降低数据的分辨率。可视化工具箱提供了几个工具来提取部分或子样本数据。我们已经看到了如何使用vtkProbeFilter对数据进行子采样(参见第100页的“探测”)。其他工具包括用于子样本数据的类,以及用于在空间中提取区域内单元的工具。(子抽样工具是特定于数据集类型的。关于子采样图像数据集的信息请参见第105页的“子采样图像数据”,关于子采样结构化网格的信息请参见第113页的“子采样结构化网格”。)在本节中,我们描述如何提取包含在空间区域内的数据集的片段。

        类vtkExtractGeometry提取数据集中位于vtkImplicitFunction内部或外部的所有单元格(记住,隐式函数可以由其他隐式函数的布尔组合组成)。下面的脚本创建两个椭球的布尔组合,用作提取区域。vtkShrinkFilter也用于收缩单元格,以便您可以看到提取的内容。(Tcl脚本来自VTK/Examples/VisualizationAlgorithms/Tcl/ExtractGeometry.tcl。)

vtkQuadric quadric
 quadric SetCoefficients .5 1 .2 0 .1 0 0 .2 0 0
vtkSampleFunction sample
 sample SetSampleDimensions 50 50 50
 sample SetImplicitFunction quadric
 sample ComputeNormalsOff
vtkTransform trans
 trans Scale 1 .5 .333
vtkSphere sphere
 sphere SetRadius 0.25
 sphere SetTransform trans
vtkTransform trans2
 trans2 Scale .25 .5 1.0
vtkSphere sphere2
 sphere2 SetRadius 0.25
 sphere2 SetTransform trans2
vtkImplicitBoolean union
 union AddFunction sphere
 union AddFunction sphere2
 union SetOperationType 0;#union
vtkExtractGeometry extract
 extract SetInputConnection [sample GetOutputPort]
 extract SetImplicitFunction union
vtkShrinkFilter shrink
 shrink SetInputConnection [extract GetOutputPort]
 shrink SetShrinkFactor 0.5
vtkDataSetMapper dataMapper
 dataMapper SetInputConnection [shrink GetOutputPort]
vtkActor dataActor
 dataActor SetMapper dataMapper

        vtkExtractGeometry的输出始终是vtkUnstructuredGrid。这是因为提取过程通常会破坏数据集的拓扑结构,以及最一般的数据集形式
(即,vtkUnstructuredGrid)必须用来表示输出。
        作为旁注:隐式函数可以通过给它们赋值vtkTransform来转换。如果指定,vtkTransform用于修改隐式函数的求值。您可能希望对这种功能进行试验。

提取网格作为多边形数据

        大多数数据集类型不能由图形硬件或库直接呈现。渲染系统通常只支持多边形数据(vtkPolyData)。图形系统也支持结构化数据集,尤其是图像,有时还有卷。如果要渲染所有其他数据集,则需要对它们进行特殊处理。在VTK中,呈现非多边形数据集的一种方法是将它们转换为多边形数据。这是vtkGeometryFilter的函数。

        vtkGeometryFilter接受输入任何类型的vtkDataSet,并在输出上生成vtkPolyData。它使用以下规则执行转换。所有拓扑维度为2或更小的输入单元(如多边形、直线、顶点)都被传递到输出。如果维度3的单元格的面位于数据集的边界上,则将其发送到输出。(一个面是在边界上,如果它只被一个单元格使用。)

        vtkGeometryFilter的主要用途是作为一个转换过滤器。下面的示例来自VTK/Examples/ datamanmanipulation /Tcl/pointToCellData。tcl使用vtkGeometryFilter将2D非结构化网格转换为多边形数据,以便稍后通过接受vtkPolyData作为输入的过滤器进行处理。在这里,vtkConnectivityFilter将数据提取为vtkUnstructuredGrid,然后使用vtkGeometryFilter将其转换为多边形。

vtkConnectivityFilter connect2
 connect2 SetInputConnection [thresh GetOutputPort]
vtkGeometryFilter parison
 parison SetInputConnection [connect2 GetOutputPort]
vtkPolyDataNormals normals2
 normals2 SetInputConnection [parison GetOutputPort]
 normals2 SetFeatureAngle 60
vtkLookupTable lut
 lut SetHueRange 0.0 0.66667
vtkPolyDataMapper parisonMapper
 parisonMapper SetInputConnection [normals2 GetOutputPort]
 parisonMapper SetLookupTable lut
 parisonMapper SetScalarRange 0.12 1.0
vtkActor parisonActor
 parisonActor SetMapper parisonMapper

        事实上,vtkDataSetMapper映射器在内部使用vtkGeometryFilter将任何类型的数据集转换为多边形数据。(过滤器足够智能,可以将输入vtkPolyData直接传递到其输出,而无需处理。)

        此外,vtkGeometryFilter的方法允许您根据点id、单元id的范围或单元是否位于空间中的特定矩形区域来提取单元。vtkGeometryFilter使用PointClippingOn(), SetPointMinimum(), SetPointMaximum()和CellClippingOn(), SetCellMinimum(), SetCellMaximum()方法提取基于点和单元id的数据集片段。最小值和最大值指定要提取的id范围。另外,您可以在空间中使用一个矩形区域来限制提取的内容。使用ExtentClippingOn()和SetExtent()方法来启用区段剪切并指定区段。范围由六个值组成,它们在空间中定义一个边界框(xmin,xmax, ymin,ymax, zmin,zmax)。可以任意组合使用点、单元格和范围裁剪。在调试数据或只想查看数据的一部分时,这是一个有用的特性。

5.2多边形数据可视化

        多边形数据(vtkPolyData)是可视化数据的重要形式。它的重要性在于它被用作图形硬件/渲染引擎的几何接口。除了vtkImageData(图像和体积)使用特殊的成像或体渲染技术外,其他数据类型必须转换为多边形数据才能渲染。您可能希望参考第104页的“将单元提取为多边形数据”来了解如何执行此转换。

        多边形数据(vtkPolyData)由顶点和多边形的组合组成;线和折线;三角形、四边形和多边形;还有三角带。大多数过滤器(输入vtkPolyData)将处理此数据的任何组合;然而,一些过滤器(如vtkDecimatePro和vtkTubeFilter)将只处理部分数据(三角形网格和线条)。

手动创建vtkPolyData

多边形数据可以用几种不同的方式构造。通常,您将创建一个vtkPoints来表示点,然后创建一个到四个vtkCellArrays来表示顶点、线、多边形和三角形带的连接。下面是一个取自VTK/Examples/ datamanmanipulation /Tcl/的例子
CreateStrip.tcl。它创建了一个带有单个三角形带的vtkPolyData。

vtkPoints points
 points InsertPoint 0 0.0 0.0 0.0
 points InsertPoint 1 0.0 1.0 0.0
 points InsertPoint 2 1.0 0.0 0.0
 points InsertPoint 3 1.0 1.0 0.0
 points InsertPoint 4 2.0 0.0 0.0
 points InsertPoint 5 2.0 1.0 0.0
 points InsertPoint 6 3.0 0.0 0.0
 points InsertPoint 7 3.0 1.0 0.0
vtkCellArray strips
 strips InsertNextCell 8;#number of points
 strips InsertCellPoint 0
 strips InsertCellPoint 1
 strips InsertCellPoint 2
 strips InsertCellPoint 3
 strips InsertCellPoint 4
 strips InsertCellPoint 5
 strips InsertCellPoint 6
 strips InsertCellPoint 7
vtkPolyData profile
 profile SetPoints points
 profile SetStrips strips
vtkPolyDataMapper map
 map SetInput profile
vtkActor strip
 strip SetMapper map
 [strip GetProperty] SetColor 0.3800 0.7000 0.1600

在c++中,这里是另一个展示如何创建多维数据集的示例(VTK/Examples/ datamanmanipulation /Cxx/ cube . Cxx)。这一次,我们创建了六个四边形多边形,以及立方体顶点的标量值。

int i;
 static double x[8][3]={{0,0,0}, {1,0,0}, {1,1,0}, {0,1,0},
 {0,0,1}, {1,0,1}, {1,1,1}, {0,1,1}};
 static vtkIdType pts[6][4]={{0,1,2,3}, {4,5,6,7}, {0,1,5,4},
 {1,2,6,5}, {2,3,7,6}, {3,0,4,7}};
 // Create the building blocks of polydata including data attributes.
 vtkPolyData *cube = vtkPolyData::New();
 vtkPoints *points = vtkPoints::New();
 vtkCellArray *polys = vtkCellArray::New();
 vtkFloatArray *scalars = vtkFloatArray::New();
// Load the point, cell, and data attributes.
 for (i=0; i<8; i++) points->InsertPoint(i,x[i]);
 for (i=0; i<6; i++) polys->InsertNextCell(4,pts[i]);
 for (i=0; i<8; i++) scalars->InsertTuple1(i,i);
 // We now assign the pieces to the vtkPolyData.
 cube->SetPoints(points);
 points->Delete();
 cube->SetPolys(polys);
 polys->Delete();
 cube->GetPointData()->SetScalars(scalars);
 scalars->Delete();

        vtkPolyData可以用顶点、直线、多边形和三角形带的任何组合来构造。
此外,vtkPolyData支持一组广泛的操作符,允许您编辑和修改底层结构。更多信息请参考第345页的“多边形数据”。

生成表面法线

        当你渲染一个多边形网格时,你可能会发现图像清楚地显示了网格的多面性(图5-10)。图像可以通过使用Gouraud阴影来改进(参见第53页的“Actor属性”)。然而,Gouraud着色依赖于网格中每个点的法线的存在。vtkPolyDataNormals过滤器可用于在网格上生成法线。第217页的“挤压”脚本,第94页的“字形”脚本和第102页的“用另一个标量给等值面上色”脚本都使用了vtkpolydatanorals。

        两个重要的实例变量是Splitting和FeatureAngle。如果开启了分割,则特征边缘(定义为边缘两侧的多边形法线形成大于或等于特征角度的边缘)被“分割”,也就是说,沿边缘复制点,并且在特征边缘的两侧分离网格(参见可视化工具箱文本)。这创建了新的点,但允许尖锐的角落呈现清晰。另一个重要的实例变量是FlipNormals。调用FlipNormalsOn()会导致过滤器反转法线的方向(以及多边形连接列表的顺序)。

抽取器

        多边形数据,尤其是三角形网格,是一种常见的图形数据形式。过滤器如vtkContourFilter生成三角形网格。通常,这些网格是相当大的,不能被修改订购或处理足够快,可用于交互式应用程序。抽取技术的发展就是为了解决这个问题。抽取,也被称为多边形简化、网格简化或多分辨率建模,是一个减少三角形网格中三角形数量的过程,同时保持对原始网格的忠实近似。

        VTK支持三种抽取方法:vtkDecimatePro、vtkQuadricClustering和vtkQuadricDecimation。所有的都是类似的使用和应用程序,虽然他们各自提供的优点和缺点如下:

        •vtkDecimatePro是相对较快的,并有能力在减少过程中修改拓扑。它使用边缘折叠过程来消除顶点和三角形。它的误差度量是基于到平面的距离/到边缘的距离。vtkDecimatePro的一个很好的功能是,你可以实现任何级别的减少请求,因为算法将开始撕裂网格成块来实现这一点(如果拓扑修改是允许的)。

        •vtkQuadricDecimation使用Garland和Heckbert在Siggraph ' 97使用quadric error Metrics的曲面简化中提出的二次误差度量。它使用边缘折叠来消除顶点和三角形。二次误差度量是公认的较好的误差度量之一。

        •vtkQuadricClustering是最快的算法。它是基于Peter Lindstrom在他的Siggraph 2000论文《大型多边形模型的核外简化》中提出的算法。它能够快速减少巨大的网格,并且类支持处理网格块的能力(使用StartAppend(), Append()和EndAppend()方法)。这使用户可以避免将整个网格读入内存。该算法适用于大型网格;当网格变得更小时,三角测量过程就不能很好地工作了。(将这种算法与其他算法结合起来是一种很好的方法。)下面是一个使用vtkDecimatePro的例子。它改编自Tcl脚本VTK/Examples/ VisualizationAlgorithms/Tcl/deciFran。tcl(图5-11)。

vtkDecimatePro deci
 deci SetInputConnection [fran GetOutputPort]
 deci SetTargetReduction 0.9
 deci PreserveTopologyOn
vtkPolyDataNormals normals
 normals SetInputConnection [fran GetOutputPort]
 normals FlipNormalsOn
vtkPolyDataMapper franMapper
 franMapper SetInputConnection [normals GetOutputPort]
vtkActor franActor
 franActor SetMapper franMapper
 eval [franActor GetProperty] SetColor 1.0 0.49 0.25

        vtkDecimatePro的两个重要实例变量是targereduce和PreserveTopology。TargetReduction是所请求的减少量(例如,值为0.9意味着我们希望将网格中的三角形数量减少90%)。取决于您是否允许拓扑更改(PreserveTopologyOn/Off()),您可能会或可能不会实现所要求的减少。如果PreserveTopology关闭,那么vtkDecimatePro将为您提供所请求的减少。最后注意:抽取过滤器将三角形数据作为输入。如果你有一个多边形网格,你可以用vtkTriangleFilter将多边形转换为三角形。

非光滑网格

        多边形网格通常包含影响渲染图像质量的噪声或过度粗糙度。例如,等表面低分辨率数据可以显示混叠或步进效果。处理这个问题的一种方法是使用平滑。平滑是一个过程,调整点的位置,以减少在表面的噪声内容。

        VTK提供了两个平滑对象:vtkSmoothPolyDataFilter和vtkWindowedSincPolyDataFilter。两者中,vtkWindowedSincPolyDataFilter给出了最好的结果,并且稍微快一些。下面的例子(取自VTK/Examples/VisualizationAlgorithms/Tcl/ smoothfranc . Tcl)展示了如何使用平滑滤波器。该示例与前一节中的示例相同,只是添加了平滑滤波器。图5-12显示了平滑对抽取网格的影响。

# decimate and smooth data
vtkDecimatePro deci
 deci SetInputConnection [fran GetOutputPort]
 deci SetTargetReduction 0.9
 deci PreserveTopologyOn
vtkSmoothPolyDataFilter smoother
 smoother SetInputConnection [deci GetOutputPort]
 smoother SetNumberOfIterations 50
vtkPolyDataNormals normals
 normals SetInputConnection [smoother GetOutputPort]
 normals FlipNormalsOn
vtkPolyDataMapper franMapper
 franMapper SetInputConnection [normals GetOutputPort]
vtkActor franActor
 franActor SetMapper franMapper
 eval [franActor GetProperty] SetColor 1.0 0.49 0.25

两种平滑滤波器的使用相似。有一些可选的方法来控制沿特征边缘和边界平滑的效果。查看在线文档和/或.h文件以获取更多信息。

素材数据

        裁剪和裁剪(参见第98页的“裁剪”)一样,使用隐式函数来定义要裁剪的曲面。剪切将多边形网格分割成多个部分,如图5-13所示。裁剪将多边形原语分割成裁剪表面两侧的独立部分。与剪切一样,剪切允许您设置定义隐式剪切函数值的剪切值。

        下面的例子使用一个平面来剪辑一个奶牛的多边形模型。剪辑值用于沿其法线移动平面,以便可以在不同位置剪辑模型。下面显示的示例Tcl脚本取自VTK/Examples/VisualizationAlgorithms/Tcl/ClipCow.tcl。

# Read the polygonal data and generate vertex normals
vtkBYUReader cow
 cow SetGeometryFileName "$VTK_DATA_ROOT/Data/Viewpoint/cow.g"
vtkPolyDataNormals cowNormals
 cowNormals SetInputConnection [cow GetOutputPort]
# Define a clip plane to clip the cow in half
vtkPlane plane
 plane SetOrigin 0.25 0 0
 plane SetNormal -1 -1 0
vtkClipPolyData clipper
 clipper SetInputConnection [cowNormals GetOutputPort]
 clipper SetClipFunction plane
clipper GenerateClippedOutputOn
 clipper SetValue 0.5
vtkPolyDataMapper clipMapper
 clipMapper SetInputConnection [clipper GetOutputPort]
vtkActor clipActor
 clipActor SetMapper clipMapper
 eval [clipActor GetProperty] SetColor $peacock
# Create the rest of the cow in wireframe
vtkPolyDataMapper restMapper
 restMapper SetInputConnection [clipper GetClippedOutputPort]
vtkActor restActor
 restActor SetMapper restMapper
 [restActor GetProperty] SetRepresentationToWireframe

        GenerateClippedOutputOn()方法使过滤器创建第二个输出:被剪掉的数据。该输出以线框形式显示在图中。如果使用SetValue()方法更改剪辑值,则隐式函数将在与原始平面平行但高于或低于原始平面的点进行切割。(你也可以改变vtkPlane的定义来达到同样的结果。)

Generate Texture Coordinates

        有几个过滤器可用于生成纹理坐标:vtkTextureMapToPlane, vtktexturemapto圆柱体和vtkTextureMapToSphere。这些对象分别基于平面、圆柱和球面坐标系生成纹理坐标。此外,类vtkTransformTextureCoordinates允许您通过翻译和缩放纹理坐标来定位纹理映射在表面上。下面的例子展示了使用vtktexturemapto圆柱体为vtkDelaunay3D对象生成的非结构化网格创建纹理坐标(更多信息请参阅第218页的“Delaunay Triangulation”)。完整的例子可以在VTK/ Examples/VisualizationAlgorithms/Tcl/ generatetexturecords . Tcl找到。

vtkPointSource sphere
 sphere SetNumberOfPoints 25
vtkDelaunay3D del
 del SetInputConnection [sphere GetOutputPort]
 del SetTolerance 0.01
vtkTextureMapToCylinder tmapper
 tmapper SetInputConnection [del GetOutputPort]
 tmapper PreventSeamOn
vtkTransformTextureCoords xform
 xform SetInputConnection [tmapper GetOutputPort]
 xform SetScale 4 4 1
vtkDataSetMapper mapper
 mapper SetInputConnection [xform GetOutputPort]
vtkBMPReader bmpReader
 bmpReader SetFileName "$VTK_DATA_ROOT/Data/masonry.bmp"
vtkTexture atext
 atext SetInputConnection [bmpReader GetOutputPort]
 atext InterpolateOn
vtkActor triangulation
 triangulation SetMapper mapper
 triangulation SetTexture atext

        在这个例子中,单位球面上的一组随机点被三角化。然后在三角形上生成纹理坐标。这些纹理坐标然后在i-j纹理颜色中缩放-确定方向以引起纹理重复。最后,读取纹理贴图并将其分配给角色。

        (作为旁注:vtkDataSetMapper的实例是接受任何类型的数据作为输入的映射器。他们使用vtkGeometryFilter的内部实例,然后使用vtkPolyDataMapper将数据转换为多边形原语,然后将其传递给渲染引擎。有关更多信息,请参阅第104页的“将单元格提取为多边形数据”。)

        要了解更多关于纹理坐标的信息,您可能希望运行VTK/Examples/VisualizationAlgorithms/Tcl/ transformtexturecords . Tcl中的示例。这个GUI允许你选择多边形模型,纹理贴图,选择不同的纹理生成技术,并为你提供使用vtktransformtexturecords转换纹理的方法。

5.3可视化结构化网格

        结构网格拓扑结构规则,几何结构不规则,如图3-2 (c)所示。结构网格常用于数值分析(如计算流体动力学)。vtkStructuredGrid数据集由六面体(vtkHexahedron)或四边形(vtkQuad)单元组成。


手动创建vtkStructuredGrid
通过指定网格尺寸(定义拓扑)以及定义x-y-z点坐标(定义几何形状)的vtkPoints对象来创建结构化网格。这个代码来源于VTK/
例子/ DataManipulation Cxx / SGrid.cxx。

vtkPoints points
points InsertPoint 0 0.0 0.0 0.0
...etc...
vtkStructuredGrid sgrid
sgrid SetDimensions 13 11 11
sgrid SetPoints points

确保vtkPoints对象中的点数与i、j和k拓扑方向上的三维值的乘积所定义的点数一致。

提取计算平面

        在大多数情况下,结构化网格由接受vtkDataSet作为输入的过滤器处理(参见第89页的“可视化技术”)。一个直接接受vtkStructuredGrid作为输入的过滤器是vtkStructuredGridGeometryFilter。该过滤器用于根据Extent实例变量的指定,将网格的部分提取为点、线或多边形“平面”。(Extent是一个6向量,描述了一个(imin,imax, jmin,jmax, kmin,kmax)拓扑区域。)

        在下面的示例中,我们读取一个结构化网格,提取三个平面,并使用相关的矢量数据(来自VTK/Examples/VisualizationAlgorithms/Tcl/warpComb.tcl)扭曲这些平面。

vtkPLOT3DReader pl3d
 pl3d SetXYZFileName "$VTK_DATA_ROOT/Data/combxyz.bin"
 pl3d SetQFileName "$VTK_DATA_ROOT/Data/combq.bin"
 pl3d SetScalarFunctionNumber 100
 pl3d SetVectorFunctionNumber 202
 pl3d Update
vtkStructuredGridGeometryFilter plane
 plane SetInputConnection [pl3d GetOutputPort]
 plane SetExtent 10 10 1 100 1 100
vtkStructuredGridGeometryFilter plane2
 plane2 SetInputConnection [pl3d GetOutputPort]
 plane2 SetExtent 30 30 1 100 1 100
vtkStructuredGridGeometryFilter plane3
 plane3 SetInputConnection [pl3d GetOutputPort]
 plane3 SetExtent 45 45 1 100 1 100
vtkAppendPolyData appendF
 appendF AddInputConnection [plane GetOutputPort]
 appendF AddInputConnection [plane2 GetOutputPort]
 appendF AddInputConnection [plane3 GetOutputPort]
vtkWarpScalar warp
 warp SetInputConnection [appendF GetOutputPort]
 warp UseNormalOn
 warp SetNormal 1.0 0.0 0.0
 warp SetScaleFactor 2.5
vtkPolyDataNormals normals
 normals SetInputConnection [warp GetOutputPort]
 normals SetFeatureAngle 60
vtkPolyDataMapper planeMapper
 planeMapper SetInputConnection [normals GetOutputPort]
 eval planeMapper SetScalarRange [[pl3d GetOutput] GetScalarRange]
vtkActor planeActor
 planeActor SetMapper planeMapper

次采样结构化网格

结构化网格可以像图像数据一样进行子采样(参见第105页的“图像数据子采样”)。vtkExtractGrid执行子采样和数据提取。

vtkPLOT3DReader pl3d
 pl3d SetXYZFileName "$VTK_DATA_ROOT/Data/combxyz.bin"
 pl3d SetQFileName "$VTK_DATA_ROOT/Data/combq.bin"
 pl3d SetScalarFunctionNumber 100
 pl3d SetVectorFunctionNumber 202
 pl3d Update
vtkExtractGrid extract
 extract SetInputConnection [pl3d GetOutputPort]
 extract SetVOI 30 30 -1000 1000 -1000 1000
extract SetSampleRate 1 2 3
 extract IncludeBoundaryOn

在本例中,以(1,2,3)的采样率提取原始结构化网格(尺寸为57x33x25)的一个子集,从而得到尺寸为(1,17,9)的结构化网格。IncludeBoundaryOn方法确保即使采样率没有拾取边界,也可以提取边界。

5.4可视化直线网格

直线网格在拓扑上是规则的,在几何上是半规则的(如图3-2 (b))。在数值分析中经常使用直线网格。vtklineargrid数据集由体素组成
(vtkVoxel)或像素(vtkPixel)单元。

手动创建vtklineargrid

通过指定网格尺寸(定义拓扑)以及三个标量数组(定义x-y-z轴上的点坐标)创建直线网格(定义几何形状)。此代码由VTK/Examples/ datamanmanipulation /Cxx/RGrid.cxx修改而来。

vtkFloatArray *xCoords = vtkFloatArray::New();
for (i=0; i<47; i++) xCoords->InsertNextValue(x[i]);
vtkFloatArray *yCoords = vtkFloatArray::New();
for (i=0; i<33; i++) yCoords->InsertNextValue(y[i]);
vtkFloatArray *zCoords = vtkFloatArray::New();
for (i=0; i<44; i++) zCoords->InsertNextValue(z[i]);
vtkRectilinearGrid *rgrid = vtkRectilinearGrid::New();
rgrid->SetDimensions(47,33,44);
rgrid->SetXCoordinates(xCoords);
rgrid->SetYCoordinates(yCoords);
rgrid->SetZCoordinates(zCoords);

确保x、y和z方向上的标量数量等于i、j和k拓扑方向上的三维值。

提取计算平面

在大多数情况下,直线网格由接受vtkDataSet作为输入的过滤器处理(参见第89页的“可视化技术”)。一个直接接受vtkreclineargrid作为输入的过滤器是vtkreclineargridgeometryfilter。该过滤器用于根据Extent实例变量的指定,将网格的部分提取为点、线或多边形“平面”。(Extent是一个6向量,描述了一个(imin,imax, jmin,jmax, kmin,kmax)拓扑区域。)
下面的例子,我们从之前在VTK/Examples/ datamanmanipulation /Cxx/RGrid.cxx中找到的继续

vtkRectilinearGridGeometryFilter *plane =
vtkRectilinearGridGeometryFilter::New();
plane->SetInput(rgrid);
plane->SetExtent(0,46, 16,16, 0,43);

5.5可视化非结构化网格

非结构化网格在拓扑和几何上都是不规则的(见图3-2 (f))。非结构化网格常用于数值分析(如有限元分析)。任何和所有单元格类型都可以在非结构化网格中表示。

手动创建vtkUnstructuredGrid

通过vtkPoints实例定义几何形状,并通过插入单元定义拓扑结构来创建非结构化网格。(此脚本源自示例VTK/Examples/ datamanmanipulation /
Tcl / BuildUGrid.tcl)。

vtkPoints tetraPoints
 tetraPoints SetNumberOfPoints 4
 tetraPoints InsertPoint 0 0 0 0
 tetraPoints InsertPoint 1 1 0 0
 tetraPoints InsertPoint 2 .5 1 0
 tetraPoints InsertPoint 3 .5 .5 1
vtkTetra aTetra
 [aTetra GetPointIds] SetId 0 0
 [aTetra GetPointIds] SetId 1 1
 [aTetra GetPointIds] SetId 2 2
 [aTetra GetPointIds] SetId 3 3
vtkUnstructuredGrid aTetraGrid
 aTetraGrid Allocate 1 1
 aTetraGrid InsertNextCell [aTetra GetCellType] [aTetra GetPointIds]
 aTetraGrid SetPoints tetraPoints
...insert other cells if any...

在将单元格插入vtkUnstructuredGrid实例之前,必须调用Allocate()方法。提供给此方法的值是数据的初始大小,以及在需要额外内存时扩展分配的大小。较大的值通常会提供更好的性能(因为需要更少的内存重新分配)。

提取部分网格

在大多数情况下,非结构化网格由接受vtkDataSet作为输入的过滤器处理(参见第89页的“可视化技术”)。一个直接接受vtkUnstructuredGrid作为输入的过滤器是vtkExtractUnstructuredGrid。此过滤器用于使用一系列点id、单元id或几何边界(定义边界框的Extent实例变量)提取网格的部分。这个脚本来源于Tcl脚本VTK/Examples/VisualizationAlgorithms/Tcl/
ExtractUGrid.tcl。

vtkDataSetReader reader
 reader SetFileName "$VTK_DATA_ROOT/Data/blow.vtk"
 reader SetScalarsName "thickness9"
 reader SetVectorsName "displacement9"
vtkCastToConcrete castToUnstructuredGrid
 castToUnstructuredGrid SetInputConnection [reader GetOutputPort]
vtkWarpVector warp
 warp SetInput [castToUnstructuredGrid GetUnstructuredGridOutput]
vtkConnectivityFilter connect
 connect SetInputConnection [warp GetOutputPort]
 connect SetExtractionModeToSpecifiedRegions
 connect AddSpecifiedRegion 0
 connect AddSpecifiedRegion 1
vtkDataSetMapper moldMapper
 moldMapper SetInputConnection [reader GetOutputPort]
 moldMapper ScalarVisibilityOff
vtkActor moldActor
 moldActor SetMapper moldMapper
 [moldActor GetProperty] SetColor .2 .2 .2
 [moldActor GetProperty] SetRepresentationToWireframe
vtkConnectivityFilter connect2
 connect2 SetInputConnection [warp GetOutputPort]
 connect2 SetExtractionModeToSpecifiedRegions
 connect2 AddSpecifiedRegion 2
vtkExtractUnstructuredGrid extractGrid
 extractGrid SetInputConnection [connect2 GetOutputPort]
 extractGrid CellClippingOn
 extractGrid SetCellMinimum 0
 extractGrid SetCellMaximum 23
vtkGeometryFilter parison
 parison SetInputConnection [extractGrid GetOutputPort]
vtkPolyDataNormals normals2
 normals2 SetInputConnection [parison GetOutputPort]
 normals2 SetFeatureAngle 60
vtkLookupTable lut
 lut SetHueRange 0.0 0.66667
vtkPolyDataMapper parisonMapper
 parisonMapper SetInputConnection [normals2 GetOutputPort]
 parisonMapper SetLookupTable lut
 parisonMapper SetScalarRange 0.12 1.0
vtkActor parisonActor
 parisonActor SetMapper parisonMapper

        在这个例子中,我们使用单元剪辑(即,使用单元id)结合连接过滤器来提取网格的部分。类似地,我们可以使用点id和几何范围来提取网格的部分。vtkConnectivityFilter(和相关类vtkPolyDataConnectivityFilter)用于提取数据集的连接部分。(当细胞共享点时,它们是连接在一起的。)SetExtractionModeToSpecifiedRegions()方法向过滤器指明要提取的连接区域。默认情况下,连通性过滤器提取遇到的最大连接区域。如何- 现在,也可以像这个例子一样指定一个特定的区域,这当然需要一些实验来确定哪个区域是哪个。

轮廓非结构化网格

一个特殊的等高线类可用于生成非结构化网格的等高线。类vtkContourGrid是一个比通用vtkContourFilter等高轮廓过滤器性能更高的版本。
通常你不需要实例化这个类,因为vtkContourFilter会自动创建vtkContourGrid的内部实例,如果它感觉到它的输入类型是vtkUnstructuredGrid。
这就是我们对可视化技术的概述。你也可以参考下一章,它描述了图像处理和体绘制。另外,请参见“过滤器摘要”

本书为英文翻译而来,供学习vtk.js的人参考。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
VTK用户指南 版本4.0 William J. Schroeder 1998-2000 第一部分 VTK 介绍 第1章 欢迎 机构-----------------------------------------------------------------------------------------------8 怎样使用VTK----------------------------------------------------------------------------------8 附加资源-----------------------------------------------------------------------------------------8 第2章 安装 2.1 概述-----------------------------------------------------------------------------------------------9 2.2 安装VTK到Windows9x/NT/ME/2000/XP------------------------------------------------9 二进制安装-------------------------------------------------------------------------------------9 源代码安装-------------------------------------------------------------------------------------9 2.3 安装VTK到Unix操作系统 源代码安装------------------------------------------------------------------------------------10 运行CMake------------------------------------------------------------------------------------11 编译源代码 建立VTK多平台 安装VTK 第3章 系统概述 3.1 系统设计---------------------------------------------------------------------------------------12 图形模型--------------------------------------------------------------------------------------13 可视化模型-----------------------------------------------------------------------------------15 3.2 创建一个应用---------------------------------------------------------------------------------19 用户方法、对象和命令--------------------------------------------------------------------19 Tcl----------------------------------------------------------------------------------------------19 C++---------------------------------------------------------------------------------------------20 Java Phthon Visual Basic/COM/ActiveX 3.3 在两种语言间转换 第二部分 通过例子学习VTK 第4章 基础 4.1 创建1个简单的模型-------------------------------------------------------------------------24 程序化源对象---------------------------------------------------------------------------------24 读取源对象------------------------------------------------------------------------------------26 4.2 使用VTK交互器-----------------------------------------------------------------------------27 vtk绘制窗口交互器 交互风格 4.3 滤波数据---------------------------------------------------------------------------------------29 4.4 控制相机---------------------------------------------------------------------------------------30 安装相机 简单操作方法 控制视角方向 透视与正交视 保存与恢复相机状态 4.5 控制光线---------------------------------------------------------------------------------------32 位置光 4.6 控制3D道具-----------------------------------------------------------------------------------32 指定vtk道具3D位置 演员 演员的详细级 装配 体 vtk装载3D道具 4.7 作用纹理---------------------------------------------------------------------------------------37 4.8 拾取---------------------------------------------------------------------------------------------38 vtk装配路线 例子 4.9 vtk坐标和坐标系---------------------------------------------------------------------------40 4.10 控制vtk演员2D----------------------------------------------------------------------------41 4.11 注释--------------------------------------------------------------------------------------------41 2D注释 3D注释和vtk跟踪 4.12 特殊绘图类-----------------------------------------------------------------------------------44 尺度棒 X-Y绘制 边界盒轴 标记数据 4.13 变换数据--------------------------------------------------------------------------------------48 高级变换 第5章 可视化技术 5.1 可视化VTK数据集vtkDataSet(和子类) -------------------------------------------------50 使用数据属性进行工作 颜色映射 轮廓化 浮雕化 流线图 流线表面 剪裁 融合数据 附加数据 用另外一个尺度给等值面赋颜色 抽取单元格子集 抽取单元格作为多边形数据 5.2 可视化多边形数据---------------------------------------------------------------------------67 手工产生多边形数据 产生表面当量 十比一抽取 平滑网格 粘贴数据 产生纹理坐标 5.3 可视化结构网格-----------------------------------------------------------------------------74 手工产生结构化网格 抽取计算平面 结构网格子样化 5.4 可视化直线网格-----------------------------------------------------------------------------76 手工产生VTK直线网格 抽取计算平面 5.5 可视化非结构网格--------------------------------------------------------------------------77 手工产生VTK非结构网格 抽取部分网格 非结构网格轮廓化 第6章 可视化图像和体数据 6.1 VTK结构化点的历史表示-----------------------------------------------------------------80 6.2 手工产生VTK图像数据-------------------------------------------------------------------80 6.3 抽取图像数据子样--------------------------------------------------------------------------81 6.4 基于尺度值的弯曲--------------------------------------------------------------------------83 6.5 图像显示--------------------------------------------------------------------------------------83 图像观察者 图像演员 6.6 图像源-----------------------------------------------------------------------------------------85 2D帆布图像源 3D椭圆体图像源 高斯图像源 网格图像源 噪声图像源 正弦曲线源 6.7 图像处理--------------------------------------------------------------------------------------88 梯度化 高斯平滑 直方图 图像逻辑 重新切片 6.8 体绘制-----------------------------------------------------------------------------------------92 一个简单的例子 为什么会有多种体绘制技术? 产生一个VTK体 使用片层化函数 使用颜色变换函数 在一个体属性中控制颜色和透明度 在一个体属性中控制阴影 产生一个体映射 裁剪一个体 粘贴一个体 对一个体应用3D纹理 控制标准编码 体素光线计算 2D纹理映射 VolumePro绘制硬件 速度和精确度交替使用 使用vtkLODProp3D改善性能 可行性/局限性技术 第7章 建立模型 7.1 隐模型----------------------------------------------------------------------------------------114 定义隐函数 对隐函数进行抽样 7.2 挤压-------------------------------------------------------------------------------------------117 7.3 构建表面-------------------------------------------------------------------------------------119 Delaunay三角形化 高斯油彩 无组织点产生表面 第三部分 VTK研发者指南 第8章 数据接口和其他 8.1 读入器----------------------------------------------------------------------------------------130 多边形数据读入器 图像和体素读入器 数据集读入器 结构化网格读入器 线性网格读入器 非结构化网格读入器 8.2 写入器----------------------------------------------------------------------------------------131 多边形数据读入器 图像和体素读入器 结构化网格读入器 线性网格读入器 非结构化网格读入器 8.3 输入者----------------------------------------------------------------------------------------132 8.4 输出者----------------------------------------------------------------------------------------132 8.5 创建硬拷贝----------------------------------------------------------------------------------132 保存图像 保存大(高分辨率)图像 8.6 产生动画(使用样条) -----------------------------------------------------------------------134 8.7 使用现场数据工作--------------------------------------------------------------------------136 第9章 贡献编码 9.1 编码补偿--------------------------------------------------------------------------------------141 为VTK贡献编码的条件 编码风格 如何贡献编码 9.2 标准方法: 创建和消除对象---------------------------------------------------------------142 9.3 拷贝对象和受保护的方法------------------------------------------------------------------143 9.4 写一个VTK类: 综述-----------------------------------------------------------------------144 找到一个相似类 识别一个超类 单个类Per.h 文件 必需的方法 文档编码 使用SetGet宏 向VTK中添加类 9.5 对象工厂--------------------------------------------------------------------------------------145 综述 如何写一个工厂 如何安装一个工厂 例子工厂 第10章 流水线执行管理 10.1 执行过程--------------------------------------------------------------------------------------151 概述和术语 更新信息通道 传播更新扩展通道 触发异步更新通道 更新数据通道 10.2 使用流---------------------------------------------------------------------------------------162 第11章 VTK数据对象接口 11.1 数据组---------------------------------------------------------------------------------------166 方法 11.2 数据集---------------------------------------------------------------------------------------169 11.3 VTK数据集接口---------------------------------------------------------------------------170 方法 例子 11.4 VTK图像数据接口-----------------------------------------------------------------------174 方法 例子 11.5 VTK点集接口-----------------------------------------------------------------------------176 方法 例子 11.6 VTK结构化网格接口---------------------------------------------------------------------178 方法 例子 11.7 VTK线性网格接口-----------------------------------------------------------------------178 方法 例子 11.8 VTK多边形数据接口---------------------------------------------------------------------179 方法 例子 11.9 VTK非结构化网格接口-----------------------------------------------------------------184 方法 例子 11.10 单元格接口(VTK单元格子类) ------------------------------------------------------185 11.11 其他接口----------------------------------------------------------------------------------187 点 单元格数组 单元格类型 单元格连接 11.12 现场和属性数据接口------------------------------------------------------------------193 现场数据方法 数据集属性方法 第12章 如何写一个过程方法 12.1 概述----------------------------------------------------------------------------------------196 永远不要修改输入数据 参考计数数据 使用Debug宏 回收/删除截入的内在 修改时间 过程事件和异常终止执行 12.2 如何写一个绘图过滤器---------------------------------------------------------------199 概述 简单过滤器 复杂过滤器和流水线执行 抽取绘图过滤器 程序过滤器 重载流水执行方法 12.3 如何写一个图像过滤器---------------------------------------------------------------210 实现一个图像过滤器 第13章 用窗口系统集成 13.1 绘制窗口交互风格--------------------------------------------------------------------------216 13.2 GUI交互的总指导线------------------------------------------------------------------------217 13.3 X Window, Xt, and Motif--------------------------------------------------------------------221 13.4 MS Windows/Microsoft Foundation Classes---------------------------------------------226 13.5 Tcl/Tk-------------------------------------------------------------------------------------------227 13.6 Java 第14章 编码资源 14.1 对象图表--------------------------------------------------------------------------------------230 基础 单元格 数据集 流水线 源 过滤器 映射器 图形 体绘制 成像 OpenGL绘制器 拾取 变换塔形结构 14.2 过滤器总结-----------------------------------------------------------------------------------237 可视化过滤器 映射者对象 演员对象 14.3 VTK文件格式--------------------------------------------------------------------------------244 二进制文件 数据集属性格式 例子 第15章 光盘 15.1 源代码 15.2 例子代码 15.3 Window 9x/NT/ME/2000/XP 预编译二进制 15.4 数据 15.5 文档 15.6 退化测试图像 15.7 Kitware 应用

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值