我有一个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&’
我该如何解决?
答案 0 :(得分:1)
代码中的问题是您正在使用points()
的{{1}}方法,该方法返回一系列CGAL::Point_set_3
类型的点,而该属性映射您使用的({{ 1}}等)直接应用于类型CGAL::Point_set_3::Point_range
。
因此,您应该只在points.point_map()
而不是CGAL::Point_set_3
上调用write_ply_points_with_properties()
。
还请注意,如果您将颜色存储在简单类型上(例如,使用三个类型为points
的{{1}}属性),则可以利用函数CGAL::write_ply_point_set()
来自动写找到的所有简单类型的属性,这使得使用起来非常简单(只需points.points()
,就可以完成)。
最后一件事实际上是与您的问题无关的细节,但是您应该避免使用Point_set_3
来存储除实际几何3D矢量(例如颜色)以外的任何内容。如果您将代码编码为0到255之间的整数值(unsigned char
就是这样),那么这会使您的代码更难阅读,并且存储颜色也是一种无效的方式。