如何使用 VTK 存储向量场?C++,VTKWriter [英] How to store a vector field with VTK? C++, VTKWriter

查看:41
本文介绍了如何使用 VTK 存储向量场?C++,VTKWriter的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

比方说,我有一个向量场 u,它具有分量 ux、uy 和 uz,定义在空间 rx、ry 和 rz 中的(非结构化)位置.

Let's say, I have a vector field u, with components ux, uy and uz, defined at (unstructured) positions in space rx, ry and rz.

我想要的只是使用 VTK 格式存储这个向量场,即使用 libvtk 中的vtkwriter"类来启用 Paraview 的可视化.

All I want, is to store this vector field with the VTK format, i.e. with the class "vtkwriter" from libvtk to enable visualization with Paraview.

我想我得到了正确合并位置的代码,但不知何故我不知道如何合并数据:

I think I got the code for incorporating the positions right, but somehow I can't figure out, how to incorporate the data:

#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处理坐标?

The first question is: is the general way correct, i.e. the coordinate's treatment with vtkPoints?

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

When searching the internet, I find many results, how the final file should look like. I could probably generate that format by hand, but that isn't really what I want to do.

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

On the other hand, I'm somehow not able to understand VTK's documentation. Whenever I look up the documentation of a class, it refers to the documentation of some other classes, and these other classes' documentations refer back to the first one.

同样适用于示例.到目前为止,我还没有找到一个解释如何处理向量值数据的例子,它定义在任意位置,其他例子太复杂了,我完全卡在这里了.

The same holds for the examples. So far, I haven't found one, that explains how to handle vector valued data, that is defined at arbitrary positions, and the other examples are so complicated, that I'm completely stuck here.

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

I think, the solution somehow uses vtkPolyData, but I can't figure out, how to insert data. I think, it needs a vtkDoubleArray, but I haven't found so far, how to make if vector valued.

提前致谢.

推荐答案

好的,经过反复试验,我搞定了.定义矢量场的坐标应该是 vtkPoints,感兴趣的数据应该是 vtkDoubleArray.合并到最终的 vtkPolyData 对象是通过 vtkPolyData::GetPointData()->SetVectors(...) 完成的.

Ok, I got it done after enough trial and error. The coordinates, where the vector field is defined should be vtkPoints and the data of interest should be a vtkDoubleArray. The incorporation into the final vtkPolyData object is done via vtkPolyData::GetPointData()->SetVectors(...).

最后需要设置cell类型为vtkVertex:

Finally, the cell type needs to be be set as 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 文档在某种程度上也毫无用处.

The reason, why I didn't got this at first was, because the interaction between points, cells, vertices, pointdata and polydata isn't easy to grasp when one is new to VTK, the tutorials do not really cover this at all, and VTK's Doxygen documentation is also somehow useless at this point.

这篇关于如何使用 VTK 存储向量场?C++,VTKWriter的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