File: custom_property_map.cpp

package info (click to toggle)
cgal 6.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 144,912 kB
  • sloc: cpp: 810,858; ansic: 208,477; sh: 493; python: 411; makefile: 286; javascript: 174
file content (112 lines) | stat: -rw-r--r-- 4,006 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/point_generators_3.h>
#include <CGAL/jet_estimate_normals.h>
#include <CGAL/mst_orient_normals.h>

using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel;
using Point_3 = Kernel::Point_3;
using Vector_3 = Kernel::Vector_3;
using Generator = CGAL::Random_points_on_sphere_3<Point_3>;

// Example of readable property map to get CGAL::Point_3 objects from
// 3 coordinate arrays
struct Custom_point_map
{
  using key_type = std::size_t; // The iterator's value type is an index
  using value_type = Point_3;   // The object manipulated by the algorithm is a Point_3
  using reference = Point_3;    // The object does not exist in memory, so there's no reference
  using category = boost::readable_property_map_tag; // The property map is only used for reading

  double *x, *y, *z;

  Custom_point_map (double* x = nullptr, double* y = nullptr, double* z = nullptr)
    : x(x), y(y), z(z) { }

  // The get() function returns the object expected by the algorithm (here, Point_3)
  friend Point_3 get (const Custom_point_map& map, std::size_t idx)
  {
    return Point_3 (map.x[idx], map.y[idx], map.z[idx]);
  }
};

// Example of read-write property map to get CGAL::Vector_3 objects from
// a buffer array and put CGAL::Vector_3 values in this buffer
struct Custom_normal_map
{
  using key_type = std::size_t; // The iterator's value type is an index
  using value_type = Vector_3;  // The object manipulated by the algorithm is a Vector_3
  using reference = Vector_3;   // The object does not exist in memory, so there's no reference
  using category = boost::read_write_property_map_tag; // The property map is used both
                                                       // for reading and writing data
  double *buffer;

  Custom_normal_map (double* buffer = nullptr)
    : buffer (buffer) { }

  // The get() function returns the object expected by the algorithm (here, Vector_3)
  friend Vector_3 get (const Custom_normal_map& map, std::size_t idx)
  {
    return Vector_3 (map.buffer[idx * 3    ],
                     map.buffer[idx * 3 + 1],
                     map.buffer[idx * 3 + 2]);
  }

  // The put() function updated the user's data structure from the
  // object handled by the algorithm (here Vector_3)
  friend void put (const Custom_normal_map& map, std::size_t idx, const Vector_3& vector_3)
  {
    map.buffer[idx * 3    ] = vector_3.x();
    map.buffer[idx * 3 + 1] = vector_3.y();
    map.buffer[idx * 3 + 2] = vector_3.z();
  }
};


int main()
{
  constexpr std::size_t nb_points = 1000;

  // in this example, points are stored as separate coordinate arrays
  double x[nb_points];
  double y[nb_points];
  double z[nb_points];

  // generate random points
  Generator generator;
  for (std::size_t i = 0; i < nb_points; ++ i)
  {
    Point_3 p = *(generator ++ );
    x[i] = p.x();
    y[i] = p.y();
    z[i] = p.z();
  }

  // normals are stored as a contiguous double array
  double normals[3 *nb_points];

  // we use a vector of indices to access arrays
  std::vector<std::size_t> indices;
  indices.reserve (nb_points);
  for (std::size_t i = 0; i < nb_points; ++ i)
    indices.push_back(i);

  // estimate and orient normals using directly user's data structure
  // instead of creating deep copies using Point_3 and Vector_3
  CGAL::jet_estimate_normals<CGAL::Sequential_tag>
    (indices, 12,
     CGAL::parameters::point_map (Custom_point_map(x,y,z)).
     normal_map (Custom_normal_map(normals)));

  CGAL::mst_orient_normals
    (indices, 12,
     CGAL::parameters::point_map (Custom_point_map(x,y,z)).
     normal_map (Custom_normal_map(normals)));

  // Display first 10 points+normals
  for (std::size_t i = 0; i < 10; ++ i)
    std::cerr << "Point(" << i << ") = " << x[i] << " " << y[i] << " " << z[i]
              << "\tNormal(" << i << ") = "
              << normals[3*i] << " " << normals[3*i+1] << " " << normals[3*i+2] << std::endl;

  return EXIT_SUCCESS;
}