一、环境
IDE:VS2017 X64
工具库:Boost 1.7.1 、CGAL5.5.2
简介:通过读取"xyz"格式的点云文件,将点云转换成三维模型。
二、代码
#pragma once
#include <array>
#include <string>
#include <iostream>
#include <fstream>
#include <algorithm>
//CGAL SDK
#include <CGAL/Surface_mesh.h>
#include <CGAL/disable_warnings.h>
#include <CGAL/Projection_traits_xy_3.h>//xy投影面
#include <CGAL/Delaunay_triangulation_2.h>//Delaunay三角剖分
#include <CGAL/Advancing_front_surface_reconstruction.h>
#include <CGAL/Polygon_mesh_processing/compute_normal.h>
#include <CGAL/Polygon_mesh_processing/IO/polygon_mesh_io.h>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>// 内核
#include <CGAL/boost/graph/graph_traits_Delaunay_triangulation_2.h>
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef Kernel::Point_3 Point_3;
typedef Kernel::Vector_3 Vector_3;
typedef std::array<std::size_t, 3> Facet;
typedef CGAL::Surface_mesh<Point_3> Mesh;
typedef boost::graph_traits<Mesh>::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<Mesh>::vertex_descriptor v;
v = add_vertex(mesh);
mesh.point(v) = *b;
}
}
Construct& operator=(const Facet f)
{
typedef boost::graph_traits<Mesh>::vertex_descriptor vertex_descriptor;
typedef boost::graph_traits<Mesh>::vertices_size_type size_type;
mesh.add_face(vertex_descriptor(static_cast<size_type>(f[0])),
vertex_descriptor(static_cast<size_type>(f[1])),
vertex_descriptor(static_cast<size_type>(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<Point_3> points;
std::copy(std::istream_iterator<Point_3>(in), std::istream_iterator<Point_3>(), 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<vertex_descriptor, Vector_3>("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 <iostream>
#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<<" "<<y<<" "<<z<< std::endl;
}
}
fout.close();
}
void zongzi()
{
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);
float y = cos(j);
float z = cos(i+j);
fout << x << " " << y << " " << z << std::endl;
}
}
fout.close();
}
//@2023.6.26
//info:针对破角修改
void zongzi_new()
{
float Scale = 1.0f;
//
float u = PI * 2;
float v = PI;
std::ofstream fout(XYZ, ios::out | ios::app);
for (float i = 0; i <= u *Scale; i += 0.01f)
{
for (float j = 0; j <= v*Scale; j += 0.01f)
{
float x = cos(i);
float y = cos(j);
float z = cos(i+j);
fout << x << " " << y << " " << z << std::endl;
}
}
fout.close();
}
效果图文章来源:https://www.toymoban.com/news/detail-815252.html
文章来源地址https://www.toymoban.com/news/detail-815252.html
到了这里,关于[C++][CGAL]点云转OBJ模型(可导入Unity)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!