Merge pull request #1791 from sgiraudot/Point_set_3-GF

New package Point Set 3
This commit is contained in:
Laurent Rineau 2017-01-09 11:21:23 +01:00
commit 904a889e6d
32 changed files with 33436 additions and 9 deletions

View File

@ -67,6 +67,7 @@ Three
Triangulation_3
Triangulation
Ridges_3
Point_set_3
Point_set_processing_3
Point_set_shape_detection_3
Polyline_simplification_2

View File

@ -116,6 +116,7 @@ h1 {
\package_listing{Surface_mesh_skeletonization}
\package_listing{Ridges_3}
\package_listing{Jet_fitting_3}
\package_listing{Point_set_3}
\package_listing{Point_set_processing_3}
\package_listing{Point_set_shape_detection_3}
\package_listing{Stream_lines_2}

View File

@ -151,6 +151,13 @@ and <code>src/</code> directories).
This package implements Generalized Maps in d dimensions. A generalized map is a data structure enabling to represent an orientable or non orientable subdivided object by describing all the cells of the subdivision (for example in 3D vertices, edges, faces, volumes) and all the incidence and adjacency relationships between these cells. This data structure is the generalization of the combinatorial maps in order to be able to represent non orientable objects.</li>
</li>
</ul>
<h3>3D Point Set</h3>
<ul>
<li>New package providing a flexible data
structure <code>CGAL::Point_set_3</code> that allows the user to
easily handle point sets with an arbitrary number of attributes
(such as normal vectors, colors, labeling, etc.).</li>
</ul>
<!-- Major and breaking changes -->
<h3>Combinatorial Maps and Linear cell complex</h3>
<ul>

View File

@ -0,0 +1,2 @@
@INCLUDE = ${CGAL_DOC_PACKAGE_DEFAULTS}
PROJECT_NAME = "CGAL ${CGAL_DOC_VERSION} - 3D Point Set"

View File

@ -0,0 +1,66 @@
/*!
\defgroup PkgPointSet3 3D Point Set Reference
\cgalPkgDescriptionBegin{3D Point Set, PkgPointSet3Summary}
\cgalPkgPicture{point_set_3.png}
\cgalPkgSummaryBegin
\cgalPkgAuthors{Simon Giraudot}
\cgalPkgDesc{This component provides the user with a flexible 3D point set data structure. The user can define any additional property needed such as normal vectors, colors or labels. \cgal algorithms can be easily applied to this data structure.}
\cgalPkgManuals{Chapter_Point_Set_3, PkgPointSet3}
\cgalPkgSummaryEnd
\cgalPkgShortInfoBegin
\cgalPkgSince{4.10}
\cgalPkgBib{cgal:g-ps}
\cgalPkgLicense{\ref licensesGPL "GPL"}
\cgalPkgDemo{Operations on Polyhedra,polyhedron_3.zip}
\cgalPkgShortInfoEnd
\cgalPkgDescriptionEnd
\cgalClassifedRefPages
## Class ##
- `CGAL::Point_set_3<Point,Vector>`
\defgroup PkgPointSet3PointSetProcessing3 Point Set Processing
\ingroup PkgPointSet3
\brief This module offers convenience overloads of functions available in the
\ref PkgPointSetProcessingSummary package. These overloads allow the
user to call point set processing algorithms without having to handle
manually property maps and iterators.
The overloads, available after including
`CGAL/Point_set_3/Point_set_processing_3.h`, all follow the same
pattern based on the original point set processing functions:
- Iterators and property maps of the original functions are replaced
with a single parameter `CGAL::Point_set_3<Point,Vector>`
- The other parameters (and their potential default values) are
following in the same order as the original function.
For a complete documentation of these functions, please refer to the
\ref PkgPointSetProcessing manual.
\defgroup PkgPointSet3IO Input/Output
\ingroup PkgPointSet3
\brief This module offers convenience overloads of input/ouput
functions available in the \ref PkgPointSetProcessingSummary package.
These overloads, available after including `CGAL/Point_set_3/IO.h`,
allow the user to call point set processing algorithms without having
to handle manually property maps and iterators.
Input functions instanciate all the necessary property maps:
- if found in the input, normal vectors are stored in the usual
`CGAL::Point_set_3` property `normal` with template type `Vector`
- for PLY input only, other properties are stored as properties in the
`Point_set_3` class with the name and type given by the PLY header
For a complete documentation of these functions, please refer to the
\ref PkgPointSetProcessing manual.
*/

View File

