スポンサーリンク

VTK 9.5.1 で .vtkhdf 形式でファイル保存/読み込み(vtkMultiBlockDataSet)

.vtkhdf形式は複数のオブジェクトを一つのファイルにまとめて保存できる。

ただしバイナリ形式なのと、保存形式が複数あるのでややこしい。今回はvtkMultiBlockDataSet形式で保存する。

saveMultiblock.hpp

vtkhdfで保存・読み込みを行う。データはvtkMultiBlockDataSetで保存する

#pragma once

#include "createpoly.hpp"

#include <vtkDataArraySelection.h>


/////////////////////////////////////////
/////////////////////////////////////////
// 保存コード
/////////////////////////////////////////
/////////////////////////////////////////
void save_as_Multiblock() {

    vtkSmartPointer<vtkPolyData> polypoints = createPoints();
    vtkSmartPointer<vtkPolyData> polycone = createCone();
    vtkSmartPointer<vtkPolyData> polyline = createPolyLine();

    auto mb = vtkSmartPointer<vtkMultiBlockDataSet>::New();
    mb->SetNumberOfBlocks(3);

    mb->SetBlock(0, polypoints);
    mb->SetBlock(1, polycone);
    mb->SetBlock(2, polyline);

    auto w = vtkSmartPointer<vtkHDFWriter>::New();
    w->SetInputData(mb);
    w->SetFileName("scene.vtkhdf");
    w->Write();

}

/////////////////////////////////////////
/////////////////////////////////////////
// 読み込みコード
/////////////////////////////////////////
/////////////////////////////////////////
std::vector< vtkSmartPointer<vtkPolyData> > load_as_Multiblock() {

    std::vector< vtkSmartPointer<vtkPolyData> > polyvec;


    auto reader = vtkSmartPointer<vtkHDFReader>::New();
    reader->SetFileName("scene.vtkhdf");

    reader->GetPointDataArraySelection()->EnableAllArrays();
    reader->GetCellDataArraySelection()->EnableAllArrays();

    reader->Update();

    //vtkDataObject* out = reader->GetOutput();
    vtkDataObject* out = reader->GetOutputDataObject(0);
    auto mb = vtkMultiBlockDataSet::SafeDownCast(out);

    std::cout << "MultiBlock with " << mb->GetNumberOfBlocks() << " blocks\n";

	// 各ブロックを処理
    for (unsigned int i = 0; i < mb->GetNumberOfBlocks(); i++) {

        vtkPolyData* poly = vtkPolyData::SafeDownCast(mb->GetBlock(i));

        if (poly) {

            // RGB配列があればアクティブにする例
            if (poly->GetPointData()->HasArray("RGB")) {
                poly->GetPointData()->SetActiveScalars("RGB");
            }

        }

        polyvec.push_back(poly);
    }


    return polyvec;
}

createpoly.hpp

データを作成する。

#pragma once

#include <vtkSmartPointer.h>

#include <vtkDoubleArray.h>
#include <vtkPointData.h>

#include <vtkConeSource.h>

#include <vtkCellArray.h>
#include <vtkPoints.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>

#include <vtkUnsignedCharArray.h>
#include <array>

#include <vtkCellData.h>
 
vtkSmartPointer<vtkPolyData> createPoints() {

    // 頂点配列
    vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();

    // 色情報の配列
    vtkSmartPointer<vtkUnsignedCharArray> colors = vtkSmartPointer<vtkUnsignedCharArray>::New();
    colors->SetNumberOfComponents(3);
    colors->SetName("RGB");

    // 頂点インデクスの配列
    vtkSmartPointer<vtkCellArray> cells = vtkSmartPointer<vtkCellArray>::New();



    for (size_t i = 0; i < 100000; i++) {

        double x = (double)rand() / (double)RAND_MAX;
        double y = (double)rand() / (double)RAND_MAX;
        double z = (double)rand() / (double)RAND_MAX;

        points->InsertNextPoint(x, y, z);  // 座標追加

        unsigned char r = static_cast<unsigned char>(x * 255.0);
        unsigned char g = static_cast<unsigned char>(y * 255.0);
        unsigned char b = static_cast<unsigned char>(z * 255.0);
        colors->InsertNextTypedTuple(std::array<unsigned char, 3>{r, g, b}.data());

        cells->InsertNextCell(1);  // 要素数
        cells->InsertCellPoint(i); // 頂点インデックスを追加

    }

    // --- vtkPolyData作成 ---
    auto polydata = vtkSmartPointer<vtkPolyData>::New();
    polydata->SetPoints(points);
    polydata->SetVerts(cells);
    polydata->GetPointData()->SetScalars(colors);
    polydata->GetPointData()->SetActiveScalars("RGB");

    return polydata;
}

vtkSmartPointer<vtkPolyData> createCone() {
    vtkSmartPointer<vtkConeSource> coneSource;
    coneSource = vtkSmartPointer<vtkConeSource>::New();
    coneSource->SetHeight(1.0);
    coneSource->SetRadius(0.2);
    coneSource->SetResolution(10);
    coneSource->Update();
    vtkSmartPointer<vtkPolyData> conePolyData = coneSource->GetOutput();
    return conePolyData;
}

vtkSmartPointer<vtkPolyData> createPolyLine() {

    // VTKのデータ構造で W の形状を作成
    // 頂点配列
    vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
    // 色情報の配列
    vtkSmartPointer<vtkUnsignedCharArray> colors = vtkSmartPointer<vtkUnsignedCharArray>::New();
    colors->SetNumberOfComponents(3);
    colors->SetName("RGB");

    // 頂点インデクスの配列
    vtkSmartPointer<vtkCellArray> cells = vtkSmartPointer<vtkCellArray>::New();
    // 頂点追加
    points->InsertNextPoint(0.0, 0.0, 0.0);  // 0
    colors->InsertNextTypedTuple(std::array<unsigned char, 3>{255,0,0}.data());


    points->InsertNextPoint(0.5, 1.0, 0.0);  // 1
    colors->InsertNextTypedTuple(std::array<unsigned char, 3>{0,255, 0}.data());

    points->InsertNextPoint(1.0, 0.0, 0.0);  // 2
    colors->InsertNextTuple3(0.0, 0.0, 1.0);
    colors->InsertNextTypedTuple(std::array<unsigned char, 3>{0, 0, 255}.data());

    points->InsertNextPoint(1.5, 1.0, 0.0);  // 3
    colors->InsertNextTypedTuple(std::array<unsigned char, 3>{255, 255, 0}.data());

    points->InsertNextPoint(2.0, 0.0, 0.0);  // 4
    colors->InsertNextTypedTuple(std::array<unsigned char, 3>{255, 0, 255}.data());

    // 頂点インデクス追加
    cells->InsertNextCell(5); // 要素数
    cells->InsertCellPoint(0);
    cells->InsertCellPoint(1);
    cells->InsertCellPoint(2);
    cells->InsertCellPoint(3);
    cells->InsertCellPoint(4);
    // --- vtkPolyData作成 ---
    auto polydata = vtkSmartPointer<vtkPolyData>::New();
    polydata->SetPoints(points);
    polydata->SetLines(cells);
    polydata->GetPointData()->SetScalars(colors);


    return polydata;

}

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)


この記事のトラックバックURL: