vcpkg和cgal安装和使用

1. 下载并安装visual studio 2019

windows下最方便的安装方式就是用visual studio来安装, 并勾选使用C++的桌面开发和右侧的MSVC v142...Windows 10 SDK。注意vcpkg会使用到$vswhereExe = "$programFiles\Microsoft Visual Studio\Installer\vswhere.exe",因此需要visual studio 2015及其以上版本才行。否则运行bootstrap-vcpkg.bat会报错。

2. 安装vcpkg

在github上下载vcpkg,然后运行如下命令

bootstrap-vcpkg.bat

将会生成vcpkg.exe文件,将此加入到环境变量。
##3. 利用vcpkg安装和卸载包

vcpkg install pkg:x64-windows

vcpkg remove pkg:x64-windows

安装的包会放在cvpkg/packages下面。

4. 使用cgal

下载cgal的官方demo,然后使用cmake打开:

cd Triangulation_2
mkdir build

cd build
cmake-gui ..

然后利用cmake指定Boost_DIR, CGAL, GMP, MPFR

Boost_INCLUDE_DIR D:\boost_1_72_0

CGAL_DIR D:/vcpkg/packages/cgal_x64-windows/share/cgal

GMP_INCLUDE_DIR D:/vcpkg/packages/mpir_x64-windows/include
GMP_LIBRARIES D:/vcpkg/packages/mpir_x64-windows/lib/mpir.lib

MPFR_INCLUDE_DIR D:/vcpkg/packages/mpfr_x64-windows/include
MPFR_LIBRARIES D:/vcpkg/packages/mpfr_x64-windows/lib/mpfr.lib

注意安装cgal包时要使用vcpkg install cgal[qt]:x64-windows而不是直接使用vcpkg install cgal:x64-windows。安装完成之后再安装qt相关的包vcpkg install qt5:x64-windows。然后指定

Qt5_DIR  D:/vcpkg/packages/qt5-base_x64-windows/share/cmake/Qt5

否则会报错:

The example draw_triangulation_2 requires Qt and will not be compiled.

注意libraries一定要指定到具体的lib文件,否则在generate项目时会报如下错误:

WARNING: Target requests linking to directory Targets may link only to libraries. CMake is dropping the item.

然后在项目link时会提示找不到lib,即:

unresolved external symbol .....

。然后生成vs项目。在vs项目中可能需要进行额外配置。右击工程,选择Properties,然后在"C/C++\general\Additional Include Directories"下面添加cgal,gmp(mpir), mpfr的相关include目录。在Linker\General\Additional Library Directories下面添加相应的lib目录以消除link时unresolved external symbol的错误。然后运行时在Build Events\Post-Build Event中的Command Line下添加如下命令以消除dll missing的错误:

xcopy /y /d "D:\vcpkg\packages\mpir_x64-windows\bin\mpir.dll" "$(outdir)"

如果需要拷贝多个dll文件,则添加如下命令:

xcopy /y /d "D:\vcpkg\packages\qt5-base_x64-windows\debug\bin\*d.dll" "$(outdir)"
xcopy /y /d "D:\vcpkg\packages\zlib_x64-windows\bin\*.dll" "$(outdir)"
xcopy /y /d "D:\vcpkg\packages\zlib_x64-windows\debug\bin\*.dll" "$(outdir)"
xcopy /y /d "D:\vcpkg\packages\harfbuzz_x64-windows\bin\*.dll" "$(outdir)"
xcopy /y /d "D:\vcpkg\packages\libpng_x64-windows\bin\*.dll" "$(outdir)"
xcopy /y /d "D:\vcpkg\packages\libpng_x64-windows\debug\bin\*.dll" "$(outdir)"
xcopy /y /d "D:\vcpkg\packages\icu_x64-windows\debug\bin\*.dll" "$(outdir)"
xcopy /y /d "D:\vcpkg\packages\pcre2_x64-windows\debug\bin\*.dll" "$(outdir)"
xcopy /y /d "D:\vcpkg\packages\zstd_x64-windows\debug\bin\*.dll" "$(outdir)"
xcopy /y /d "D:\vcpkg\packages\freetype_x64-windows\bin\*.dll" "$(outdir)"
xcopy /y /d "D:\vcpkg\packages\freetype_x64-windows\debug\bin\*.dll" "$(outdir)"
xcopy /y /d "D:\vcpkg\packages\bzip2_x64-windows\bin\*.dll" "$(outdir)"
xcopy /y /d "D:\vcpkg\packages\bzip2_x64-windows\debug\bin\*.dll" "$(outdir)"
xcopy /y /d "D:\vcpkg\packages\brotli_x64-windows\bin\*.dll" "$(outdir)"
xcopy /y /d "D:\vcpkg\packages\brotli_x64-windows\debug\bin\*.dll" "$(outdir)"
xcopy /y /d "D:\vcpkg\packages\qt5-svg_x64-windows\debug\bin\Qt5svgd.dll" "$(outdir)"
xcopy /y /d "D:\vcpkg\packages\qt5-base_x64-windows\debug\bin\*.dll" "$(outdir)"
xcopy /y /d "D:\vcpkg\packages\qt5-base_x64-windows\debug\bin\*.dll" "$(outdir)"
xcopy /y /d "D:\vcpkg\packages\qt5-base_x64-windows\bin\*.dll" "$(outdir)"
xcopy /y /d "D:\vcpkg\packages\qt5-base_x64-windows\plugins\platforms\*.dll" "$(outdir)"

