How to store a vector field with VTK? C++, VTKWriter

好久不见. 提交于 2019-12-11 00:38:17

问题


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.

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 ();
}

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.

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.

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.

Thanks in advance.


回答1:


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(...).

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 ();
}

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.



来源:https://stackoverflow.com/questions/38937139/how-to-store-a-vector-field-with-vtk-c-vtkwriter

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!