スポンサーリンク
#pragma once #include <vtkCellArray.h> #include <vtkPoints.h> #include <vtkPolyData.h> #include <vtkPolyDataMapper.h> #include <vtkActor.h> #include <vtkDoubleArray.h> #include <vtkSmartPointer.h> #include <vtkPointData.h> #include <vtkProperty.h> #include <open3d/Open3D.h> #include <open3d/geometry/PointCloud.h> #include <Eigen/Core> #include "vtkFromO3dCommon.hpp" namespace vtko3d {
vtkSmartPointer<vtkPolyData> toCloudPolyData(const open3d::geometry::PointCloud& cloud, USEVALUE usedata=POINT_RGB) { // 頂点配列 vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New(); // 色情報の配列 vtkSmartPointer<vtkDoubleArray> colors = vtkSmartPointer<vtkDoubleArray>::New(); colors->SetNumberOfComponents(3); colors->SetName("Colors"); auto normals = vtkSmartPointer<vtkDoubleArray>::New(); normals->SetNumberOfComponents(3); // x, y, z normals->SetName("Normals"); // 頂点インデクスの配列 vtkSmartPointer<vtkCellArray> cells = vtkSmartPointer<vtkCellArray>::New(); for (size_t i = 0; i < cloud.points_.size(); i++) { double x = cloud.points_[i].x(); double y = cloud.points_[i].y(); double z = cloud.points_[i].z(); points->InsertNextPoint(x, y, z); // 座標追加 if (usedata & POINT_RGB) { double r = cloud.colors_[i].x(); double g = cloud.colors_[i].y(); double b = cloud.colors_[i].z(); colors->InsertNextTuple3(r, g, b); // 色情報追加 } if (usedata & POINT_NORMAL) { double nx = cloud.normals_[i].x(); double ny = cloud.normals_[i].y(); double nz = cloud.normals_[i].z(); normals->InsertNextTuple3(nx, ny, nz); // 法線ベクトル追加 } cells->InsertNextCell(1); // 要素数 cells->InsertCellPoint(i); // 頂点インデックスを追加 } // --- vtkPolyData作成 --- auto polydata = vtkSmartPointer<vtkPolyData>::New(); polydata->SetPoints(points); polydata->SetVerts(cells); if (usedata & POINT_RGB) { polydata->GetPointData()->SetScalars(colors); } if (usedata & POINT_NORMAL) { polydata->GetPointData()->SetNormals(normals); } return polydata; }
vtkSmartPointer<vtkActor> toCloudActor(vtkSmartPointer<vtkPolyDataMapper> mapper, int point_size = 1,std::optional< std::array<double, 3> > single_color = std::nullopt) { auto actor = vtkSmartPointer<vtkActor>::New(); if (single_color.has_value()) { mapper->SetScalarVisibility(false); // 頂点ごとの色情報を無視 } actor->SetMapper(mapper); if (mapper->GetScalarVisibility() == false) { if (single_color.has_value()) { actor->GetProperty()->SetColor(single_color.value()[0], single_color.value()[1], single_color.value()[2]); // 単色(R, G, B)を指定 } } actor->GetProperty()->SetPointSize(point_size); // 頂点サイズを5に設定(ピクセル単位) actor->GetProperty()->SetLighting(false); return actor; }
std::shared_ptr<open3d::geometry::PointCloud> createSampleCloud() { auto pointcloud = std::make_shared<open3d::geometry::PointCloud>(); 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; pointcloud->points_.emplace_back(x, y, z); // 座標追加 pointcloud->colors_.emplace_back(x, y, z); // 色情報追加 pointcloud->normals_.emplace_back(x, y, z); // 法線ベクトル追加 } return pointcloud; }
}
auto cloud = vtko3d::createSampleCloud(); auto polyData = vtko3d::toCloudPolyData(*cloud, vtko3d::POINT_RGB); auto mapper = vtko3d::toMapper(polyData); auto actor = vtko3d::toCloudActor(mapper,3);