@ -0,0 +1,172 @@
namespace CGAL {
/*!
\mainpage User Manual
\anchor Chapter_Point_Set_3
\cgalAutoToc
\author Simon Giraudot
\cgal provides several algorithms for processing point sets, ranging from
\ref Chapter_Point_Set_Shape_Detection "Shape Detection" to
\ref Chapter_Advancing_Front_Surface_Reconstruction "Surface Reconstruction"
through standard \ref Chapter_Point_Set_Processing "Point Set Processing" tools.
While these algorithms do not impose specific data structures to work
on, this package provides a 3D point set structure to make it easier for the
user to handle additional properties such as normal vectors, colors,
labels, and to call \cgal algorithms on them.
\section Point_set_3_Principle General Principle
`CGAL::Point_set_3<Point,Vector>` is a vector based data structure
that contains a default property (named `point`) for the coordinates
of the points.
Any property the user needs can be easily added, modified, and
removed at runtime. A property is identified by a unique name and a
type. Convenience methods are provided to handle the normal vectors
(property named `normal`) that is a very common property on point sets.
To optimize memory allocation and deallocation, each point is associated an index.
The removal of a point simply marks the index as removed.
Internally, this avoids the property vectors to be modified at each removal,
and allow insertion of new points to reuse indices of points marked as removed.
In particular this implies that a point inserted after some removal was done
might has a non default initialized property.
If the user needs memory to be effectively deallocated, the element marked as removed
can be actually deleted from memory using `Point_set_3::garbage_collect()`.
\section Point_set_3_Usage Simple Usage
The data structure is designed to be easy to use despite its potential
complexity when using properties. Several convenience methods are
provided to handle points and normals without having to handle
properties directly.
The following example shows how to fill a point set, add a
normal property, set the normal values, add and remove a point.
\cgalExample{Point_set_3/point_set.cpp}
\section Point_set_3_Properties Using Additional Properties
Every information in the point set is a property. A raw point set
comes only with a `point` property. As we saw in the previous example,
the user can easily add a _normal_ property. But this mechanism is
generalized to any type of property.
The following example shows how to define a color property and an
intensity property, and how to modify the point set according to this.
\cgalExample{Point_set_3/point_set_property.cpp}
\section Point_set_3_Algorithms Applying CGAL Algorithms
Most \cgal algorithms let the user free to choose an input data
structure: the points and attributes are then accessed
through iterators and property maps. The `CGAL::Point_set_3`
class directly provides these iterators and property maps so that
applying \cgal algorithms is straightforward.
In addition, all functions of the package
\ref Chapter_Point_Set_Processing "Point Set Processing" are overloaded so
that the user only has to call them with a `CGAL::Point_set_3`
object as a parameter.
\subsection Point_set_3_PSP Point Set Processing
The following example shows how to apply some algorithms from the
\cgal library using a point set object:
- generating a point set around a sphere
- estimating the normals with `CGAL::jet_estimate_normals()`
- simplifying the point set with `CGAL::grid_simplify_point_set()`
- detecting the sphere shape with `CGAL::Shape_detection_3::Efficient_RANSAC`
\cgalExample{Point_set_3/point_set_algo.cpp}
\subsection Point_set_3_IO Input/Output
The following example shows how to read a point set in the XYZ format, normalize
and invert the normal vectors, and write the result in the OFF
format.
\cgalExample{Point_set_3/point_set_read_xyz.cpp}
The PLY format is the usual choice when storing an arbitrary number of
additional properties of points is needed. \cgal provides a function
`read_ply_point_set()` that allows the user to recover any PLY
property wanted, provided the adapted PLY interpreter is
implemented.
A `CGAL::Point_set_3` object can be filled with all readable properties
of a PLY input. Each PLY property is read and stored into as a
property with similar name and type.
For example, if the following line is found in the PLY header:
> property uchar red
Then a property named `red` and with type `boost::uint8_t` (`boost`
types are used because of their fixed memory size) will be
instantiated in the point set and filled with the corresponding
values.
Points and normals are recovered as properties with specific class
types (namely the template types `Point` and `Vector`). Other non-1D
properties are stored with simple number types. For example, if a
color is given with integer red, green and blue values, 3 integer
properties `red`, `green` and `blue` will be created. A
user-defined interpreter must be implemented if such properties should
be stored all together (a unique property `color` of type
`CGAL::cpp11::array` for example).
The following example shows how to use this interpreter and how to
access a specific property afterwards:
\cgalExample{Point_set_3/point_set_read_ply.cpp}
\subsection Point_set_3_Avdanced Advanced Usage
Using functions of \cgal to read files requires a slightly different
behavior because internally the properties of a point are defined
_before_ this point is inserted into the point set (which is not
possible with `CGAL::Point_set_3`). Although using the provided
overloads presented in the previous subsection should cover most
usages, we document the specific back inserters and property maps that
are used internally:
- `CGAL::Point_set_3::index_back_inserter()` is used as an output iterator that creates
new points.
- `CGAL::Point_set_3::point_push_map()` is a property map for setting the coordinates
of a point. It will first insert the point create in the structure if it has not been
created first (by `index_back_inserter()` for example).
- `CGAL::Point_set_3::normal_push_map()` works similarly but for normal vectors.
Such _push property maps_ are also available for other user-defined
properties (see `CGAL::Point_set_3::push_property_map()`).
The following example shows how to read OFF point without using the
overload provided for `CGAL::Point_set_3`:
\cgalExample{Point_set_3/point_set_advanced.cpp}
\section Point_set_3_History History
This package has been created to fill the need for a practical data
structure that handles points with a user-defined set of
properties. A property mechanism was already implemented in the
\ref Chapter_3D_Surface_mesh "Surface Mesh" package: all the classes
dedicated to the management of properties were extracted so that they
can be used in this package. `CGAL::Surface_mesh<Point>` and
`CGAL::Point_set_3<Point,Vector>` now follow a similar API for property
management.
*/
} /* namespace CGAL */

View File

@ -0,0 +1,10 @@
Manual
Kernel_23
STL_Extension
Algebraic_foundations
Circulator
Stream_support
Point_set_processing_3
Point_set_shape_detection_3
Advancing_front_surface_reconstruction
Surface_mesh

