diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt
new file mode 100644
index 00000000000..cc20dc36c12
--- /dev/null
+++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt
@@ -0,0 +1,180 @@
+
+namespace CGAL {
+/*!
+
+\mainpage User Manual
+\anchor Chapter_Advancing_Front_Surface_Reconstruction
+\anchor I1ChapterAdvancingFrontSurfaceReconstruction
+\cgalAutoToc
+\author Tran Kai Frank Da and David Cohen-Steiner
+
+
+Surface reconstruction from an unstructured point set is to find
+a surface that approximates these points. Several techniques have
+been applied to this problem. Among them are variational
+methods \cgalCite{s-lsm-96}\cgalCite{zomk-insru-00}, tensor voting \cgalCite{cgal:ml-cfsg-00}, implicit surface \cgalCite{hddhjmss-pssr-94}\cgalCite{bc-ssrnn-00},
+and Delaunay triangulations.
+
+For Delaunay based algorithms the output surface
+usually is the union of some triangles selected in the Delaunay
+triangulation of the input points. Such algorithms can be volume oriented
+which output the boundary of selected tetrahedra \cgalCite{abe-cbscc-97}\cgalCite{ack-pcubm-01}, or surface
+oriented, that is they explicitely select triangles.
+
+In most surface oriented Delaunay-based algorithms triangles are
+selected independently, that is in parallel \cgalCite{agj-lcsr-00}\cgalCite{ab-srvf-98}.
+
+The surface oriented Delaunay-based surface reconstruction algorithm
+presented in this chapter selects triangles sequentially, that is by
+using previous selected triangles to select a new one. It adds the
+most *plausible* triangle first, and only adds triangles in a way
+that the surface remains an orientable manifold.
+
+Two other examples of this greedy approach are the ball pivoting
+algorithm and Boyer and Petitjean's algorithm \cgalCite{bmrst-bpasr-99}\cgalCite{pb-rnrps-01}. In both
+algorithms a triangulated surface is incrementally grown starting from
+a seed triangle. Ball pivoting is fast, but the quality of the
+reconstruction depends on user defined parameters corresponding to the
+sampling density. The Boyer Petitjean approach can handle non-uniform
+sampling, but fails when near cocircular points are encountered, and
+it does not provide any guarantee on the topology of the surface.
+
+In the next sections we describe the algorithm, and give
+examples.
+
+
+\section AFSR_Definitions Definitions and the Algorithm
+
+A detailed description of the algorithm and the underlying theory can be found
+in \cgalCite{cgal:csd-gdbsra-04}.
+
+
+
+The first step of the algorithm is the construction of a 3D Delaunay
+triangulation of the point set.
+The Delaunay triangle with the smallest radius is the starting point
+for the greedy algorithm. It is the initial surface and it has three
+boundary edges.
+
+The algorithm maintains a priority queue of
+candidate triangles, that is of triangles incident to the boundary
+edges of the current surface. The priority is the \em plausibility.
+While this priority queue
+is not empty, the algorithm selects the most plausible candidate triangle and adds into the
+surface, and inserts new candidate triangles into the priority queue in case
+there are new boundary edges. As the algorithm creates a two-manifold surface
+some candidate triangles can not be selected due to topological constraints which are explained next.
+
+
+\subsection AFSR_Topology Topological Constraints
+
+Any triangle \f$t\f$ considered as next potential candidate has to share an
+edge \f$e\f$ with the boundary of the current reconstruction. Let \f$b\f$
+be the vertex of \f$t\f$ opposite to \f$e\f$. There are four
+possible situations where \f$t\f$ may be added to the surface.
+- extension, if \f$b\f$ is not yet on the surface.
+- hole filling, if \f$b\f$ is on the boundary and both neighbors of \f$b\f$ on the boundary are on edge \f$e\f$.
+- ear filling, if \f$b\f$ is on the boundary and one neighbor of \f$b\f$ on the boundary is on edge \f$e\f$.
+- glueing, if \f$b\f$ is on the boundary and no neighbor of \f$b\f$ on the boundary is on edge \f$e\f$.
+
+\cgalFigureBegin{figAFSRvalid,valid.png}
+Valid candidates.
+\cgalFigureEnd
+
+While the first three operations would never induce a non-manifold edge or vertex,
+we only can perform glueing, if triangle \f$t\f$ has a *twin* facet, that is a
+triangle with an edge on the boundary and incident to \f$b\f$, and the
+third vertex on edge \f$e\f$.
+
+We call a triangle on which the above operations can be applied *valid*.
+
+\subsection AFSR_Selection Plausibility of a Candidate Triangle
+
+Valid triangles for an edge on the boundary are compared through what
+we call their *radius*. The radius of a triangle \f$t\f$ is the radius of
+the smallest sphere passing through the vertices of \f$t\f$ and enclosing no
+sample point. In other words, the radius \f$r_t\f$ is the distance
+from any vertex of \f$t\f$ to the Voronoi edge dual to \f$t\f$.
+
+While the radius is a good criterion in the case of 2D smooth curve
+reconstruction \cgalCite{b-cccda-94}, we need another criterion for 3D surface
+reconstruction, namely the dihedral angle between triangles on the
+surface, that is the angle between the normals of the triangles.
+
+We denote by \f$ \beta_t\f$ the angle between the normal of a triangle
+\f$ t\f$ incident on a boundary edge \f$ e \f$ and the normal of the
+triangle on the surface incident to \f$ e \f$.
+
+The *candidate* triangle of an edge \f$ e \f$ is the triangle
+with the smallest radius, that is valid for \f$ e \f$
+and that has \f$ \beta_t < \alpha_\mathrm{sliver} \f$.
+There may be no such triangle. In the implementation
+of the algorithm \f$ \alpha_\mathrm{sliver} = 5\pi/6 \f$.
+
+
+We define the *plausibility* grade \f$ p(t) \f$ as \f$ 1/r_t \f$, if
+\f$ \beta_t < \beta \f$, and \f$ -\beta_t \f$ else. The parameter \f$
+\beta \f$ can be chosen by the user and is by default \f$ \pi/6\f$.
+
+
+\subsection AFSR_Boundaries Dealing with Multiple Components, Boundaries and Sharp Edges
+
+By construction the output of the algorithm is a connected orientable
+manifold with or without boundary. To cope with multiple components we
+merely look for a new seed facet among facets disjoint from the
+surface. In case of noisy data or outliers, the user has to filter out
+small surface components.
+
+It is impossible to handle all kinds of boundaries and non uniform sampling
+at the same time. A void can either be an undersampled zone of the surface,
+or a hole.
+
+As we do not want the algorithm to rely on a uniformity condition on
+the sampling it will fill holes cut off from "flat" regions of the
+surface. However, in many cases a boundary component cannot be closed
+by adding a spanning disk such that the resulting disk is well
+sampled. Typically, closing a boundary component due to a transversal
+clipping of the operation, would yield large dihedral angles at
+boundary edges. Moreover, if the boundary is sufficiently well
+sampled, the radii of the two triangles incident on a boundary edge
+would be very different. These heuristic facts can be used for
+boundary detection.
+
+We discard any candidate triangle \f$ t \f$, for an edge \f$ e \f$
+such that \f$ p(t) < 0\f$, and \f$ r_t > k r_{t'}\f$ where \f$ t'\f$ is
+the triangle on the surface incident on \f$ e \f$. The parameter \f$ k \f$
+can be chosen by the user and is by default 5.
+
+
+Note that this heuristic implies that
+where the sampling is too sparse with respect to curvature, it must
+be sufficiently uniform for our algorithm to work.
+
+
+\section AFSR_Examples Examples
+
+\subsection AFSR_Example_function Example for Global Function
+
+The global function `advancing_front_surface_reconstruction()`
+takes an iterator range of points as input and writes for each face of the
+reconstructed surface a triple of point indices into an output iterator.
+In the example we write the surface in the OFF format to `std::cout`.
+
+\cgalExample{Advancing_front_surface_reconstruction/reconstruction_fct.cpp}
+
+
+\subsection AFSR_Example_class Example for the Reconstruction Class
+
+When using the class `Advancing_front_surface_reconstruction`
+you can access a 2D triangulation data structure describing the surface.
+You can explore the surface by going from faces to neighboring faces,
+and you can also go to the underlying 3D Delaunay triangulation.
+
+In the example we write the surface in the STL (Stereo Lithography) format
+to `std::cout`.
+
+\cgalExample{Advancing_front_surface_reconstruction/reconstruction_class.cpp}
+
+*/
+} /* namespace CGAL */
+
diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h
new file mode 100644
index 00000000000..2112aeb7402
--- /dev/null
+++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h
@@ -0,0 +1,193 @@
+
+namespace CGAL {
+
+/*!
+\ingroup PkgAdvancingFrontSurfaceReconstruction
+
+The class `Advancing_front_surface_reconstruction`
+
+\tparam Dt must be a `Delaunay_triangulation_3` with
+`Advancing_front_surface_reconstruction_vertex_base_3` and `Advancing_front_surface_reconstruction_cell_base_3` blended into the vertex and cell type, and the geometric traits class must be the `Exact_predicates_inexact_constructions_kernel`.
+
+*/
+
+template< typename Dt>
+class Advancing_front_surface_reconstruction {
+public:
+
+/// \name Types
+/// @{
+
+/*!
+ The type of the 2D triangulation data structure describing the reconstructed surface.
+ The type `TDS_2::Vertex` is model of the concept `TriangulationDataStructure_2::Vertex` and has additionally the
+ method `vertex_3()` that returns a `Vertex_handle` to the associated 3D vertex
+ The type `TDS_2::Face` is model of the concept `TriangulationDataStructure_2::Face` and has additionally the
+ method `facet()` that returns the associated `Facet`, and a method `bool is_on_surface()`
+ for testing if a face is part of the reconstructed surface or a face incident to a boundary edge.
+ In case the surface has boundaries, the 2D surface has one vertex which is associated to the infinite
+ vertex of the 3D triangulation.
+*/
+ typedef unspecified_type TDS_2;
+
+/*!
+The type of the 3D triangulation.
+
+*/
+ typedef Dt Triangulation_3;
+
+/*!
+The vertex handle type of the 3D triangulation.
+
+*/
+ typedef typename Triangulation_3::Vertex_handle Vertex_handle;
+
+/*!
+The cell handle type of the 3D triangulation.
+
+*/
+ typedef typename Triangulation_3::Cell_handle Cell_handle;
+
+/*!
+The facet type of the 3D triangulation.
+
+*/
+ typedef typename Triangulation_3::Facet Facet;
+
+
+/*!
+ A bidirectional iterator which allows to enumerate all points that were removed
+ from the 3D Delaunay triangulation during the surface reconstruction. The value type
+ of the iterator is `Triangulation_3::Point_3`.
+*/
+typedef unspecified_type Outlier_iterator;
+
+/*!
+ A forward iterator which allows to visit all boundaries. It
+ visits the entry point of each boundary twice. This allows to
+ detect that the traversal of a boundary is finished. One more increment
+ brings us to the vertex on the next boundary.
+ The value type of the iterator is `Triangulation_3::Vertex_handle`.
+*/
+typedef unspecified_type Boundary_iterator;
+
+
+/// @}
+
+/// \name Creation
+/// @{
+
+/*!
+Initializes from a 3D Delaunay triangulation of a point set.
+*/
+Advancing_front_surface_reconstruction(Dt& dt);
+
+
+/// @}
+
+/// \name Operations
+/// @{
+
+/*!
+calls the surface reconstruction function with the default parameters.
+
+\param k described in Section \ref AFSR_Boundaries
+\param beta described in Section \ref AFSR_Selection
+
+*/
+ void operator()(double k=5, double beta= 0.18);
+
+/*!
+returns the reconstructed surface.
+*/
+const TDS_2&
+tds_2();
+
+/*!
+returns the underlying 3D Delaunay triangulation.
+*/
+const Triangulation_3&
+triangulation_3();
+
+
+
+
+/*!
+An iterator over the outliers.
+*/
+Outlier_iterator outliers_begin();
+
+/*!
+Past-the-end iterator.
+*/
+Outlier_iterator outliers_end();
+
+/*!
+An iterator over the boundary vertices.
+*/
+Boundary_iterator boundaries_begin();
+
+/*!
+Past-the-end iterator.
+*/
+Boundary_iterator boundaries_end();
+
+/// @}
+
+/// \name Predicates
+/// @{
+
+/*!
+returns `true` if the reconstructed surface has boundaries.
+*/
+bool
+has_boundaries() const;
+
+
+/*!
+returns `true` if the facet is on the surface.
+*/
+bool
+has_on_surface(Facet f) const;
+
+/*!
+returns `true` if the facet f is on the surface.
+*/
+bool
+has_on_surface(TDS_2::Face_handle f2) const;
+
+/*!
+returns `true` if the facet f is on the surface.
+*/
+bool
+has_on_surface(TDS_2::Vertex_handle v2) const;
+/// @}
+
+
+
+
+}; /* end Advancing_front_surface_reconstruction */
+
+
+/*!
+\ingroup PkgAdvancingFrontSurfaceReconstruction
+
+For a sequence of points computes a sequence of index triples
+describing the faces of the reconstructed surface.
+
+\tparam PointInputIterator must be an input iterator with 3D points from the `Exact_predicates_inexact_constructions_kernel` as value type.
+\tparam IndicesOutputIterator must be an output iterator to which
+`CGAL::cpp11::tuple` can be assigned.
+
+\param begin iterator on the first point of the sequence
+\param end past the end iterator the point sequence
+\param out output iterator
+\param K described in Section \ref AFSR_Boundaries
+\param beta described in Section \ref AFSR_Selection
+
+*/
+ template
+ IndicesOutputIterator advancing_front_surface_reconstruction(PointInputIterator b, PointInputIterator e, IndicesOutputIterator out, double k=5, double beta= 0.18 );
+
+
+} /* end namespace CGAL */
diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction_cell_base_3.h b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction_cell_base_3.h
new file mode 100644
index 00000000000..3b902c4e79d
--- /dev/null
+++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction_cell_base_3.h
@@ -0,0 +1,22 @@
+
+namespace CGAL {
+
+/*!
+\ingroup PkgAdvancingFrontSurfaceReconstruction
+
+The class `Advancing_front_surface_reconstruction_cell_base_3` is the default
+cell type for the class `Advancing_front_surface_reconstruction`.
+
+\tparam Traits has to be a model of `DelaunayTriangulationTraits_3`.
+
+\tparam Cb has to be a model of `TriangulationCellBase_3`.
+
+*/
+template< typename Traits, typename Cb = Triangulation_cell_base_3 >
+class Advancing_front_surface_reconstruction_cell_base_3 : public Cb {
+public:
+
+/// @}
+
+}; /* end Advancing_front_surface_reconstruction_cell_base_3 */
+} /* end namespace CGAL */
diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h
new file mode 100644
index 00000000000..49414059b97
--- /dev/null
+++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h
@@ -0,0 +1,23 @@
+
+namespace CGAL {
+
+/*!
+\ingroup PkgAdvancingFrontSurfaceReconstruction
+
+The class `Advancing_front_surface_reconstruction_vertex_base_3` is the default
+vertex type for the class `Advancing_front_surface_reconstruction`.
+
+\tparam Traits has to be a model of `DelaunayTriangulationTraits_3`.
+
+\tparam Vb has to be a model of `TriangulationVertexBase_3`.
+
+
+*/
+ template< typename Traits, typename Vb = Triangulation_vertex_base_3 >
+class Advancing_front_surface_reconstruction_vertex_base_3 : public Vb {
+public:
+
+/// @}
+
+}; /* end Advancing_front_surface_reconstruction_vertex_base_3 */
+} /* end namespace CGAL */
diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Doxyfile.in b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Doxyfile.in
new file mode 100644
index 00000000000..b440784ea24
--- /dev/null
+++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Doxyfile.in
@@ -0,0 +1,10 @@
+@INCLUDE = ${CGAL_DOC_PACKAGE_DEFAULTS}
+
+PROJECT_NAME = "CGAL ${CGAL_CREATED_VERSION_NUM} - Advancing Front Surface Reconstruction"
+
+
+INPUT = ${CMAKE_SOURCE_DIR}/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/
+
+
+
+MULTILINE_CPP_IS_BRIEF = YES
\ No newline at end of file
diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/PackageDescription.txt b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/PackageDescription.txt
new file mode 100644
index 00000000000..e8ab4401e8e
--- /dev/null
+++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/PackageDescription.txt
@@ -0,0 +1,29 @@
+/// \defgroup PkgAdvancingFrontSurfaceReconstruction Advancing Front Surface Reconstruction Reference
+
+/*!
+\addtogroup PkgAdvancingFrontSurfaceReconstruction
+
+\cgalPkgDescriptionBegin{Advancing Front Surface Reconstruction,PkgAdvancingFrontSurfaceReconstructionSummary}
+\cgalPkgPicture{afsr-detail.png}
+\cgalPkgSummaryBegin
+\cgalPkgAuthors{Tran Kai Frank Da, David Cohen-Steiner}
+\cgalPkgDesc{This package provides a greedy algorithm for surface reconstruction from an
+unorganized point set. Starting from a seed facet, a piecewise linear
+surface is grown by adding Delaunay triangles one by one. The most
+plausible triangles are added first, in a way that avoids the appearance
+of topological singularities. }
+\cgalPkgManuals{Chapter_Advancing_Front_Surface_Reconstruction,PkgAdvancingFrontSurfaceReconstruction}
+\cgalPkgSummaryEnd
+\cgalPkgShortInfoBegin
+\cgalPkgSince{4.4}
+\cgalPkgDependsOn{\ref PkgTriangulation3Summary}
+\cgalPkgBib{cgal:dc-afsr}
+\cgalPkgLicense{\ref licensesGPL "GPL"}
+\cgalPkgShortInfoEnd
+\cgalPkgDescriptionEnd
+
+
+
+
+*/
+
diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/dependencies b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/dependencies
new file mode 100644
index 00000000000..160ff7cc8ce
--- /dev/null
+++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/dependencies
@@ -0,0 +1,9 @@
+Manual
+Kernel_23
+STL_Extension
+Algebraic_foundations
+Circulator
+Stream_support
+Triangulation_2
+Triangulation_3
+Number_types
diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/examples.txt b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/examples.txt
new file mode 100644
index 00000000000..2f14a4e739c
--- /dev/null
+++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/examples.txt
@@ -0,0 +1,4 @@
+/*!
+\example Advancing_front_surface_reconstruction/reconstruction_fct.cpp
+\example Advancing_front_surface_reconstruction/reconstruction_class.cpp
+*/
diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/fig/afsr-detail.png b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/fig/afsr-detail.png
new file mode 100755
index 00000000000..5fd4b3e6c2a
Binary files /dev/null and b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/fig/afsr-detail.png differ
diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/fig/valid.png b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/fig/valid.png
new file mode 100644
index 00000000000..97f747c6d8b
Binary files /dev/null and b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/fig/valid.png differ
diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/CMakeLists.txt b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/CMakeLists.txt
new file mode 100644
index 00000000000..6467152a14f
--- /dev/null
+++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/CMakeLists.txt
@@ -0,0 +1,36 @@
+# Created by the script cgal_create_cmake_script
+# This is the CMake script for compiling a CGAL application.
+
+
+project( Advancing_front_surface_reconstruction_example )
+
+CMAKE_MINIMUM_REQUIRED(VERSION 2.4.5)
+
+set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true)
+
+if ( COMMAND cmake_policy )
+ cmake_policy( SET CMP0003 NEW )
+endif()
+
+find_package(CGAL QUIET COMPONENTS Core )
+
+if ( CGAL_FOUND )
+
+ include( ${CGAL_USE_FILE} )
+
+ include( CGAL_CreateSingleSourceCGALProgram )
+
+ include_directories (BEFORE ../../include)
+# include_directories (BEFORE ../../../../../trunk/Triangulation_2/include)
+
+ create_single_source_cgal_program( "extract.cpp" )
+ create_single_source_cgal_program( "reconstruction_fct.cpp" )
+ create_single_source_cgal_program( "reconstruction_class.cpp" )
+ create_single_source_cgal_program( "reconstruction_polyhedron.cpp" )
+
+else()
+
+ message(STATUS "This program requires the CGAL library, and will not be compiled.")
+
+endif()
+
diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp
new file mode 100644
index 00000000000..a56866a511c
--- /dev/null
+++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp
@@ -0,0 +1,464 @@
+#define NOLAZY
+#define BLIND
+
+
+#include
+#include
+#include
+#include
+
+#include
+
+// Kernel
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+#include
+
+
+
+
+typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
+
+typedef Kernel::Point_3 Point;
+
+typedef CGAL::Advancing_front_surface_reconstruction_vertex_base_3 LVb;
+typedef CGAL::Advancing_front_surface_reconstruction_cell_base_3 LCb;
+
+typedef CGAL::Triangulation_data_structure_3 Tds;
+typedef CGAL::Delaunay_triangulation_3 Triangulation_3;
+
+typedef Triangulation_3::Vertex_handle Vertex_handle;
+
+typedef CGAL::Advancing_front_surface_reconstruction Surface;
+typedef CGAL::AFSR_options Options;
+
+
+//---------------------------------------------------------------------
+
+struct Auto_count : public std::unary_function >{
+ mutable int i;
+ Auto_count() : i(0){}
+ std::pair operator()(const Point& p) const {
+ return std::make_pair(p,i++);
+ }
+};
+
+
+bool
+file_input(const Options& opt, std::vector& points)
+{
+ const char* finput = opt.finname;
+ bool xyz = opt.xyz;
+
+ std::ios::openmode mode = (opt.binary) ? std::ios::binary : std::ios::in;
+ std::ifstream is(finput, mode);
+
+ if(opt.binary){
+ CGAL::set_binary_mode(is);
+ }
+ if(is.fail())
+ {
+ std::cerr << "+++unable to open file for input" << std::endl;
+ exit(0);
+ return false;
+ }
+ else
+ std::cerr << "Input from file : " << finput << std::endl;
+
+ std::size_t n;
+ if(! xyz){
+ is >> n;
+ std::cerr << " reading " << n << " points" << std::endl;
+ points.reserve(n);
+ CGAL::cpp11::copy_n(std::istream_iterator(is), n, std::back_inserter(points));
+ } else {
+ // we do not know beforehand how many points we will read
+ std::istream_iterator it(is), eof;
+ char ignore[256];
+ while(it!= eof){
+ points.push_back(*it);
+ is.getline(ignore,256); // ignore what comes after 3 doubles in a line
+ it++;
+ }
+ n = points.size();
+ }
+
+ return true;
+}
+
+
+
+void usage(char* program)
+{
+ std::cerr << std::endl << "NAME " << std::endl
+ << program << " - surface extension -" << std::endl << std::endl;
+
+ std::cerr << std::endl << "OPTIONS" << std::endl
+ << " -xyz : input data in xyz format" << std::endl
+ << " -no_border -nb : " << std::endl
+ << " -in fname : reads points from file fname" << std::endl
+ << " -out fname : writes points to file fname" << std::endl
+ << " -out_format -of : choose file format for output (iv, wrl, off, medit," << std::endl
+ << " ply, stl, all, none)" << std::endl
+ << " -rgb r g b : color of the surface" << std::endl
+ << " -no_header : The Vrml header and footer are not written" << std::endl
+ << " -area a : No faces larger than area * average_area" << std::endl
+ << " -perimeter p : No faces larger than perimeter * average_perimeter" << std::endl
+ << " -abs_area a : No faces larger than abs_area" << std::endl
+ << " -abs_perimeter p : No faces with perimeter longer than abs_perimeter" << std::endl
+ << "\n Options for internal use" << std::endl
+
+ << " -binary : binary I/O" << std::endl
+ << " -delta x : set the delta constant" << std::endl
+ << " -ki x y : set the K interval (default : [1.1 5])" << std::endl
+ << " -ks x : set the K step (default : .1)" << std::endl
+ << " -k x : set the K constant (only one pass)" << std::endl
+ << " -Delaunay : display the underlying Delaunay triangulation" << std::endl
+ << " -max_of_connected_components x : set the max of connected components" << std::endl
+ << " (default : non-active)" << std::endl
+ << " -post x : set a number for the post process" << std::endl
+ << " -contours : display contours" << std::endl;
+}
+
+
+
+bool
+parse(int argc, char* argv[], Options &opt)
+{
+ std::strcpy(opt.program, argv[0]);
+ --argc;
+ argv++;
+ if(argc == 0)
+ std::cerr << "nothing ???" << std::endl;
+
+ while ((argc > 0) && (argv[0][0] == '-')){
+ if ((!std::strcmp(argv[0], "-D")) || (!std::strcmp(argv[0], "-Delaunay"))) {
+ opt.Delaunay = true;
+ argv++;
+ argc--;
+ std::cerr << "-D ";
+ }
+ else if ((!std::strcmp(argv[0], "-c")) || (!std::strcmp(argv[0], "-contours"))) {
+ opt.contour = true;
+ argv++;
+ argc--;
+ std::cerr << "-c ";
+ }
+ else if ((!std::strcmp(argv[0], "-b")) || (!std::strcmp(argv[0], "-binary"))) {
+ opt.binary = true;
+ argv++;
+ argc--;
+ std::cerr << "-b ";
+ }
+ else if ((!std::strcmp(argv[0], "-x")) || (!std::strcmp(argv[0], "-xyz"))) {
+ opt.xyz = true;
+ argv++;
+ argc--;
+ std::cerr << "-x ";
+ }
+ else if ((!std::strcmp(argv[0], "-nb")) || (!std::strcmp(argv[0], "-no_border"))) {
+ opt.K = HUGE_VAL;
+ opt.K_init = opt.K;
+ argv++;
+ argc--;
+ std::cerr << "-nb ";
+ }
+ else if ((!std::strcmp(argv[0], "-nh")) || (!std::strcmp(argv[0], "-no_header"))) {
+ opt.no_header = true;
+ argv++;
+ argc--;
+ std::cerr << "-nh ";
+ }
+ else if ((!std::strcmp(argv[0], "-d")) || (!std::strcmp(argv[0], "-delta"))){
+ if (sscanf(argv[1], "%lf", &opt.delta) != 1) {
+ std::cerr << "Argument for delta must be a number"
+ << std::endl;
+ }
+ argv += 2;
+ argc -= 2;
+ std::cerr << "-d " << opt.delta << " ";
+ }
+ else if ((!std::strcmp(argv[0], "-a")) || (!std::strcmp(argv[0], "-area"))){
+ if (sscanf(argv[1], "%lf", &opt.area) != 1) {
+ std::cerr << "Argument for area must be a number"
+ << std::endl;
+ }
+ argv += 2;
+ argc -= 2;
+ std::cerr << "-a " << opt.area << " ";
+ }
+ else if ((!std::strcmp(argv[0], "-pe")) || (!std::strcmp(argv[0], "-perimeter"))){
+ if (sscanf(argv[1], "%lf", &opt.perimeter) != 1) {
+ std::cerr << "Argument for perimeter must be a number"
+ << std::endl;
+ }
+ argv += 2;
+ argc -= 2;
+ std::cerr << "-perimeter " << opt.perimeter << " ";
+ }
+ else if ((!std::strcmp(argv[0], "-aa")) || (!std::strcmp(argv[0], "-abs_area"))){
+ if (sscanf(argv[1], "%lf", &opt.abs_area) != 1) {
+ std::cerr << "Argument for abs_area must be a number"
+ << std::endl;
+ }
+ argv += 2;
+ argc -= 2;
+ std::cerr << "-abs_area " << opt.abs_area << " ";
+ }
+ else if ((!std::strcmp(argv[0], "-ae")) || (!std::strcmp(argv[0], "-abs_perimeter"))){
+ if (sscanf(argv[1], "%lf", &opt.abs_perimeter) != 1) {
+ std::cerr << "Argument for abs_perimeter must be a number"
+ << std::endl;
+ }
+ argv += 2;
+ argc -= 2;
+ std::cerr << "-abs_perimeter " << opt.abs_perimeter << " ";
+ }
+ else if ((!std::strcmp(argv[0], "-ki"))){
+ if ((sscanf(argv[1], "%lf", &opt.K_init) != 1)||
+ (sscanf(argv[2], "%lf", &opt.K) != 1)){
+ std::cerr << "Argument for K must be a number"
+ << std::endl;
+ }
+ argv += 3;
+ argc -= 3;
+ std::cerr << "-ki " << opt.K_init << " " << opt.K << " ";
+ }
+ else if ((!std::strcmp(argv[0], "-rgb"))){
+ if ((sscanf(argv[1], "%lf", &opt.red) != 1)||
+ (sscanf(argv[2], "%lf", &opt.green) != 1) ||
+ (sscanf(argv[3], "%lf", &opt.blue) != 1)){
+ std::cerr << "Argument for rgb must be three numbers"
+ << std::endl;
+ }
+ argv += 4;
+ argc -= 4;
+ std::cerr << "-rgb " << opt.red << " " << opt.green << " " << opt.blue << " " ;
+ }
+ else if ((!std::strcmp(argv[0], "-ks"))){
+ if (sscanf(argv[1], "%lf", &opt.K_step) != 1) {
+ std::cerr << "Argument for K must be a number"
+ << std::endl;
+ }
+ argv += 2;
+ argc -= 2;
+ std::cerr << "-ks " << opt.K_step << " ";
+ }
+ else if ((!std::strcmp(argv[0], "-k"))){
+ if (sscanf(argv[1], "%lf", &opt.K) != 1) {
+ std::cerr << "Argument for K must be a number"
+ << std::endl;
+ }
+ opt.K_init = opt.K;
+ argv += 2;
+ argc -= 2;
+ std::cerr << "-k " << opt.K_init << " ";
+ }
+ else if ((!std::strcmp(argv[0], "-m")) || (!std::strcmp(argv[0], "-max_of_connected_components"))){
+ if (sscanf(argv[1], "%d", &opt.max_connected_comp) != 1) {
+ std::cerr << "Argument for the number of connected components must be a number"
+ << std::endl;
+ }
+ /*
+ if(opt.max_connected_comp < 1) {
+ std::cerr << "Argument for the number of connected components must be a positive number"
+ << "It is set to 1" << std::endl;
+ opt.max_connected_comp = 1;
+ }
+ */
+ argv += 2;
+ argc -= 2;
+ std::cerr << "-m " << opt.max_connected_comp << " ";
+ }
+ else if ((!std::strcmp(argv[0], "-p")) || (!std::strcmp(argv[0], "-post"))){
+ if (sscanf(argv[1], "%d", &opt.NB_BORDER_MAX) != 1) {
+ std::cerr << "Argument for post process must be a number"
+ << std::endl;
+ }
+ argv += 2;
+ argc -= 2;
+ std::cerr << "-p " << opt.NB_BORDER_MAX << " ";
+ }
+ else if ((!std::strcmp(argv[0], "-i")) || (!std::strcmp(argv[0], "-in"))) {
+ std::strcpy(opt.finname, argv[1]);
+ opt.file_input = true;
+ argv += 2;
+ argc -= 2;
+ std::cerr << "-i " << opt.finname << " ";
+ }
+ else if ((!std::strcmp(argv[0], "-s")) || (!std::strcmp(argv[0], "-sect_in"))) {
+ std::strcpy(opt.finname, argv[1]);
+ opt.Section_file = true;
+ opt.file_input = true;
+ argv += 2;
+ argc -= 2;
+ std::cerr << "-s " << opt.finname << " ";
+ }
+ else if ((!std::strcmp(argv[0], "-o")) || (!std::strcmp(argv[0], "-out"))) {
+ std::strcpy(opt.foutname, argv[1]);
+ opt.file_output = true;
+ argv += 2;
+ argc -= 2;
+ std::cerr << "-o " << opt.foutname << " ";
+ }
+ else if ((!std::strcmp(argv[0], "-of")) || (!std::strcmp(argv[0], "-out_format"))) {
+ if (!std::strcmp(argv[1], "wrl"))
+ opt.out_format = 0;
+ else if (!std::strcmp(argv[1], "off"))
+ opt.out_format = 1;
+ else if (!std::strcmp(argv[1], "medit"))
+ opt.out_format = 2;
+ else if (!std::strcmp(argv[1], "ply"))
+ opt.out_format = 3;
+ else if(!std::strcmp(argv[1], "iv"))
+ opt.out_format = 4;
+ else if(!std::strcmp(argv[1], "stl"))
+ opt.out_format = 5;
+ else if (!std::strcmp(argv[1], "all"))
+ opt.out_format = -1;
+ else if (!std::strcmp(argv[1], "none"))
+ opt.out_format = -2;
+ else
+ std::cerr << "unrecognized file format." << std::endl;
+ opt.file_output = true;
+ std::cerr << "-of " << argv[1] << " ";
+ argv += 2;
+ argc -= 2;
+ }
+ else if ((!std::strcmp(argv[0], "-?")) ||
+ (!std::strcmp(argv[0], "-h")) ||
+ (!std::strcmp(argv[0], "-help"))) {
+ usage(opt.program);
+ return false;
+ }
+ else {
+ std::cerr << "unrecognized option " << argv[0] << std::endl;
+ usage(opt.program);
+ return false;
+ }
+ }
+ if(argc > 0){
+ std::cerr << "unrecognized option " << argv[0] << std::endl;
+ usage(opt.program);
+ return false;
+ }
+ return true;
+}
+
+template
+void reconstruction_test(PointIterator point_begin, PointIterator
+ point_end, TripleOutputIterator out, bool filter_input_points=false,
+ double perimeter=0)
+{
+ Options opt;
+ opt.abs_perimeter = perimeter;
+ std::cerr << "Compute Delaunay Tetrahedrization " << std::endl;
+ CGAL::Timer t1;
+ t1.start();
+
+ Triangulation_3 dt( boost::make_transform_iterator(point_begin, Auto_count()),
+ boost::make_transform_iterator(point_end, Auto_count() ) );
+ t1.stop();
+ std::cerr << " Inserted " << dt.number_of_vertices() << " points, "
+ << dt.number_of_cells() << " cells computed in "
+ << t1.time() << " sec." << std::endl;
+
+ t1.reset();
+ t1.start();
+ Surface S(dt, opt);
+ t1.stop();
+ std::cerr << "Reconstruction takes " << t1.time() << " sec.\n";
+ std::cerr << " " << S.number_of_outliers() << " outliers.\n";
+ std::cerr << " Reconstructed surface: " << S.number_of_facets() <<
+ " facets, " << S.number_of_vertices() << " vertices.\n";
+ std::cerr << " " << S.number_of_border_edges() <<
+ " border edges.\n";
+ std::cerr << " number of connected components <= "
+ << (std::max)(1, S.number_of_connected_components()-1)
+ << std::endl;
+ write_triple_indices(out, S);
+}
+
+
+//___________________________________________
+int main(int argc, char* argv[])
+{
+ CGAL::Timer timer, total;
+ total.start();
+ timer.start();
+ //parse command line
+ Options opt;
+ std::cerr << "Option line for this execution is :" << std::endl;
+ if (!parse(argc, argv, opt))
+ exit(0);
+ std::cerr << std::endl << std::endl;
+
+ std::vector points;
+
+ file_input(opt, points);
+
+#if 0
+ std::cerr << "Time for reading " << timer.time() << " sec." << std::endl;
+ std::vector > triples;
+ reconstruction_test(points.begin(), points.end(), std::back_inserter(triples));
+
+
+ std::cout << triples.size() << std::endl;
+ for(int i = 0; i < triples.size(); ++i){
+ std::cout << "3 " << get<0>(triples[i]) << " " << get<1>(triples[i]) << " " << get<2>(triples[i]) << " " << std::endl;
+ }
+
+#else
+
+ std::cerr << "Compute Delaunay Tetrahedrization " << std::endl;
+ CGAL::Timer t1;
+ t1.start();
+
+ Triangulation_3 dt( boost::make_transform_iterator(points.begin(),Auto_count()),
+ boost::make_transform_iterator(points.end(), Auto_count() ) );
+ t1.stop();
+ std::cerr << " Inserted " << dt.number_of_vertices() << " points, "
+ << dt.number_of_cells() << " cells computed in "
+ << t1.time() << " sec." << std::endl;
+
+ if (dt.dimension() < 3) {
+ std::cerr << "-- 2D sample of points ???" << std::endl;
+ exit(0);
+ }
+
+ points.clear();
+
+
+ Surface S(dt, opt);
+ S();
+
+ std::cerr << "Total time: " << timer.time() << " sec." << std::endl;
+ // write_to_file_vrml2(opt.foutname, S, opt.contour, opt.red, opt.green, opt.blue, opt.no_header);
+ write_to_file(opt.foutname, S, opt.contour, opt.out_format, opt.red, opt.green, opt.blue, opt.no_header);
+
+ std::cerr << " " << S.number_of_outliers()
+ << " outliers." << std::endl;
+ std::cerr << " Reconstructed surface: " << S.number_of_facets() <<
+ " facets, " << S.number_of_vertices() << " vertices." << std::endl;
+ std::cerr << " " << S.number_of_border_edges() <<
+ " border edges." << std::endl;
+ std::cerr << " number of connected components <= "
+ << (std::max)(1, S.number_of_connected_components()-1)
+ << std::endl << std::endl;
+
+#endif
+ total.stop();
+ std::cerr << "Total = " << total.time() << " sec." << std::endl;
+ return 0;
+}
+
+
+
+
diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/fill.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/fill.cpp
new file mode 100644
index 00000000000..91b210b2f82
--- /dev/null
+++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/fill.cpp
@@ -0,0 +1,138 @@
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+typedef double NT;
+
+struct K : public CGAL::Filtered_kernel > {};
+typedef K::Point_3 Point;
+typedef K::Vector_3 Vector;
+typedef K::Segment_3 Segment;
+typedef K::Triangle_3 Triangle;
+
+NT
+weight(const Point& p, const Point& q, const Point& r){
+ NT area = std::sqrt(Triangle(p,q,r).squared_area());
+ NT l1 = std::sqrt((p-q) * (p-q));
+ NT l2 = std::sqrt((p-r) * (p-r));
+ NT l3 = std::sqrt((q-r) * (q-r));
+ if(l1>l2) std::swap(l1,l2);
+ if(l2>l3) std::swap(l2,l3);
+ if(l1>l2) std::swap(l1,l2);
+ if(l2>l3) std::swap(l2,l3);
+
+ // Taken from Piecewise-Linear Interpolation between Polygonal Slices
+ // from Gill Barequet and Micha Sharir
+ return 0.85 * area + 0.05 * (l1 +l2 + l3) + 0.1 * l3/l1;
+}
+
+
+void
+insert(std::set >& triangles, int i, int j, int k){
+ std::cout << i << ", " << j << ", " << k << std::endl;
+ if(i>j) std::swap(i,j);
+ if(j>k) std::swap(j,k);
+ if(i>j) std::swap(i,j);
+ if(j>k) std::swap(j,k);
+ std::cout << i << ", " << j << ", " << k << std::endl;
+ triangles.insert(CGAL::make_triple(i,j,k));
+}
+
+
+void
+collect(int i, int k, int n, const std::vector& O, std::set >& triangles){
+
+ std::cout << "collect(" << i << ", " << k << ")" << std::endl;
+ if((i+2) == k){
+ insert(triangles, i, i+1, k);
+ }else {
+ int o = O[i*n+k];
+
+ if(o != (i+1)){
+ collect(i, o, n, O, triangles);
+ }
+ insert(triangles, i, o, k);
+ if(o != (k-1)){
+ collect(o, k, n, O, triangles);
+ }
+ }
+}
+
+
+
+int
+main(){
+
+ int n;
+ std::cin >> n;
+
+ std::vector points(n);
+ CGAL::copy_n(std::istream_iterator(std::cin), n, points.begin());
+
+
+ std::set > triangles;
+
+ std::vector W(n*n);
+ std::vector O(n*n);
+
+ for(int i = 0; i <= n-2; i++){
+ W[i*n + i + 1] = 0;
+ }
+ for(int i = 0; i <= n-3; i++){
+ W[i*n + i + 2] = weight(points[i], points[i+1], points[i+3]);
+ }
+
+ for(int j = 3; j <= n-1; j++){
+ for(int i=0; i <= n - j - 1; i++){
+ int k = i + j;
+ double lmin = -1;
+ int lmin_index;
+ for(int m = i+1; m < k; m++){
+ double d = W[i*n + m] + W[m*n + k] + weight(points[i], points[m], points[k]);
+ if( (lmin == -1) || (d < lmin )){
+ lmin = d;
+ lmin_index = m;
+ }
+ }
+ W[i*n + k] = lmin;
+ O[i*n + k] = lmin_index;
+
+ }
+ }
+
+ collect(0, n-1, n, O, triangles);
+
+ std::cout << "Shape {\n"
+ "appearance Appearance {\n"
+ "material Material { diffuseColor .9 .5 .1}}\n"
+ "geometry\n"
+ "IndexedFaceSet {\n"
+ "coord DEF def_coords Coordinate {\n"
+ "point [ \n" ;
+
+ for (int i = 0; i < n; i++){
+ std::cout << points[i].x() << " " << points[i].y() << " " << points[i].z() << ",\n ";
+ }
+ std::cout << "]\n"
+ "}\n"
+ "solid FALSE\n"
+ "coordIndex [ \n";
+
+ for(std::set >::iterator it = triangles.begin();
+ it != triangles.end();
+ it++){
+ std::cout << it->first << ", " << it->second << ", " << it->third << ", -1,\n ";
+ }
+ std::cout << "]\n"
+ "}# IndexedFaceSet\n"
+ "}# Shape\n";
+
+ return 1;
+}
+
+
diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_class.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_class.cpp
new file mode 100644
index 00000000000..b25b6aff530
--- /dev/null
+++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_class.cpp
@@ -0,0 +1,43 @@
+#include
+#include
+#include
+#include
+#include
+typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
+typedef CGAL::Advancing_front_surface_reconstruction Reconstruction;
+typedef Reconstruction::Triangulation_3 Triangulation_3;
+typedef Reconstruction::TDS_2 TDS_2;
+typedef K::Point_3 Point_3;
+
+int main()
+{
+
+ std::istream_iterator begin(std::cin);
+ std::istream_iterator end;
+
+ Triangulation_3 dt(begin,end);
+
+ Reconstruction reconstruction(dt);
+
+ reconstruction();
+
+ const TDS_2& tds = reconstruction.tds_2();
+
+ if(! reconstruction.has_boundaries()){
+ for(TDS_2::Face_iterator fit = tds.faces_begin();
+ fit != tds.faces_end();
+ ++fit){
+ Triangulation_3::Facet f = fit->facet();
+ Triangulation_3::Cell_handle ch = f.first;
+ int ci = f.second;
+ for(int i = 0; i < 4; i++){
+ if(ci != i){
+ std:: cout << ch->vertex(i)->point() << " ";
+ }
+ }
+ std::cout << std::endl;
+ }
+ }
+
+ return 0;
+}
diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_fct.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_fct.cpp
new file mode 100644
index 00000000000..18b9a189c3e
--- /dev/null
+++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_fct.cpp
@@ -0,0 +1,45 @@
+
+
+#include
+#include
+#include
+#include
+#include
+
+typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
+typedef Kernel::Point_3 Point_3;
+
+typedef CGAL::cpp11::tuple Facet;
+
+namespace std {
+ std::ostream&
+ operator<<(std::ostream& os, const Facet& f)
+ {
+ os << "3 " << get<0>(f) << " " << get<1>(f) << " " << get<2>(f);
+ return os;
+ }
+}
+
+int main()
+{
+ std::vector points;
+ std::vector facets;
+
+ std::copy(std::istream_iterator(std::cin),
+ std::istream_iterator(),
+ std::back_inserter(points));
+
+ CGAL::advancing_front_surface_reconstruction(points.begin(),
+ points.end(),
+ std::back_inserter(facets));
+
+ std::cout << "OFF\n" << points.size() << " " << facets.size() << " 0\n";
+ std::copy(points.begin(),
+ points.end(),
+ std::ostream_iterator(std::cout, "\n"));
+ std::copy(facets.begin(),
+ facets.end(),
+ std::ostream_iterator(std::cout, "\n"));
+
+ return 0;
+}
diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_polyhedron.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_polyhedron.cpp
new file mode 100644
index 00000000000..4b6da452bf0
--- /dev/null
+++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_polyhedron.cpp
@@ -0,0 +1,32 @@
+
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
+typedef Kernel::Point_3 Point_3;
+
+typedef CGAL::Polyhedron_3 Polyhedron;
+
+
+int main()
+{
+ std::vector points;
+ Polyhedron P;
+
+ std::copy(std::istream_iterator(std::cin),
+ std::istream_iterator(),
+ std::back_inserter(points));
+
+ CGAL::advancing_front_surface_reconstruction(points.begin(),
+ points.end(),
+ P);
+
+ std::cout << P << std::endl;
+
+ return 0;
+}
diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/Surface_face_base_2.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/Surface_face_base_2.h
new file mode 100644
index 00000000000..d59bf2048c6
--- /dev/null
+++ b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/Surface_face_base_2.h
@@ -0,0 +1,88 @@
+#ifndef CGAL_AFSR_SURFACE_FACE_BASE_2_H
+#define CGAL_AFSR_SURFACE_FACE_BASE_2_H
+
+// This face class stores a facet in the tetrahedrization
+// When it gets reoriented by the TDS, it also changes the facet
+
+namespace CGAL {
+namespace AFSR {
+
+template < typename GT,
+ typename F3,
+ typename Fb = CGAL::Triangulation_ds_face_base_2<> >
+class Surface_face_base_2
+ : public Fb
+{
+ typedef typename Fb::Triangulation_data_structure Tds;
+
+public:
+ typedef typename Tds::Face_handle Face_handle;
+ typedef typename Tds::Vertex_handle Vertex_handle;
+
+ template < typename TDS2 >
+ struct Rebind_TDS {
+ typedef typename Fb::template Rebind_TDS::Other Fb2;
+ typedef Surface_face_base_2 Other;
+ };
+
+private:
+ F3 _facet;
+ bool _is_on_surface;
+
+public:
+ Surface_face_base_2()
+ : Fb(), _is_on_surface(true)
+ {}
+
+ Surface_face_base_2(Vertex_handle v0,
+ Vertex_handle v1,
+ Vertex_handle v2)
+ : Fb(v0, v1, v2), _is_on_surface(true)
+ {}
+
+ Surface_face_base_2(Vertex_handle v0,
+ Vertex_handle v1,
+ Vertex_handle v2,
+ Face_handle n0,
+ Face_handle n1,
+ Face_handle n2)
+ : Fb(v0, v1, v2, n0, n1, n2), _is_on_surface(true)
+ {}
+
+ void set_facet(const F3& facet)
+ {
+ _facet = facet;
+ }
+
+ const F3& facet() const
+ {
+ return _facet;
+ }
+
+ void set_is_on_surface(bool is_on_surface)
+ {
+ _is_on_surface = is_on_surface;
+ }
+
+ bool is_on_surface() const
+ {
+ return _is_on_surface;
+ }
+
+
+ void reorient()
+ {
+ Fb::reorient();
+ if( is_on_surface()){
+ _facet = std::make_pair(_facet.first->neighbor(_facet.second),
+ _facet.first->neighbor(_facet.second)->index(_facet.first));
+ }
+ }
+
+};
+
+
+} // namespace AFSR
+} // namespace CGAL
+
+#endif // CGAL_AFSR_SURFACE_FACE_BASE_2_H
diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/Surface_vertex_base_2.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/Surface_vertex_base_2.h
new file mode 100644
index 00000000000..d274a07cef7
--- /dev/null
+++ b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/Surface_vertex_base_2.h
@@ -0,0 +1,76 @@
+// Copyright (c) 2005 GeometryFactory Sarl
+// All rights reserved.
+//
+// This file is part of CGAL (www.cgal.org); you may redistribute it under
+// the terms of the Q Public License version 1.0.
+// See the file LICENSE.QPL distributed with CGAL.
+//
+// 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.
+//
+//
+// Author(s) : Andreas Fabri
+
+
+#ifndef CGAL_AFSR_SURFACE_VERTEX_BASE_2_H
+#define CGAL_AFSR_SURFACE_VERTEX_BASE_2_H
+
+#include
+#include
+
+namespace CGAL {
+namespace AFSR {
+
+template < typename GT,
+ typename V3,
+ typename Vb = CGAL::Triangulation_ds_vertex_base_2<> >
+class Surface_vertex_base_2
+ : public Vb
+
+{
+ typedef typename Vb::Triangulation_data_structure Tds;
+public:
+ typedef GT Geom_traits;
+ typedef typename GT::Point_3 Point;
+ typedef Tds Triangulation_data_structure;
+ typedef typename Tds::Face_handle Face_handle;
+ typedef typename Tds::Vertex_handle Vertex_handle;
+
+ template < typename TDS2 >
+ struct Rebind_TDS {
+ typedef typename Vb::template Rebind_TDS::Other Vb2;
+ typedef Surface_vertex_base_2 Other;
+ };
+
+private:
+ V3 _vertex;
+public:
+ Surface_vertex_base_2() : Vb() {}
+ Surface_vertex_base_2(Face_handle f) : Vb(f) {}
+
+ void set_vertex(const V3& v)
+ {
+ _vertex = v;
+ }
+
+ V3 vertex_3() const
+ {
+ return _vertex;
+ }
+
+ const Point& point() const { return _vertex->point(); }
+
+
+};
+
+
+
+
+
+} // namespace AFSR
+} // namespace CGAL
+
+#endif //CGAL::AFSR_SURFACE_VERTEX_BASE_2_H
diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_polyhedron.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_polyhedron.h
new file mode 100644
index 00000000000..74afdc5c9ed
--- /dev/null
+++ b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_polyhedron.h
@@ -0,0 +1,74 @@
+#ifndef CGAL_AFSR_CONSTRUCT_POLYHEDRON_2
+#define CGAL_AFSR_CONSTRUCT_POLYHEDRON_2
+
+#include
+#include
+
+namespace CGAL {
+
+template
+class Advancing_front_polyhedron_reconstruction;
+
+namespace AFSR {
+
+ template
+class Construct_polyhedron: public CGAL::Modifier_base {
+
+ const Surface& s;
+
+public:
+ Construct_polyhedron(Surface& s)
+ : s(s)
+ {}
+
+ void operator()( HDS& hds)
+ {
+ CGAL::Polyhedron_incremental_builder_3 B( hds, true);
+ B.begin_surface( s.number_of_vertices(), s.number_of_facets(), 6* s.number_of_facets());
+ typedef typename HDS::Vertex Vertex;
+ typedef typename Vertex::Point Point;
+
+ typedef typename Surface::TDS_2 TDS_2;
+ typedef typename TDS_2::Face_iterator Face_iterator;
+ typedef typename TDS_2::Vertex_iterator Vertex_iterator;
+ typedef typename Surface::Cell_handle Cell_handle;
+
+ const TDS_2& tds = s.tds_2();
+
+ int index = 0;
+ Vertex_iterator end = tds.vertices_end();
+
+ for(Vertex_iterator vit = tds.vertices_begin(); vit != end; ++vit){
+ if(vit->vertex_3() != s.triangulation().infinite_vertex()){
+ B.add_vertex(vit->point());
+ vit->vertex_3()->id() = index++;
+ }
+ }
+
+ for(Face_iterator fit = tds.faces_begin(); fit != tds.faces_end(); ++fit){
+
+ if(fit->is_on_surface()){
+ B.begin_facet();
+ for(int i=0; i < 3; i++){
+ B.add_vertex_to_facet(fit->vertex(i)->vertex_3()->id());
+ }
+ B.end_facet();
+ }
+ }
+ B.end_surface();
+ }
+
+};
+
+template
+void
+construct_polyhedron(Polyhedron& P, Surface& surface)
+{
+ typedef typename Polyhedron::HalfedgeDS HalfedgeDS;
+ Construct_polyhedron builder(surface);
+ P.delegate(builder);
+}
+
+} // namespace AFSR
+} // namespace CGAL
+#endif // CGAL_AFSR_CONSTRUCT_POLYHEDRON_2
diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_surface_2.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_surface_2.h
new file mode 100644
index 00000000000..203e2aabc5f
--- /dev/null
+++ b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_surface_2.h
@@ -0,0 +1,128 @@
+#ifndef CGAL_AFSR_CONSTRUCT_SURFACE_2
+#define CGAL_AFSR_CONSTRUCT_SURFACE_2
+
+namespace CGAL {
+
+template
+class Advancing_front_surface_reconstruction;
+
+namespace AFSR {
+
+
+template
+typename TDS::Vertex_handle
+construct_surface(TDS& tds, const CGAL::Advancing_front_surface_reconstruction& surface)
+{
+
+ typedef typename TDS::Vertex_handle Vertex_handle;
+ typedef std::pair Vh_pair;
+ typedef typename TDS::Face_handle Face_handle;
+ typedef typename TDS::Edge Edge;
+
+
+ Triangulation& T = surface.triangulation();
+ // create an infinite-vertex and infinite faces with the
+ // boundary edges if any.
+ // return the infinite vertex if created
+ Vertex_handle vinf;
+
+ std::vector vvh;
+ if(tds.number_of_vertices() != 0){
+ tds.clear();
+ }
+ int dim = 2;
+ tds.set_dimension(dim);
+
+ CGAL::Unique_hash_map vertex_index_map(-1, T.number_of_vertices());
+
+ int i=0;
+ for (typename Triangulation::Finite_vertices_iterator v_it = T.finite_vertices_begin();
+ v_it != T.finite_vertices_end();
+ v_it++){
+ typename CGAL::Unique_hash_map::Data& d = vertex_index_map[v_it];
+ if ((!v_it->is_exterior()) && d == -1){
+ d = i;
+ Vertex_handle vh = tds.create_vertex();
+ vvh.push_back(vh);
+ vh->set_vertex(typename Triangulation::Vertex_handle(v_it));
+ i++;
+ }
+ }
+ std::map edge_map;
+
+ for(typename Triangulation::Finite_facets_iterator f_it = T.finite_facets_begin();
+ f_it != T.finite_facets_end();
+ f_it++)
+ {
+ typename Triangulation::Cell_handle n, c = (*f_it).first;
+ int ni, ci = (*f_it).second;
+ n = c->neighbor(ci);
+ ni = n->index(c);
+ int i1, i2 ,i3;
+
+ if (c->is_selected_facet(ci))
+ {
+ i1 = (ci+1) & 3;
+ i2 = (ci+2) & 3;
+ i3 = (ci+3) & 3;
+
+ Face_handle fh = tds.create_face(vvh[vertex_index_map[c->vertex(i1)]],
+ vvh[vertex_index_map[c->vertex(i2)]],
+ vvh[vertex_index_map[c->vertex(i3)]]);
+ fh->set_facet(*f_it);
+ vvh[vertex_index_map[c->vertex(i1)]]->set_face(fh);
+ vvh[vertex_index_map[c->vertex(i2)]]->set_face(fh);
+ vvh[vertex_index_map[c->vertex(i3)]]->set_face(fh);
+ for (int ih = 0; ih < 3; ++ih) {
+ tds.set_adjacency(fh, ih, edge_map);
+ }
+ }
+
+ if (n->is_selected_facet(ni))
+ {
+ i1 = (ni+1) & 3;
+ i2 = (ni+2) & 3;
+ i3 = (ni+3) & 3;
+ Face_handle fh = tds.create_face(vvh[vertex_index_map[n->vertex(i1)]],
+ vvh[vertex_index_map[n->vertex(i2)]],
+ vvh[vertex_index_map[n->vertex(i3)]]);
+ fh->set_facet(std::make_pair(n, ni));
+ vvh[vertex_index_map[n->vertex(i1)]]->set_face(fh);
+ vvh[vertex_index_map[n->vertex(i2)]]->set_face(fh);
+ vvh[vertex_index_map[n->vertex(i3)]]->set_face(fh);
+ for (int ih = 0; ih < 3; ++ih) {
+ tds.set_adjacency(fh, ih, edge_map);
+ }
+ }
+
+ }
+
+ if ( !edge_map.empty()) {
+ vinf = tds.create_vertex();
+ vinf->set_vertex(T.infinite_vertex());
+ std::map inf_edge_map;
+ while (!edge_map.empty()) {
+ Face_handle fh = edge_map.begin()->second.first;
+ int ih = edge_map.begin()->second.second;
+ Face_handle fn = tds.create_face( vinf,
+ fh->vertex(TDS::cw(ih)),
+ fh->vertex(TDS::ccw(ih)));
+ fn->set_facet(std::make_pair( typename Triangulation::Cell_handle(),0));
+ fn->set_is_on_surface(false);
+ vinf->set_face(fn);
+ tds.set_adjacency(fn, 0, fh, ih);
+ tds.set_adjacency(fn, 1, inf_edge_map);
+ tds.set_adjacency(fn, 2, inf_edge_map);
+ edge_map.erase(edge_map.begin());
+ }
+ CGAL_triangulation_assertion(inf_edge_map.empty());
+ }
+ tds.reorient_faces();
+ return vinf;
+
+}
+
+
+} // namespace AFSR
+} // namespace CGAL
+#endif // CGAL_AFSR_CONSTRUCT_SURFACE_2
diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/orient.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/orient.h
new file mode 100644
index 00000000000..c74232afe88
--- /dev/null
+++ b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/orient.h
@@ -0,0 +1,120 @@
+#ifndef CGAL_AFSR_ORIENT
+
+namespace CGAL {
+namespace AFSR {
+
+
+template
+typename TDS::Vertex_handle
+orient(TDS& tds, const Advancing_front_surface_reconstruction& surface)
+{
+
+ typedef typename TDS::Vertex_handle Vertex_handle;
+ typedef std::pair Vh_pair;
+ typedef typename TDS::Face_handle Face_handle;
+ typedef typename TDS::Edge Edge;
+
+ Triangulation& T = surface.triangulation();
+ // create an infinite-vertex and infinite faces with the
+ // boundary edges if any.
+ // return the infinite vertex if created
+ Vertex_handle vinf;
+
+ std::vector vvh;
+ if(tds.number_of_vertices() != 0) tds.clear();
+ int dim = 2;
+ tds.set_dimension(dim);
+
+ CGAL::Unique_hash_map vertex_index_map(-1, T.number_of_vertices());
+
+ int i=0;
+ for (typename Triangulation::Finite_vertices_iterator v_it = T.finite_vertices_begin();
+ v_it != T.finite_vertices_end();
+ v_it++){
+ typename CGAL::Unique_hash_map::Data& d = vertex_index_map[v_it];
+ if ((!v_it->is_exterior()) && d == -1){
+ d = i;
+ Vertex_handle vh = tds.create_vertex();
+ vvh.push_back(vh);
+ vh->set_point(v_it->point());
+ i++;
+ }
+ }
+ std::map edge_map;
+
+
+ for(typename Triangulation::Finite_facets_iterator f_it = T.finite_facets_begin();
+ f_it != T.finite_facets_end();
+ f_it++)
+ {
+ typename Triangulation::Cell_handle n, c = (*f_it).first;
+ int ni, ci = (*f_it).second;
+ n = c->neighbor(ci);
+ ni = n->index(c);
+ int i1, i2 ,i3;
+
+ if (c->is_selected_facet(ci))
+ {
+ i1 = (ci+1) & 3;
+ i2 = (ci+2) & 3;
+ i3 = (ci+3) & 3;
+
+ Face_handle fh = tds.create_face(vvh[vertex_index_map[c->vertex(i1)]],
+ vvh[vertex_index_map[c->vertex(i2)]],
+ vvh[vertex_index_map[c->vertex(i3)]]);
+ vvh[vertex_index_map[c->vertex(i1)]]->set_face(fh);
+ vvh[vertex_index_map[c->vertex(i2)]]->set_face(fh);
+ vvh[vertex_index_map[c->vertex(i3)]]->set_face(fh);
+ for (int ih = 0; ih < 3; ++ih) {
+ tds.set_adjacency(fh, ih, edge_map);
+ }
+ }
+
+ if (n->is_selected_facet(ni))
+ {
+ i1 = (ni+1) & 3;
+ i2 = (ni+2) & 3;
+ i3 = (ni+3) & 3;
+ Face_handle fh = tds.create_face(vvh[vertex_index_map[n->vertex(i1)]],
+ vvh[vertex_index_map[n->vertex(i2)]],
+ vvh[vertex_index_map[n->vertex(i3)]]);
+ vvh[vertex_index_map[n->vertex(i1)]]->set_face(fh);
+ vvh[vertex_index_map[n->vertex(i2)]]->set_face(fh);
+ vvh[vertex_index_map[n->vertex(i3)]]->set_face(fh);
+ for (int ih = 0; ih < 3; ++ih) {
+ tds.set_adjacency(fh, ih, edge_map);
+ }
+ }
+
+ }
+
+ if ( !edge_map.empty()) {
+ vinf = tds.create_vertex();
+ std::map inf_edge_map;
+ while (!edge_map.empty()) {
+ Face_handle fh = edge_map.begin()->second.first;
+ int ih = edge_map.begin()->second.second;
+ Face_handle fn = tds.create_face( vinf,
+ fh->vertex(TDS::cw(ih)),
+ fh->vertex(TDS::ccw(ih)));
+ vinf->set_face(fn);
+ tds.set_adjacency(fn, 0, fh, ih);
+ tds.set_adjacency(fn, 1, inf_edge_map);
+ tds.set_adjacency(fn, 2, inf_edge_map);
+ edge_map.erase(edge_map.begin());
+ }
+ CGAL_triangulation_assertion(inf_edge_map.empty());
+ }
+
+
+ tds.reorient_faces();
+ return vinf;
+
+}
+
+
+
+} // namespace AFSR
+} // namespace CGAL
+
+#endif //CGAL_AFSR_ORIENT
diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/write_triple_indices.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/write_triple_indices.h
new file mode 100644
index 00000000000..333a1dd32bf
--- /dev/null
+++ b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/write_triple_indices.h
@@ -0,0 +1,38 @@
+#ifndef CGAL_AFSR_WRITE_TRIPLE_INDICES_H
+#define CGAL_AFSR_WRITE_TRIPLE_INDICES_H
+
+#include
+
+namespace CGAL {
+
+template
+class Advancing_front_surface_reconstruction;
+
+
+
+ template
+OutputIterator
+ write_triple_indices(OutputIterator out, const Advancing_front_surface_reconstruction& S)
+{
+ typedef Advancing_front_surface_reconstruction Surface;
+ typedef typename Surface::TDS_2 TDS_2;
+ typedef typename TDS_2::Face_iterator Face_iterator;
+ typedef typename Surface::Cell_handle Cell_handle;
+
+ const TDS_2& tds = S.tds_2();
+
+ for(Face_iterator fit = tds.faces_begin(); fit != tds.faces_end(); ++fit){
+
+ if(fit->is_on_surface()){
+ *out++ = CGAL::cpp11::tuple(fit->vertex(0)->vertex_3()->id(),
+ fit->vertex(1)->vertex_3()->id(),
+ fit->vertex(2)->vertex_3()->id());
+ }
+ }
+ return out;
+}
+
+}
+
+
+#endif
diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR_options.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR_options.h
new file mode 100644
index 00000000000..3fda69a12c2
--- /dev/null
+++ b/Advancing_front_surface_reconstruction/include/CGAL/AFSR_options.h
@@ -0,0 +1,46 @@
+#ifndef CGAL_AFSR_OPTIONS_H
+#define CGAL_AFSR_OPTIONS_H
+
+
+namespace CGAL {
+
+class AFSR_options {
+public:
+ AFSR_options()
+ : file_input(true), file_output(false),
+ Delaunay(false), contour(false), binary(false), xyz(false),
+ Section_file(false), max_connected_comp(-1),
+ delta(.86), K_init(1.1), K_step(.1), K(5), out_format(0),
+ NB_BORDER_MAX(15), red(0), green(0), blue(0), no_header(false), area(0), perimeter(0),
+ abs_area(0), abs_perimeter(0)
+ {
+ std::strcpy(finname,"finput");
+ std::strcpy(foutname,"foutput");
+ }
+
+ char program[100];
+ char finname[100];
+ char foutname[100];
+ bool file_input;
+ bool file_output;
+ bool Delaunay;
+ bool contour;
+ bool binary;
+ bool xyz;
+ bool Section_file;
+ int max_connected_comp;
+ double delta;
+ double K_init;
+ double K_step;
+ double K;
+ int out_format;
+ int NB_BORDER_MAX;
+ double red, green, blue;
+ bool no_header;
+ double area, perimeter, abs_area, abs_perimeter;
+};
+
+
+} // namespace CGAL
+
+#endif // CGAL_AFSR_OPTIONS_H
diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR_vertex_base_3.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR_vertex_base_3.h
new file mode 100644
index 00000000000..1820698a372
--- /dev/null
+++ b/Advancing_front_surface_reconstruction/include/CGAL/AFSR_vertex_base_3.h
@@ -0,0 +1,473 @@
+#ifndef CGAL_AFSR_VERTEX_BASE_3_H
+#define CGAL_AFSR_VERTEX_BASE_3_H
+
+#include
+
+#include
+#include