赞
踩
VTK中的Spline样条可以将顶点连接成平滑的线段,并且对线段重新采样。目前主要有vtkSCurveSpline、vtkKochanekSpline、vtkCardinalSpline和vtkParametricSpline四种Spline可以用,后文将对比这四种Spline的效果。
后文的示例都是用同样的四个单独顶点来完成,顶点的顺序可以更改,而Spline是严格根据点集中顶点的顺序来完成连接的,所以调换顶点顺序可以更改Spline的模样。
//定义点集
vtkPoints* ps = vtkPoints::New();
double a[3] = { 0,0,0 }; //插入顶点a
ps->InsertNextPoint(a);
double b[3] = { 1,0,0 }; //插入顶点b
ps->InsertNextPoint(b);
double c[3] = { 1,1,0 }; //插入顶点c
ps->InsertNextPoint(c);
double d[3] = { 0,1,0 }; //插入顶点d
ps->InsertNextPoint(d);
//将顶点插入到vtkPolyData中,没有定义拓扑
vtkNew<vtkPolyData> pointData;
pointData->SetPoints(ps);
//代码参考官方示例 vtkNew<vtkKochanekSpline> xSpline; vtkNew<vtkKochanekSpline> ySpline; vtkNew<vtkKochanekSpline> zSpline; vtkNew<vtkParametricSpline> spline; spline->SetXSpline(xSpline); spline->SetYSpline(ySpline); spline->SetZSpline(zSpline); spline->SetPoints(ps); vtkParametricFunctionSource* functionSource = vtkParametricFunctionSource::New(); functionSource->SetParametricFunction(spline); functionSource->SetUResolution(50 * ps->GetNumberOfPoints()); functionSource->SetVResolution(50 * ps->GetNumberOfPoints()); functionSource->SetWResolution(50 * ps->GetNumberOfPoints()); functionSource->Update(); vtkPolyData* out = functionSource->GetOutput();
vtkKochanekSpline生成的曲线弯曲幅度会相对小一点。
vtkSmartPointer<vtkCardinalSpline> xSpline = vtkSmartPointer<vtkCardinalSpline>::New(); vtkSmartPointer<vtkCardinalSpline> ySpline = vtkSmartPointer<vtkCardinalSpline>::New(); vtkSmartPointer<vtkCardinalSpline> zSpline = vtkSmartPointer<vtkCardinalSpline>::New(); vtkSmartPointer<vtkParametricSpline> spline = vtkSmartPointer<vtkParametricSpline>::New(); spline->SetXSpline(xSpline); spline->SetYSpline(ySpline); spline->SetZSpline(zSpline); spline->SetPoints(ps); vtkParametricFunctionSource* functionSource = vtkParametricFunctionSource::New(); functionSource->SetParametricFunction(spline); functionSource->SetUResolution(50 * ps->GetNumberOfPoints()); functionSource->SetVResolution(50 * ps->GetNumberOfPoints()); functionSource->SetWResolution(50 * ps->GetNumberOfPoints()); functionSource->Update(); vtkPolyData* out = functionSource->GetOutput();
vtkCardinalSpline生成曲线的弯曲幅度会相对更大一点。
vtkNew<vtkParametricSpline> spline;
spline->SetPoints(ps);
vtkParametricFunctionSource* functionSource =
vtkParametricFunctionSource::New();
functionSource->SetParametricFunction(spline);
functionSource->SetUResolution(50 * ps->GetNumberOfPoints());
functionSource->SetVResolution(50 * ps->GetNumberOfPoints());
functionSource->SetWResolution(50 * ps->GetNumberOfPoints());
functionSource->Update();
vtkPolyData* out = functionSource->GetOutput();
vtkParametricSpline生成曲线的效果目前看来和vtkCardinalSpline类似,实际上vtkParametricSpline默认使用的就是vtkCardinalSpline方法。
vtkNew<vtkSCurveSpline> xSpline;
vtkNew<vtkSCurveSpline> ySpline;
vtkNew<vtkSCurveSpline> zSpline;
vtkNew<vtkParametricSpline> spline;
spline->SetXSpline(xSpline);
spline->SetYSpline(ySpline);
spline->SetZSpline(zSpline);
spline->SetPoints(ps);
vtkParametricFunctionSource* functionSource =
vtkParametricFunctionSource::New();
functionSource->SetParametricFunction(spline);
functionSource->Update();
vtkPolyData* out = functionSource->GetOutput();
如果需要用直线连接点集合的话,vtkSCurveSpline很合适。
如果你的顶点数量很大的话,要用以上Filter连接顶点前,注意要先对顶点排序,目前VTK还没有能直接用来对顶点集合排序的函数,因此基本需要自行实现。
这个函数要使用的话需要额外的第三方依赖:
//在编译VTK时的CMakeList文件中或者CMAKE界面中设置
''Module_SplineDrivenImageSlicer:BOOL=ON'' or
''VTK_MODULE_ENABLE_VTK_SplineDrivenImageSlicer:STRING=WANT''
主要作用:能够输入一组线段(例如上文代码段中的数据输出out),然后经过该Filter的处理,能够得到该线段在各顶点处的法向量和切向量属性数据。
// Create the frame vtkNew<vtkFrenetSerretFrame> frame; //functionSource为上文代码段中的生成曲线的结果 frame->SetInputConnection(functionSource->GetOutputPort()); frame->ConsistentNormalsOn(); frame->Update(); vtkNew<vtkGlyph3D> glyph3DNormals; vtkNew<vtkGlyph3D> glyph3DTangents; vtkNew<vtkGlyph3D> glyph3DBinormals; // for each vector, create a Glyph3D and DeepCopy the output double radius = 0.05; frame->GetOutput()->GetPointData()->SetActiveVectors("FSNormals"); MakeGlyphs(frame->GetOutput(), radius, glyph3DNormals.GetPointer()); vtkNew<vtkPolyData> normalsPolyData; normalsPolyData->DeepCopy(glyph3DNormals->GetOutput()); frame->GetOutput()->GetPointData()->SetActiveVectors("FSTangents"); MakeGlyphs(frame->GetOutput(), radius, glyph3DTangents.GetPointer()); vtkNew<vtkPolyData> tangentsPolyData; tangentsPolyData->DeepCopy(glyph3DTangents->GetOutput()); frame->GetOutput()->GetPointData()->SetActiveVectors("FSBinormals"); MakeGlyphs(frame->GetOutput(), radius, glyph3DBinormals.GetPointer()); vtkNew<vtkPolyData> binormalsPolyData; binormalsPolyData->DeepCopy(glyph3DBinormals->GetOutput());
将各属性渲染出来如下图所示:
示例链接
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。