I have the following classes:
#pragma once
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef Kernel::Point_3 Point;
typedef Kernel::Vector_3 Vector;
class Vertex {
private:
Point position;
Vector normal;
public:
Vertex(
double positionX, double positionY, double positionZ,
double normalX, double normalY, double normalZ) :
position{ positionX, positionY, positionZ },
normal{ normalX, normalY, normalZ } {};
Point& getPosition() { return position; };
Vector& getNormal() { return normal; };
};
#include <vector>
#include "Vertex.h"
class VertexCloud {
private:
std::vector<Vertex> vertices;
public:
void addVertex(Vertex vertex) { vertices.push_back(vertex); };
void addVertices(std::vector<Vertex> vertices) { this->vertices.insert(this->vertices.end(), vertices.begin(), vertices.end()); };
std::vector<Vertex>& getVertices() { return vertices; }
};
And if I would like to execute a simplification on my point cloud I'd need to do something like that:
std::unique_ptr<VertexCloud> CgalSimplification::gridSimplification(VertexCloud& vertexCloud, double epsilon) {
std::vector<Point> points;
std::vector<Vector> normals;
// This is eating up some performance. Need to improve.
for (Vertex vertex : vertexCloud.getVertices()) {
points.push_back(vertex.getPosition());
normals.push_back(vertex.getNormal());
}
std::vector<std::size_t> indices(points.size());
for (std::size_t i = 0; i < points.size(); ++i) {
indices[i] = i;
}
// Simplification by clustering using erase-remove idiom.
double cell_size{epsilon};
std::vector<std::size_t>::iterator end;
end = CGAL::grid_simplify_point_set(
indices,
cell_size,
CGAL::parameters::point_map(CGAL::make_property_map(points))
);
std::size_t k = end - indices.begin();
{
std::vector<Point> tmp_points(k);
std::vector<Vector> tmp_normals(k);
for (std::size_t i = 0; i < k; ++i) {
tmp_points[i] = points[indices[i]];
tmp_normals[i] = normals[indices[i]];
}
points.swap(tmp_points);
normals.swap(tmp_normals);
}
auto simplifiedVertexCloud = std::make_unique<VertexCloud>();
for (int i = 0; i < points.size(); i++) {
simplifiedVertexCloud->addVertex(
Vertex(
points[i].x(),
points[i].y(),
points[i].z(),
normals[i].x(),
normals[i].y(),
normals[i].z()
)
);
}
return simplifiedVertexCloud;
}
What I want to do is bypass the transferation of the data from my vertexCloud object into a vector of Point
objects to pass it later to CGAL::parameters::point_map(CGAL::make_property_map(points))
in the simplification function.
I've searched on in the manual here and here and found the template CGAL::Dereference_property_map
. I assume that it gives me the ability to create a class that overloads the []
operator and is usable for the simplification function.
Sadly I'm just starting to programm C++ more seriously and do struggle with the documentation. Can anyone provide an example on usage of CGAL::Dereference_property_map
?
I've tried something like
#include <vector>
#include "Vertex.h"
#include <CGAL/property_map.h>
class VertexCloud : CGAL::Dereference_property_map<VertexCloud> {
private:
std::vector<Vertex> vertices;
public:
void addVertex(Vertex vertex) { vertices.push_back(vertex); };
void addVertices(std::vector<Vertex> vertices) { this->vertices.insert(this->vertices.end(), vertices.begin(), vertices.end()); };
std::vector<Vertex>& getVertices() { return vertices; }
Point& operator[](int i) { return vertices[i].getPosition(); };
};
and
CGAL::parameters::point_map(vertexCloud)
but it's not working and I can't figure it out ...
The vertex point map that you have to provide must be a model of ReadablePropertyMap
. Since you have a custom vertex type, you have to write a custom property map that will simply return the point stored in the Vertex class.
Something like that should work:
struct My_vertex_point_map{
typedef Vertex key_type;
typedef Point value_type;
typedef const value_type& reference;
typedef boost::readable_property_map_tag category;
friend reference get(const My_vertex_point_map&, const key_type& v) {
return v.position;
}
};
then pass an instance of this vertex point map as parameter to vertex_point_map
.