mirror of https://github.com/CGAL/cgal
Update branch from master after trailing whitespaces and tabs removal
This commit is contained in:
commit
cf9629fc4b
|
|
@ -3,4 +3,4 @@
|
||||||
PROJECT_NAME = "CGAL ${CGAL_DOC_VERSION} - CGAL and Boost Property Maps"
|
PROJECT_NAME = "CGAL ${CGAL_DOC_VERSION} - CGAL and Boost Property Maps"
|
||||||
INPUT += ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/property_map.h
|
INPUT += ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/property_map.h
|
||||||
EXCLUDE += ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/Dynamic_property_map.h
|
EXCLUDE += ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/Dynamic_property_map.h
|
||||||
EXAMPLE_PATH = ${CGAL_Point_set_processing_3_EXAMPLE_DIR}
|
EXAMPLE_PATH += ${CGAL_Point_set_processing_3_EXAMPLE_DIR}
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,13 @@
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
\mainpage User Manual
|
\mainpage User Manual
|
||||||
\anchor Chapter_CGAL_and_Boost_Property_Maps
|
\anchor Chapter_CGAL_and_Boost_Property_Maps
|
||||||
|
|
||||||
\anchor chapterProperty_map
|
\anchor chapterProperty_map
|
||||||
|
|
||||||
|
\cgalAutoToc
|
||||||
|
|
||||||
\authors Andreas Fabri and Laurent Saboret
|
\authors Andreas Fabri and Laurent Saboret
|
||||||
|
|
||||||
\section Property_mapA A Short Introduction to the Boost Property Maps Library
|
\section Property_mapA A Short Introduction to the Boost Property Maps Library
|
||||||
|
|
@ -25,15 +27,15 @@ Property maps in the Boost manuals: <A HREF="https://www.boost.org/libs/property
|
||||||
|
|
||||||
Some algorithms in \cgal take as input parameters iterator ranges and property maps to access information attached to elements of the sequence.
|
Some algorithms in \cgal take as input parameters iterator ranges and property maps to access information attached to elements of the sequence.
|
||||||
|
|
||||||
For example, the algorithms of chapters \ref Chapter_Point_Set_Processing "Point Set Processing" and
|
For example, the algorithms of chapters \ref Chapter_Point_Set_Processing "Point Set Processing" and
|
||||||
\ref Chapter_Poisson_Surface_Reconstruction "Poisson Surface Reconstruction"
|
\ref Chapter_Poisson_Surface_Reconstruction "Poisson Surface Reconstruction"
|
||||||
take as input parameters iterator ranges and property
|
take as input parameters iterator ranges and property
|
||||||
maps to access each point's position and normal. Position and normal
|
maps to access each point's position and normal. Position and normal
|
||||||
might be represented in various ways, e.g., as a class derived from
|
might be represented in various ways, e.g., as a class derived from
|
||||||
the \cgal point class, or as a `std::pair<Point_3<K>, Vector_3<K> >`,
|
the \cgal point class, or as a `std::pair<Point_3<K>, Vector_3<K> >`,
|
||||||
or as a `boost::tuple<..,Point_3<K>, ..., Vector_3<K> >`.
|
or as a `boost::tuple<..,Point_3<K>, ..., Vector_3<K> >`.
|
||||||
|
|
||||||
This component provides property maps to support these cases:
|
This component provides property maps to support these cases:
|
||||||
|
|
||||||
- `Identity_property_map<T>`
|
- `Identity_property_map<T>`
|
||||||
- `First_of_pair_property_map<Pair>` and `Second_of_pair_property_map<Pair>`
|
- `First_of_pair_property_map<Pair>` and `Second_of_pair_property_map<Pair>`
|
||||||
|
|
@ -55,6 +57,20 @@ The following example reads a point set from an input file and writes it to a fi
|
||||||
The following example reads a point set in the `xyz` format and computes the average spacing. %Index, position and color are stored in a tuple and accessed through property maps.
|
The following example reads a point set in the `xyz` format and computes the average spacing. %Index, position and color are stored in a tuple and accessed through property maps.
|
||||||
\cgalExample{Point_set_processing_3/average_spacing_example.cpp}
|
\cgalExample{Point_set_processing_3/average_spacing_example.cpp}
|
||||||
|
|
||||||
*/
|
\section Property_mapCustom Writing Custom Property Maps
|
||||||
|
|
||||||
|
Property maps are especially useful when using predefined data
|
||||||
|
structures that are not part of the \cgal library: algorithms written
|
||||||
|
with property maps can be called on these data structures provided the
|
||||||
|
user writes the required property maps, without the need to create
|
||||||
|
deep copies of potentially large data into \cgal formats.
|
||||||
|
|
||||||
|
The following example shows how to write a readable point map and a
|
||||||
|
read-write normal map to run \cgal normal estimation and orientation
|
||||||
|
algorithm on raw `double` arrays:
|
||||||
|
\cgalExample{Property_map/custom_property_map.cpp}
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
} /* namespace CGAL */
|
} /* namespace CGAL */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,4 +2,5 @@
|
||||||
\example Point_set_processing_3/remove_outliers_example.cpp
|
\example Point_set_processing_3/remove_outliers_example.cpp
|
||||||
\example Point_set_processing_3/read_write_xyz_point_set_example.cpp
|
\example Point_set_processing_3/read_write_xyz_point_set_example.cpp
|
||||||
\example Point_set_processing_3/average_spacing_example.cpp
|
\example Point_set_processing_3/average_spacing_example.cpp
|
||||||
|
\example Property_map/custom_property_map.cpp
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ find_package( CGAL QUIET COMPONENTS )
|
||||||
if ( NOT CGAL_FOUND )
|
if ( NOT CGAL_FOUND )
|
||||||
|
|
||||||
message(STATUS "This project requires the CGAL library, and will not be compiled.")
|
message(STATUS "This project requires the CGAL library, and will not be compiled.")
|
||||||
return()
|
return()
|
||||||
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
@ -20,7 +20,7 @@ if ( NOT Boost_FOUND )
|
||||||
|
|
||||||
message(STATUS "This project requires the Boost library, and will not be compiled.")
|
message(STATUS "This project requires the Boost library, and will not be compiled.")
|
||||||
|
|
||||||
return()
|
return()
|
||||||
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
@ -32,4 +32,10 @@ endif()
|
||||||
|
|
||||||
create_single_source_cgal_program( "dynamic_properties.cpp" )
|
create_single_source_cgal_program( "dynamic_properties.cpp" )
|
||||||
|
|
||||||
|
find_package(Eigen3 3.1.0) #(requires 3.1.0 or greater)
|
||||||
|
if (EIGEN3_FOUND)
|
||||||
|
create_single_source_cgal_program( "custom_property_map.cpp" )
|
||||||
|
CGAL_target_use_Eigen(custom_property_map)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,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;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue