如何将 write_ply_with_properties() 与 Point_set_3 一起使用
How to use write_ply_with_properties() with Point_set_3
我有一个 CGAL::Point_set_3 点集,其中包含点法线和颜色。我想使用 write_ply_with_properties()
函数将所有属性保存到 PLY 文件。
我的目标是使完整版工作(见下面的代码),但即使是简单版本也无法编译,与完整版出现相同的错误。
我使用 CGAL 4.14 版和 gcc 7.4.0 开发 Linux。
代码如下:
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Point_set_3.h>
#include <CGAL/Point_set_3/IO.h>
#include <tuple> // for std::tie
#include <fstream>
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef Kernel::Point_3 Point;
typedef Kernel::Vector_3 Vector;
typedef CGAL::Point_set_3<Point> Point_set;
int main(int argc, char*argv[])
{
Point_set points;
points.insert(Point(1., 2., 3.));
points.insert(Point(4., 5., 6.));
// add normal map
points.add_normal_map();
auto normal_map = points.normal_map();
// add color map
typedef Point_set::Property_map< Vector > ColorMap;
bool success = false;
ColorMap color_map;
std::tie(color_map, success) =
points.add_property_map< Vector >("color");
assert(success);
// populate normal and color map
for(auto it = points.begin(); it != points.end(); ++it)
{
normal_map[*it] = Vector(10., 11., 12.);
color_map[*it] = Vector(20., 21., 22.);
}
std::ofstream out("out.ply");
#if 1
// simple version
if(!out || !CGAL::write_ply_points_with_properties(
out,
points.points(), // const PointRange
CGAL::make_ply_point_writer(points.point_map())))
#else
// full version
if(!out || !CGAL::write_ply_points_with_properties(
out,
points.points(), // const PointRange
CGAL::make_ply_point_writer(points.point_map()),
CGAL::make_ply_normal_writer(points.normal_map()),
std::make_tuple(color_map,
CGAL::PLY_property< double >("red"),
CGAL::PLY_property< double >("green"),
CGAL::PLY_property< double >("blue"))))
#endif
{
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
编译错误为:
...
/usr/include/boost/property_map/property_map.hpp:303:54: error: no match for ‘operator[]’ (operand types are ‘const CGAL::Point_set_3<CGAL::Point_3<CGAL::Epick> >::Property_map<CGAL::Point_3<CGAL::Epick> >’ and ‘const CGAL::Point_3<CGAL::Epick>’)
Reference v = static_cast<const PropertyMap&>(pa)[k];
CGAL-4.14/include/CGAL/Surface_mesh/Properties.h:567:15: note: candidate: CGAL::Properties::Property_map_base<I, T, CRTP_derived_class>::reference CGAL::Properties::Property_map_base<I, T, CRTP_derived_class>::operator[](const I&) [with I = CGAL::Point_set_3<CGAL::Point_3<CGAL::Epick> >::Index; T = CGAL::Point_3<CGAL::Epick>; CRTP_derived_class = CGAL::Point_set_3<CGAL::Point_3<CGAL::Epick> >::Property_map<CGAL::Point_3<CGAL::Epick> >; CGAL::Properties::Property_map_base<I, T, CRTP_derived_class>::reference = CGAL::Point_3<CGAL::Epick>&]
reference operator[](const I& i)
^~~~~~~~
CGAL-4.14/include/CGAL/Surface_mesh/Properties.h:567:15: note: no known conversion for argument 1 from ‘const CGAL::Point_3<CGAL::Epick>’ to ‘const CGAL::Point_set_3<CGAL::Point_3<CGAL::Epick> >::Index&’
我该如何解决?
您的代码中的问题是您正在使用 CGAL::Point_set_3
的方法 points()
,其中 returns 类型为 CGAL::Point_set_3::Point_range
的点范围,而 属性 您使用的映射(points.point_map()
等)直接应用于类型 CGAL::Point_set_3
。
所以你应该简单地在 points
上调用 write_ply_points_with_properties()
,而不是在 points.points()
上调用 write_ply_points_with_properties()
。
另请注意,如果您将颜色存储在简单类型上(例如,使用三个 Point_set_3
类型的 unsigned char
属性),您可以利用函数 CGAL::write_ply_point_set()
自动写入它找到的所有 simply-typed 属性,这使得使用起来非常简单(只需执行 CGAL::write_ply_point_set(out, points)
即可)。
最后一件事实际上是与您的问题无关的细节,但您应该避免使用 CGAL::Vector_3
来存储除实际几何 3D 矢量(如您的情况下的颜色)之外的任何其他内容。这会使您的代码更难阅读,并且如果将颜色编码为 0 到 255 之间的整数值(这就是 unsigned char
的用途),这也是一种非常低效的存储颜色的方法。
我有一个 CGAL::Point_set_3 点集,其中包含点法线和颜色。我想使用 write_ply_with_properties()
函数将所有属性保存到 PLY 文件。
我的目标是使完整版工作(见下面的代码),但即使是简单版本也无法编译,与完整版出现相同的错误。
我使用 CGAL 4.14 版和 gcc 7.4.0 开发 Linux。
代码如下:
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Point_set_3.h>
#include <CGAL/Point_set_3/IO.h>
#include <tuple> // for std::tie
#include <fstream>
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef Kernel::Point_3 Point;
typedef Kernel::Vector_3 Vector;
typedef CGAL::Point_set_3<Point> Point_set;
int main(int argc, char*argv[])
{
Point_set points;
points.insert(Point(1., 2., 3.));
points.insert(Point(4., 5., 6.));
// add normal map
points.add_normal_map();
auto normal_map = points.normal_map();
// add color map
typedef Point_set::Property_map< Vector > ColorMap;
bool success = false;
ColorMap color_map;
std::tie(color_map, success) =
points.add_property_map< Vector >("color");
assert(success);
// populate normal and color map
for(auto it = points.begin(); it != points.end(); ++it)
{
normal_map[*it] = Vector(10., 11., 12.);
color_map[*it] = Vector(20., 21., 22.);
}
std::ofstream out("out.ply");
#if 1
// simple version
if(!out || !CGAL::write_ply_points_with_properties(
out,
points.points(), // const PointRange
CGAL::make_ply_point_writer(points.point_map())))
#else
// full version
if(!out || !CGAL::write_ply_points_with_properties(
out,
points.points(), // const PointRange
CGAL::make_ply_point_writer(points.point_map()),
CGAL::make_ply_normal_writer(points.normal_map()),
std::make_tuple(color_map,
CGAL::PLY_property< double >("red"),
CGAL::PLY_property< double >("green"),
CGAL::PLY_property< double >("blue"))))
#endif
{
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
编译错误为:
...
/usr/include/boost/property_map/property_map.hpp:303:54: error: no match for ‘operator[]’ (operand types are ‘const CGAL::Point_set_3<CGAL::Point_3<CGAL::Epick> >::Property_map<CGAL::Point_3<CGAL::Epick> >’ and ‘const CGAL::Point_3<CGAL::Epick>’)
Reference v = static_cast<const PropertyMap&>(pa)[k];
CGAL-4.14/include/CGAL/Surface_mesh/Properties.h:567:15: note: candidate: CGAL::Properties::Property_map_base<I, T, CRTP_derived_class>::reference CGAL::Properties::Property_map_base<I, T, CRTP_derived_class>::operator[](const I&) [with I = CGAL::Point_set_3<CGAL::Point_3<CGAL::Epick> >::Index; T = CGAL::Point_3<CGAL::Epick>; CRTP_derived_class = CGAL::Point_set_3<CGAL::Point_3<CGAL::Epick> >::Property_map<CGAL::Point_3<CGAL::Epick> >; CGAL::Properties::Property_map_base<I, T, CRTP_derived_class>::reference = CGAL::Point_3<CGAL::Epick>&]
reference operator[](const I& i)
^~~~~~~~
CGAL-4.14/include/CGAL/Surface_mesh/Properties.h:567:15: note: no known conversion for argument 1 from ‘const CGAL::Point_3<CGAL::Epick>’ to ‘const CGAL::Point_set_3<CGAL::Point_3<CGAL::Epick> >::Index&’
我该如何解决?
您的代码中的问题是您正在使用 CGAL::Point_set_3
的方法 points()
,其中 returns 类型为 CGAL::Point_set_3::Point_range
的点范围,而 属性 您使用的映射(points.point_map()
等)直接应用于类型 CGAL::Point_set_3
。
所以你应该简单地在 points
上调用 write_ply_points_with_properties()
,而不是在 points.points()
上调用 write_ply_points_with_properties()
。
另请注意,如果您将颜色存储在简单类型上(例如,使用三个 Point_set_3
类型的 unsigned char
属性),您可以利用函数 CGAL::write_ply_point_set()
自动写入它找到的所有 simply-typed 属性,这使得使用起来非常简单(只需执行 CGAL::write_ply_point_set(out, points)
即可)。
最后一件事实际上是与您的问题无关的细节,但您应该避免使用 CGAL::Vector_3
来存储除实际几何 3D 矢量(如您的情况下的颜色)之外的任何其他内容。这会使您的代码更难阅读,并且如果将颜色编码为 0 到 255 之间的整数值(这就是 unsigned char
的用途),这也是一种非常低效的存储颜色的方法。