如果利用到qt,运行时可能还会遇到以下错误:

qt.qpa.plugin: Could not find the Qt platform plugin "windows" in ""
This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.

此时需要将qt5-base_x64-windows\debug\plugins下面的platforms\qwindowsd.dll目录拷贝到与exe同级目录下。网上说是拷贝qwindows.dll,但在我的情况下需要拷贝qwindowsd.dll文件。至于其他的设置环境变量等其他solution均无效。

5. 画一个3d的Triangulations

#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Delaunay_triangulation_3.h>
#include <CGAL/point_generators_3.h>
#include <CGAL/draw_triangulation_3.h>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Delaunay_triangulation_3<K>                   DT3;
typedef CGAL::Creator_uniform_3<double, K::Point_3>          Creator;
int main()
{
	std::vector<K::Point_3> points;
	CGAL::Random_points_in_sphere_3<K::Point_3, Creator> g(1.0);
	std::copy_n(g, 50, std::back_inserter(points));
	DT3 dt3(points.begin(), points.end());
	CGAL::draw(dt3);
	return EXIT_SUCCESS;
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jHHJe1OI-1608775634192)(pics/30.png)]

如果运行没问题,则证明所有安装都成功。

6. 常见问题

如果画图时出现:

Impossible to draw, CGAL_USE_BASIC_VIEWER is not defined.

则需要参考examples里面的Tranigulation_2里面的CMakeLists.txt文件,加入如下几行

find_package(CGAL COMPONENTS Qt5)

if(CGAL_Qt5_FOUND)
  add_definitions(-DCGAL_USE_BASIC_VIEWER -DQT_NO_KEYWORDS)
endif()

