Как сохранить векторное поле с помощью VTK? C++, VTKWriter

Допустим, у меня есть векторное поле u с компонентами ux, uy и uz, определенными в (неструктурированных) позициях в пространстве rx, ry и rz.

Все, что я хочу, это сохранить это векторное поле в формате VTK, то есть с классом "vtkwriter" из libvtk, чтобы включить визуализацию с 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?

При поиске в интернете я нахожу много результатов о том, как должен выглядеть окончательный файл. Я мог бы, вероятно, сгенерировать этот формат вручную, но это не совсем то, что я хочу сделать.

С другой стороны, я почему-то не могу понять документацию ВТК. Всякий раз, когда я просматриваю документацию класса, она ссылается на документацию некоторых других классов, а документация этих других классов ссылается на первый.

То же самое относится и к примерам. До сих пор я не нашел ни одного, который объяснял бы, как обращаться с векторными данными, который определен в произвольных позициях, а другие примеры настолько сложны, что я полностью застрял здесь.

Я думаю, решение как-то использует vtkPolyData, но я не могу понять, как вставить данные. Я думаю, это нужно vtkDoubleArray, но я пока не нашел, как сделать, если вектор ценится.

Заранее спасибо.

1 ответ

Решение

Хорошо, я сделал это после достаточно проб и ошибок. Координаты, в которых определяется векторное поле, должны быть vtkPoints и интересующие данные должны быть 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 ();
}

Причина, по которой я сначала этого не понял, заключалась в том, что взаимодействие между точками, ячейками, вершинами, точечными данными и полиданными нелегко понять, когда кто-то новичок в VTK, учебники на самом деле не охватывают это вообще, и документация ВТК по Doxygen также почему-то бесполезна на этом этапе.

Другие вопросы по тегам