如何用 VTK 存储矢量场? C++、VTK编写器
How to store a vector field with VTK? C++, VTKWriter
假设我有一个矢量场 u,其分量为 ux、uy 和 uz,定义在 space rx、ry 和 rz 中的(非结构化)位置。
我想要的就是用 VTK 格式存储这个矢量场,即用 libvtk 的 class "vtkwriter" 来启用 Paraview 的可视化。
我想我得到了正确合并位置的代码,但不知何故我不知道如何合并数据:
#include <vtkPoints.h>
#include <vtkPolyDataWriter.h>
#include <vtkSmartPointer.h>
void write_file (double* rx, double* ry, double* rz,
double* ux, double* uy, double* uz,
int n, const char* filename)
{
vtkSmartPointer<vtkPoints> points =
vtkSmartPointer<vtkPoints>::New ();
points->SetNumberOfPoints(n);
for (int i = 0; i < n; ++i) {
points->SetPoint(i, rx[i], ry[i], rz[i]);
}
// how to incorporate the vector field u?
vtkSmartPointer<vtkPolyDataWriter> writer =
vtkSmartPointer<vtkPolyDataWriter>::New ();
writer->setFileName (filename);
// how to tell the writer, what to write?
writer->Write ();
}
第一个问题是:一般的方法是否正确,即坐标的处理方式vtkPoints
?
在网上搜索时,我发现了很多结果,最终文件应该是什么样子。
我可能可以手动生成该格式,但这并不是我真正想要做的。
另一方面,我无法理解 VTK 的文档。每当我查找 class 的文档时,它会引用其他一些 classes 的文档,而这些其他 classes 的文档又会引用第一个 [=14] =]
示例也是如此。
到目前为止,我还没有找到一个解释如何处理在任意位置定义的矢量值数据的示例,而其他示例非常复杂,我完全被困在这里。
我认为,该解决方案以某种方式使用 vtkPolyData
,但我不知道如何插入数据。
我想,它需要一个 vtkDoubleArray
,但到目前为止我还没有找到,如果矢量值如何制作。
提前致谢。
好的,经过反复试验,我完成了它。
定义矢量场的坐标应为 vtkPoints
,感兴趣的数据应为 vtkDoubleArray
。
通过 vtkPolyData::GetPointData()->SetVectors(...)
.
合并到最终的 vtkPolyData
对象中
最后需要设置cell类型为vtkVertex
:
#include <vtkCellArray.h>
#include <vtkDoubleArray.h>
#include <vtkPointData.h>
#include <vtkPoints.h>
#include <vtkPolyData.h>
#include <vtkPolyDataWriter.h>
#include <vtkSmartPointer.h>
#include <vtkVertex.h>
void VTKWriter::write_file(double* rx, double *ry, double *rz,
double* ux, double *uy, double *uz,
int n, const char* filename)
{
vtkSmartPointer<vtkPoints> points =
vtkSmartPointer<vtkPoints>::New();
points->SetNumberOfPoints(n);
vtkSmartPointer<vtkCellArray> vertices =
vtkSmartPointer<vtkCellArray>::New();
vertices->SetNumberOfCells(n);
for (int i = 0; i < n; ++i) {
points->SetPoint(i, rx[i], ry[i], rz[i]);
vtkSmartPointer<vtkVertex> vertex =
vtkSmartPointer<vtkVertex>::New();
vertex->GetPointIds()->SetId(0, i);
vertices->InsertNextCell(vertex);
}
vtkSmartPointer<vtkDoubleArray> u =
vtkSmartPointer<vtkDoubleArray>::New();
u->SetName("u");
u->SetNumberOfComponents(3);
u->SetNumberOfTuples(n);
for (int i = 0; i < n; ++i) {
u->SetTuple3(i, ux[i], uy[i], uz[i]);
}
vtkSmartPointer<vtkPolyData> polydata =
vtkSmartPointer<vtkPolyData>::New();
polydata->SetPoints(points);
polydata->SetVerts(vertices);
polydata->GetPointData()->SetVectors(u);
vtkSmartPointer<vtkPolyDataWriter> writer =
vtkSmartPointer<vtkPolyDataWriter>::New();
writer->SetFileName(filename);
writer->SetInputData(polydata);
writer->Write ();
}
之所以一开始没看懂是因为点、单元格、顶点、点数据和多边形数据之间的交互对于刚接触VTK的人来说不太容易掌握,所以教程不是很清楚完全涵盖这一点,VTK 的 Doxygen 文档在这一点上也毫无用处。
假设我有一个矢量场 u,其分量为 ux、uy 和 uz,定义在 space rx、ry 和 rz 中的(非结构化)位置。
我想要的就是用 VTK 格式存储这个矢量场,即用 libvtk 的 class "vtkwriter" 来启用 Paraview 的可视化。
我想我得到了正确合并位置的代码,但不知何故我不知道如何合并数据:
#include <vtkPoints.h>
#include <vtkPolyDataWriter.h>
#include <vtkSmartPointer.h>
void write_file (double* rx, double* ry, double* rz,
double* ux, double* uy, double* uz,
int n, const char* filename)
{
vtkSmartPointer<vtkPoints> points =
vtkSmartPointer<vtkPoints>::New ();
points->SetNumberOfPoints(n);
for (int i = 0; i < n; ++i) {
points->SetPoint(i, rx[i], ry[i], rz[i]);
}
// how to incorporate the vector field u?
vtkSmartPointer<vtkPolyDataWriter> writer =
vtkSmartPointer<vtkPolyDataWriter>::New ();
writer->setFileName (filename);
// how to tell the writer, what to write?
writer->Write ();
}
第一个问题是:一般的方法是否正确,即坐标的处理方式vtkPoints
?
在网上搜索时,我发现了很多结果,最终文件应该是什么样子。 我可能可以手动生成该格式,但这并不是我真正想要做的。
另一方面,我无法理解 VTK 的文档。每当我查找 class 的文档时,它会引用其他一些 classes 的文档,而这些其他 classes 的文档又会引用第一个 [=14] =]
示例也是如此。 到目前为止,我还没有找到一个解释如何处理在任意位置定义的矢量值数据的示例,而其他示例非常复杂,我完全被困在这里。
我认为,该解决方案以某种方式使用 vtkPolyData
,但我不知道如何插入数据。
我想,它需要一个 vtkDoubleArray
,但到目前为止我还没有找到,如果矢量值如何制作。
提前致谢。
好的,经过反复试验,我完成了它。
定义矢量场的坐标应为 vtkPoints
,感兴趣的数据应为 vtkDoubleArray
。
通过 vtkPolyData::GetPointData()->SetVectors(...)
.
vtkPolyData
对象中
最后需要设置cell类型为vtkVertex
:
#include <vtkCellArray.h>
#include <vtkDoubleArray.h>
#include <vtkPointData.h>
#include <vtkPoints.h>
#include <vtkPolyData.h>
#include <vtkPolyDataWriter.h>
#include <vtkSmartPointer.h>
#include <vtkVertex.h>
void VTKWriter::write_file(double* rx, double *ry, double *rz,
double* ux, double *uy, double *uz,
int n, const char* filename)
{
vtkSmartPointer<vtkPoints> points =
vtkSmartPointer<vtkPoints>::New();
points->SetNumberOfPoints(n);
vtkSmartPointer<vtkCellArray> vertices =
vtkSmartPointer<vtkCellArray>::New();
vertices->SetNumberOfCells(n);
for (int i = 0; i < n; ++i) {
points->SetPoint(i, rx[i], ry[i], rz[i]);
vtkSmartPointer<vtkVertex> vertex =
vtkSmartPointer<vtkVertex>::New();
vertex->GetPointIds()->SetId(0, i);
vertices->InsertNextCell(vertex);
}
vtkSmartPointer<vtkDoubleArray> u =
vtkSmartPointer<vtkDoubleArray>::New();
u->SetName("u");
u->SetNumberOfComponents(3);
u->SetNumberOfTuples(n);
for (int i = 0; i < n; ++i) {
u->SetTuple3(i, ux[i], uy[i], uz[i]);
}
vtkSmartPointer<vtkPolyData> polydata =
vtkSmartPointer<vtkPolyData>::New();
polydata->SetPoints(points);
polydata->SetVerts(vertices);
polydata->GetPointData()->SetVectors(u);
vtkSmartPointer<vtkPolyDataWriter> writer =
vtkSmartPointer<vtkPolyDataWriter>::New();
writer->SetFileName(filename);
writer->SetInputData(polydata);
writer->Write ();
}
之所以一开始没看懂是因为点、单元格、顶点、点数据和多边形数据之间的交互对于刚接触VTK的人来说不太容易掌握,所以教程不是很清楚完全涵盖这一点,VTK 的 Doxygen 文档在这一点上也毫无用处。