cvl-robot's diary

研究ノート メモメモ https://github.com/dotchang/

c++版Open3DのVisualizationは、openFrameworks0.10.0で自前で作ると便利。

Open3Dは、3次元点群処理が簡単に出来て便利です。ですが、いくつか弱点があって
・Visualizationが便利なようで自由が利かず不便
・フォーマットが良く分からなくなることがある。ex. PointCloudとTriangleMeshの違いは?
・他のライブラリとのリンクが不便、だった(過去形)。

openFrameworks0.9.8以前では、Open3Dのリンクはとても面倒くさかったのですが、openFramworks0.10.0からは普通にリンクできるようになりました。
インタラクティブな3D表示はopenFrameworksの得意技なので、もうこっちに任せてしまいましょう。

編集中
ofxThreeGeometries.h

#pragma once

#include <iostream>
#include <memory>
#include <Eigen/Dense>

#include <Core/Core.h>
#include <IO/IO.h>
#include <Visualization/Visualization.h>

#include <ofNode.h>
#include <ofMesh.h>

class ofxThreeGeometries : public ofNode
{
public:
	ofVboMesh mesh;
        // ofMesh mesh;
	std::vector<ofMatrix4x4> mat;
	int mat_id;

	ofxThreeGeometries() { 
		mat.clear();
		mat_id = -1;
	}
	~ofxThreeGeometries() { 
		mat.clear();
		mesh.clear();
	}

	int set(const three::TriangleMesh &source) {
		switch (source.GetGeometryType()) {
		case three::Geometry::GeometryType::Unspecified:
			std::cout << "Unspecified" << std::endl;
			break;
		case three::Geometry::GeometryType::PointCloud:
			std::cout << "PointCloud" << std::endl;
			break;
		case three::Geometry::GeometryType::LineSet:
			std::cout << "LineSet" << std::endl;
			break;
		case three::Geometry::GeometryType::TriangleMesh:
			std::cout << "TriangleMesh" << std::endl;
			mesh.clear();
			if (source.HasVertices()) {
				for (int i = 0; i < source.vertices_.size(); i++) {
					ofVec3f v(source.vertices_.at(i).x(), source.vertices_.at(i).y(), source.vertices_.at(i).z());
					mesh.addVertex(v);
					if (source.HasVertexColors()) {
						ofColor c(source.vertex_colors_.at(i).x() * 255, source.vertex_colors_.at(i).y() * 255, source.vertex_colors_.at(i).z() * 255);
						mesh.addColor(c);
					}
					if (source.HasVertexNormals()) {
						ofVec3f n(source.vertex_normals_.at(i).x(), source.vertex_normals_.at(i).y(), source.vertex_normals_.at(i).z());
						mesh.addNormal(n);
					}
				}
			}
			if (source.HasTriangles()) {
				for (int i = 0; i < source.triangles_.size(); i++) {
					mesh.addTriangle(source.triangles_.at(i).x(), source.triangles_.at(i).y(), source.triangles_.at(i).z());
					if (source.HasTriangleNormals()) {
						// source.triangle_normals_.at(i).x();
					}
				}
			}
			{
				Eigen::Vector3d c = 0.5 * (source.GetMinBound() + source.GetMaxBound());
				this->setPosition(c.x(), c.y(), c.z());
				this->setOrientation(ofQuaternion());
			}
			break;
		case three::Geometry::GeometryType::Image:
			std::cout << "Image" << std::endl;
			break;
		default:
			break;
		}
		return 0;
	}

	int set(const three::PointCloud &source) {
		switch (source.GetGeometryType()) {
		case three::Geometry::GeometryType::Unspecified:
			std::cout << "Unspecified" << std::endl;
			break;
		case three::Geometry::GeometryType::PointCloud:
			//std::cout << "PointCloud" << std::endl;
			mesh.clear();
			if (source.HasPoints()) {
				for (int i = 0; i < source.points_.size(); i++) {
					ofVec3f v(source.points_.at(i).x(), source.points_.at(i).y(), source.points_.at(i).z());
					mesh.addVertex(v);

					if (source.HasColors()) {
						ofColor c(source.colors_.at(i).x() * 255, source.colors_.at(i).y() * 255, source.colors_.at(i).z() * 255);
						mesh.addColor(c);
					}
					if (source.HasNormals()) {
						ofVec3f n(source.normals_.at(i).x(), source.colors_.at(i).y(), source.colors_.at(i).z());
						mesh.addNormal(n);
					}
				}
			}
			{
				Eigen::Vector3d c = 0.5 * (source.GetMinBound() + source.GetMaxBound());
				this->setPosition(c.x(), c.y(), c.z());
			}
			break;
		case three::Geometry::GeometryType::LineSet:
			std::cout << "LineSet" << std::endl;
			break;
		case three::Geometry::GeometryType::TriangleMesh:
			std::cout << "TriangleMesh" << std::endl;
			break;
		case three::Geometry::GeometryType::Image:
			std::cout << "Image" << std::endl;
			break;
		default:
			break;
		}
	}

	void addTransformation(const Eigen::Matrix4d &Transformation) {
		// Transposed
		ofMatrix4x4 m(Transformation(0, 0), Transformation(1, 0), Transformation(2, 0), Transformation(3, 0),
				Transformation(0, 1), Transformation(1, 1), Transformation(2, 1), Transformation(3, 1),
				Transformation(0, 2), Transformation(1, 2), Transformation(2, 2), Transformation(3, 2),
				Transformation(0, 3), Transformation(1, 3), Transformation(2, 3), Transformation(3, 3));
		mat.push_back(m);
	}

	void setTransformationId(int i) {
		if (i >= 0 && i < mat.size()) {
			mat_id = i;
			this->setPosition(mat[mat_id].getTranslation());
			this->setOrientation(mat[mat_id].getRotate());
		}
	}

	int getTransformationId() {
		return mat_id;
	}

	void draw(ofPolyRenderMode renderMode) {
		ofPushMatrix();
		if (mat_id >= 0 && mat_id < mat.size()) {
			ofMultMatrix(mat[mat_id]);
		}
		mesh.draw(renderMode);
		
		ofPopMatrix();
	}

	void draw() {
		draw(ofPolyRenderMode::OF_MESH_POINTS);
	}
};

f:id:cvl-robot:20180607192817p:plainf:id:cvl-robot:20180607192828p:plainf:id:cvl-robot:20180607192823p:plain