如何用VTK存储矢量场?C++、VTKWriter

hoe*_*zlw 5 c++ vtk

假设我有一个向量场 u,其分量为 ux、uy 和 uz,定义在空间 rx、ry 和 rz 中的(非结构化)位置。

我想要的只是用 VTK 格式存储这个向量场,即用 libvtk 中的“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 ();
}
Run Code Online (Sandbox Code Playgroud)

第一个问题是:一般的方式,即坐标的处理是否正确vtkPoints

在互联网上搜索时,我找到了很多结果,最终文件应该是什么样子。我可能可以手动生成该格式,但这并不是我真正想要做的。

另一方面,我不知何故无法理解 VTK 的文档。每当我查找一个类的文档时,它都会引用其他一些类的文档,而这些其他类的文档又引用第一个类的文档。

对于示例也同样如此。到目前为止,我还没有找到一个解释如何处理在任意位置定义的向量值数据的例子,而其他示例非常复杂,我完全被困在这里。

我认为,解决方案以某种方式使用vtkPolyData,但我不知道如何插入数据。我认为,它需要一个vtkDoubleArray,但到目前为止我还没有找到如何使向量值。

提前致谢。

hoe*_*zlw 5

好的,经过足够的尝试和错误,我完成了。定义矢量场的坐标应该是vtkPoints,感兴趣的数据应该是 a vtkDoubleArray。并入最终vtkPolyData对象是通过 完成的vtkPolyData::GetPointData()->SetVectors(...)

最后,单元格类型需要设置为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 ();
}
Run Code Online (Sandbox Code Playgroud)

我一开始没有明白这一点的原因是,因为当一个人刚接触 VTK 时,点、单元、顶点、点数据和多数据之间的交互并不容易掌握,教程根本没有真正涵盖这一点, VTK 的 Doxygen 文档此时也毫无用处。