我们已经看到了如何使用源对象(阅读器和过程对象)来创建几何图形。(参见第42页的“创建简单模型”。)VTK提供了其他几种技术来生成更复杂的模型。本章涵盖的三种技术是隐式建模、挤压和从无组织点进行表面重建。
如果你正在处理缺乏拓扑或几何结构的数据,VTK可以将这些信息表示为字段数据(使用类vtkDataObject,参见第249页的“使用字段数据”),可以使用本章中的技术进一步处理以生成可视化数据集。例如,通过选择三个变量作为独立变量,可以将n维财务记录简化为三维。然后,这里描述的技术——德劳内三角剖分、高斯飞溅和表面重建——可以用来创建适合于用标准方法可视化的结构。
10.1隐式建模
隐式建模是一种使用三维轮廓(等值面生成)来创建多边形表面网格的强大技术。等高线操作应用于已合成标量值的vtkImageData数据集(常规卷)。隐式建模的关键是可以使用各种各样的技术生成标量场。这些技术包括通过生成原语(例如,表示到一组直线和/或多边形的距离的字段)来产生距离字段,以及使用布尔集合操作来组合标量字段。
创建隐式模型
这里有一个例子,使用一些线来生成一个复杂的多边形表面。这些线被排列成拼写单词“HELLO”,并作为生成种子的几何形状(图10-1)。(Tcl脚本取自VTK/Examples/ modeling /Tcl/hello.tcl。)
# create lines
vtkPolyDataReader reader
reader SetFileName "$VTK_DATA_ROOT/Data/hello.vtk"
vtkPolyDataMapper lineMapper
lineMapper SetInputConnection [reader GetOutputPort]
vtkActor lineActor
lineActor SetMapper lineMapper
eval [lineActor GetProperty] SetColor $red
# create implicit model
vtkImplicitModeller imp
imp SetInputConnection [reader GetOutputPort]
imp SetSampleDimensions 110 40 20
imp SetMaximumDistance 0.25
imp SetModelBounds -1.0 10.0 -1.0 3.0 -1.0 1.0
vtkContourFilter contour
contour SetInputConnection [imp GetOutputPort]
contour SetValue 0 0.25
vtkPolyDataMapper impMapper
impMapper SetInputConnection [contour GetOutputPort]
impMapper ScalarVisibilityOff
vtkActor impActor
impActor SetMapper impMapper
eval [impActor GetProperty] SetColor $peacock
[impActor GetProperty] SetOpacity 0.5
在这个脚本中发生的事情是,划掉单词“hello”的行作为生成原语。vtkimplicitmodeler类计算从线到输出vtkImageData中的点的距离(取到任何线的最近距离),并将此距离分配为数据集中每个点的标量值。然后将输出传递给vtkContourFilter,它生成一个多边形等值面。(等值面值是到生成原语的距离。)
在vtkimplicitmodeler中有几个重要的参数。MaximumDistance实例变量控制距离生成原语有多远才能继续进行距离计算。这个实例变量,表示为网格长度的一小部分,对计算速度有很大的影响:较小的值导致更快的计算,但是如果值太小,等值面可能会变得起伏不定或破裂。SampleDimensions实例变量控制输出vtkImageData的分辨率,ModelBounds控制数据集在空间中的位置和大小。
抽样隐式函数
另一种强大的建模技术是隐式函数的使用。隐式函数有这样的形式
F(x,y,z) = constant
球体、锥体、椭球、平面和许多其他有用的几何实体都可以用隐式函数来描述。例如,以原点为中心的半径为R的球体S可以用方程F(x,y,z) = R2 - x2 - y2 - z2来描述。当F(x,y,z)=0时,方程准确地描述了S。当F(x,y,z) <0,我们描述一个在球面S内的球体,当F(x,y,z) >0,我们描述一个位于球面s外的球面,顾名思义,隐函数隐式地定义了一个曲面;生成表面的显式表示(例如,多边形)需要在一个体积上对函数进行采样,然后执行下一个示例中演示的等等高线操作。
除了建模之外,隐式函数还可以使用集合操作(并、交、差)进行组合。这些操作允许您使用隐式函数的组合创建复杂的几何形状。下面是一个示例脚本,它使用一个球体(冰淇淋)、一个由两个平面相交的圆锥体(创建一个有限范围的圆锥体)和另一个球体来模拟冰淇淋的“咬”。该脚本取自VTK/Examples/ modeling /Tcl/ iceCream.tcl。
# create implicit function primitives
vtkCone cone
cone SetAngle 20
vtkPlane vertPlane
vertPlane SetOrigin .1 0 0
vertPlane SetNormal -1 0 0
vtkPlane basePlane
basePlane SetOrigin 1.2 0 0
basePlane SetNormal 1 0 0
vtkSphere iceCream
iceCream SetCenter 1.333 0 0
iceCream SetRadius 0.5
vtkSphere bite
bite SetCenter 1.5 0 0.5
bite SetRadius 0.25
# combine primitives to build ice-cream cone
vtkImplicitBoolean theCone
theCone SetOperationTypeToIntersection
theCone AddFunction cone
theCone AddFunction vertPlane
theCone AddFunction basePlane
# take a bite out of the ice cream
vtkImplicitBoolean theCream
theCream SetOperationTypeToDifference
theCream AddFunction iceCream
theCream AddFunction bite
# iso-surface to create geometry of the cone
vtkSampleFunction theConeSample
theConeSample SetImplicitFunction theCone
theConeSample SetModelBounds -1 1.5 -1.25 1.25 -1.25 1.25
theConeSample SetSampleDimensions 60 60 60
theConeSample ComputeNormalsOff
vtkContourFilter theConeSurface
theConeSurface SetInputConnection [theConeSample GetOutputPort]
theConeSurface SetValue 0 0.0
vtkPolyDataMapper coneMapper
coneMapper SetInputConnection [theConeSurface GetOutputPort]
coneMapper ScalarVisibilityOff
vtkActor coneActor
coneActor SetMapper coneMapper
eval [coneActor GetProperty] SetColor $chocolate
# iso-surface to create geometry of the ice cream
vtkSampleFunction theCreamSample
theCreamSample SetImplicitFunction theCream
theCreamSample SetModelBound 0 2.5 -1.25 1.25 -1.25 1.25
theCreamSample SetSampleDimensions 60 60 60
theCreamSample ComputeNormalsOff
vtkContourFilter theCreamSurface
theCreamSurface SetInputConnection [theCreamSample GetOutputPort]
theCreamSurface SetValue 0 0.0
vtkPolyDataMapper creamMapper
creamMapper SetInputConnection [theCreamSurface GetOutputPort]
creamMapper ScalarVisibilityOff
vtkActor creamActor
creamActor SetMapper creamMapper
eval [creamActor GetProperty] SetColor $mint
类vtkSampleFunction和vtkContourFilter是构建多边形几何的关键。vtkSampleFunction计算隐式函数(实际上是隐式函数的布尔组合)以生成横跨卷(vtkImageData)数据集的标量。然后使用vtkContourFilter来生成一个近似隐式函数的等值面。近似的准确性取决于隐式函数的性质,以及vtkSampleFunction生成的体积的分辨率(使用SetSampleDimensions()方法指定)。
一些使用注意事项:布尔组合可以嵌套到任意深度。只要确保层次结构不包含自引用循环即可。此外,您可能希望使用vtkDecimatePro来减少轮廓过滤器输出的原语数量,因为三角形的数量可能相当大。有关更多信息,请参阅第107页的“抽取”。
10.2挤压
挤出是一种建模技术,它沿着路径扫描生成对象以创建表面。例如,我们可以在垂直于直线的方向上扫描直线来创建一个平面。
可视化工具包提供了两种挤压方法:线性挤压和旋转挤压。在VTK中,生成对象是vtkPolyData数据集。线条、顶点和“自由边”(仅由一个多边形使用的边)用于生成挤出表面。vtkLinearExtrusionFilter沿着直线路径扫描生成原语;vtkRotationalExtrusionFilter沿着旋转路径扫描它们。(旋转过程中的平移也是可能的。)
在这个例子中,我们将使用一个八角形多边形(即近似于一个圆盘)来扫描一个组合的旋转/平移路径来模拟一个“弹簧”(图10-3)。过滤器围绕z轴挤压其输入(生成原语),同时还沿着z轴平移(在旋转期间)并调整扫描半径。默认情况下,实例变量Capping处于开启状态,因此挤压表面(空心管)由生成原语覆盖。此外,我们必须设置Resolution实例变量以生成合理的近似值。(以下示例中使用的vtkPolyDataNormals过滤器在第107页的“生成表面法线”中有描述。)
# create spring profile (a disk)
vtkPoints points
points InsertPoint 0 1.0 0.0 0.0
points InsertPoint 1 1.0732 0.0 -0.1768
points InsertPoint 2 1.25 0.0 -0.25
points InsertPoint 3 1.4268 0.0 -0.1768
points InsertPoint 4 1.5 0.0 0.00
points InsertPoint 5 1.4268 0.0 0.1768
points InsertPoint 6 1.25 0.0 0.25
points InsertPoint 7 1.0732 0.0 0.1768
vtkCellArray poly
poly InsertNextCell 8;#number of points
poly InsertCellPoint 0
poly InsertCellPoint 1
poly InsertCellPoint 2
poly InsertCellPoint 3
poly InsertCellPoint 4
poly InsertCellPoint 5
poly InsertCellPoint 6
poly InsertCellPoint 7
vtkPolyData profile
profile SetPoints points
profile SetPolys poly
# extrude profile to make spring
vtkRotationalExtrusionFilter extrude
extrude SetInput profile
extrude SetResolution 360
extrude SetTranslation 6
extrude SetDeltaRadius 1.0
extrude SetAngle 2160.0;#six revolutions
vtkPolyDataNormals normals
normals SetInputConnection [extrude GetOutputPort]
normals SetFeatureAngle 60
vtkPolyDataMapper map
map SetInputConnection [normals GetOutputPort]
vtkActor spring
spring SetMapper map
[spring GetProperty] SetColor 0.6902 0.7686 0.8706
[spring GetProperty] SetDiffuse 0.7
[spring GetProperty] SetSpecular 0.4
[spring GetProperty] SetSpecularPower 20
[spring GetProperty] BackfaceCullingOn
vtkLinearExtrusionFilter是类似的,但它比vtkRotationalExtrusionFilter更容易使用。
线性挤压可以沿着用户指定的矢量进行
(setextrusiontypetovectoreextrusion())或指向用户指定的点
(SetExtrusionTypeToPointExtrusion ());或者挤压可以在生成表面的表面法线方向上进行(SetExtrusionTypeToNormalExtrusion())。
10.3构造曲面
通常我们希望从一组非结构化点或其他数据构造一个曲面。所述点可以来自激光数字化系统,也可以由多变量数据组装而成。在本节中,我们将研究从这种形式的数据构建新表面的技术。您可能还希望参考213页的“构建模型”,了解从生成原语(即隐式建模)创建表面的其他方法。Delaunay三角剖分法在计算几何中得到了广泛的应用。Delaunay三角剖分的基本应用是从一组点创建一个简单的网格(即2D的三角形,3D的四面体)。
- 三角网
生成的网格可以以各种方式使用,包括使用标准的可视化技术进行处理。在VTK中,有两个对象用于创建Delaunay三角形:vtkDelaunay2D和vtkDelaunay3D。
注意:Delaunay三角测量是数字敏感的。当前版本的vtkDelaunay3D可能不够强大,无法可靠地处理大量的点。这将在不久的将来得到改善。
vtkDelaunay2D。vtkDelaunay2D对象接受vtkPointSet(或其任何子类)作为输入,并在输出上生成vtkPolyData。通常输出是三角形网格,但如果使用非零Alpha值,则可以生成由三角形,线条和顶点组成的网格。(该参数控制输出原语的“大小”。原始尺寸由n维圆周测量;只有那些圆周半径小于或等于alpha值的网格块被发送到输出。例如,如果长度为L的边小于2*Alpha,则输出该边)。
在下面的Tcl示例中,我们使用(0,1)x-y平面上的随机分布生成点。(vtkDelaunay2D在执行期间忽略z分量,尽管它确实输出z值。)为了创建一个更好的图片,我们使用vtkTubeFilter和vtkGlyph3D在网格边缘周围创建管和网格点周围的球体。该脚本来自VTK/Examples/ modeling /Tcl/ DelMesh.tcl。
# create some points
vtkMath math
vtkPoints points
for {set i 0} {$i<50} {incr i 1} {
eval points InsertPoint $i [math Random 0 1] \
[math Random 0 1] 0.0
}
vtkPolyData profile
profile SetPoints points
# triangulate them
vtkDelaunay2D del
del SetInput profile
del SetTolerance 0.001
vtkPolyDataMapper mapMesh
mapMesh SetInputConnection [del GetOutputPort]
vtkActor meshActor
meshActor SetMapper mapMesh
[meshActor GetProperty] SetColor .1 .2 .4
vtkExtractEdges extract
extract SetInputConnection [del GetOutputPort]
vtkTubeFilter tubes
tubes SetInputConnection [extract GetOutputPort]
tubes SetRadius 0.01
tubes SetNumberOfSides 6
vtkPolyDataMapper mapEdges
mapEdges SetInputConnection [tubes GetOutputPort]
vtkActor edgeActor
edgeActor SetMapper mapEdges
eval [edgeActor GetProperty] SetColor $peacock
[edgeActor GetProperty] SetSpecularColor 1 1 1
[edgeActor GetProperty] SetSpecular 0.3
[edgeActor GetProperty] SetSpecularPower 20
[edgeActor GetProperty] SetAmbient 0.2
[edgeActor GetProperty] SetDiffuse 0.8
vtkSphereSource ball
ball SetRadius 0.025
ball SetThetaResolution 12
ball SetPhiResolution 12
vtkGlyph3D balls
balls SetInputConnection [del GetOutputPort]
balls SetSourceConnection [ball GetOutputPort]
vtkPolyDataMapper mapBalls
mapBalls SetInputConnection [balls GetOutputPort]
vtkActor ballActor
ballActor SetMapper mapBalls
eval [ballActor GetProperty] SetColor $hot_pink
[ballActor GetProperty] SetSpecularColor 1 1 1
[ballActor GetProperty] SetSpecular 0.3
[ballActor GetProperty] SetSpecularPower 20
[ballActor GetProperty] SetAmbient 0.2
[ballActor GetProperty] SetDiffuse 0.8
Tolerance实例变量用于确定点是否重合。位于距离公差(或更小)的点被认为是重合的,其中一个点可以被丢弃。公差表示为输入点边界框对角线长度的分数。vtkDelaunay2D的另一个有用的功能是定义约束边和多边形的能力。
通常,vtkDelaunay2D将生成满足圆周准则的输入点集的Delaunay三角剖分。然而,在许多情况下,指定三角剖分中的边(约束边)或数据中的“孔”(约束多边形)的附加信息可能是可用的。通过指定约束边和多边形,vtkDelaunay2D可以用来生成复杂的点三角剖分。下面的例子(取自VTK/Examples/ modeling /Tcl/constrainedDelaunay.tcl)演示了这一点。
vtkPoints points
points InsertPoint 0 1 4 0
points InsertPoint 1 3 4 0
points InsertPoint 2 7 4 0
...(more points defined)...
vtkCellArray polys
polys InsertNextCell 12
polys InsertCellPoint 0
polys InsertCellPoint 1
polys InsertCellPoint 2
...(a total of two polygons defined)...
vtkPolyData polyData
polyData SetPoints points
polyData SetPolys polys
# generate constrained triangulation
vtkDelaunay2D del
del SetInput polyData
del SetSource polyData
vtkPolyDataMapper mapMesh
mapMesh SetInputConnection [del GetOutputPort]
vtkActor meshActor
meshActor SetMapper mapMesh
# tubes around mesh
vtkExtractEdges extract
extract SetInputConnection [del GetOutputPort]
vtkTubeFilter tubes
tubes SetInputConnection [extract GetOutputPort]
tubes SetRadius 0.1
tubes SetNumberOfSides 6
vtkPolyDataMapper mapEdges
mapEdges SetInputConnection [tubes GetOutputPort]
vtkActor edgeActor
edgeActor SetMapper mapEdges
eval [edgeActor GetProperty] SetColor $peacock
[edgeActor GetProperty] SetSpecularColor 1 1 1
[edgeActor GetProperty] SetSpecular 0.3
[edgeActor GetProperty] SetSpecularPower 20
[edgeActor GetProperty] SetAmbient 0.2
[edgeActor GetProperty] SetDiffuse 0.8
在这个例子中(结果如图10-5左边所示),第二个输入vtkDelaunay2D已经被定义(使用SetSource()方法)。这个输入定义了两个多边形,一个是逆时针顺序的,定义外部矩形边界,另一个是顺时针顺序的,定义三角形中的“vtk”孔。
使用约束边要简单得多,因为边的顺序并不重要。参考示例VTK/Examples/ modeling /Tcl/faultLines。tcl,约束边(提供给第二个输入源的直线和折线)用于沿一组边约束三角剖分。(见图10-5右侧)
vtkDelaunay3D。vtkDelaunay3D类似于vtkDelaunay2D。主要区别在于vtkDelaunay3D的输出是一个非结构化网格数据集(即四面体网格)。
vtkMath math
vtkPoints points
for {set i 0} {$i<25} {incr i 1} {
points InsertPoint $i [math Random 0 1]\
[math Random 0 1] [math Random 0 1]}
vtkPolyData profile
profile SetPoints points
# triangulate them
vtkDelaunay3D del
del SetInput profile
del BoundingTriangulationOn
del SetTolerance 0.01
del SetAlpha 0.2
# shrink the result to help see it better
vtkShrinkFilter shrink
shrink SetInputConnection [del
GetOutputPort]
shrink SetShrinkFactor 0.9
vtkDataSetMapper map
map SetInputConnection [shrink GetOutputPort]
vtkActor triangulation
triangulation SetMapper map
[triangulation GetProperty] SetColor 1 0 0
在这个例子中(取自VTK/Examples/ modeling /Tcl/Delaunay3D.tcl),我们沿着每个坐标轴对3D空间中(0,1)范围内的一组随机点进行三角测量。一个非零
使用Alpha,因此网格由四面体、三角形、线和点的集合组成。得到的四面体网格用vtkShrinkFilter收缩,用vtkDataSetMapper映射。
高斯抛雪球算法
很多时候,数据没有固有的结构,或者数据的维度相对于2D、3D或4D(带有动画的3D)可视化技术所能表示的维度来说很高。这样的数据集的一个例子是标量值(即温度),位于热电偶测量系统在空间中的随机点。多维财务数据(即,许多记录,每个记录有几个变量)是另一个例子。处理此类数据的最简单和最可靠的方法之一是重新采样卷上的数据(即vtkImageData数据集),然后可视化重新采样的数据集。在下面的c++示例(VTK/Examples/ modeling /Cxx/finance.cxx)中,我们展示了如何对多变量财务数据进行此操作。您可能希望参考第249页的“使用字段数据”,以获得处理该数据的另一种方法。
数据由一个包含3188条财务记录的ASCII文本文件组成。每条记录包含以下信息:拖欠贷款的时间(TIME_LATE);贷款的月供(MONTHLY_PAYMENT);贷款剩余本金(UNPAID_PRINCIPAL);贷款的原始金额(LOAN_AMOUNT);贷款利率(INTEREST_RATE);以及借款人的月收入(MONTHLY_INCOME)。
可视化的目的是理解这些变量与主要关注的变量TIME_LATE之间的关系。建立数学模型或理解这些数据有助于金融机构降低贷款风险。在这个例子中,我们要做的是在贷款总人数的上下文中显示逾期还款贷款。我们首先选择MONTHLY_PAYMENT作为x轴,INTEREST_RATE作为y轴,LOAN_AMOUNT作为z轴,然后选择TIME_LATE作为因变量(即,我们通过选择三个变量并忽略其他变量来降低数据的维数)。类vtkGaussianSplatter用于简化图10-6的非零alpha的3D Delaunay三角剖分。金融数据,并使用高斯椭球将它们“飞溅”到vtkImageData数据集中。然后使用vtkContourFilter生成等值面。请注意,vtkGaussianSplatter的第一个实例在不缩放splats的情况下对整个数据集进行splats,而vtkGaussianSplatter的第二个实例根据标量值(即TIME_LATE)对splats进行缩放。逾期贷款以红色呈现,而总人口以半透明白色呈现。(如图10-7所示)下面是演示高斯飞溅的c++代码。
main ()
{
double bounds[6];
vtkDataSet *dataSet;
...read data...
if ( ! dataSet ) exit(0);
// construct pipeline for original
population
vtkGaussianSplatter *popSplatter =
vtkGaussianSplatter::New();
popSplatter->SetInput(dataSet);
popSplatter-
>SetSampleDimensions(50,50,50);
popSplatter->SetRadius(0.05);
popSplatter->ScalarWarpingOff();
vtkContourFilter *popSurface = vtkContourFilter::New();
popSurface->SetInputConnection(popSplatter->GetOutputPort());
popSurface->SetValue(0,0.01);
vtkPolyDataMapper *popMapper = vtkPolyDataMapper::New();
popMapper->SetInputConnection(popSurface->GetOutputPort());
popMapper->ScalarVisibilityOff();
vtkActor *popActor = vtkActor::New();
popActor->SetMapper(popMapper);
popActor->GetProperty()->SetOpacity(0.3);
popActor->GetProperty()->SetColor(.9,.9,.9);
// construct pipeline for delinquent population
vtkGaussianSplatter *lateSplatter = vtkGaussianSplatter::New();
lateSplatter->SetInput(dataSet);
lateSplatter->SetSampleDimensions(50,50,50);
lateSplatter->SetRadius(0.05);
lateSplatter->SetScaleFactor(0.005);
vtkContourFilter *lateSurface = vtkContourFilter::New();
lateSurface->SetInputConnection(lateSplatter->GetOutputPort());
lateSurface->SetValue(0,0.01);
vtkPolyDataMapper *lateMapper = vtkPolyDataMapper::New();
lateMapper->SetInputConnection(lateSurface->GetOutputPort());
lateMapper->ScalarVisibilityOff();
vtkActor *lateActor = vtkActor::New();
lateActor->SetMapper(lateMapper);
lateActor->GetProperty()->SetColor(1.0,0.0,0.0);
// create axes
popSplatter->Update();
popSplatter->GetOutput()->GetBounds(bounds);
vtkAxes *axes = vtkAxes::New();
axes->SetOrigin(bounds[0], bounds[2], bounds[4]);
axes->SetScaleFactor(
popSplatter->GetOutput()->GetLength()/5);
vtkTubeFilter *axesTubes = vtkTubeFilter::New();
axesTubes->SetInputConnection(axes->GetOutputPort());
axesTubes->SetRadius(axes->GetScaleFactor()/25.0);
axesTubes->SetNumberOfSides(6);
vtkPolyDataMapper *axesMapper = vtkPolyDataMapper::New();
axesMapper->SetInputConnection(axesTubes->GetOutputPort());
vtkActor *axesActor = vtkActor::New();
axesActor->SetMapper(axesMapper);
// graphics stuff
vtkRenderer *renderer = vtkRenderer::New();
vtkRenderWindow *renWin = vtkRenderWindow::New();
renWin->AddRenderer(renderer);
vtkRenderWindowInteractor *iren =
vtkRenderWindowInteractor::New();
iren->SetRenderWindow(renWin);
// read data, set up renderer
renderer->AddActor(lateActor);
renderer->AddActor(axesActor);
renderer->AddActor(popActor);
renderer->SetBackground(1,1,1);
renWin->SetSize(300,300);
// interact with data
iren->Initialize();
iren->Start();
...clean up...
}
这个例子的有趣之处在于,大多数延迟付款发生在高利率(预期)和较低月付款金额的地区。因此,这些数据中的问题是利率较高的小额贷款。
另一个用于将数据重新采样到卷中的过滤器是vtkShepardMethod。
来自无组织点的曲面
您可能希望修改前面的c++示例来使用这个类。在计算机图形应用程序中,表面通常表示为三维无组织点。激光和其他数字化设备通常是这些点集的来源。从点云重建曲面在计算和算法上都具有挑战性。虽然前面描述的方法(Delaunay三角剖分和高斯飞溅)可以用于不同的个成功的从点云重建表面,VTK有一个专门为此目的设计的类。
vtkSurfaceReconstructionFilter可以用来从点云重建表面。这个过滤器以vtkDataSet作为输入,定义假定位于3D对象表面上的点。下面的脚本(VTK/Examples/ modeling /Tcl/reconstructSurface.tcl)展示了如何使用过滤器。操作结果如图10-8所示。
vtkProgrammableSource pointSource
pointSource SetExecuteMethod readPoints
proc readPoints {} {
set output [pointSource GetPolyDataOutput]
vtkPoints points
$output SetPoints points
set file [open "$VTK_DATA_ROOT/Data/
cactus.3337.pts" r]
while { [gets $file line] != -1 } {
scan $line "%s" firstToken
if { $firstToken == "p" } {
scan $line "%s %f %f %f" firstToken x y z
points InsertNextPoint $x $y $z
}
}
points Delete; #okay, reference counting
}
# Construct the surface and create isosurface
vtkSurfaceReconstructionFilter surf
surf SetInputConnection [pointSource GetOutputPort]
vtkContourFilter cf
cf SetInputConnection [surf GetOutputPort]
cf SetValue 0 0.0
vtkReverseSense reverse
reverse SetInputConnection [cf GetOutputPort]
reverse ReverseCellsOn
reverse ReverseNormalsOn
vtkPolyDataMapper map
map SetInputConnection [reverse GetOutputPort]
map ScalarVisibilityOff
vtkActor surfaceActor
surfaceActor SetMapper map
该示例首先使用vtkProgrammableSource过滤器从文件读取点。(参见第419页的“可编程过滤器”获取更多信息)vtkSurfaceReconstructionFilter获取这些点并生成一个体积表示(类似于vtkGaussianSplatter在上一节中所做的)。将体积轮廓化(等值面值=0.0)以生成表面和顶点法线。由于数据的性质,顶点法线指向内,因此使用vtkReverseSense来反转法线和多边形排序。(在一些系统中,向内指向法线会导致渲染过程中的黑色表面。)
图10-8曲面重构。只要点足够近,算法就能很好地工作。可以设置实例变量samplespace来控制输出卷的尺寸。如果samplespace的值为负值,则算法对体素大小进行猜测。输出体积限制输入点云。
本书为英文翻译而来,供学习vtk.js的人参考。