View File

@ -0,0 +1,8 @@
/*!
\example Point_set_3/point_set.cpp
\example Point_set_3/point_set_property.cpp
\example Point_set_3/point_set_algo.cpp
\example Point_set_3/point_set_read_xyz.cpp
\example Point_set_3/point_set_read_ply.cpp
\example Point_set_3/point_set_advanced.cpp
*/

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

View File

@ -0,0 +1,64 @@
# Created by the script cgal_create_CMakeLists
# This is the CMake script for compiling a set of CGAL applications.
project( Point_set_3 )
cmake_minimum_required(VERSION 2.8.11)
# CGAL and its components
find_package( CGAL QUIET COMPONENTS )
if ( NOT CGAL_FOUND )
message(STATUS "This project requires the CGAL library, and will not be compiled.")
return()
endif()
# include helper file
include( ${CGAL_USE_FILE} )
# Boost and its components
find_package( Boost REQUIRED )
if ( NOT Boost_FOUND )
message(STATUS "This project requires the Boost library, and will not be compiled.")
return()
endif()
# include for local directory
include_directories( BEFORE include )
# include for local package
include_directories( BEFORE ../../include )
# Creating entries for all C++ files with "main" routine
# ##########################################################
include( CGAL_CreateSingleSourceCGALProgram )
create_single_source_cgal_program( "point_set.cpp" )
create_single_source_cgal_program( "point_set_property.cpp" )
create_single_source_cgal_program( "point_set_read_xyz.cpp" )
create_single_source_cgal_program( "point_set_read_ply.cpp" )
create_single_source_cgal_program( "point_set_advanced.cpp" )
find_package(Eigen3 3.1.0) #(requires 3.1.0 or greater)
if (NOT EIGEN3_FOUND)
find_package(LAPACK)
if(LAPACK_FOUND)
include( ${LAPACK_USE_FILE} )
endif(LAPACK_FOUND)
else()
include( ${EIGEN3_USE_FILE} )
create_single_source_cgal_program( "point_set_algo.cpp" )
endif()

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,19 @@
ply
format ascii 1.0
comment Example for CGAL PLY reader
element vertex 3
property double x
property double y
property double z
property double nx
property double ny
property double nz
property uchar red
property uchar green
property uchar blue
property double intensity
property int label
end_header
0.0 0.0 0.0 0.0 0.0 1.0 255 0 0 0.8 1
0.0 0.0 1.0 0.0 0.0 1.0 0 255 0 0.76 0
0.0 1.0 0.0 0.0 0.0 1.0 0 0 255 0.99 1

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,69 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Point_set_3.h>
#include <fstream>
#include <limits>
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef Kernel::FT FT;
typedef Kernel::Point_3 Point;
typedef Kernel::Vector_3 Vector;
typedef CGAL::Point_set_3<Point> Point_set;
void print_point_set (const Point_set& point_set)
{
std::cerr << "Content of point set:" << std::endl;
for (Point_set::const_iterator it = point_set.begin();
it != point_set.end(); ++ it)
std::cerr << "* Point " << *it
<< ": " << point_set.point(*it) // or point_set[it]
<< " with normal " << point_set.normal(*it)
<< std::endl;
}
int main (int, char**)
{
Point_set point_set;
// Add points
point_set.insert (Point (0., 0., 0.));
point_set.insert (Point (0., 0., 1.));
point_set.insert (Point (0., 1., 0.));
point_set.add_normal_map();
print_point_set(point_set); // Normals have default values
// Change normal values
Point_set::iterator it = point_set.begin();
point_set.normal(*(it++)) = Vector (1., 0., 0.);
point_set.normal(*(it++)) = Vector (0., 1., 0.);
point_set.normal(*(it++)) = Vector (0., 0., 1.);
// Add point + normal
point_set.insert (Point (1., 2., 3.), Vector (4., 5., 6.));
print_point_set(point_set);
// Add new item
Point_set::iterator new_item = point_set.insert(Point (7., 8., 9.));
point_set.normal(*new_item) = Vector (10., 11., 12.);
print_point_set(point_set); // New item has default values
point_set.remove (point_set.begin() + 2,
point_set.begin() + 4);
print_point_set(point_set); // New item has default values
// Display information
std::cerr << "Number of removed points: " <<point_set.number_of_removed_points() << std::endl;
point_set.collect_garbage();
// Display information (garbage should be gone)
std::cerr << "After garbage collection: " <<point_set.number_of_removed_points() << std::endl;
return 0;
}

View File