if(CGAL_FOUND)
	file(GLOB cppfiles RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
    foreach(cppfile ${cppfiles})
    	create_single_source_cgal_program( "${cppfile}" )
    endforeach()

    if(CGAL_Qt5_FOUND)
        message(STATUS "Qt5 found")
        target_link_libraries(draw_triangulation_2 PUBLIC CGAL::CGAL_Qt5)
      else()
        message(STATUS "NOTICE: The example draw_triangulation_2 requires Qt and will not be compiled.")
      endif()
 endif()

然后在vs的post-build的command-line里拷贝如下dll文件:

xcopy /y /d "D:\vcpkg\packages\qt5-base_x64-windows\debug\bin\*.dll" "$(outdir)"
xcopy /y /d "D:\vcpkg\packages\qt5-svg_x64-windows\debug\bin\*.dll" "$(outdir)"
xcopy /y /d "D:\vcpkg\packages\zlib_x64-windows\debug\bin\*.dll" "$(outdir)"
xcopy /y /d "D:\vcpkg\packages\harfbuzz_x64-windows\debug\bin\*.dll" "$(outdir)"
xcopy /y /d "D:\vcpkg\packages\libpng_x64-windows\debug\bin\*.dll" "$(outdir)"
xcopy /y /d "D:\vcpkg\packages\icu_x64-windows\debug\bin\*.dll" "$(outdir)"
xcopy /y /d "D:\vcpkg\packages\pcre2_x64-windows\debug\bin\*.dll" "$(outdir)"
xcopy /y /d "D:\vcpkg\packages\zstd_x64-windows\debug\bin\*.dll" "$(outdir)"
xcopy /y /d "D:\vcpkg\packages\freetype_x64-windows\debug\bin\*.dll" "$(outdir)"
xcopy /y /d "D:\vcpkg\packages\bzip2_x64-windows\debug\bin\*.dll" "$(outdir)"
xcopy /y /d "D:\vcpkg\packages\brotli_x64-windows\debug\bin\*.dll" "$(outdir)"

然后将上面的platforms\qwindowsd.dll拷贝到相关目录下。注意\方向不能错。

注意相关的文件一定要放到与.sln文件同级的build目录下,即debug的上级目录。如果文件没找到可能不会有提示,因此可以加入以下几行:

inline bool exist(const std::string& name)
{
    std::ifstream file(name);
    if(!file)            // If the file was not found, then file is 0, i.e. !file=1 or true.
        return false;    // The file was not found.
    else                 // If the file was found, then file is non-0.
        return true;     // The file was found.
}

然后调用:

if (exist(filename))
	std::cout << "Good" << std::endl;
else
	std::cout << "Bad" << std::endl;

7. 画一个mesh

#include <CGAL/Simple_cartesian.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/draw_surface_mesh.h>
#include <fstream>

typedef CGAL::Simple_cartesian<double>                       Kernel;
typedef Kernel::Point_3                                      Point;
typedef CGAL::Surface_mesh<Point>                            Mesh;

inline bool exist(const std::string& name)
{
    std::ifstream file(name);
    if (!file)            // If the file was not found, then file is 0, i.e. !file=1 or true.
        return false;    // The file was not found.
    else                 // If the file was found, then file is non-0.
        return true;     // The file was found.
}

int main(int argc, char* argv[])
{
  Mesh sm1;

  if(exist("data/elephant.off") )
      std::cout << "Good" << std::endl;
  else
  std::cout << "bad" << std::endl;

  std::ifstream in1((argc>1)?argv[1]:"data/elephant.off");
  in1 >> sm1;

  CGAL::draw(sm1);

  return EXIT_SUCCESS;
}

8. CGAL基础

CGAL的头文件都在子目录include\CGAL中。所有的CGAL类都在命名空间CGAL中,类以大写字母开头,全局函数以小写字母开头,变量全部大写,object的维度作为后缀出现。

几何原语(如点的类型)被定义为kernel

判断3点是否共线:

#include <iostream>
#include <CGAL\Simple_cartesian.h>

using namespace std;

typedef CGAL::Simple_cartesian<double> Kernel;
typedef Kernel::Point_2 Point_2;
typedef Kernel::Segment_2 Segment_2;

int main()
{
	Point_2 p(1, 1), q(10, 10);

	cout << "p = " << p << endl;
	cout << "q = " << q.x() << " " << q.y() << endl;
	cout << "sqdist(p, q) = " << CGAL::squared_distance(p, q) << endl;

	Segment_2 s(p, q);
	Point_2 m(5, 9);
	cout << "p, q, and m ";
	switch (CGAL::orientation(p, q, m))
	{
	case CGAL::COLLINEAR:
		cout << "are collinear\n";
		break;
	case CGAL::LEFT_TURN:
		cout << "make a left turn\n";
		break;
	case CGAL::RIGHT_TURN:
		cout << "make a right turn\n";
		break;
	}

	cout << " midpoint(p, q) = " << CGAL::midpoint(p, q) << endl;
	return 0;
}

计算凸包:

#include <iostream>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/convex_hull_2.h>

using namespace std;

typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef K::Point_2 Point_2;

int main()
{
	Point_2 points[5] = { Point_2(0, 0), Point_2(10, 0), Point_2(10, 10), Point_2(6, 5), Point_2(4, 1) };
	Point_2 result[5];

	Point_2* ptr = CGAL::convex_hull_2(points, points + 5, result);
	cout << ptr - result << " points on the convex hull:" << endl;
	for (int i = 0; i < ptr - result; i++)
	{
		cout << result[i] << endl;
	}

	return 0;
}

凸包结合vector

#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/convex_hull_2.h>

#include <vector>

typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef K::Point_2 Point_2;
typedef std::vector<Point_2> Points;

int main()
{
	Points points, result;
	points.push_back(Point_2(0, 0));
	points.push_back(Point_2(10, 0));
	points.push_back(Point_2(10, 10));
	points.push_back(Point_2(6, 5));
	points.push_back(Point_2(4, 1));

	CGAL::convex_hull_2(points.begin(), points.end(), std::back_inserter(result));
	std::cout << result.size() << " Points on the convex hull" << std::endl;

	return 0;
}

visual studio中添加命令行参数:
Properties->Configuration Properties->Debugging->Command Arguments,然后添加:

"-hide_banner"  "Z:/media/subtitle/internal/divx/496x496.divx"

则传递给main函数的argc为3,其中argv[0]为程序名,argv[1]为"-hide_banner",argv[2]为"Z:/media/subtitle/internal/divx/496x496.divx"。各参数不是必须用"“引用起来,但使用”"可以防止参数本身有空格被误判。

9. PLY文件格式

CGAL::Surface_mesh<Point_3> output_mesh;
		CGAL::poisson_surface_reconstruction_delaunay(
			points.begin(), points.end(),
			points.point_map(), points.normal_map(),
			output_mesh, spacing
		);

ofstream f("out.ply", std::ios_base::binary);
CGAL::set_ascii_mode(f);
//CGAL::set_binary_mode(f);
CGAL::write_ply(f, output_mesh);
f.close();

每个PLY档都包含档头(header),用以设定网格模型的“元素”与“属性”,以及在档头下方接着一连串的元素“数值资料”。一般而言,网格模型的“元素”就是顶点(vertices)、面(faces),另外还可能包含有边(edges)、深度图样本(samples of range maps)与三角带(triangle strips)等元素。无论是纯文字与二元码的PLY档,档头资讯都是以ASCII编码编写,接续其后的数值资料才有编码之分。

PLY档案以此行作为开头,以识别PLY格式。接着第二行是版本资讯,目前有三种写法:

PLY
format ascii 1.0
format binary_little_endian 1.0
format binary_big_endian 1.0

其中ascii, binary_little_endian, binary_big_endian是档案储存的编码方式,而1.0是遵循的标准版本(现阶段仅有PLY 1.0版)。在档头中可使用’comment’作为一行的开头以编写注解。

描述元素及属性,必须使用’element’及’property’的关键字,一般的格式为element下方接着属性列表,例如:

element <element name> <number in file>
property <data_type> <property name 1>
property <data_type> <property name 2>
property <data_type> <property name 3>

property’不仅定义了资料的型态,其出现顺序亦定义了资料的顺序。内定的资料形态有两种写法:一种是char uchar short ushort int uint float double,另外一种是具有位元长度的int8 uint8 int16 uint16 int32 uint32 float32 float64。 例如,描述一个包含12个顶点的物体,每个顶点使用3个单精度浮点数 (x,y,z)代表点的座标,使用3个unsigned char代表顶点颜色,颜色顺序为 (B, G, R),则档头的写法为:

element vertex 12
property float x
property float y
property float z
property uchar blue
property uchar green
property uchar red

其中vertex是内定的元素类型,接续的6行property描述构成vertex元素的数值字段顺序代表的意义,及其资料形态。另一个常使用的元素是面。由于一个面是由3个以上的顶点所组成,因此使用一个“顶点列表”即可描述一个面, PLY格式使用一个特殊关键字’property list’定义之。 例如,一个具有10个面的物体,其PLY档头可能包含:

element face 10
property list uchar int vertex_indices

‘property list’表示该元素face的特性是由一行的顶点列表来描述。列表开头以uchar型态的数值表示列表的项目数,后面接着资料型态为int的顶点索引值(vertex_indices),顶点索引值从0开始。
最后,标头必须以此行结尾:

end_header

档头后接着的是元素资料(端点座标、拓朴连结等)。在ASCII格式中各个端点与面的资讯都是以独立的一行描述,而二元编码格式则连续储存这些资料,载入时须以’element’定义的元素数目以及’property’中设定的资料形态计算各笔字段的长度。

一个典型的PLY文件结构分成三部分:

文件头 (从ply开始到end_header)
顶点元素列表
面元素列表

其中的顶点元素列表一般以x y z方式排列,形态如文件头所定义;而面元素列表是以下列格式表示。

<组成面的端点數N> <端点#1的索引> <端点#2的索引> ... <端点#N的索引>

存为ply文件之后,文件组成如下:

ply
format ascii 1.0
comment made by anonymous
comment this file is a cube
element vertex 8
property float32 x
property float32 y
property float32 z
element face 12
property list uint8 int32 vertex_index
end_header
0 0 0
0 25.8 0
18.9 0 0
18.9 25.8 0
0 0 7.5
0 25.8 7.5
18.9 0 7.5
18.9 25.8 7.5
3 5 1 0
3 5 4 0
3 4 0 2
3 4 6 2
3 7 5 4
3 7 6 4
3 3 2 1
3 1 2 0
3 5 7 1
3 7 1 3
3 7 6 3
3 6 3 2

10. 从点云文件(.xyz)构建3维Mesh

官方tutorial

#include <CGAL\Exact_predicates_inexact_constructions_kernel.h>

#include <CGAL\Point_set_3.h>
#include <CGAL\Point_set_3\IO.h>

#include <CGAL\remove_outliers.h>
#include <CGAL\grid_simplify_point_set.h>
#include <CGAL\jet_estimate_normals.h>
#include <CGAL\jet_smooth_point_set.h>
#include <CGAL\mst_orient_normals.h>

#include <CGAL\poisson_surface_reconstruction.h>
#include <CGAL\Advancing_front_surface_reconstruction.h>
#include <CGAL\Scale_space_surface_reconstruction_3.h>
#include <CGAL\Scale_space_reconstruction_3\Jet_smoother.h>
#include <CGAL\Scale_space_reconstruction_3\Advancing_front_mesher.h>

#include <CGAL\Surface_mesh.h>
#include <CGAL\Polygon_mesh_processing\polygon_soup_to_polygon_mesh.h>

#include <CGAL\draw_surface_mesh.h>

#include <cstdlib>
#include <vector>
#include <fstream>
#include <iostream>

using namespace std;

typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef Kernel::FT FT;
typedef Kernel::Point_3 Point_3;
typedef Kernel::Vector_3 Vector_3;
typedef Kernel::Sphere_3 Sphere_3;
typedef CGAL::Point_set_3<Point_3, Vector_3> Point_set;

int main(int argc, char* argv[])
{
	Point_set points;
	if (argc < 2)
	{
		cerr << "Usage: " << argv[0] << " [input.xyz/off/ply/las]" << endl;
		return EXIT_FAILURE;
	}

	const char* input_file = argv[1];
	ifstream stream(input_file, ios_base::binary);
	if (!stream)
	{
		std::cerr << "Error: cannot read file " << input_file << std::endl;
		return EXIT_FAILURE;
	}

	stream >> points;

	cout << "Read " << points.size() << " point(s)" << endl;

	if (points.empty())
		return EXIT_FAILURE;

	CGAL::remove_outliers<CGAL::Sequential_tag>(
		points,
		24, // Number of neighbors considered for evaluation
		points.parameters().threshold_percent(5.0) // Percentage of points to remove
		);

	cout << points.number_of_removed_points() << " point(s) are outliers." << std::endl;

	// Applying point set processing algorithm to a CGAL::Point_set_3
   // object does not erase the points from memory but place them in
   // the garbage of the object: memory can be freeed by the user.
	points.collect_garbage();

	// Compute average spacing using neighborhood of 6 points
	double spacing = CGAL::compute_average_spacing<CGAL::Sequential_tag>(points, 6);

	// Simplify using a grid of size 2 * average spacing
	CGAL::grid_simplify_point_set(points, 2. * spacing);

	cout << points.number_of_removed_points() << " point(s) removed after simplification." << std::endl;

	points.collect_garbage();

	CGAL::jet_smooth_point_set<CGAL::Sequential_tag>(points, 24);

	unsigned int reconstruction_choice = (argc < 3 ? 0 : atoi(argv[2]));

	if (reconstruction_choice == 0)//Poisson
	{
		CGAL::jet_estimate_normals<CGAL::Sequential_tag>(points, 24); // Use 24 neighbors

		typename Point_set::iterator unoriented_points_begin = CGAL::mst_orient_normals(points, 24); // Use 24 neighbors

		points.remove(unoriented_points_begin, points.end());

		CGAL::Surface_mesh<Point_3> output_mesh;
		CGAL::poisson_surface_reconstruction_delaunay(
			points.begin(), points.end(),
			points.point_map(), points.normal_map(),
			output_mesh, spacing
		);

		CGAL::draw(output_mesh);
		ofstream f("out.ply", std::ios_base::binary);
		CGAL::set_ascii_mode(f);
		//CGAL::set_binary_mode(f);
		CGAL::write_ply(f, output_mesh);
		f.close();
	}
	else if (reconstruction_choice == 1) //Advancing frong
	{
		typedef array<size_t, 3> Facet; // triple of indices
		vector<Facet> facets;

		// The function is called using directly the points raw iterators

		CGAL::advancing_front_surface_reconstruction(
			points.points().begin(),
			points.points().end(),
			back_inserter(facets)
		);

		cout << facets.size() << " facet(s) generated by reconstruction." << std::endl;

		// copy points for random access
		vector<Point_3> vertices;
		vertices.reserve(points.size());
		copy(points.points().begin(), points.points().end(), back_inserter(vertices));

		CGAL::Surface_mesh<Point_3> output_mesh;
		CGAL::Polygon_mesh_processing::polygon_soup_to_polygon_mesh(vertices, facets, output_mesh);

		ofstream f("out.off");
		f << output_mesh;
		f.close();
	}
	else if (reconstruction_choice == 2) // Scale space
	{
		CGAL::Scale_space_surface_reconstruction_3<Kernel> reconstruct
		(points.points().begin(), points.points().end());

		// Smooth using 4 iterations of Jet Smoothing
		reconstruct.increase_scale(4, CGAL::Scale_space_reconstruction_3::Jet_smoother<Kernel>());

		// Mesh with the Advancing Front mesher with a maximum facet length of 0.5
		reconstruct.reconstruct_surface(CGAL::Scale_space_reconstruction_3::Advancing_front_mesher<Kernel>(0.5));

		ofstream f("out.off");
		f << "OFF" << endl << points.size() << " "
			<< reconstruct.number_of_facets() << " 0" << endl;

		for (Point_set::Index idx : points)
			f << points.point(idx) << endl;

		for (const auto& facet : CGAL::make_range(reconstruct.facets_begin(), reconstruct.facets_end()))
			f << "3 " << facet << endl;
		f.close();
	}
	else // Handle error
	{
		std::cerr << "Error: invalid reconstruction id: " << reconstruction_choice << std::endl;
		return EXIT_FAILURE;
	}

	return EXIT_SUCCESS;
}

数据文件应该拷贝到build目录下,

11. kernel介绍

Exact_predicates_inexact_constructions_kernel:A typedef to a kernel which has the following properties:

  • It uses Cartesian representation.
  • It supports constructions of points from double Cartesian coordinates.
  • It provides exact geometric predicates, but inexact geometric constructions.

12 xyz文件格式

xyz为点云文件,格式如下:

-0.0721898 -0.159749 -0.108444 0.340472 0.937712 -0.0690972
0.145233 -0.163455 0.107108 0.821548 0.302589 0.483218
0.126784 -0.175123 -0.0474613 0.625688 0.275329 -0.729869

就是点坐标的集合,前3个数带标xyz,后面3个数代表法向量。

_predicates_inexact_constructions_kernel`:A typedef to a kernel which has the following properties:

  • It uses Cartesian representation.
  • It supports constructions of points from double Cartesian coordinates.
  • It provides exact geometric predicates, but inexact geometric constructions.

12 xyz文件格式

xyz为点云文件,格式如下:

-0.0721898 -0.159749 -0.108444 0.340472 0.937712 -0.0690972
0.145233 -0.163455 0.107108 0.821548 0.302589 0.483218
0.126784 -0.175123 -0.0474613 0.625688 0.275329 -0.729869

就是点坐标的集合,前3个数带标xyz,后面3个数代表法向量。

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值