问题描述:如何读写.vtk文件中的polygons部分的triangularmeshconnectivity。事实上这些polygons除了triangle,还可以是任何类型的vtkCellArray,比如:quad,line或vertex。以triangle为例,假设现在需要将a.vtk文件里的点读出来进行一些处理(e.g.,归一化),处理完的点保存为一个新的文件b.vtk,并将a.vtk中的meshconnectivity部分也存入b.vtk中。(对点的操作不影响点之间的连接关系。)
a.vtk文件部分内容如下:
# vtk DataFile Version 3.0 vtk output ASCII DATASET POLYDATA POINTS 106 float 0.61315 0.47236 0.52229 0.59243 0.47742 0.52472 0.58274 0.49616 0.51892 0.56334 0.51798 0.51629 0.53354 0.53861 0.51642 0.5015 0.54841 0.51615 ...... 0.49798 0.5287 0.47898 0.46925 0.52361 0.47613 0.45389 0.51279 0.47315 0.44238 0.49115 0.46563 0.42996 0.47329 0.45953 0.40371 0.46865 0.46676 0.38897 0.45678 0.48526 POLYGONS 208 832 3 0 1 14 3 14 13 0 3 13 14 27 3 27 26 13 3 1 2 15 3 15 14 1 3 14 15 28 3 28 27 14 3 2 3 16 3 16 15 2 3 15 16 29 ......
a.vtk可视化是这个样子:
代码如下(playWithPoly.cpp):
#include <vtkPolyDataWriter.h> #include <vtkPolyDataReader.h> #include "vtkPolyData.h" #include "vtkPoints.h" #include "vtkSmartPointer.h" #include <vtkCellArray.h> #include <iostream> int main( int argc, char* argv[] ){ // read in the .vtk file vtkSmartPointer<vtkPolyDataReader> reader = vtkSmartPointer<vtkPolyDataReader>::New(); reader->SetFileName(argv[1]); reader->Update(); vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New(); polyData = reader->GetOutput(); // define a new vtkPoints object to hold the new points vtkSmartPointer<vtkPoints> point_new = vtkSmartPointer<vtkPoints>::New(); // get access to the points for(unsigned int i = 0; i < polyData->GetNumberOfPoints(); i++){ double p[3]; polyData->GetPoint(i,p); point_new->InsertNextPoint(p[0]+0.1,p[1],p[2]); // simple example: translate by 0.2 in x direction to each point } // get access to polygons (points connectivity) vtkSmartPointer<vtkCellArray> polys = vtkSmartPointer<vtkCellArray>::New(); polys = polyData->GetPolys(); // save the scaled points and the polygons to a new vtkPolyData vtkSmartPointer<vtkPolyData> polyData_new = vtkSmartPointer<vtkPolyData>::New(); polyData_new->SetPoints(point_new); polyData_new->SetPolys(polys); // save this new vtkPolyData to a new .vtk file (location specified by argv[2]) vtkSmartPointer<vtkPolyDataWriter> polyDataWriter = vtkSmartPointer<vtkPolyDataWriter>::New(); polyDataWriter->SetInput(polyData_new); polyDataWriter->SetFileName(argv[2]); polyDataWriter->Update(); std::cout<<"---Finished!"<<std::endl; return 0; }
运行:
./playWithPoly ~/Desktop/a.vtk~/Desktop/b.vtk
运行后a.vtk和b.vtk同时显示的效果(a.vtk,b.vtk和运行结果截图已打包可以点这里下载):
说明:
在实际应用中,构建一个点集的.vtkfile with point meshconnectivity时,Polygon通常都是需要自己根据逻辑创建的。可以参考如下几个很好的例子:
http://www.paraview.org/Wiki/VTK/Examples/Cxx/GeometricObjects/Polygon
http://www.cmake.org/Wiki/VTK/Examples/Python/GeometricObjects/Display/Polygon
http://www.cmake.org/Wiki/VTK/Examples/Cxx/Boneyard/GeometricObjects/WriteFile/Polygon
http://www.vtk.org/Wiki/VTK/Examples/Cxx/PolyData/VertexConnectivity
http://www.vtk.org/Wiki/VTK/Examples/Cxx/PolyData/CellPointNeighbors
另一个例子:
I have polygon data in a vtkCellArray instance, how can I get access to the point ids in each triangle cell?
http://public.kitware.com/pipermail/vtkusers/2013-January/078000.html