@ -0,0 +1,33 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Point_set_3.h>
#include <CGAL/IO/read_off_points.h>
#include <fstream>
#include <limits>
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef Kernel::FT FT;
typedef Kernel::Point_3 Point;
typedef Kernel::Vector_3 Vector;
typedef CGAL::Point_set_3<Point> Point_set;
int main (int argc, char** argv)
{
std::ifstream f (argc > 1 ? argv[1] : "data/camel.off");
Point_set point_set;
point_set.add_normal_map();
// Reading input in OFF format
if (!f || !CGAL::read_off_points_and_normals
(f,
point_set.index_back_inserter(), // OutputIterator
point_set.point_push_map(),
point_set.normal_push_map()))
{
std::cerr << "Can't read input file " << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}

View File

@ -0,0 +1,74 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Point_set_3.h>
#include <CGAL/Point_set_3/Point_set_processing_3.h>
#include <CGAL/Point_set_3/IO.h>
#include <CGAL/grid_simplify_point_set.h>
#include <CGAL/point_generators_3.h>
#include <CGAL/Shape_detection_3.h>
#include <fstream>
#include <limits>
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef Kernel::FT FT;
typedef Kernel::Point_3 Point;
typedef Kernel::Vector_3 Vector;
typedef CGAL::Random_points_on_sphere_3<Point> Point_generator;
typedef CGAL::Point_set_3<Point> Point_set;
typedef CGAL::Shape_detection_3::Efficient_RANSAC_traits
<Kernel, Point_set, Point_set::Point_map, Point_set::Vector_map> Traits;
typedef CGAL::Shape_detection_3::Efficient_RANSAC<Traits> Efficient_ransac;
typedef CGAL::Shape_detection_3::Sphere<Traits> Sphere;
int main (int, char**)
{
Point_set point_set;
// Generate points on a unit sphere
Point_generator generator(1.);
std::size_t nb_pts = 10000;
point_set.reserve (nb_pts);
for (std::size_t i = 0; i < nb_pts; ++ i)
point_set.insert (*(generator ++));
// Add normal property and estimate normal values
CGAL::jet_estimate_normals<CGAL::Sequential_tag> (point_set,
12); // Number of neighbors
// Simplify point set
CGAL::grid_simplify_point_set (point_set,
0.1); // Size of grid cell
std::vector<std::string> properties = point_set.properties();
std::cerr << "Properties:" << std::endl;
for (std::size_t i = 0; i < properties.size(); ++ i)
std::cerr << " * " << properties[i] << std::endl;
// Detect sphere with RANSAC
Efficient_ransac ransac;
ransac.set_input(point_set,
point_set.point_map(), // Call built-in property map
point_set.normal_map()); // Call built-in property map
ransac.add_shape_factory<Sphere>();
Efficient_ransac::Parameters parameters;
parameters.probability = 0.05;
parameters.min_points = std::size_t(point_set.size() / 3);
parameters.epsilon = 0.01;
parameters.cluster_epsilon = 0.5;
parameters.normal_threshold = 0.9;
ransac.detect(parameters);
BOOST_FOREACH(boost::shared_ptr<Efficient_ransac::Shape> shape, ransac.shapes())
if (Sphere* sphere = dynamic_cast<Sphere*>(shape.get()))
std::cerr << "Detected sphere of center " << sphere->center() // Center should be approx 0, 0, 0
<< " and of radius " << sphere->radius() << std::endl; // Radius should be approx 1
return 0;
}

View File

@ -0,0 +1,78 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Point_set_3.h>
#include <CGAL/Random.h>
#include <fstream>
#include <limits>
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef Kernel::FT FT;
typedef Kernel::Point_3 Point;
typedef Kernel::Vector_3 Vector;
typedef CGAL::cpp11::array<unsigned char, 3> Color;
typedef CGAL::Point_set_3<Point> Point_set;
typedef Point_set::Property_map<Color> Color_map;
typedef Point_set::Property_map<FT> FT_map;
void print_point_set (const Point_set& point_set)
{
Color_map color;
boost::tie (color, boost::tuples::ignore) = point_set.property_map<Color>("color");
FT_map intensity;
boost::tie (intensity, boost::tuples::ignore) = point_set.property_map<FT>("intensity");
std::cerr << "Content of point set:" << std::endl;
for (Point_set::const_iterator it = point_set.begin();
it != point_set.end(); ++ it)
std::cerr << "* Point " << point_set.point(*it) // or point_set[it]
<< " with color [" << (int)(color[*it][0])
<< " " << (int)(color[*it][1])
<< " " << (int)(color[*it][2])
<< "] and intensity " << intensity[*it]
<< std::endl;
}
int main (int, char**)
{
Point_set point_set;
Color black = {{ 0, 0, 0 }};
bool success = false;
Color_map color;
boost::tie (color, success) = point_set.add_property_map<Color> ("color", black);
assert (success);
FT_map intensity;
boost::tie (intensity, success) = point_set.add_property_map<FT> ("intensity", 0.);
assert (success);
point_set.reserve (10); // For memory optimization
for (std::size_t i = 0; i < 10; ++ i)
{
Point_set::iterator it = point_set.insert (Point (double(i), double(i), double(i)));
Color c = {{ (unsigned char)(CGAL::get_default_random().get_int(0, 255)),
(unsigned char)(CGAL::get_default_random().get_int(0, 255)),
(unsigned char)(CGAL::get_default_random().get_int(0, 255)) }};
color[*it] = c;
intensity[*it] = rand() / (double)(RAND_MAX);
}
print_point_set (point_set);
// Remove points with intensity less than 0.5
Point_set::iterator it = point_set.begin();
while (it != point_set.end())
{
if (intensity[*it] < 0.5)
point_set.remove(it);
else
++ it;
}
print_point_set (point_set); // point set is filtered
return 0;
}

View File

@ -0,0 +1,48 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Point_set_3.h>
#include <CGAL/Point_set_3/IO.h>
#include <fstream>
#include <limits>
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef Kernel::FT FT;
typedef Kernel::Point_3 Point;
typedef Kernel::Vector_3 Vector;
typedef CGAL::Point_set_3<Point> Point_set;
int main (int argc, char** argv)
{
std::ifstream f (argc > 1 ? argv[1] : "data/example.ply");
Point_set point_set;
if (!f || !CGAL::read_ply_point_set (f, point_set))
{
std::cerr << "Can't read input file " << std::endl;
}
// Shows which properties are defined
std::vector<std::string> properties = point_set.properties();
std::cerr << "Properties:" << std::endl;
for (std::size_t i = 0; i < properties.size(); ++ i)
std::cerr << " * " << properties[i] << std::endl;
// Recover "label" property of type int
Point_set::Property_map<boost::int32_t> label_prop;
bool found = false;
boost::tie (label_prop, found) = point_set.property_map<boost::int32_t> ("label");
if (found)
{
std::cerr << "Point set has an integer \"label\" property with values:" << std::endl;
for (Point_set::iterator it = point_set.begin(); it != point_set.end(); ++ it)
std::cerr << " * " << label_prop[*it] << std::endl;
}
std::ofstream out ("out.ply");
CGAL::write_ply_point_set (out, point_set);
return 0;
}

View File

@ -0,0 +1,47 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Point_set_3.h>
#include <CGAL/Point_set_3/IO.h>
#include <fstream>
#include <limits>
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef Kernel::FT FT;
typedef Kernel::Point_3 Point;
typedef Kernel::Vector_3 Vector;
typedef CGAL::Point_set_3<Point> Point_set;
int main (int argc, char** argv)
{
std::ifstream f (argc > 1 ? argv[1] : "data/oni.xyz");
Point_set point_set;
// Reading input in XYZ format
if (!f || !CGAL::read_xyz_point_set (f, point_set))
{
std::cerr << "Can't read input file " << std::endl;
return EXIT_FAILURE;
}
if (point_set.has_normal_map())
{
// Normalization + inversion of normal vectors
for (Point_set::iterator it = point_set.begin(); it != point_set.end(); ++ it)
{
Vector n = point_set.normal(*it);
n = - n / std::sqrt (n * n);
point_set.normal(*it) = n;
}
}
// Writing result in OFF format
std::ofstream out("normalized_normals.off");
if (!out || !CGAL::write_off_point_set (out, point_set))
{
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}

View File

@ -1,5 +1,3 @@
// NOTE: file to remove once Point_set_3 package is available
// Copyright (c) 2016 Geometry Factory
// All rights reserved.
//
@ -61,6 +59,7 @@ private:
struct Abstract_ply_property_to_point_set_property
{
virtual ~Abstract_ply_property_to_point_set_property() { }
virtual void assign (Ply_reader& reader, typename Point_set::Index index) = 0;
};

View File

@ -1,5 +1,3 @@
// NOTE: file to remove once Point_set_3 package is available
// Copyright (c) 2016 GeometryFactory Sarl (France).
// All rights reserved.
//

View File

@ -1,5 +1,3 @@
// NOTE: file to remove once Point_set_3 package is available
// Copyright (c) 2016 GeometryFactory Sarl (France).
// All rights reserved.
//
@ -218,6 +216,7 @@ namespace internal
class Abstract_property_printer
{
public:
virtual ~Abstract_property_printer() { }
virtual std::string get_string(const typename CGAL::Point_set_3<Point,Vector>::Index& index) = 0;
};
@ -269,7 +268,7 @@ namespace internal
\ingroup PkgPointSet3IO
\brief Inserts the point set in an output stream in Ascii PLY
\brief Inserts the point set in an output stream in ASCII PLY
format. All properties are inserted in their instantiation order.
\relates Point_set_3

View File

@ -0,0 +1,307 @@
// Copyright (c) 2016 GeometryFactory Sarl (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
// You can redistribute it and/or modify it under the terms of the GNU
// General Public License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
//
//
// Author(s) : Simon Giraudot
#ifndef CGAL_POINT_SET_3_POINT_SET_PROCESSING_3_H
#define CGAL_POINT_SET_3_POINT_SET_PROCESSING_3_H
#include <CGAL/bilateral_smooth_point_set.h>
#include <CGAL/compute_average_spacing.h>
#include <CGAL/edge_aware_upsample_point_set.h>
#include <CGAL/grid_simplify_point_set.h>
#include <CGAL/hierarchy_simplify_point_set.h>
#include <CGAL/jet_estimate_normals.h>
#include <CGAL/jet_smooth_point_set.h>
#include <CGAL/mst_orient_normals.h>
#include <CGAL/pca_estimate_normals.h>
#include <CGAL/random_simplify_point_set.h>
#include <CGAL/remove_outliers.h>
#include <CGAL/vcm_estimate_normals.h>
#include <CGAL/wlop_simplify_and_regularize_point_set.h>
namespace CGAL {
/*!
\ingroup PkgPointSet3PointSetProcessing3
*/
template <typename Concurrency_tag,
typename Point,
typename Vector>
double
bilateral_smooth_point_set(
CGAL::Point_set_3<Point, Vector>& point_set, ///< point set
const unsigned int k, ///< number of neighbors.
double sharpness_angle) ///< control sharpness(0-90)
{
return CGAL::bilateral_smooth_point_set<Concurrency_tag>
(point_set.begin(), point_set.end(),
point_set.point_map(), point_set.normal_map(),
k, sharpness_angle);
}
/*!
\ingroup PkgPointSet3PointSetProcessing3
*/
template <typename Concurrency_tag,
typename Point, typename Vector>
double
compute_average_spacing(
const CGAL::Point_set_3<Point, Vector>& point_set, ///< point set
unsigned int k) ///< number of neighbors.
{
return CGAL::compute_average_spacing<Concurrency_tag>
(point_set.begin(), point_set.end(), point_set.point_map(), k);
}
/*!
\ingroup PkgPointSet3PointSetProcessing3
*/
template <typename Concurrency_tag,
typename Point, typename Vector>
void
edge_aware_upsample_point_set(
CGAL::Point_set_3<Point, Vector>& point_set, ///< point set
double sharpness_angle = 30, ///< control sharpness(0-90)
double edge_sensitivity = 1, ///< edge sensitivity(0-5)
double neighbor_radius = -1, ///< initial size of neighbors.
const std::size_t number_of_output_points = 1000)///< number of output points.
{
CGAL::edge_aware_upsample_point_set<Concurrency_tag>
(point_set.begin(), point_set.end(),
point_set.point_back_inserter(),
point_set.point_map(), point_set.normal_map(),
sharpness_angle, edge_sensitivity, neighbor_radius, number_of_output_points);
}
/*!
\ingroup PkgPointSet3PointSetProcessing3
\note No iterator is returned, points simplified are directly
removed from the point set.
*/
template <typename Point, typename Vector>
void grid_simplify_point_set(
CGAL::Point_set_3<Point, Vector>& point_set, ///< point set
double epsilon) ///< tolerance value when merging 3D points.
{
point_set.remove_from
(CGAL::grid_simplify_point_set
(point_set.begin(), point_set.end(), point_set.point_map(), epsilon));
}
/*!
\ingroup PkgPointSet3PointSetProcessing3
\note No iterator is returned, points simplified are directly
removed from the point set.
*/
template <typename Point, typename Vector>
void hierarchy_simplify_point_set(
CGAL::Point_set_3<Point, Vector>& point_set, ///< point set
const unsigned int size = 10, ///< maximum cluster size
const double var_max = 0.333) ///< maximal surface variation
{
point_set.remove_from
(CGAL::hierarchy_simplify_point_set
(point_set.begin(), point_set.end(), point_set.point_map(), size, var_max,
CGAL::Default_diagonalize_traits<double, 3>()));
}
/*!
\ingroup PkgPointSet3PointSetProcessing3
\note This function adds a normal map to the point set.
*/
template <typename Concurrency_tag,
typename Point, typename Vector>
void
jet_estimate_normals(
CGAL::Point_set_3<Point, Vector>& point_set, ///< point set
unsigned int k, ///< number of neighbors.
unsigned int degree_fitting = 2) ///< fitting degree
{
point_set.add_normal_map();
CGAL::jet_estimate_normals<Concurrency_tag>
(point_set.begin(), point_set.end(),
point_set.point_map(), point_set.normal_map(),
k, degree_fitting);
}
/*!
\ingroup PkgPointSet3PointSetProcessing3
*/
template <typename Concurrency_tag,
typename Point, typename Vector>
void
jet_smooth_point_set(
CGAL::Point_set_3<Point, Vector>& point_set, ///< point set
unsigned int k, ///< number of neighbors.
unsigned int degree_fitting = 2, ///< fitting degree
unsigned int degree_monge = 2) ///< Monge degree
{
CGAL::jet_smooth_point_set<Concurrency_tag>
(point_set.begin(), point_set.end(), point_set.point_map(),
k, degree_fitting, degree_monge);
}
/*!
\ingroup PkgPointSet3PointSetProcessing3
*/
template <typename Point, typename Vector>
typename CGAL::Point_set_3<Point, Vector>::iterator
mst_orient_normals(
CGAL::Point_set_3<Point, Vector>& point_set, ///< point set
unsigned int k) ///< number of neighbors
{
return CGAL::mst_orient_normals
(point_set.begin(), point_set.end(),
point_set.point_map(), point_set.normal_map(), k);
}
/*!
\ingroup PkgPointSet3PointSetProcessing3
\note This function adds a normal map to the point set.
*/
template <typename Concurrency_tag,
typename Point, typename Vector>
void
pca_estimate_normals(
CGAL::Point_set_3<Point, Vector>& point_set, ///< point set
unsigned int k) ///< number of neighbors.
{
point_set.add_normal_map();
CGAL::pca_estimate_normals<Concurrency_tag>
(point_set.begin(), point_set.end(),
point_set.point_map(), point_set.normal_map(),
k);
}
/*!
\ingroup PkgPointSet3PointSetProcessing3
\note No iterator is returned, points simplified are directly
removed from the point set.
*/
template <typename Point, typename Vector>
void random_simplify_point_set(
CGAL::Point_set_3<Point, Vector>& point_set, ///< point set
double removed_percentage) ///< percentage of points to remove
{
point_set.remove_from
(CGAL::random_simplify_point_set
(point_set.begin(), point_set.end(), point_set.point_map(), removed_percentage));
}
/*!
\ingroup PkgPointSet3PointSetProcessing3
\note No iterator is returned, points simplified are directly
removed from the point set.
*/
template <typename Point, typename Vector>
void remove_outliers(
CGAL::Point_set_3<Point, Vector>& point_set, ///< point set
unsigned int k, ///< number of neighbors.
double threshold_percent) ///< percentage of points to remove
{
point_set.remove_from
(CGAL::remove_outliers
(point_set.begin(), point_set.end(), point_set.point_map(), k, threshold_percent));
}
/*!
\ingroup PkgPointSet3PointSetProcessing3
\note This function adds a normal map to the point set.
*/
template <typename Point, typename Vector>
void
vcm_estimate_normals(
CGAL::Point_set_3<Point, Vector>& point_set, ///< point set
double offset_radius, ///< offset radius.
double convolution_radius) ///< convolution radius.
{
point_set.add_normal_map();
CGAL::vcm_estimate_normals
(point_set.begin(), point_set.end(),
point_set.point_map(), point_set.normal_map(),
offset_radius, convolution_radius);
}
/*!
\ingroup PkgPointSet3PointSetProcessing3
\note This function adds a normal map to the point set.
*/
template <typename Point, typename Vector>
void
vcm_estimate_normals(
CGAL::Point_set_3<Point, Vector>& point_set, ///< point set
double offset_radius, ///< offset radius.
unsigned int nb_neighbors_convolve) ///< number of neighbors used during the convolution.
{
point_set.add_normal_map();
CGAL::vcm_estimate_normals
(point_set.begin(), point_set.end(),
point_set.point_map(), point_set.normal_map(),
offset_radius, nb_neighbors_convolve);
}
/*!
\ingroup PkgPointSet3PointSetProcessing3
*/
template <typename Concurrency_tag,
typename Point, typename Vector>
void
wlop_simplify_and_regularize_point_set(
const CGAL::Point_set_3<Point, Vector>& input_point_set, ///< input point set
CGAL::Point_set_3<Point, Vector>& output_point_set, ///< output point set
const double select_percentage = 5, ///< percentage of points to retain
double neighbor_radius = -1, ///< size of neighbors.
const unsigned int max_iter_number = 35, ///< number of iterations.
const bool require_uniform_sampling = false ///< if needed to compute density
/// to generate more rugularized result.
)
{
CGAL::wlop_simplify_and_regularize_point_set
(input_point_set.begin(), input_point_set.end(),
output_point_set.point_back_inserter(),
input_point_set.point_map(),
select_percentage,
neighbor_radius,
max_iter_number,
require_uniform_sampling);
}
} // namespace CGAL
#endif // CGAL_POINT_SET_3_POINT_SET_PROCESSING_3_H

View File

@ -0,0 +1 @@
GeometryFactory (France)

View File

@ -0,0 +1 @@
GPL (v3 or later)

View File

@ -0,0 +1 @@
Simon Giraudot (simon.giraudot@geometryfactory.com)

View File

@ -0,0 +1,48 @@
# Created by the script cgal_create_CMakeLists
# This is the CMake script for compiling a set of CGAL applications.
project( Point_set_3 )
cmake_minimum_required(VERSION 2.8.11)
# CGAL and its components
find_package( CGAL QUIET COMPONENTS )
if ( NOT CGAL_FOUND )
message(STATUS "This project requires the CGAL library, and will not be compiled.")
return()
endif()
# include helper file
include( ${CGAL_USE_FILE} )
# Boost and its components
find_package( Boost REQUIRED )
if ( NOT Boost_FOUND )
message(STATUS "This project requires the Boost library, and will not be compiled.")
return()
endif()
# include for local directory
# include for local package
include_directories( BEFORE ../../include )
# Creating entries for all C++ files with "main" routine
# ##########################################################
include( CGAL_CreateSingleSourceCGALProgram )
create_single_source_cgal_program( "point_set_test.cpp" )
create_single_source_cgal_program( "point_set_test_join.cpp" )

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,123 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Point_set_3.h>
#include <CGAL/Point_set_3/Point_set_processing_3.h>
#include <CGAL/Point_set_3/IO.h>
#include <CGAL/grid_simplify_point_set.h>
#include <fstream>
#include <limits>
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef Kernel::FT FT;
typedef Kernel::Point_3 Point;
typedef Kernel::Vector_3 Vector;
typedef CGAL::Point_set_3<Point> Point_set;
typedef CGAL::cpp11::array<unsigned char, 3> Color;
std::size_t nb_test = 0;
std::size_t nb_success = 0;
void test (bool expr, const char* msg)
{
++ nb_test;
if (!expr)
std::cerr << "Error on test " << nb_test << ": " << msg << std::endl;
else
++ nb_success;
}
int main (int, char**)
{
Point_set point_set;
test (!(point_set.has_normal_map()), "point set shouldn't have normals.");
point_set.add_normal_map();
test (point_set.has_normal_map(), "point set should have normals.");
std::ifstream f ("data/oni.pwn");
CGAL::read_xyz_point_set(f, point_set);
f.close ();
Point_set::iterator
first_to_remove = CGAL::grid_simplify_point_set (point_set.begin(),
point_set.end(),
point_set.point_map(),
0.1);
std::size_t size = point_set.size ();
point_set.remove_from (first_to_remove);
test ((point_set.size() + point_set.garbage_size() == size), "sizes before and after removal do not match.");
Point_set::Point_range
range = point_set.points();
{
Point_set::const_iterator psit = point_set.begin();
bool range_okay = true;
for (Point_set::Point_range::const_iterator it = range.begin(); it != range.end(); ++ it)
{
if (*it != point_set.point (*psit))
{
range_okay = false;
break;
}
++ psit;
}
test (range_okay, "range access does not follow property map based access.");
}
test (point_set.has_garbage(), "point set should have garbage.");
point_set.collect_garbage();
test (!(point_set.has_garbage()), "point set shouldn't have garbage.");
test (!(point_set.has_property_map<Color> ("color")), "point set shouldn't have colors.");
Point_set::Property_map<Color> color_prop;
bool garbage;
boost::tie (color_prop, garbage) = point_set.add_property_map ("color", Color());
test (point_set.has_property_map<Color> ("color"), "point set should have colors.");
for (Point_set::iterator it = point_set.begin(); it != point_set.end(); ++ it)
{
Color c = {{ static_cast<unsigned char>(rand() % 255),
static_cast<unsigned char>(rand() % 255),
static_cast<unsigned char>(rand() % 255) }};
put (color_prop, *it, c);
test ((get (color_prop, *it) == c), "recovered color is incorrect.");
}
Point_set::Property_map<Color> color_prop_2;
boost::tie (color_prop_2, garbage) = point_set.property_map<Color>("color");
test ((color_prop_2 == color_prop), "color property not recovered correctly.");
point_set.remove_normal_map ();
test (!(point_set.has_normal_map()), "point set shouldn't have normals.");
test (point_set.has_property_map<Color> ("color"), "point set should have colors.");
point_set.remove_property_map<Color> (color_prop);
test (!(point_set.has_property_map<Color> ("color")), "point set shouldn't have colors.");
point_set.add_property_map<int> ("label", 0);
point_set.add_property_map<double> ("intensity", 0.0);
test (point_set.base().n_properties() == 4, "point set should have 4 properties.");
Point p_before = *(point_set.points().begin());
point_set.clear_properties();
test (point_set.base().n_properties() == 2, "point set should have 2 properties.");
test (!(point_set.has_property_map<int>("label")), "point set shouldn' have labels.");
test (!(point_set.has_property_map<double>("intensity")), "point set shouldn' have intensity.");
test (!(point_set.empty()), "point set shouldn' be empty.");
Point p_after = *(point_set.points().begin());
test (p_before == p_after, "points should not change when clearing properties.");
std::cerr << nb_success << "/" << nb_test << " test(s) succeeded." << std::endl;
return EXIT_SUCCESS;
}

View File

@ -0,0 +1,66 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Point_set_3.h>
#include <CGAL/IO/read_xyz_points.h>
#include <CGAL/IO/write_xyz_points.h>
#include <CGAL/grid_simplify_point_set.h>
#include <fstream>
#include <limits>
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef Kernel::FT FT;
typedef Kernel::Point_3 Point;
typedef Kernel::Vector_3 Vector;
typedef CGAL::Point_set_3<Point> Point_set;
typedef CGAL::cpp11::array<unsigned char, 3> Color;
std::size_t nb_test = 0;
std::size_t nb_success = 0;
void test (bool expr, const char* msg)
{
++ nb_test;
if (!expr)
std::cerr << "Error on test " << nb_test << ": " << msg << std::endl;
else
++ nb_success;
}
void print_point_set (const Point_set& ps, const char* msg)
{
std::cerr << msg << std::endl;
if (ps.has_normal_map())
for (Point_set::const_iterator it = ps.begin(); it != ps.end(); ++ it)
std::cerr << *it << ": " << ps.point(*it)
<< ", normal " << ps.normal(*it) << std::endl;
else
for (Point_set::const_iterator it = ps.begin(); it != ps.end(); ++ it)
std::cerr << *it << ": " << ps.point(*it) << std::endl;
}
int main (int, char**)
{
Point_set ps1, ps2;
ps1.add_normal_map();
for (std::size_t i = 0; i < 5; ++ i)
ps1.insert (Point (double(i), double(i), double(i)), Vector (double(i), double(i), double(i)));
ps1.remove (ps1.end() - 3);
for (std::size_t i = 5; i < 10; ++ i)
ps2.insert (Point (double(i), double(i), double(i)));
ps2.remove (ps2.end() - 3);
print_point_set (ps1, "PS1 = ");
print_point_set (ps2, "PS2 = ");
ps1 += ps2;
print_point_set (ps1, "JOINT PS1 = ");
return EXIT_SUCCESS;
};

View File

@ -234,7 +234,7 @@ jet_smooth_point_set(
{
for(it = first; it != beyond; it++)
{
typename boost::property_traits<PointPMap>::reference p = get(point_pmap, *it);
const typename boost::property_traits<PointPMap>::reference p = get(point_pmap, *it);
put(point_pmap, *it ,
internal::jet_smooth_point<Kernel, SvdTraits>(
p,tree,k,degree_fitting,degree_monge) );

View File

@ -396,7 +396,12 @@ public:
parrays_[i]->swap(i0, i1);
}
// swap content with other Property_container
void swap (Property_container& other)
{
this->parrays_.swap (other.parrays_);
}
private:
std::vector<Base_property_array*> parrays_;
size_t size_;