.vtkhdf形式は複数のオブジェクトを一つのファイルにまとめて保存できる。
ただしバイナリ形式なのと、保存形式が複数あるのでややこしい。今回はvtkMultiBlockDataSet形式で保存する。
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; }
データを作成する。
#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; }