//VTK_MODULE_INITに必要 #include <vtkAutoInit.h> #include <vtkSmartPointer.h> #include <vtkRenderer.h> #include <vtkRenderWindow.h> #include <vtkRenderWindowInteractor.h> #include <eigen/Core> #include <vtkPolyDataMapper.h> #include <vtkPolyData.h> #include <vtkPoints.h> #include <vtkPointData.h> #include <vtkProperty.h> // 色を設定するために必要 #include <vtkUnsignedCharArray.h> // 色を設定するために必要 #include <vtkVertexGlyphFilter.h> // 点を描画するために必要 #include <vtkGlyph3D.h> // 点を球にするために必要 #include <vtkSphereSource.h> // 球を作成するために必要 #pragma comment(lib,"opengl32.lib") #pragma comment(lib,"psapi.lib") #pragma comment(lib,"dbghelp.lib") #pragma comment(lib,"ws2_32.lib") //必須 VTK_MODULE_INIT(vtkRenderingOpenGL2); VTK_MODULE_INIT(vtkInteractionStyle);
void CreatePointArray( std::vector<Eigen::Vector3d>& vertices, vtkSmartPointer<vtkPolyData> vtk_mesh, vtkSmartPointer<vtkPoints> vtk_points) { // 頂点配列を作成 for (const auto& v : vertices) { vtk_points->InsertNextPoint(v.x(), v.y(), v.z()); } // 頂点配列を設定 vtk_mesh->SetPoints(vtk_points); }
void CreateColorsArray( std::vector<Eigen::Vector3d>& vertex_colors, vtkSmartPointer<vtkPolyData> vtk_mesh, vtkSmartPointer<vtkUnsignedCharArray> vtk_colors) { vtk_colors->SetNumberOfComponents(3); for (const auto& c : vertex_colors) { vtk_colors->InsertNextTuple3(c.x() * 255, c.y() * 255, c.z() * 255); } vtk_mesh->GetPointData()->SetScalars(vtk_colors); }
vtkSmartPointer<vtkActor> CreatePointCloudActor( std::vector<Eigen::Vector3d> vertices, std::vector<Eigen::Vector3d> colors, vtkAlgorithmOutput* glyphpoly // 点を球にするためのvtkPolyData ) { auto vtk_cloud = vtkSmartPointer<vtkPolyData>::New(); auto vtk_points = vtkSmartPointer<vtkPoints>::New(); auto vtk_colors = vtkSmartPointer<vtkUnsignedCharArray>::New(); /////////////////////////////////////////////////////// // 頂点の配列を生成 CreatePointArray(vertices, vtk_cloud, vtk_points); /////////////////////////////////////////////////////// // 色の配列を生成 CreateColorsArray(colors, vtk_cloud, vtk_colors); /////////////////////////////////////////////////////// /////////////////////////////////////////////////////// // Glyph3Dを使用して点に球を描画 vtkSmartPointer<vtkGlyph3D> glyph3D = vtkSmartPointer<vtkGlyph3D>::New(); glyph3D->SetSourceConnection(glyphpoly); glyph3D->SetInputData(vtk_cloud); glyph3D->SetColorModeToColorByScalar(); // 色情報を使用 glyph3D->SetScaleFactor(0.1); // 球をスケーリング glyph3D->SetScaleModeToDataScalingOff(); // サイズを一定にする glyph3D->Update(); /////////////////////////////////////////////////////// auto vtk_mapper = vtkSmartPointer<vtkPolyDataMapper>::New(); vtk_mapper->SetInputConnection(glyph3D->GetOutputPort()); auto vtk_actor = vtkSmartPointer<vtkActor>::New(); vtk_actor->SetMapper(vtk_mapper); return vtk_actor; }
int main(int /*argc*/, char** /*argv*/) { //////////////////////////////////////// // 点群の定義 // ランダムの1000頂点を作成 std::vector<Eigen::Vector3d> vertices; for (int i = 0; i < 1000; i++) { vertices.push_back(Eigen::Vector3d::Random()); } // ランダムの色を設定 std::vector<Eigen::Vector3d> colors; for (int i = 0; i < 1000; i++) { Eigen::Vector3d rnd = Eigen::Vector3d::Random(); // -1~1の乱数 Eigen::Vector3d v01 = 0.5 * (rnd + Eigen::Vector3d::Ones()); // 0~1に変換 colors.push_back(v01); } //////////////////////////////////////// // 球を作成 vtkSmartPointer<vtkSphereSource> sphereSource = vtkSmartPointer<vtkSphereSource>::New(); sphereSource->SetRadius(1.0); // 球の半径を設定 sphereSource->Update(); // 点群のアクタを作戦 auto actor = CreatePointCloudActor(vertices, colors,sphereSource->GetOutputPort() ); ////////////////////////////////////// auto renderer = vtkSmartPointer<vtkRenderer>::New(); renderer->AddActor(actor); renderer->ResetCamera(); ////////////////////////////////////// auto interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New(); ////////////////////////////////////// auto renderWindow = vtkSmartPointer<vtkRenderWindow>::New(); renderWindow->AddRenderer(renderer); renderWindow->SetInteractor(interactor); renderWindow->Render(); interactor->Start(); //イベントループへ入る return 0; }
球サイズのスカラー値の配列を指定することで、球のサイズを変更できる
void CreateColorsArray( std::vector<Eigen::Vector3d>& vertex_colors, vtkSmartPointer<vtkPolyData> vtk_mesh, vtkSmartPointer<vtkUnsignedCharArray> vtk_colors) { vtk_colors->SetName("MY_POINT_COLOR"); // 明示的に指定するため名前を付ける vtk_colors->SetNumberOfComponents(3); for (const auto& c : vertex_colors) { vtk_colors->InsertNextTuple3(c.x() * 255, c.y() * 255, c.z() * 255); } vtk_mesh->GetPointData()->SetScalars(vtk_colors); }
vtkSmartPointer<vtkFloatArray> CreateSizeScalarArray(const std::vector<Eigen::Vector3d>& points) { auto size_scalars = vtkSmartPointer<vtkFloatArray>::New(); size_scalars->SetName("MY_SIZE_SCALAR"); // 明示的にアクティブにするため名前を付ける size_scalars->SetNumberOfComponents(1); size_scalars->SetNumberOfTuples(points.size()); for (int i = 0; i < points.size(); i++) { float sz = points[i].z() + 1.0; sz *= 0.05; size_scalars->SetValue(i, sz); } return size_scalars; }
vtkSmartPointer<vtkActor> CreatePointCloudActor( std::vector<Eigen::Vector3d> vertices, std::vector<Eigen::Vector3d> colors, vtkAlgorithmOutput* glyphpoly // 点を球にするためのvtkPolyData ) { auto vtk_cloud = vtkSmartPointer<vtkPolyData>::New(); auto vtk_points = vtkSmartPointer<vtkPoints>::New(); auto vtk_colors = vtkSmartPointer<vtkUnsignedCharArray>::New(); /////////////////////////////////////////////////////// // 頂点の配列を生成 CreatePointArray(vertices, vtk_cloud, vtk_points); /////////////////////////////////////////////////////// // 色の配列を生成 CreateColorsArray(colors, vtk_cloud, vtk_colors); /////////////////////////////////////////////////////// // 球のサイズを設定するスカラー配列を生成 auto size_scalar_array = CreateSizeScalarArray(vertices); // 点群にサイズのスカラー配列を追加 vtk_cloud->GetPointData()->AddArray(size_scalar_array); vtk_cloud->GetPointData()->SetActiveScalars("MY_SIZE_SCALAR"); /////////////////////////////////////////////////////// // Glyph3Dを使用して点に球を描画 vtkSmartPointer<vtkGlyph3D> glyph3D = vtkSmartPointer<vtkGlyph3D>::New(); glyph3D->SetSourceConnection(glyphpoly); glyph3D->SetInputData(vtk_cloud); glyph3D->SetColorModeToColorByScalar(); // 色情報を使用 //glyph3D->SetScaleFactor(0.1); // 球をスケーリング glyph3D->SetScaleModeToScaleByScalar(); // スケールをスカラー値にする //glyph3D->SetScaleModeToDataScalingOff(); // サイズを一定にする glyph3D->Update(); /////////////////////////////////////////////////////// auto vtk_mapper = vtkSmartPointer<vtkPolyDataMapper>::New(); vtk_mapper->SetInputConnection(glyph3D->GetOutputPort()); // 色の設定はデフォルトでアクティブなスカラー値が使用されるが // glyph3Dでスケーリングの指定をするため、スケール用のスカラー値をアクティブにする必要があるため // カラー用のスカラー値は明示的に指定する vtk_mapper->SetScalarModeToUsePointFieldData(); vtk_mapper->SelectColorArray("MY_POINT_COLOR"); auto vtk_actor = vtkSmartPointer<vtkActor>::New(); vtk_actor->SetMapper(vtk_mapper); return vtk_actor; }