vtk用户指南 第十章 建筑模型

本文介绍了VTK生成复杂模型的三种技术,包括隐式建模、挤压和从无组织点进行表面重建。隐式建模可创建多边形表面网格;挤压有线性和旋转两种方式;表面重建涉及德劳内三角剖分、高斯飞溅等方法,还能处理高维数据,帮助理解变量关系。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        我们已经看到了如何使用源对象(阅读器和过程对象)来创建几何图形。(参见第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的人参考。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值