[C++][CGAL]点云转OBJ模型(可导入Unity)

一、环境

        IDE:VS2017   X64
        工具库:Boost 1.7.1 、CGAL5.5.2

         简介:通过读取"xyz"格式的点云文件,将点云转换成三维模型。

二、代码

#pragma once
#include 
#include 
#include 
#include 
#include 

//CGAL SDK
#include 
#include 
#include //xy投影面
#include //Delaunay三角剖分
#include 
#include 
#include 
#include // 内核
#include 

typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef Kernel::Point_3 Point_3;
typedef Kernel::Vector_3  Vector_3;
typedef std::array Facet;
typedef CGAL::Surface_mesh Mesh;
typedef boost::graph_traits::vertex_descriptor  vertex_descriptor;


struct Construct
{
	Mesh& mesh;
	template < typename PointIterator>
	Construct(Mesh& mesh, PointIterator b, PointIterator e)
		: mesh(mesh)
	{
		for (; b != e; ++b)
		{
			boost::graph_traits::vertex_descriptor v;
			v = add_vertex(mesh);
			mesh.point(v) = *b;
		}
	}
	Construct& operator=(const Facet f)
	{
		typedef boost::graph_traits::vertex_descriptor vertex_descriptor;
		typedef boost::graph_traits::vertices_size_type size_type;
		mesh.add_face(vertex_descriptor(static_cast(f[0])),
			vertex_descriptor(static_cast(f[1])),
			vertex_descriptor(static_cast(f[2])));
		return *this;
	}
	Construct&
		operator*() { return *this; }
	Construct&
		operator++() { return *this; }
	Construct
		operator++(int) { return *this; }
};


class PointCloud2Mesh
{
public:
	PointCloud2Mesh();
	~PointCloud2Mesh();
public:
	static void CreateMesh(std::string xyzfile, std::string objfile = "mesh.obj");
};

#include "PointCloud2Mesh.h"

PointCloud2Mesh::PointCloud2Mesh()
{
}

PointCloud2Mesh::~PointCloud2Mesh()
{

}

void PointCloud2Mesh::CreateMesh(std::string xyzfile, std::string objfile)
{
	//加载点云数据
	std::string filePath = CGAL::data_file_path(xyzfile);
	std::ifstream in(filePath);
	std::vector points;
	std::copy(std::istream_iterator(in), std::istream_iterator(), std::back_inserter(points));
	in.close();

	//转行Mesh
	Mesh dsm_mesh;
	Construct construct(dsm_mesh, points.begin(), points.end());
	CGAL::advancing_front_surface_reconstruction(points.begin(), points.end(), construct);

	auto vnormals = dsm_mesh.add_property_map("v:normals", CGAL::NULL_VECTOR).first;

	CGAL::Polygon_mesh_processing::compute_vertex_normals(dsm_mesh, vnormals);

	std::ofstream dsm_ofile(objfile, std::ios_base::binary);
	CGAL::IO::set_binary_mode(dsm_ofile);
	CGAL::IO::write_OBJ(dsm_ofile, dsm_mesh);

	for (vertex_descriptor vd : vertices(dsm_mesh))
	{
		dsm_ofile << "vn " << vnormals[vd].x() << " "
			<< vnormals[vd].y() << " "
			<< vnormals[vd].z() << "\n";
	}
	dsm_ofile.close();
}

三、使用

#include 
#include "PointCloud2Mesh.h"

using namespace std;


#define PI 3.1415926

#define XYZ "points_3/zongzi.xyz"

void Ball();
void zongzi();

int main(int argc, char** argv)
{
	//
	//Ball();
	zongzi();

	PointCloud2Mesh::CreateMesh(XYZ);
	return EXIT_SUCCESS;
}

void Ball()
{
	float Scale = 10.0f;
	//
	float u = PI * 2;
	float v = PI;

	std::ofstream fout(XYZ, ios::out | ios::app);

	for (int i = 0; i < u *Scale; i++)
	{
		for (int j = 0; j < v*Scale; j++)
		{
			float x = cos(i) * sin(j);
			float y = sin(i) * sin(j);
			float z = cos(j);
			fout << x<<" "<

效果图

[C++][CGAL]点云转OBJ模型(可导入Unity)_第1张图片

你可能感兴趣的:(c++)