Merge branch 'master' into sdglinf-philaris

Conflicts:
	Installation/changes.html
This commit is contained in:
Laurent Rineau
2015-07-06 18:33:08 +02:00
57 changed files with 5400 additions and 103 deletions
@@ -0,0 +1,272 @@
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 cloud amounts to
generate a plausible surface that approximates well the input
points. This problem is ill-posed as many surfaces can be generated. A
wide range of approaches have been proposed to tackle 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 is commonly generated
as the union of some triangles selected in the 3D Delaunay
triangulation of the input points. Such algorithms are either
volume-based by generating as output the boundary of selected
tetrahedra \cgalCite{abe-cbscc-97}\cgalCite{ack-pcubm-01},
or surface-based by selecting a set of triangles.
In most surface based Delaunay algorithms the triangles are
selected independently, that is in parallel \cgalCite{agj-lcsr-00}\cgalCite{ab-srvf-98}.
This chapter presents a surface-based Delaunay surface
reconstruction algorithm that sequentially selects the triangles, that
is it uses previously selected triangles to select a new triangle for
advancing the front. At each advancing step the most plausible
triangle is selected, and such that the triangles selected
generates an orientable manifold triangulated surface.
Two other examples of this greedy approach are the ball pivoting
algorithm and Boyer-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 co-circular points are encountered, and it does
not provide any guarantee on the topology of the surface.
We describe next the algorithm and provide examples.
\section AFSR_Definitions Definitions and the Algorithm
A detailed description of the algorithm and the underlying theory are provided
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 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$. This triangle with
three boundary edges is the initial triangulated surface, and its
boundary is the advancing front.
The Delaunay triangle with the smallest radius is the starting point
for the greedy algorithm.
The algorithm maintains a priority queue of candidate triangles, that
is of valid triangles incident to the boundary edges of the current
surface. The priority is the plausibility. While the priority queue is
not empty, the algorithm pops from the queue the most plausible
candidate triangle and adds it to the surface. New candidate triangles
are pushed to the priority queue when new boundary edges appear on the
advancing front. 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 the next potential candidate shares an
edge \f$e\f$ with the front of the current reconstruction. Let \f$b\f$
be the vertex of \f$t\f$ opposite to \f$e\f$. There are four
configurations where \f$t\f$ is added to the surface.
- extension, if \f$b\f$ is not yet on the surface.
- hole filling, if \f$b\f$ is on the front and both neighbors of \f$b\f$ on the front are on edge \f$e\f$.
- ear filling, if \f$b\f$ is on the front and one neighbor of \f$b\f$ on the front is on edge \f$e\f$.
- glueing, if \f$b\f$ is on the front and no neighbor of \f$b\f$ on the front is on edge \f$e\f$.
\cgalFigureBegin{figAFSRvalid,valid.png}
Valid candidates.
\cgalFigureEnd
While the first three operations never induce a non-manifold edge or vertex,
we only can perform gluing, if triangle \f$t\f$ has a *twin* facet, that is a
triangle with an edge on the front and incident to \f$b\f$, and the
third vertex on edge \f$e\f$.
A triangle is said *valid* when the above operations can be applied.
\subsection AFSR_Selection Plausibility of a Candidate Triangle
Valid triangles for an edge on the front are compared through their
radius. 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. There are three bounds namely \f$ \alpha_\mathrm{sliver} \f$,
\f$ \beta \f$, and \f$ \delta \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$, and
- that has its internal angles with \f$ e \f$ smaller than \f$ \delta \f$.
There may be no such triangle. In the implementation
of the algorithm \f$ \alpha_\mathrm{sliver} \f$ and \f$ \delta\f$ are equal
to \f$ 5\pi/6 \f$.
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$.
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 specified by the user and is set by default to \f$ \pi/6\f$.
Let's have a look at the figure below.
\cgalFigureBegin{figAFSRplausible,wedges.png}
Plausibility. Triangle `t'` and incidident triangles sharing edge `e` seen from the side.
\cgalFigureEnd
\f$ \alpha_\mathrm{sliver}\f$ corresponds to the red wedge. The algorithm will never select triangle `t1`
even if it is the only candidate triangle.
\f$\beta\f$ corresponds to the green wedge. If there is a candidate triangle in this zone,
the one with the smallest radius is the most plausible.
If there is no candidate triangle in the green wedge, the triangle with the smallest
angle between its normal and the normal of `t'` is chosen. In the figure above
this would be triangle `t4`.
\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 must filter out
small surface components.
It is impossible to handle all kinds of boundaries and non uniform sampling
at the same time, as a void can either be an undersampled area 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.
More specifically, 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 > \mathrm{radius\_ratio\_bound} \times r_{t'}\f$ where \f$ t'\f$ is
the triangle on the surface incident on \f$ e \f$. The parameter \f$\mathrm{radius\_ratio\_bound}\f$
is specified by the user and is set by default to 5.
For the example given in \cgalFigureRef{figAFSRplausible}, we said that if there
was no triangle `t3` in the green wedge, triangle `t4` would be chosen as it has
the smallest angle between its normal and the normal of triangle `t'`.
However, in case its radius was \f$\mathrm{radius\_ratio\_bound}\f$ times larger than the radius of triangle `t'`,
triangle `t2` would be chosen, assuming that its radius is not \f$\mathrm{radius\_ratio\_bound}\f$ times larger.
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
The first of the following three examples presents a free function for doing surface
reconstruction. For a sequence of points the function produces a sequence
of triplets of indices describing the triangles of the surface.
The second example presents a class that enables to traverse the
surface represented in a 2D triangulation data structure where
the faces are connected with the facets of underlying 3D Delaunay triangulation.
The third example shows how to get outliers and the boundaries of
the surface.
\subsection AFSR_Example_function Examples 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 triplet of point indices into an output iterator.
The following example writes the output triangulated surface to `std::cout`
in accordance to the OFF format.
The function has an overload with an additional argument that allows to filter triangles,
for example to avoid the generation of triangles with a perimeter larger
than a given bound.
\cgalExample{Advancing_front_surface_reconstruction/reconstruction_fct.cpp}
While the first example just writes index triples, the second example
uses as output iterator a wrapper around a reference to a `Surface_mesh`
and calls the function `add_face()`.
\cgalExample{Advancing_front_surface_reconstruction/reconstruction_surface_mesh.cpp}
\subsection AFSR_Example_class Example for the Reconstruction Class
The class `Advancing_front_surface_reconstruction` provides
access to a 2D triangulation data structure describing the output surface.
The latter can be explored by hopping from a face to its neighboring faces,
and by hopping from faces of the 2D triangulation data structure to
corresponding facets of the underlying 3D Delaunay triangulation.
The type of the 2D triangulation data structure describing the
reconstructed surface is the nested type
\link Advancing_front_surface_reconstruction::Triangulation_data_structure_2 `Advancing_front_surface_reconstruction::Triangulation_data_structure_2`\endlink.
The type `Advancing_front_surface_reconstruction::Triangulation_data_structure_2::Vertex` is model of the
concept `TriangulationDataStructure_2::Vertex` and has additionally
the method `vertex_3()` that returns an `Advancing_front_surface_reconstruction::Vertex_handle` to the
associated 3D vertex.
The type `Advancing_front_surface_reconstruction::Triangulation_data_structure_2::Face` is model of the concept
`TriangulationDataStructure_2::Face` and has additionally the method
`facet()` that returns the associated `Advancing_front_surface_reconstruction::Facet`,
and a method `is_on_surface()` for testing if a face is part of the reconstructed
surface.
In case the surface
has boundaries, the 2D surface has one vertex which is associated to
the infinite vertex of the 3D triangulation.
The underlying 3D Delaunay triangulation can be accessed as well,
using the API of the class `Delaunay_triangulation_3`.
The following example writes the surface to `std::cout` in accordance
to the STL (Stereo Lithography) format.
\cgalExample{Advancing_front_surface_reconstruction/reconstruction_class.cpp}
\subsection AFSR_Example_boundaries Example for Outliers and Boundaries
Input points which are not on
a surface are outliers. The member function \link Advancing_front_surface_reconstruction::outliers() `outliers()`\endlink
returns an iterator range of those points.
Boundary edges can be traversed with the member function \link Advancing_front_surface_reconstruction::boundaries() `boundaries()`\endlink
It returns an iterator range type \link Advancing_front_surface_reconstruction::Boundary_range `Boundary_range`\endlink whose iterators have the value type
\link Advancing_front_surface_reconstruction::Vertex_on_boundary_range `Vertex_on_boundary_range`\endlink. This is again an iterator range whose iterators have the value type
\link Advancing_front_surface_reconstruction::Vertex_handle `Vertex_handle`\endlink.
\cgalExample{Advancing_front_surface_reconstruction/boundaries.cpp}
*/
} /* namespace CGAL */
@@ -0,0 +1,11 @@
@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/ \
${CMAKE_SOURCE_DIR}/Advancing_front_surface_reconstruction/include
EXTRACT_ALL = false
HIDE_UNDOC_MEMBERS = true
HIDE_UNDOC_CLASSES = true
MULTILINE_CPP_IS_BRIEF = YES
@@ -0,0 +1,39 @@
/// \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.7}
\cgalPkgDependsOn{\ref PkgTriangulation3Summary}
\cgalPkgBib{cgal:dc-afsr}
\cgalPkgLicense{\ref licensesGPL "GPL"}
\cgalPkgShortInfoEnd
\cgalPkgDescriptionEnd
\cgalClassifedRefPages
## Classes ##
- `CGAL::Advancing_front_surface_reconstruction`
- `CGAL::Advancing_front_surface_reconstruction_vertex_base_3`
- `CGAL::Advancing_front_surface_reconstruction_cell_base_3`
## Functions ##
- `CGAL::advancing_front_surface_reconstruction()`
*/
@@ -0,0 +1,12 @@
Manual
Kernel_23
STL_Extension
Algebraic_foundations
Circulator
Stream_support
TDS_2
Triangulation_2
Triangulation_3
Number_types
Surface_mesh
Polyhedron
@@ -0,0 +1,6 @@
/*!
\example Advancing_front_surface_reconstruction/reconstruction_fct.cpp
\example Advancing_front_surface_reconstruction/reconstruction_class.cpp
\example Advancing_front_surface_reconstruction/reconstruction_surface_mesh.cpp
\example Advancing_front_surface_reconstruction/boundaries.cpp
*/
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

@@ -0,0 +1,72 @@
#include <fstream>
#include <iostream>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Advancing_front_surface_reconstruction.h>
#include <boost/foreach.hpp>
struct Perimeter {
double bound;
Perimeter(double bound)
: bound(bound)
{}
// The point type that will be injected here will be
// CGAL::Exact_predicates_inexact_constructions_kernel::Point_3
template <typename Point>
bool operator()(const Point& p, const Point& q, const Point& r) const
{
// bound == 0 is better than bound < infinity
// as it avoids the distance computations
if(bound == 0){
return false;
}
double d = sqrt(squared_distance(p,q));
if(d>bound) return true;
d += sqrt(squared_distance(p,r)) ;
if(d>bound) return true;
d+= sqrt(squared_distance(q,r));
return d>bound;
}
};
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Advancing_front_surface_reconstruction<CGAL::Default, Perimeter> Reconstruction;
typedef Reconstruction::Triangulation_3 Triangulation_3;
typedef Reconstruction::Outlier_range Outlier_range;
typedef Reconstruction::Boundary_range Boundary_range;
typedef Reconstruction::Vertex_on_boundary_range Vertex_on_boundary_range;
typedef Reconstruction::Vertex_handle Vertex_handle;
typedef K::Point_3 Point_3;
int main(int argc, char* argv[])
{
std::ifstream in((argc>1)?argv[1]:"data/half.xyz");
std::istream_iterator<Point_3> begin(in);
std::istream_iterator<Point_3> end;
Perimeter perimeter(0.5);
Triangulation_3 dt(begin, end);
Reconstruction reconstruction(dt, perimeter);
reconstruction.run();
std::cout << reconstruction.number_of_outliers() << " outliers:\n" << std::endl;
BOOST_FOREACH(const Point_3& p, reconstruction.outliers()){
std::cout << p << std::endl;
}
std::cout << "Boundaries:" << std::endl ;
BOOST_FOREACH(const Vertex_on_boundary_range & vobr, reconstruction.boundaries()){
std::cout << "boundary\n";
// As we use BOOST_FOREACH we do not use the type Boundary_range
BOOST_FOREACH(Vertex_handle v, vobr){
std::cout << v->point() << std::endl;
}
}
return 0;
}
@@ -0,0 +1,325 @@
-7.515480024991e-007 0.4928415052762 -1.734723475977e-018
0.1362245936528 0.2204059209894 -0.4192549456997
-0.3566293497428 0.2204059209894 -0.2590997754675
-0.3566293497428 0.2204059209894 0.2590997754675
0.3566293497428 -0.2204059209894 -0.2590997754675
-0.1362245936528 -0.2204059209894 -0.4192549456997
-0.4408118419787 -0.2204059209894 1.734723475977e-018
7.515480024995e-007 -0.4928415052762 8.673617379884e-019
0.1304938471362 0.4747717502931 0
0.2574163248409 0.4195039861274 0
0.3648848981566 0.3296449948398 0
0.03997961642157 0.4744285141983 -0.1241
0.0795435898012 0.4194849174555 -0.2448222222222
0.1127521490808 0.3296439354692 -0.347001509329
-0.1056956186181 0.4744094455264 -0.07636388888889
-0.2082580899232 0.4194838580848 -0.1512841049383
-0.2951937466481 0.3296438766152 -0.2144713266892
-0.1053014650092 0.4744083861557 0.0769075617284
-0.2082361925005 0.4194837992309 0.1513143089849
-0.2951925301246 0.3296438733456 0.2144730046918
0.04027120169883 0.4740650912069 0.1239115312071
0.07955978898327 0.4194647272893 0.2448117517337
0.4057914855631 0.2478389397683 -0.1245861111111
0.3382717491979 0.2583549410982 -0.245688117284
0.2435693606629 0.2475891554198 -0.3471802540174
0.006912096818534 0.2478388809144 -0.4244420252794
-0.1291490501767 0.2583549378286 -0.3976273347377
-0.2549567859204 0.2475891519685 -0.3389332464941
-0.4015346164662 0.2478388776447 -0.1377400612309
-0.4180935898037 0.2583549376469 -6.055895727388e-005
-0.4011314149817 0.2475891517768 0.1377367900668
-0.2550845488815 0.2478388774631 0.3393151544533
0.4715474070857 0.1170580478199 -0.07682700617284
0.468102633727 4.489154554834e-005 -0.152037611454
0.4266601101928 -0.1173339460802 -0.214804854829
0.07264926058174 0.1170580445502 -0.4721859428322
4.440336565236e-005 4.489136390043e-005 -0.4921631079351
-0.07245809390484 -0.1173339460903 -0.472134336313
-0.4266507759005 0.1170580443686 -0.2150022131499
-0.4680750431056 4.489135380887e-005 -0.152122345175
-0.4714381602825 -0.1173339460909 -0.07699290806528
-0.3363035499236 0.1170580443585 0.3393230516623
0.2188162897165 0.1170890622755 -0.4242178412527
0.289253682762 4.661457086236e-005 -0.398159324514
0.3356412857054 -0.1173940695833 -0.3392729974895
-0.3358187173091 0.1170890620737 -0.3391936241729
-0.2892982620727 4.661455964952e-005 -0.3981274235652
-0.2189461638684 -0.1173940695844 -0.4240731503099
-0.426378573036 0.1170890620625 0.2145810898443
-0.4680599207242 4.661455902659e-005 0.1520989494358
-0.4709811068325 -0.1173940695845 0.0771753356317
0.2549872575249 -0.248327777254 -0.3390290429421
0.1292592643069 -0.2583820987363 -0.397573835719
-0.007139690180596 -0.2480762203231 -0.4237896176518
-0.2436511531956 -0.2483277772541 -0.3472376720005
-0.3381861751775 -0.2583820987363 -0.2457770928889
-0.4052408987466 -0.2480762203231 -0.1241677778308
-0.4055440527117 -0.2483277772541 0.1244125186462
0.4180767837242 -0.2583820987363 6.030299350821e-005
0.4008425690922 -0.2480762203225 -0.1377552404057
0.1055711528638 -0.4747717502931 -0.07668888888889
0.2082511751591 -0.4195039861274 -0.1513021604938
0.2946533528622 -0.3291285502607 -0.2140964566283
-0.04059822753268 -0.4744285141983 -0.123899382716
-0.07957795708515 -0.4194849174555 -0.2448110768176
-0.112563799673 -0.3291274908901 -0.3463718506761
-0.1304037486658 -0.4744094455264 0.0003361454046639
-0.2574113193703 -0.4194838580848 1.867474470355e-005
-0.3642282284893 -0.3291274320362 1.463419778445e-005
0.1782518543444 0.4386105093375 -0.1295317901235
0.3040759062279 0.3614751872873 -0.1300503343621
0.2173702560731 0.3609754803371 -0.2488374570743
-0.06812086123992 0.4385892630703 -0.2095400120027
-0.02971955976201 0.3614728852632 -0.3293601724206
-0.1695110052039 0.3609741096017 -0.2836120109602
-0.2203384092251 0.4385880827221 3.18820492303e-005
-0.3224176917815 0.361472757373 -0.0735013427648
-0.3221005460232 0.3609740334497 0.07355522689281
-0.06808064815709 0.4385678891046 0.2095608418697
-0.1695585311816 0.3614716320434 0.283930724489
-0.02957205890907 0.3609717273766 0.3290751147583
0.1782689534811 0.4385891974954 0.1295207379412
0.4669085084433 -0.1267977790161 -0.07361031177914
0.1516674242459 -0.00115896595775 -0.4667736786963
0.214419939697 -0.1268536831645 -0.4218421599645
0.07426629152944 -0.1267977790504 -0.4668042631267
-0.3970412665771 -0.001158965980238 -0.2884886447813
-0.3349540567162 -0.1268536831664 -0.3342668879748
-0.4209964222559 -0.1267977790524 -0.2148786475953
-0.4214192677113 -0.1268536831665 0.2152714897852
0.3970309840215 0.001136860580719 -0.2884791549048
0.3349440036867 0.1267981463303 -0.3342680384429
0.421038236849 0.1267684348413 -0.2148825577428
-0.1516615620267 0.001136860569378 -0.4667610010068
-0.2144241320836 0.1267981459444 -0.4218329238876
-0.07425716575118 0.1267684311762 -0.4668451297599
-0.4907752350525 0.001136860568748 8.83510151191e-006
-0.4674743740888 0.126798145923 0.07354806141617
-0.4669446463565 0.1267684309725 -0.07363157122197
0.06807728574472 -0.4386105093375 -0.2095473060509
0.02971917239516 -0.3614600687079 -0.3292857603842
0.1694859726663 -0.3609896105791 -0.2835908090121
-0.1782828473697 -0.4385892630703 -0.1295003132991
-0.3040055260641 -0.3614588262362 -0.1300284375042
-0.2173593032536 -0.3609872429801 -0.2488070246215
-0.1782462772615 -0.4385880827221 0.1295525974779
-0.3038167909279 -0.3609871114469 0.1298222044149
0.2203380200369 -0.4385891974954 -7.233207945732e-006
0.3223478833819 -0.3614600029412 -0.07347782154124
0.05962333333333 0.4873 -0.04331666666667
0.1934666666667 0.4511666666667 -0.04381666666667
0.1199233333333 0.4697 -0.08713333333333
0.1014566666667 0.4511666666667 -0.1704666666667
0.3136333333333 0.3776166666667 -0.04411666666667
0.2509 0.41425 -0.08793333333333
0.2370666666667 0.3958666666667 -0.1722333333333
0.1611666666667 0.41425 -0.21145
0.1388833333333 0.3776166666667 -0.2846333333333
0.4092 0.27125 -0.04331666666667
0.3631166666667 0.3201166666667 -0.08743333333333
0.3547833333333 0.2953 -0.1707666666667
0.2914666666667 0.3344166666667 -0.21175
0.27205 0.2953 -0.2846333333333
0.1953666666667 0.3201166666667 -0.3183
0.16765 0.27125 -0.3757833333333
-0.02277666666667 0.4873 -0.07008333333333
0.01812333333333 0.4511666666667 -0.1975333333333
-0.04581 0.4697 -0.1409666666667
-0.1307666666667 0.4511666666667 -0.14915
0.05496833333333 0.3776166666667 -0.3119
-0.006081666666667 0.41425 -0.2657833333333
-0.09054833333333 0.3958666666667 -0.2786666666667
-0.1513 0.41425 -0.2186
-0.2278 0.3776166666667 -0.2200333333333
0.08525516666667 0.27125 -0.4025666666667
0.02905683333333 0.3201166666667 -0.37235
-0.0527765 0.2953 -0.3901833333333
-0.1113316666667 0.3344166666667 -0.3426166666667
-0.1866666666667 0.2953 -0.3466833333333
-0.2423833333333 0.3201166666667 -0.2841666666667
-0.3056 0.27125 -0.2755666666667
-0.0737 0.4873 0
-0.1822666666667 0.4511666666667 -0.07826666666667
-0.1482333333333 0.4697 0
-0.1822666666667 0.4511666666667 0.07826666666667
-0.27965 0.3776166666667 -0.14865
-0.25465 0.41425 -0.07633333333333
-0.293 0.3958666666667 0
-0.25465 0.41425 0.07633333333333
-0.27965 0.3776166666667 0.14865
-0.3565166666667 0.27125 -0.2054833333333
-0.34515 0.3201166666667 -0.1427
-0.3874 0.2953 -0.07038333333333
-0.36025 0.3344166666667 0
-0.3874 0.2953 0.07038333333333
-0.34515 0.3201166666667 0.1427
-0.3565166666667 0.27125 0.2054833333333
-0.02277666666667 0.4873 0.07008333333333
-0.1307666666667 0.4511666666667 0.14915
-0.04581 0.4697 0.1409666666667
0.01812333333333 0.4511666666667 0.1975333333333
-0.2278 0.3776166666667 0.2200333333333
-0.1513 0.41425 0.2186
-0.09054833333333 0.3958666666667 0.2786666666667
-0.006081666666667 0.41425 0.2657833333333
0.05496833333333 0.3776166666667 0.3119
-0.3056 0.27125 0.2755666666667
-0.2423833333333 0.3201166666667 0.2841666666667
-0.1866666666667 0.2953 0.3466833333333
-0.1113316666667 0.3344166666667 0.3426166666667
0.05962333333333 0.4873 0.04331666666667
0.1014566666667 0.4511666666667 0.1704666666667
0.1199233333333 0.4697 0.08713333333333
0.1934666666667 0.4511666666667 0.04381666666667
0.2509 0.41425 0.08793333333333
0.3136333333333 0.3776166666667 0.04411666666667
0.4850666666667 0.03875 -0.07826666666667
0.4844166666667 -0.04251666666667 -0.07633333333333
0.4628333333333 -0.08126666666667 -0.14865
0.46025 -0.17265 0
0.4374 -0.2144166666667 -0.07038333333333
0.4407 -0.16555 -0.1427
0.4020666666667 -0.1975666666667 -0.2054833333333
0.1448833333333 0.1520333333333 -0.4458833333333
0.2243333333333 0.03875 -0.4371333333333
0.1503166666667 0.0775 -0.4626166666667
0.07545 0.03875 -0.4855
0.2844 -0.08126666666667 -0.3942166666667
0.2223 -0.04251666666667 -0.4371
0.1499166666667 -0.08503333333333 -0.4613833333333
0.07708333333333 -0.04251666666667 -0.4843
0.001633333333333 -0.08126666666667 -0.4861
0.3196666666667 -0.1975666666667 -0.3188833333333
0.2719 -0.16555 -0.3750166666667
0.2021166666667 -0.2144166666667 -0.3942166666667
0.1422333333333 -0.17265 -0.4377
0.06822816666667 -0.2144166666667 -0.4377333333333
0.0004615 -0.16555 -0.4632166666667
-0.0711885 -0.1975666666667 -0.4458833333333
-0.3792833333333 0.1520333333333 -0.2755666666667
-0.3464 0.03875 -0.3484333333333
-0.3935166666667 0.0775 -0.2859166666667
-0.4384333333333 0.03875 -0.2217833333333
-0.28705 -0.08126666666667 -0.3923
-0.3470166666667 -0.04251666666667 -0.3464833333333
-0.3924666666667 -0.08503333333333 -0.28515
-0.4367666666667 -0.04251666666667 -0.2229666666667
-0.4618166666667 -0.08126666666667 -0.1517666666667
-0.2045 -0.1975666666667 -0.4025666666667
-0.27265 -0.16555 -0.3744666666667
-0.3124833333333 -0.2144166666667 -0.3140166666667
-0.3723333333333 -0.17265 -0.2705166666667
-0.3952166666667 -0.2144166666667 -0.20015
-0.4404 -0.16555 -0.1435833333333
-0.44605 -0.1975666666667 -0.07008333333333
-0.3792833333333 0.1520333333333 0.2755666666667
-0.4384333333333 0.03875 0.2217833333333
-0.3935166666667 0.0775 0.2859166666667
-0.4618166666667 -0.08126666666667 0.1517666666667
-0.4367666666667 -0.04251666666667 0.2229666666667
-0.44605 -0.1975666666667 0.07008333333333
-0.4404 -0.16555 0.1435833333333
-0.3952166666667 -0.2144166666667 0.20015
0.3792833333333 -0.1520333333333 -0.2755666666667
0.3464 -0.03875 -0.3484333333333
0.3935166666667 -0.0775 -0.2859166666667
0.4384333333333 -0.03875 -0.2217833333333
0.28705 0.08126666666667 -0.3923
0.3470166666667 0.04251666666667 -0.3464833333333
0.3924666666667 0.08503333333333 -0.28515
0.4367666666667 0.04251666666667 -0.2229666666667
0.4618166666667 0.08126666666667 -0.1517666666667
0.2045 0.1975666666667 -0.4025666666667
0.27265 0.16555 -0.3744666666667
0.3124833333333 0.2144166666667 -0.3140166666667
0.3723333333333 0.17265 -0.2705166666667
0.3952166666667 0.2144166666667 -0.20015
0.4404 0.16555 -0.1435833333333
0.44605 0.1975666666667 -0.07008333333333
-0.1448833333333 -0.1520333333333 -0.4458833333333
-0.2243333333333 -0.03875 -0.4371333333333
-0.1503166666667 -0.0775 -0.4626166666667
-0.07545 -0.03875 -0.4855
-0.2844 0.08126666666667 -0.3942166666667
-0.2223 0.04251666666667 -0.4371
-0.1499166666667 0.08503333333333 -0.4613833333333
-0.07708333333333 0.04251666666667 -0.4843
-0.001633333333333 0.08126666666667 -0.4861
-0.3196666666667 0.1975666666667 -0.3188833333333
-0.2719 0.16555 -0.3750166666667
-0.2021166666667 0.2144166666667 -0.3942166666667
-0.1422333333333 0.17265 -0.4377
-0.06822816666667 0.2144166666667 -0.4377333333333
-0.0004615 0.16555 -0.4632166666667
0.0711885 0.1975666666667 -0.4458833333333
-0.4688333333333 -0.1520333333333 0
-0.4850666666667 -0.03875 0.07826666666667
-0.4864333333333 -0.0775 0
-0.4850666666667 -0.03875 -0.07826666666667
-0.4628333333333 0.08126666666667 0.14865
-0.4844166666667 0.04251666666667 0.07633333333333
-0.4851333333333 0.08503333333333 0
-0.4844166666667 0.04251666666667 -0.07633333333333
-0.4628333333333 0.08126666666667 -0.14865
-0.4020666666667 0.1975666666667 0.2054833333333
-0.4407 0.16555 0.1427
-0.4374 0.2144166666667 0.07038333333333
-0.46025 0.17265 0
-0.4374 0.2144166666667 -0.07038333333333
-0.4407 0.16555 -0.1427
-0.4020666666667 0.1975666666667 -0.2054833333333
-0.2719 0.16555 0.3750166666667
-0.3196666666667 0.1975666666667 0.3188833333333
0.02277666666667 -0.4873 -0.07008333333333
-0.01812333333333 -0.4511666666667 -0.1975333333333
0.04581 -0.4697 -0.1409666666667
0.1307666666667 -0.4511666666667 -0.14915
-0.05496833333333 -0.3776166666667 -0.3119
0.006081666666667 -0.41425 -0.2657833333333
0.09054833333333 -0.3958666666667 -0.2786666666667
0.1513 -0.41425 -0.2186
0.2278 -0.3776166666667 -0.2200333333333
-0.08525516666667 -0.27125 -0.4025666666667
-0.02905683333333 -0.3201166666667 -0.37235
0.0527765 -0.2953 -0.3901833333333
0.1113316666667 -0.3344166666667 -0.3426166666667
0.1866666666667 -0.2953 -0.3466833333333
0.2423833333333 -0.3201166666667 -0.2841666666667
0.3056 -0.27125 -0.2755666666667
-0.05962333333333 -0.4873 -0.04331666666667
-0.1934666666667 -0.4511666666667 -0.04381666666667
-0.1199233333333 -0.4697 -0.08713333333333
-0.1014566666667 -0.4511666666667 -0.1704666666667
-0.3136333333333 -0.3776166666667 -0.04411666666667
-0.2509 -0.41425 -0.08793333333333
-0.2370666666667 -0.3958666666667 -0.1722333333333
-0.1611666666667 -0.41425 -0.21145
-0.1388833333333 -0.3776166666667 -0.2846333333333
-0.4092 -0.27125 -0.04331666666667
-0.3631166666667 -0.3201166666667 -0.08743333333333
-0.3547833333333 -0.2953 -0.1707666666667
-0.2914666666667 -0.3344166666667 -0.21175
-0.27205 -0.2953 -0.2846333333333
-0.1953666666667 -0.3201166666667 -0.3183
-0.16765 -0.27125 -0.3757833333333
-0.05962333333333 -0.4873 0.04331666666667
-0.1199233333333 -0.4697 0.08713333333333
-0.1934666666667 -0.4511666666667 0.04381666666667
-0.2370666666667 -0.3958666666667 0.1722333333333
-0.2509 -0.41425 0.08793333333333
-0.3136333333333 -0.3776166666667 0.04411666666667
-0.3547833333333 -0.2953 0.1707666666667
-0.3631166666667 -0.3201166666667 0.08743333333333
-0.4092 -0.27125 0.04331666666667
0.02277666666667 -0.4873 0.07008333333333
0.0737 -0.4873 0
0.1822666666667 -0.4511666666667 -0.07826666666667
0.1482333333333 -0.4697 0
0.27965 -0.3776166666667 -0.14865
0.25465 -0.41425 -0.07633333333333
0.293 -0.3958666666667 0
0.3565166666667 -0.27125 -0.2054833333333
0.34515 -0.3201166666667 -0.1427
0.3874 -0.2953 -0.07038333333333
0.36025 -0.3344166666667 0
@@ -0,0 +1,56 @@
#include <iostream>
#include <fstream>
#include <algorithm>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Advancing_front_surface_reconstruction.h>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Advancing_front_surface_reconstruction<> Reconstruction;
typedef Reconstruction::Triangulation_3 Triangulation_3;
typedef Reconstruction::Triangulation_data_structure_2 TDS_2;
typedef K::Point_3 Point_3;
typedef K::Vector_3 Vector_3;
int main(int argc, char* argv[])
{
std::ifstream in((argc>1)?argv[1]:"data/half.xyz");
std::istream_iterator<Point_3> begin(in);
std::istream_iterator<Point_3> end;
Triangulation_3 dt(begin,end);
Reconstruction reconstruction(dt);
reconstruction.run();
const TDS_2& tds = reconstruction.triangulation_data_structure_2();
std::cout << "solid produced with CGAL::Advancing_front_surface_reconstruction\n";
for(TDS_2::Face_iterator fit = tds.faces_begin();
fit != tds.faces_end();
++fit){
if(reconstruction.has_on_surface(fit)){
Triangulation_3::Facet f = fit->facet();
Triangulation_3::Cell_handle ch = f.first;
int ci = f.second;
Point_3 points[3];
for(int i = 0, j = 0; i < 4; i++){
if(ci != i){
points[j] = ch->vertex(i)->point();
j++;
}
}
std::cout << " facet normal "
<< CGAL::unit_normal(points[0],points[1], points[2]) << "\n"
<< " outer loop\n"
<< " vertex " << points[0] << "\n"
<< " vertex " << points[1] << "\n"
<< " vertex " << points[2] << "\n"
<< " endloop\n"
<< " endfacet\n";
}
}
std::cout << "endsolid" << std::endl;
return 0;
}
@@ -0,0 +1,74 @@
#include <iostream>
#include <fstream>
#include <algorithm>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Advancing_front_surface_reconstruction.h>
#include <CGAL/tuple.h>
typedef CGAL::Simple_cartesian<double> K;
typedef K::Point_3 Point_3;
typedef CGAL::cpp11::array<std::size_t,3> Facet;
namespace std {
std::ostream&
operator<<(std::ostream& os, const Facet& f)
{
os << "3 " << f[0] << " " << f[1] << " " << f[2];
return os;
}
}
struct Perimeter {
double bound;
Perimeter(double bound)
: bound(bound)
{}
// The point type that will be injected here will be
// CGAL::Exact_predicates_inexact_constructions_kernel::Point_3
template <typename Point>
bool operator()(const Point& p, const Point& q, const Point& r) const
{
// bound == 0 is better than bound < infinity
// as it avoids the distance computations
if(bound == 0){
return false;
}
double d = sqrt(squared_distance(p,q));
if(d>bound) return true;
d += sqrt(squared_distance(p,r)) ;
if(d>bound) return true;
d+= sqrt(squared_distance(q,r));
return d>bound;
}
};
int main(int argc, char* argv[])
{
std::ifstream in((argc>1)?argv[1]:"data/half.xyz");
std::vector<Point_3> points;
std::vector<Facet> facets;
std::copy(std::istream_iterator<Point_3>(in),
std::istream_iterator<Point_3>(),
std::back_inserter(points));
Perimeter perimeter(0);
CGAL::advancing_front_surface_reconstruction(points.begin(),
points.end(),
std::back_inserter(facets),
perimeter);
std::cout << "OFF\n" << points.size() << " " << facets.size() << " 0\n";
std::copy(points.begin(),
points.end(),
std::ostream_iterator<Point_3>(std::cout, "\n"));
std::copy(facets.begin(),
facets.end(),
std::ostream_iterator<Facet>(std::cout, "\n"));
return 0;
}
@@ -0,0 +1,71 @@
#include <iostream>
#include <fstream>
#include <algorithm>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Advancing_front_surface_reconstruction.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/array.h>
typedef CGAL::cpp11::array<std::size_t,3> Facet;
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef Kernel::Point_3 Point_3;
typedef CGAL::Surface_mesh<Point_3> Mesh;
struct Construct{
Mesh& mesh;
template < typename PointIterator>
Construct(Mesh& mesh,PointIterator b, PointIterator e)
: mesh(mesh)
{
for(; b!=e; ++b){
boost::graph_traits<Mesh>::vertex_descriptor v;
v = add_vertex(mesh);
mesh.point(v) = *b;
}
}
Construct& operator=(const Facet f)
{
typedef boost::graph_traits<Mesh>::vertex_descriptor vertex_descriptor;
typedef boost::graph_traits<Mesh>::vertices_size_type size_type;
mesh.add_face(vertex_descriptor(static_cast<size_type>(f[0])),
vertex_descriptor(static_cast<size_type>(f[1])),
vertex_descriptor(static_cast<size_type>(f[2])));
return *this;
}
Construct&
operator*() { return *this; }
Construct&
operator++() { return *this; }
Construct
operator++(int) { return *this; }
};
int main(int argc, char* argv[])
{
std::ifstream in((argc>1)?argv[1]:"data/half.xyz");
std::vector<Point_3> points;
std::vector<Facet> facets;
Mesh m;
std::copy(std::istream_iterator<Point_3>(in),
std::istream_iterator<Point_3>(),
std::back_inserter(points));
Construct construct(m,points.begin(),points.end());
CGAL::advancing_front_surface_reconstruction(points.begin(),
points.end(),
construct);
std::cout << m << std::endl;
return 0;
}
@@ -0,0 +1,253 @@
// Copyright (c) 2015 INRIA Sophia-Antipolis (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) : Frank Da, David Cohen-Steiner, Andreas Fabri
#ifndef CGAL_ADVANCING_FRONT_SURFACE_RECONSTRUCTION_CELL_BASE_3_H
#define CGAL_ADVANCING_FRONT_SURFACE_RECONSTRUCTION_CELL_BASE_3_H
#include <CGAL/Triangulation_cell_base_3.h>
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<Traits> >
class Advancing_front_surface_reconstruction_cell_base_3 : public Cb
{
public:
template < typename TDS2 >
struct Rebind_TDS {
typedef typename Cb::template Rebind_TDS<TDS2>::Other Cb2;
typedef Advancing_front_surface_reconstruction_cell_base_3<Traits,Cb2> Other;
};
typedef typename Cb::Vertex_handle Vertex_handle;
typedef typename Cb::Cell_handle Cell_handle;
private:
#ifdef AFSR_FACET_NUMBER
int _facet_number[4];
#endif
typedef double coord_type;
#ifdef AFSR_LAZY
typedef typename CGAL::Simple_cartesian<coord_type>::Point_3 D_Point;
#endif
//-------------------- DATA MEMBERS ---------------------------------
coord_type* _smallest_radius_facet_tab;
unsigned char selected_facet;
#ifdef AFSR_LAZY
D_Point* _circumcenter;
coord_type* _squared_radius;
#endif
//-------------------- CONSTRUCTORS ----------------------------------
public:
Advancing_front_surface_reconstruction_cell_base_3()
: Cb(),
_smallest_radius_facet_tab(NULL), selected_facet(0)
#ifdef AFSR_LAZY
, _circumcenter(NULL), _squared_radius(NULL)
#endif
{
#ifdef AFSR_FACET_NUMBER
for(int i = 0; i < 4; i++){
_facet_number[i] = -1;
}
#endif
}
Advancing_front_surface_reconstruction_cell_base_3(Vertex_handle v0, Vertex_handle v1, Vertex_handle v2, Vertex_handle v3)
: Cb( v0, v1, v2, v3),
_smallest_radius_facet_tab(NULL), selected_facet(0)
#ifdef AFSR_LAZY
, _circumcenter(NULL), _squared_radius(NULL)
#endif
{
#ifdef FACET_NUMBER
for(int i = 0; i < 4; i++){
_facet_number[i] = -1;
}
#endif
}
Advancing_front_surface_reconstruction_cell_base_3(Vertex_handle v0, Vertex_handle v1, Vertex_handle v2, Vertex_handle v3,
Cell_handle n0, Cell_handle n1, Cell_handle n2, Cell_handle n3)
: Cb(v0, v1, v2, v3,
n0, n1, n2, n3),
_smallest_radius_facet_tab(NULL), selected_facet(0)
#ifdef AFSR_LAZY
, _circumcenter(NULL), _squared_radius(NULL)
#endif
{
#ifdef AFSR_FACET_NUMBER
for(int i = 0; i < 4; i++){
_facet_number[i] = -1;
}
#endif
}
//-------------------- DESTRUCTOR -----------------------------------
inline ~Advancing_front_surface_reconstruction_cell_base_3()
{
if (_smallest_radius_facet_tab != NULL)
delete[] _smallest_radius_facet_tab;
#ifdef AFSR_LAZY
if (_circumcenter != NULL)
delete _circumcenter;
if (_squared_radius != NULL)
delete _squared_radius;
#endif
}
//-------------------- MEMBER FUNCTIONS ----------------------------
public:
inline void clear()
{
if (_smallest_radius_facet_tab != NULL)
delete[] _smallest_radius_facet_tab;
_smallest_radius_facet_tab = NULL;
selected_facet = 0;
#ifdef AFSR_LAZY
if (_circumcenter != NULL)
delete _circumcenter;
_circumcenter = NULL;
if (_squared_radius != NULL)
delete _squared_radius;
_squared_radius = NULL;
#endif
}
//-------------------------------------------------------------------
inline coord_type smallest_radius(const int& i)
{
if (_smallest_radius_facet_tab == NULL)
return -1;
return _smallest_radius_facet_tab[i];
}
inline void set_smallest_radius(const int& i, const coord_type& c)
{
if (_smallest_radius_facet_tab == NULL)
{
_smallest_radius_facet_tab = new coord_type[4];
for(int i = 0; i < 4; i++)
_smallest_radius_facet_tab[i] = -1;
}
_smallest_radius_facet_tab[i] = c;
}
// pour un controle de l'allocation memoire... utile???
inline bool alloc_smallest_radius_tab(coord_type* ptr)
{
if (_smallest_radius_facet_tab==NULL)
{
_smallest_radius_facet_tab = ptr;
return true;
}
return false;
}
//-------------------------------------------------------------------
#ifdef FACET_NUMBER
void set_facet_number(int i, int n){}
{
_facet_number[i] = n;
}
int facet_number(int i)
{
return _facet_number[i];
}
#else
void set_facet_number(int, int){}
int facet_number(int){return 0;}
#endif
//-------------------------------------------------------------------
inline void select_facet(const int& i)
{
selected_facet |= (1 << i);
}
inline void unselect_facet(const int& i)
{
selected_facet &= (15 - (1 << i));
}
inline bool is_selected_facet(const int& i)
{
return (selected_facet & (1 << i)) != 0;
}
inline bool has_facet_on_surface(const int& i)
{
return (selected_facet & (1 << i)) != 0;
}
#ifdef AFSR_LAZY
//-------------------------------------------------------------------
inline D_Point* lazy_circumcenter()
{
return _circumcenter;
}
inline void set_lazy_circumcenter(const D_Point& p)
{
_circumcenter = new D_Point(p);
}
//-------------------------------------------------------------------
inline coord_type* lazy_squared_radius()
{
return _squared_radius;
}
inline void set_lazy_squared_radius(const coord_type& sr)
{
_squared_radius = new coord_type(sr);
}
#endif //AFSR_LAZY
};
} // namespace CGAL
#endif // CGAL_ADVANCING_FRONT_SURFACE_RECONSTRUCTION_CELL_BASE_3_H
@@ -0,0 +1,286 @@
// Copyright (c) 2015 INRIA Sophia-Antipolis (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) : Frank Da, David Cohen-Steiner, Andreas Fabri
#ifndef CGAL_ADVANCING_FRONT_SURFACE_RECONSTRUCTION_VERTEX_BASE_WITH_ID_3_H
#define CGAL_ADVANCING_FRONT_SURFACE_RECONSTRUCTION_VERTEX_BASE_WITH_ID_3_H
#include <CGAL/Triangulation_vertex_base_3.h>
#include <CGAL/utility.h>
#include <utility>
#include <list>
namespace CGAL {
template <class B, class C> class Advancing_front_surface_reconstruction;
/*!
\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<Traits> >
class Advancing_front_surface_reconstruction_vertex_base_3 : public Vb
{
public:
template < typename TDS2 >
struct Rebind_TDS {
typedef typename Vb::template Rebind_TDS<TDS2>::Other Vb2;
typedef Advancing_front_surface_reconstruction_vertex_base_3<Traits,Vb2> Other;
};
template <class B,class C> friend class Advancing_front_surface_reconstruction;
typedef Vb Base;
typedef typename Base::Vertex_handle Vertex_handle;
typedef typename Base::Cell_handle Cell_handle;
typedef typename Vb::Point Point;
typedef double coord_type;
typedef Triple< Cell_handle, int, int > Edge;
typedef std::pair< Edge, int > Edge_incident_facet;
typedef std::pair< Edge_incident_facet, Edge_incident_facet > IO_edge_type;
typedef coord_type criteria;
typedef std::pair< criteria, IO_edge_type > Radius_edge_type;
typedef std::pair< Radius_edge_type, int > Border_elt;
typedef std::pair< Vertex_handle, Border_elt > Next_border_elt;
//par convention je remplis d'abord first et si necessaire second...
typedef std::pair< Next_border_elt*, Next_border_elt*> Intern_successors_type;
public:
typedef std::pair< criteria, IO_edge_type* > Radius_ptr_type;
typedef std::pair< Vertex_handle, Vertex_handle > Edge_like;
typedef std::pair< criteria, Edge_like > Incidence_request_elt;
typedef std::list< Incidence_request_elt > Incidence_request_type;
typedef typename Incidence_request_type::iterator Incidence_request_iterator;
//-------------------- DATA MEMBERS ---------------------------------
typedef int Info; // so that we are a model of TriangulationVertexBaseWithInfo_3
private:
int m_id;
int m_mark;
int m_post_mark;
Intern_successors_type* m_incident_border;
// Instead of having a set per vertex, there is a global list
// in the surface reconstruction class
// and two iterators per vertex in this list
// Note that m_ie_last is not past the end
// m_ie_first == m_ie_last == interior_edge.end() iff the set is empty
typename std::list<Vertex_handle>::iterator m_ie_first, m_ie_last;
// We do the same for the incidence requests
typename std::list< Incidence_request_elt >::iterator m_ir_first, m_ir_last;
//-------------------- CONSTRUCTORS ---------------------------------
public:
Advancing_front_surface_reconstruction_vertex_base_3()
: Vb(), m_mark(-1),
m_post_mark(-1)
{}
Advancing_front_surface_reconstruction_vertex_base_3(const Point & p)
: Vb(p), m_mark(-1),
m_post_mark(-1)
{}
Advancing_front_surface_reconstruction_vertex_base_3(const Point & p, Cell_handle f)
: Vb(p, f), m_mark(-1),
m_post_mark(-1)
{}
Advancing_front_surface_reconstruction_vertex_base_3(Cell_handle f)
: Vb(f), m_mark(-1),
m_post_mark(-1)
{}
Advancing_front_surface_reconstruction_vertex_base_3(const Advancing_front_surface_reconstruction_vertex_base_3& other)
: Vb(other), m_mark(-1),
m_post_mark(-1)
{}
//-------------------- MEMBER FUNCTIONS -----------------------------
public:
int& id()
{
return m_id;
}
const int& id() const
{
return m_id;
}
int& info()
{
return m_id;
}
const int& info() const
{
return m_id;
}
//-------------------------------------------------------------------
private:
void delete_border()
{
m_incident_border = NULL;
}
inline Next_border_elt* next_on_border(const int& i) const
{
if (m_incident_border == NULL) return NULL; //vh is interior
if (m_incident_border->first->first != NULL)
if (m_incident_border->first->second.second == i)
return m_incident_border->first;
if (m_incident_border->second->first != NULL)
if (m_incident_border->second->second.second == i)
return m_incident_border->second;
return NULL;
}
inline bool is_border_edge(Vertex_handle v) const
{
if (m_incident_border == NULL) return false;
return ((m_incident_border->first->first == v)||
(m_incident_border->second->first == v));
}
inline Next_border_elt* border_elt(Vertex_handle v) const
{
if (m_incident_border == NULL) return NULL;
if (m_incident_border->first->first == v) return m_incident_border->first;
if (m_incident_border->second->first == v) return m_incident_border->second;
return NULL;
}
public:
inline Next_border_elt* first_incident() const
{
if (m_incident_border == NULL) return NULL;
return m_incident_border->first;
}
private:
inline Next_border_elt* second_incident() const
{
if (m_incident_border == NULL) return NULL;
return m_incident_border->second;
}
inline void set_next_border_elt(const Next_border_elt& elt)
{
if (m_incident_border->first->first == NULL)
*m_incident_border->first = elt;
else
{
if (m_incident_border->second->first != NULL)
std::cerr << "+++probleme de MAJ du bord <Vertex_base>" << std::endl;
*m_incident_border->second = elt;
}
}
//-------------------------------------------------------------------
public:
inline bool is_on_border() const
{
return (m_mark > 0);
}
inline bool not_interior() const
{
return (m_mark != 0);
}
inline int number_of_incident_border() const
{
return m_mark;
}
inline bool is_exterior() const
{
return (m_mark < 0);
}
//-------------------------------------------------------------------
private:
inline void inc_mark()
{
if (m_mark==-1)
m_mark=1;
else
m_mark++;
}
//-------------------------------------------------------------------
public:
inline void set_post_mark(const int& i)
{
m_post_mark = i;
}
inline bool is_post_marked(const int& i)
{
return (m_post_mark == i);
}
};
} // namespace CGAL
#endif // CGAL_ADVANCING_FRONT_SURFACE_RECONSTRUCTION_VERTEX_BASE_3_H
@@ -0,0 +1,107 @@
// Copyright (c) 2015 INRIA Sophia-Antipolis (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) : Frank Da, David Cohen-Steiner, Andreas Fabri
#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<TDS2>::Other Fb2;
typedef Surface_face_base_2<GT, F3, Fb2> 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
@@ -0,0 +1,78 @@
// Copyright (c) 2015 INRIA Sophia-Antipolis (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) : Frank Da, David Cohen-Steiner, Andreas Fabri
#ifndef CGAL_AFSR_SURFACE_VERTEX_BASE_2_H
#define CGAL_AFSR_SURFACE_VERTEX_BASE_2_H
#include <CGAL/basic.h>
#include <CGAL/Triangulation_ds_vertex_base_2.h>
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<TDS2>::Other Vb2;
typedef Surface_vertex_base_2<GT,V3, Vb2> 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
@@ -0,0 +1,90 @@
// Copyright (c) 2015 INRIA Sophia-Antipolis (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) : Frank Da, David Cohen-Steiner, Andreas Fabri
#ifndef CGAL_AFSR_CONSTRUCT_POLYHEDRON_2
#define CGAL_AFSR_CONSTRUCT_POLYHEDRON_2
#include <CGAL/Polyhedron_incremental_builder_3.h>
#include <CGAL/Polyhedron_3.h>
namespace CGAL {
template <class Triangulation, class Filter>
class Advancing_front_polyhedron_reconstruction;
namespace AFSR {
template <class HDS, class Surface>
class Construct_polyhedron: public CGAL::Modifier_base<HDS> {
const Surface& s;
public:
Construct_polyhedron(Surface& s)
: s(s)
{}
void operator()( HDS& hds)
{
CGAL::Polyhedron_incremental_builder_3<HDS> B( hds, true);
B.begin_surface( s.number_of_vertices(), s.number_of_facets(), 6* s.number_of_facets());
typedef typename Surface::TDS_2 TDS_2;
typedef typename TDS_2::Face_iterator Face_iterator;
typedef typename TDS_2::Vertex_iterator Vertex_iterator;
const TDS_2& tds = s.triangulation_data_structure_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_3().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 <class Polyhedron, class Surface>
void
construct_polyhedron(Polyhedron& P, Surface& surface)
{
typedef typename Polyhedron::HalfedgeDS HalfedgeDS;
Construct_polyhedron<HalfedgeDS, Surface> builder(surface);
P.delegate(builder);
}
} // namespace AFSR
} // namespace CGAL
#endif // CGAL_AFSR_CONSTRUCT_POLYHEDRON_2
@@ -0,0 +1,147 @@
// Copyright (c) 2015 INRIA Sophia-Antipolis (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) : Frank Da, David Cohen-Steiner, Andreas Fabri
#ifndef CGAL_AFSR_CONSTRUCT_SURFACE_2
#define CGAL_AFSR_CONSTRUCT_SURFACE_2
namespace CGAL {
template <class Triangulation, class Filter>
class Advancing_front_surface_reconstruction;
namespace AFSR {
template <class Tr, class TDS, class Filter>
typename TDS::Vertex_handle
construct_surface(TDS& tds, const Advancing_front_surface_reconstruction<Tr,Filter>& surface)
{
typedef typename TDS::Vertex_handle Vertex_handle;
typedef std::pair<Vertex_handle,Vertex_handle> Vh_pair;
typedef typename TDS::Face_handle Face_handle;
typedef typename TDS::Edge Edge;
typedef typename Advancing_front_surface_reconstruction<Tr,Filter>::Triangulation_3 Triangulation;
Triangulation& T = surface.triangulation_3();
// create an infinite-vertex and infinite faces with the
// boundary edges if any.
// return the infinite vertex if created
Vertex_handle vinf;
std::vector<Vertex_handle > vvh;
if(tds.number_of_vertices() != 0){
tds.clear();
}
int dim = 2;
tds.set_dimension(dim);
CGAL::Unique_hash_map<typename Triangulation::Vertex_handle, int> 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<typename Triangulation::Vertex_handle, int>::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<Vh_pair, Edge> 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<Vh_pair, Edge> 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
@@ -0,0 +1,139 @@
// Copyright (c) 2015 INRIA Sophia-Antipolis (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) : Frank Da, David Cohen-Steiner, Andreas Fabri
#ifndef CGAL_AFSR_ORIENT
namespace CGAL {
namespace AFSR {
template <class Triangulation, class TDS, class Filter>
typename TDS::Vertex_handle
orient(TDS& tds, const Advancing_front_surface_reconstruction<Triangulation,Filter>& surface)
{
typedef typename TDS::Vertex_handle Vertex_handle;
typedef std::pair<Vertex_handle,Vertex_handle> Vh_pair;
typedef typename TDS::Face_handle Face_handle;
typedef typename TDS::Edge Edge;
Triangulation& T = surface.triangulation_3();
// create an infinite-vertex and infinite faces with the
// boundary edges if any.
// return the infinite vertex if created
Vertex_handle vinf;
std::vector<Vertex_handle > vvh;
if(tds.number_of_vertices() != 0) tds.clear();
int dim = 2;
tds.set_dimension(dim);
CGAL::Unique_hash_map<typename Triangulation::Vertex_handle, int> 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<typename Triangulation::Vertex_handle, int>::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<Vh_pair, Edge> 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<Vh_pair, Edge> 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
@@ -0,0 +1,60 @@
// Copyright (c) 2015 INRIA Sophia-Antipolis (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) : Frank Da, David Cohen-Steiner, Andreas Fabri
#ifndef CGAL_AFSR_WRITE_TRIPLE_INDICES_H
#define CGAL_AFSR_WRITE_TRIPLE_INDICES_H
#include <CGAL/array.h>
namespace CGAL {
template <class Triangulation, class Filter>
class Advancing_front_surface_reconstruction;
template <class OutputIterator, class Triangulation, class Filter>
OutputIterator
write_triple_indices(OutputIterator out, const Advancing_front_surface_reconstruction<Triangulation,Filter>& S)
{
typedef Advancing_front_surface_reconstruction<Triangulation,Filter> Surface;
typedef typename Surface::TDS_2 TDS_2;
typedef typename TDS_2::Face_iterator Face_iterator;
if(S.triangulation_3().dimension() < 3){
std::cerr << "not 3D\n";
return out;
}
const TDS_2& tds = S.triangulation_data_structure_2();
for(Face_iterator fit = tds.faces_begin(); fit != tds.faces_end(); ++fit){
if(fit->is_on_surface()){
*out++ = CGAL::make_array(std::size_t(fit->vertex(0)->vertex_3()->id()),
std::size_t(fit->vertex(1)->vertex_3()->id()),
std::size_t(fit->vertex(2)->vertex_3()->id()));
}
}
return out;
}
}
#endif
@@ -0,0 +1 @@
INRIA Sophia-Antipolis (France)
@@ -0,0 +1 @@
Surface reconstruction using an advancing front method.
@@ -0,0 +1 @@
Andreas Fabri <Andreas.Fabri@geometryfactory.com>
@@ -0,0 +1,8 @@
0 0 0
1 0 0
1 1 0
0 1 0
11 32 0
355 43 0
12 3 0
134 456 0
@@ -0,0 +1,8 @@
1 0 0
1 0 0
1 0 0
111 0 0
111 0 0
0 0 1111
1 0 0
1 0 0
@@ -0,0 +1,68 @@
#include <iostream>
#include <fstream>
#include <algorithm>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Advancing_front_surface_reconstruction.h>
typedef CGAL::Simple_cartesian<double> K;
typedef CGAL::cpp11::array<std::size_t,3> Facet;
namespace std {
std::ostream&
operator<<(std::ostream& os, const Facet& f)
{
os << "3 " << f[0] << " " << f[1] << " " << f[2];
return os;
}
}
template <typename K>
void fct(const char* fname)
{
typedef typename K::Point_3 Point_3;
std::ifstream in(fname);
std::vector<Point_3> points;
std::vector<Facet> facets;
std::copy(std::istream_iterator<Point_3>(in),
std::istream_iterator<Point_3>(),
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<Point_3>(std::cout, "\n"));
std::copy(facets.begin(),
facets.end(),
std::ostream_iterator<Facet>(std::cout, "\n"));
}
int main()
{
{
typedef CGAL::Simple_cartesian<float> K;
fct<K>("data/planar.xyz");
}
{
typedef CGAL::Simple_cartesian<double> K;
fct<K>("data/planar.xyz");
}
{
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
fct<K>("data/planar.xyz");
}
{
typedef CGAL::Exact_predicates_exact_constructions_kernel K;
fct<K>("data/planar.xyz");
}
return 0;
}
@@ -0,0 +1,53 @@
#include <iostream>
#include <fstream>
#include <algorithm>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Advancing_front_surface_reconstruction.h>
#include <CGAL/tuple.h>
typedef CGAL::Simple_cartesian<double> K;
typedef K::Point_3 Point_3;
typedef CGAL::cpp11::array<std::size_t,3> Facet;
namespace std {
std::ostream&
operator<<(std::ostream& os, const Facet& f)
{
os << "3 " << f[0] << " " << f[1] << " " << f[2];
return os;
}
}
void fct(const char* fname)
{
std::ifstream in(fname);
std::vector<Point_3> points;
std::vector<Facet> facets;
std::copy(std::istream_iterator<Point_3>(in),
std::istream_iterator<Point_3>(),
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<Point_3>(std::cout, "\n"));
std::copy(facets.begin(),
facets.end(),
std::ostream_iterator<Facet>(std::cout, "\n"));
}
int main()
{
fct("data/point.xyz");
fct("data/segment.xyz");
fct("data/triangle.xyz");
fct("data/planar.xyz");
return 0;
}
@@ -0,0 +1,47 @@
#include <iostream>
#include <fstream>
#include <algorithm>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Advancing_front_surface_reconstruction.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/IO/Polyhedron_iostream.h>
typedef CGAL::Simple_cartesian<double> K;
typedef K::Point_3 Point_3;
typedef CGAL::Polyhedron_3<K> Polyhedron;
typedef CGAL::cpp11::array<std::size_t,3> Facet;
namespace std {
std::ostream&
operator<<(std::ostream& os, const Facet& f)
{
os << "3 " << f[0] << " " << f[1] << " " << f[2];
return os;
}
}
int main()
{
Polyhedron polyhedron;
std::ifstream in("data/planar.xyz");
std::vector<Point_3> points;
std::vector<Facet> facets;
std::copy(std::istream_iterator<Point_3>(in),
std::istream_iterator<Point_3>(),
std::back_inserter(points));
CGAL::advancing_front_surface_reconstruction(points.begin(),
points.end(),
polyhedron);
std::cout << polyhedron << std::endl;
return 0;
}
@@ -26,11 +26,21 @@
#include <boost/iterator/transform_iterator.hpp>
#include <CGAL/boost/graph/properties_Surface_mesh.h>
#include <CGAL/boost/graph/iterator.h>
// ATTN: <CGAL/boost/graph/iterator.h> is included at the end of this
// file, because we need to fix some calls in that file instead of
// using ADL on broken compilers, hence those calls need to declared
// before that.
#include <CGAL/Surface_mesh.h>
namespace CGAL {
template<typename Graph>
class In_edge_iterator;
template<typename Graph>
class Out_edge_iterator;
}
namespace boost {
@@ -532,8 +542,6 @@ bool is_valid(CGAL::Surface_mesh<P>& sm, bool verbose = false)
} // namespace CGAL
#include <CGAL/boost/graph/iterator.h>
#endif // CGAL_BOOST_GRAPH_TRAITS_SURFACE_MESH_H
+31 -11
View File
@@ -20,8 +20,6 @@
#ifndef CGAL_BGL_ITERATORS_H
#define CGAL_BGL_ITERATORS_H
#include <stdexcept>
#include <boost/graph/graph_traits.hpp>
#include <boost/iterator/iterator_adaptor.hpp>
@@ -181,6 +179,28 @@ struct Opposite_face {
return face(opposite(h,*g),*g);
}
};
// With gcc 4.4 and std=c++0x do not use ADL to find next/prev.
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=40497
template<typename A, typename Mesh>
A adl_next(A a, const Mesh& m) {
#if defined(__GXX_EXPERIMENTAL_CXX0X__) && __GNUC__ == 4 && __GNUC_MINOR__ == 4
return CGAL::next(a, m);
#else
return next(a, m);
#endif
}
template<typename A, typename Mesh>
A adl_prev(A a, const Mesh& m) {
#if defined(__GXX_EXPERIMENTAL_CXX0X__) && __GNUC__ == 4 && __GNUC_MINOR__ == 4
return CGAL::prev(a, m);
#else
return prev(a, m);
#endif
}
} // namespace internal
/// \endcond
@@ -258,7 +278,7 @@ public:
}
Self& operator++() {
pos = next(opposite(pos,*g),*g);
pos = internal::adl_next(opposite(pos,*g),*g);
if ( pos == anchor)
++winding;
return *this;
@@ -271,7 +291,7 @@ public:
Self& operator--() {
if ( pos == anchor)
--winding;
pos = opposite(prev(pos,*g),*g);
pos = opposite(internal::adl_prev(pos,*g),*g);
return *this;
}
Self operator--(int) {
@@ -358,7 +378,7 @@ public:
}
Self& operator++() {
pos = opposite(next(pos,*g),*g);
pos = opposite(internal::adl_next(pos,*g),*g);
if ( pos == anchor)
++winding;
return *this;
@@ -371,7 +391,7 @@ public:
Self& operator--() {
if ( pos == anchor)
--winding;
pos = prev(opposite(pos,*g),*g);
pos = internal::adl_prev(opposite(pos,*g),*g);
return *this;
}
Self operator--(int) {
@@ -464,7 +484,7 @@ public:
if ( pos == anchor)
--winding;
pos = prev(pos,*g);
pos = internal::adl_prev(pos,*g);
return *this;
}
@@ -684,7 +704,7 @@ public:
Self& operator++()
{
CGAL_assertion(g != NULL);
pos = opposite(next(pos,*g),*g);
pos = opposite(internal::adl_next(pos,*g),*g);
return *this;
}
@@ -699,7 +719,7 @@ public:
Self& operator--()
{
CGAL_assertion(g != NULL);
pos = prev(opposite(pos,*g),*g);
pos = internal::adl_prev(opposite(pos,*g),*g);
return *this;
}
@@ -779,7 +799,7 @@ public:
Self& operator++()
{
CGAL_assertion(g != NULL);
pos = next(pos,*g);
pos = internal::adl_next(pos,*g);
return *this;
}
@@ -794,7 +814,7 @@ public:
Self& operator--()
{
CGAL_assertion(g != NULL);
pos = prev(pos,*g);
pos = internal::adl_prev(pos,*g);
return *this;
}
@@ -22,7 +22,7 @@
#define CGAL_PROPERTIES_SURFACE_MESH_H
#include <CGAL/assertions.h>
#include <CGAL/Surface_mesh/Surface_mesh.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/Kernel_traits.h>
#include <CGAL/squared_distance_3.h>
+20
View File
@@ -388,6 +388,16 @@ note="Conference version: Symp. on Geometry Processing 2003"
year="2005"
}
@article{ cgal:csd-gdbsra-04
, author = "David Cohen-Steiner and Tran Kai Frank Da"
, title = "A greedy Delaunay-based surface reconstruction algorithm"
, journal = "The Visual Computer"
, volume = 20
, pages = "4--16"
, year = 2004
}
@inproceedings{ cgal:csm-rdtnc-03,
author="D. Cohen-Steiner and J.-M. Morvan",
title="Restricted {Delaunay} triangulations and normal cycle",
@@ -1275,6 +1285,16 @@ ABSTRACT = {We present the first complete, exact and efficient C++ implementatio
update = "09.11 penarand"
}
@article{cgal:ml-cfsg-00
, author = "G. Medioni and M. Lee and C. Tang"
, title = "A Computational Framework for Segmentation and Grouping"
, journal = "Elsevier Science
, year = 2000
, pages = ""
, update = "12.13 afabri"
}
@book{ cgal:m-cst-93
,author = {Robert B. Murray}
,title = "{C{\tt ++}} Strategies and Tactics"
@@ -33,6 +33,7 @@ ALIASES += "cgalReleaseNumber=${CGAL_CREATED_VERSION_NUM}"
# all image paths, maybe auto-generate this?
IMAGE_PATH = ${CMAKE_SOURCE_DIR}/Documentation/doc/Documentation/fig \
${CMAKE_SOURCE_DIR}/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/fig \
${CMAKE_SOURCE_DIR}/Algebraic_foundations/doc/Algebraic_foundations/fig \
${CMAKE_SOURCE_DIR}/AABB_tree/doc/AABB_tree/fig \
${CMAKE_SOURCE_DIR}/Polygon/doc/Polygon/fig \
@@ -1,4 +1,5 @@
Algebraic_foundations
Advancing_front_surface_reconstruction
AABB_tree
Polygon
Number_types
@@ -88,3 +89,4 @@ Barycentric_coordinates_2
Surface_mesh
Surface_mesh_shortest_path
@@ -94,6 +94,7 @@ h1 {
\package_listing{Surface_mesher}
\package_listing{Surface_reconstruction_points_3}
\package_listing{Scale_space_reconstruction_3}
\package_listing{Advancing_front_surface_reconstruction}
\package_listing{Skin_surface_3}
\package_listing{Mesh_3}
+14 -14
View File
@@ -21,18 +21,18 @@ git clone https://github.com/CGAL/cgal.git /path/to/cgal.git
cd /path/to/cgal.git
mkdir -p build/debug
cd build/debug
cmake -DBUILD_TYPE=Debug ../..
cmake -DCMAKE_BUILD_TYPE=Debug ../..
make
```
Here is an example of how to build the library in Release:
``` {.bash}
> git clone https://github.com/CGAL/cgal.git /path/to/cgal.git
> cd /path/to/cgal.git
> mkdir -p build/debug
> cd build/debug
> cmake -DBUILD_TYPE=Release ../..
> make
git clone https://github.com/CGAL/cgal.git /path/to/cgal.git
cd /path/to/cgal.git
mkdir -p build/release
cd build/release
cmake -DCMAKE_BUILD_TYPE=Release ../..
make
```
Note that *no installation is required* to use that version of CGAL once it has been compiled.
@@ -45,18 +45,18 @@ of where you built the library (environment or cmake variable).
Here is an example of how to build in debug the examples from the 3D Triangulations package:
``` {.bash}
> cmake -DCGAL_DIR:PATH=/path/to/cgal.git/build/debug /path/to/cgal.git/Triangulation_3/examples/Triangulation_3
> make
cmake -DCGAL_DIR:PATH=/path/to/cgal.git/build/debug /path/to/cgal.git/Triangulation_3/examples/Triangulation_3
make
```
If you're trying to build examples or tests that does not already have a `CMakeLists.txt`, you can trigger its creation by calling the script [`cgal_create_cmake_script`](Scripts/scripts/cgal_create_cmake_script) found in `/path/to/cgal.git/Scripts/scripts/` at the root of the example/test directory. Here is an example for the examples of the 2D Triangulation package:
``` {.bash}
> cd /path/to/cgal.git/Triangulation_2/examples/Triangulation_2
> /path/to/cgal.git/Scripts/scripts/cgal_create_cmake_script
> cd -
> cmake -DCGAL_DIR:PATH=/path/to/cgal.git/build/debug /path/to/cgal.git/Triangulation_2/examples/Triangulation_2
> make
cd /path/to/cgal.git/Triangulation_2/examples/Triangulation_2
/path/to/cgal.git/Scripts/scripts/cgal_create_cmake_script
cd -
cmake -DCGAL_DIR:PATH=/path/to/cgal.git/build/debug /path/to/cgal.git/Triangulation_2/examples/Triangulation_2
make
```
Note If You Switch Between Branches
+23
View File
@@ -119,6 +119,8 @@ and <code>src/</code> directories).
<!-- Installation (and general changes) -->
<!-- New packages -->
<!-- sdglinf-philaris begin-->
<h3>L Infinity Segment Delaunay Graphs (new pckage)</h3>
<ul>
<li>
@@ -128,6 +130,19 @@ and <code>src/</code> directories).
and traits under the Euclidean distance. The segment Voronoi diagram in the max-norm has applications in VLSI CAD.
</li>
</ul>
<!-- sdglinf-philaris end-->
<h3>Advancing Front Surface Reconstruction (new package)</h3>
<ul>
<li>
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.
</li>
</ul>
<h3>Triangulated Surface Mesh Shortest Paths (new package)</h3>
<ul>
<li>
@@ -150,6 +165,14 @@ and <code>src/</code> directories).
<!-- Arithmetic and Algebra -->
<!-- Combinatorial Algorithms -->
<!-- Geometry Kernels -->
<h3>dD Geometry Kernel</h3>
<ul>
<li>
Epick_d gains 3 new functors: <code>Construct_circumcenter_d</code>,
<code>Compute_squared_radius_d</code>, <code>Side_of_bounded_sphere_d</code>.
Those are essential for the computation of alpha-shapes.
</li>
</ul>
<!-- Convex Hull Algorithms -->
<!-- Polygons -->
<!-- Cell Complexes and Polyhedra -->
@@ -21,15 +21,19 @@ LC_CTYPE=en_US.UTF-8
# "master" alone
0 21 * * Sun cd $HOME/CGAL/create_internal_release && $HOME/bin/create_release $HOME/CGAL/branches/master.git --public --do-it
# "integration"
0 21 * * Mon,Tue,Wed,Fri,Sat cd $HOME/CGAL/create_internal_release && $HOME/bin/create_release $HOME/CGAL/branches/integration.git $HOME/CGAL/branches/empty-dir --do-it
0 21 * * Mon,Tue,Wed,Thu,Fri,Sat cd $HOME/CGAL/create_internal_release && $HOME/bin/create_release $HOME/CGAL/branches/integration.git $HOME/CGAL/branches/empty-dir --do-it
# from branch 4.6
0 21 * * Thu cd $HOME/CGAL/create_internal_release-4.6-branch && $HOME/bin/create_release $HOME/CGAL/branches/CGAL-4.6-branch.git --public --do-it
#0 21 * * Sat cd $HOME/CGAL/create_internal_release-4.6-branch && $HOME/bin/create_release $HOME/CGAL/branches/CGAL-4.6-branch.git --public --do-it
# from branch 4.5
#0 21 * * Sat cd $HOME/CGAL/create_internal_release-4.5-branch && $HOME/bin/create_release $HOME/CGAL/branches/CGAL-4.5-branch.git --public --do-it
# Try to launch the test suite, every 10mn, from 21:00 to 22:50
*/10 21-22 * * * setarch i686 $HOME/CGAL/Scripts/developer_scripts/autotest_cgal_with_cmake
# Launch our Docker testsuite, at 2:36 am
36 2 * * * cd /home/lrineau/Git/cgal-testsuite-dockerfiles && time ./test_cgal.py --use-fedora-selinux-policy --force-rm --max-cpus 10 --container-cpus 5 --jobs 6 --upload-results --images $(docker images | awk '/docker.io\/cgal\/testsuite-docker/ {print $1 ":" $2}')
# Dump the crontab to SVN every hour at minute 18
18 * * * * $HOME/bin/dump_crontab
@@ -25,6 +25,20 @@ export MPFR_LIB_DIR="C:\3rdPartyLibs\VC-${ARCH}\gmp-5.0.1_and_mpfr-3.0.0\lib"
#paths depending on the compiler and the architecture
export QGLVIEWERROOT="C:\3rdPartyLibs\VC${VC_VERSION}-${ARCH}\libQGLViewer-2.3.17"
export QTDIR="C:\3rdPartyLibs\VC${VC_VERSION}-${ARCH}\QT-4.8.4"
#export QTDIR="C:\3rdPartyLibs\VC${VC_VERSION}-${ARCH}\QT-5.4.1"
if [ -d /cygdrive/c/3rdPartyLibs/VC${VC_VERSION}-${ARCH}/QT-5.5.0 ]; then
export Qt5_DIR=`cygpath -w /cygdrive/c/3rdPartyLibs/VC${VC_VERSION}-${ARCH}/QT-5.5.0/*/msvc*/lib/cmake/Qt5`
if [ -d /cygdrive/c/3rdPartyLibs/VC${VC_VERSION}-${ARCH}/libQGLViewer-2.6.2 ]; then
export QGLVIEWERROOT="C:\3rdPartyLibs\VC${VC_VERSION}-${ARCH}\libQGLViewer-2.6.2"
fi
else
export Qt5_DIR=`cygpath -w /cygdrive/c/3rdPartyLibs/VC${VC_VERSION}-${ARCH}/QT-5*/*/msvc*/lib/cmake/Qt5`
fi
if [ -d /cygdrive/c/3rdPartyLibs/VC${VC_VERSION}-${ARCH}/libQGLViewer-2.6.2 ]; then
export QGLVIEWERROOT="C:\3rdPartyLibs\VC${VC_VERSION}-${ARCH}\libQGLViewer-2.6.2"
fi
export PATH="`cygpath $CGAL_DIR`/bin:`cygpath $GMP_LIB_DIR`:`cygpath $QTDIR`/bin:`cygpath $BOOST_LIBRARYDIR`:`cygpath $QGLVIEWERROOT`/QGLViewer/debug:`cygpath $QGLVIEWERROOT`/QGLViewer/release:/cygdrive/c/3rdPartyLibs/VC-${ARCH}/zlib":$PATH
@@ -35,3 +49,4 @@ if [ -n "${TBB_ARCH}" ]; then
export TBB_ARCH_PLATFORM="${TBB_ARCH}/vc${VC_VERSION}"
export PATH=$PATH:"${TBBROOT}\bin\\${TBB_ARCH}\vc${VC_VERSION}"
fi
@@ -27,7 +27,7 @@ Dt::Vertex_handle nearest_neighbor(const Dt& delau, Dt::Vertex_handle v);
namespace CGAL {
/*!
\ingroup PkgPointSet2NeighborSearch
\ingroup PkgPointSet2NeighborSearch
computes the `k` nearest neighbors of `p` in `delau`, and places the
handles to the corresponding vertices as a sequence of objects of type
+5 -1
View File
@@ -35,7 +35,7 @@ foreach(DEP_PKG AABB_tree STL_Extension GraphicsView Surface_mesher Filtered_ker
endforeach()
# Include this package's headers first
include_directories( BEFORE ./ ./include ../../include ./CGAL_demo)
include_directories( BEFORE ./ ./include ../../include ./CGAL_demo ../../../Advancing_front_surface_reconstruction/include)
add_subdirectory( implicit_functions )
@@ -362,6 +362,10 @@ if(CGAL_Qt4_FOUND AND QT4_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND)
polyhedron_demo_plugin(pca_plugin Polyhedron_demo_pca_plugin)
target_link_libraries(pca_plugin scene_polyhedron_item scene_basic_objects)
qt4_wrap_ui( advancing_frontUI_FILES Polyhedron_demo_advancing_front_plugin.ui)
polyhedron_demo_plugin(advancing_front_plugin Polyhedron_demo_advancing_front_plugin ${advancing_frontUI_FILES})
target_link_libraries(advancing_front_plugin scene_polygon_soup_item scene_points_with_normal_item)
if(EIGEN3_FOUND)
qt4_wrap_ui( scale_spaceUI_FILES Polyhedron_demo_scale_space_reconstruction_plugin.ui)
polyhedron_demo_plugin(scale_space_reconstruction_plugin Polyhedron_demo_scale_space_reconstruction_plugin ${scale_spaceUI_FILES})
@@ -0,0 +1,135 @@
#include "config.h"
#include "Scene_points_with_normal_item.h"
#include "Polyhedron_demo_plugin_helper.h"
#include "Polyhedron_demo_plugin_interface.h"
#include <Scene_polyhedron_item.h>
#include "Kernel_type.h"
#include "Polyhedron_type.h"
#include <CGAL/Advancing_front_surface_reconstruction.h>
#include <QObject>
#include <QAction>
#include <QMainWindow>
#include <QApplication>
#include <QtPlugin>
#include <QInputDialog>
#include "ui_Polyhedron_demo_advancing_front_plugin.h"
struct Perimeter {
double bound;
Perimeter(double bound)
: bound(bound)
{}
bool operator()(const Kernel::Point_3& p, const Kernel::Point_3& q, const Kernel::Point_3& r) const
{
if(bound == 0){
return false;
}
double d = sqrt(squared_distance(p,q));
if(d>bound) return true;
d += sqrt(squared_distance(p,r)) ;
if(d>bound) return true;
d+= sqrt(squared_distance(q,r));
return d>bound;
}
};
class Polyhedron_demo_advancing_front_plugin :
public QObject,
public Polyhedron_demo_plugin_helper
{
Q_OBJECT
Q_INTERFACES(Polyhedron_demo_plugin_interface)
QAction* actionAdvancingFrontReconstruction;
public:
void init(QMainWindow* mainWindow, Scene_interface* scene_interface) {
actionAdvancingFrontReconstruction = new QAction(tr("Advancing Front reconstruction"), mainWindow);
actionAdvancingFrontReconstruction->setObjectName("actionAdvancingFrontReconstruction");
Polyhedron_demo_plugin_helper::init(mainWindow, scene_interface);
}
//! Applicate for Point_sets with normals.
bool applicable(QAction*) const {
return qobject_cast<Scene_points_with_normal_item*>(scene->item(scene->mainSelectionIndex()));
}
QList<QAction*> actions() const {
return QList<QAction*>() << actionAdvancingFrontReconstruction;
}
public Q_SLOTS:
void on_actionAdvancingFrontReconstruction_triggered();
}; // end class Polyhedron_demo_advancing_front_plugin
class Polyhedron_demo_advancing_front_plugin_dialog : public QDialog, private Ui::AdvancingFrontDialog
{
Q_OBJECT
public:
Polyhedron_demo_advancing_front_plugin_dialog(QWidget* /*parent*/ = 0)
{
setupUi(this);
}
double trianglePerimeter() const { return m_inputPerimeter->value(); }
};
void Polyhedron_demo_advancing_front_plugin::on_actionAdvancingFrontReconstruction_triggered()
{
const Scene_interface::Item_id index = scene->mainSelectionIndex();
Scene_points_with_normal_item* point_set_item =
qobject_cast<Scene_points_with_normal_item*>(scene->item(index));
if(point_set_item)
{
// Gets point set
Point_set* points = point_set_item->point_set();
if(!points) return;
// Gets options
Polyhedron_demo_advancing_front_plugin_dialog dialog;
if(!dialog.exec())
return;
const double sm_perimeter = dialog.trianglePerimeter();
QApplication::setOverrideCursor(Qt::WaitCursor);
// Add polyhedron to scene
// Reconstruct point set as a polyhedron
Scene_polyhedron_item* new_item = new Scene_polyhedron_item(Polyhedron());
Polyhedron& P = * const_cast<Polyhedron*>(new_item->polyhedron());
Perimeter filter(sm_perimeter);
CGAL::advancing_front_surface_reconstruction((points)->begin(), points->end(), P, filter);
new_item->setName(tr("%1 Advancing Front (%2 %3)")
.arg(point_set_item->name())
.arg(sm_perimeter));
new_item->setColor(Qt::lightGray);
scene->addItem(new_item);
// Hide point set
point_set_item->setVisible(false);
scene->itemChanged(index);
QApplication::restoreOverrideCursor();
}
}
Q_EXPORT_PLUGIN2(Polyhedron_demo_advancing_front_plugin, Polyhedron_demo_advancing_front_plugin)
#include "Polyhedron_demo_advancing_front_plugin.moc"
@@ -0,0 +1,84 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>AdvancingFrontDialog</class>
<widget class="QDialog" name="AdvancingFrontDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>376</width>
<height>170</height>
</rect>
</property>
<property name="windowTitle">
<string>Advancing front reconstruction</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Max triangle perimeter:</string>
</property>
</widget>
</item>
<item row="0" column="1" colspan="2">
<widget class="QDoubleSpinBox" name="m_inputPerimeter">
<property name="suffix">
<string/>
</property>
<property name="minimum">
<double>0.000000000000000</double>
</property>
<property name="maximum">
<double>30.000000000000000</double>
</property>
<property name="value">
<double>0.000000000000000</double>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>AdvancingFrontDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>177</x>
<y>123</y>
</hint>
<hint type="destinationlabel">
<x>53</x>
<y>125</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>AdvancingFrontDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>257</x>
<y>119</y>
</hint>
<hint type="destinationlabel">
<x>257</x>
<y>143</y>
</hint>
</hints>
</connection>
</connections>
</ui>
@@ -0,0 +1,32 @@
#include "config.h"
#include "Scene_points_with_normal_item.h"
#include "Polyhedron_demo_plugin_helper.h"
#include "Polyhedron_demo_plugin_interface.h"
#include <Scene_polyhedron_item.h>
#include "Kernel_type.h"
#include "Polyhedron_type.h"
#include "Scene_points_with_normal_item.h"
#include <CGAL/Advancing_front_surface_reconstruction.h>
Polyhedron*
advancing_front_reconstruct(const Point_set& points,
double sm_perimeter,
double sm_area)
{
typedef CGAL::Advancing_front_surface_reconstruction<Kernel> Reconstruction;
typedef Reconstruction::Triangulation_3 Triangulation_3;
Polyhedron* output_mesh = new Polyhedron;
Triangulation_3 dt(points.begin(), points.end());
Reconstruction reconstruction(dt);
reconstruction();
CGAL::AFSR::construct_polyhedron(*output_mesh, reconstruction);
return output_mesh;
}
@@ -290,42 +290,42 @@ void Scene_points_with_normal_item::computes_local_spacing(int k)
QMenu* Scene_points_with_normal_item::contextMenu()
{
const char* prop_name = "Menu modified by Scene_points_with_normal_item.";
const char* prop_name = "Menu modified by Scene_points_with_normal_item.";
QMenu* menu = Scene_item::contextMenu();
QMenu* menu = Scene_item::contextMenu();
// Use dynamic properties:
// http://doc.trolltech.com/lastest/qobject.html#property
bool menuChanged = menu->property(prop_name).toBool();
// Use dynamic properties:
// http://doc.trolltech.com/lastest/qobject.html#property
bool menuChanged = menu->property(prop_name).toBool();
if(!menuChanged) {
actionDeleteSelection = menu->addAction(tr("Delete Selection"));
actionDeleteSelection->setObjectName("actionDeleteSelection");
connect(actionDeleteSelection, SIGNAL(triggered()),this, SLOT(deleteSelection()));
if(!menuChanged) {
actionDeleteSelection = menu->addAction(tr("Delete Selection"));
actionDeleteSelection->setObjectName("actionDeleteSelection");
connect(actionDeleteSelection, SIGNAL(triggered()),this, SLOT(deleteSelection()));
actionResetSelection = menu->addAction(tr("Reset Selection"));
actionResetSelection->setObjectName("actionResetSelection");
connect(actionResetSelection, SIGNAL(triggered()),this, SLOT(resetSelection()));
actionResetSelection = menu->addAction(tr("Reset Selection"));
actionResetSelection->setObjectName("actionResetSelection");
connect(actionResetSelection, SIGNAL(triggered()),this, SLOT(resetSelection()));
actionSelectDuplicatedPoints = menu->addAction(tr("Select duplicated points"));
actionSelectDuplicatedPoints->setObjectName("actionSelectDuplicatedPoints");
connect(actionSelectDuplicatedPoints, SIGNAL(triggered()),this, SLOT(selectDuplicates()));
actionSelectDuplicatedPoints = menu->addAction(tr("Select duplicated points"));
actionSelectDuplicatedPoints->setObjectName("actionSelectDuplicatedPoints");
connect(actionSelectDuplicatedPoints, SIGNAL(triggered()),this, SLOT(selectDuplicates()));
menu->setProperty(prop_name, true);
}
menu->setProperty(prop_name, true);
}
if (isSelectionEmpty())
{
actionDeleteSelection->setDisabled(true);
actionResetSelection->setDisabled(true);
}
else
{
actionDeleteSelection->setDisabled(false);
actionResetSelection->setDisabled(false);
}
if (isSelectionEmpty())
{
actionDeleteSelection->setDisabled(true);
actionResetSelection->setDisabled(true);
}
else
{
actionDeleteSelection->setDisabled(false);
actionResetSelection->setDisabled(false);
}
return menu;
return menu;
}
void Scene_points_with_normal_item::setRenderingMode(RenderingMode m)
@@ -326,16 +326,17 @@ Scene_polygon_soup_item::bbox() const {
void
Scene_polygon_soup_item::new_vertex(const double& x,
const double& y,
const double& z)
const double& y,
const double& z)
{
soup->points.push_back(Point_3(x, y, z));
soup->points.push_back(Point_3(x, y, z));
}
void
Scene_polygon_soup_item::new_triangle(const std::size_t i,
const std::size_t j,
const std::size_t k)
const std::size_t j,
const std::size_t k)
{
Polygon_soup::Polygon_3 new_polygon(3);
new_polygon[0] = i;
@@ -165,6 +165,7 @@ else
p_sphere_function_plugin \
p_tanglecube_function_plugin \
shortest_path_plugin \
advancing_front_plugin \
all
do
if ${MAKE_CMD} -f Makefile help | grep "$target" > /dev/null; then
+2 -2
View File
@@ -19,8 +19,8 @@
#ifndef CGAL_TOP_LEVEL_SURFACE_MESH_H
#define CGAL_TOP_LEVEL_SURFACE_MESH_H
#include "CGAL/Surface_mesh/Surface_mesh_fwd.h"
#include "CGAL/Surface_mesh/Surface_mesh.h"
#include <CGAL/Surface_mesh/Surface_mesh_fwd.h>
#include <CGAL/Surface_mesh/Surface_mesh.h>
#ifdef DOXYGEN_RUNNING
namespace CGAL {
@@ -31,10 +31,6 @@
#include <boost/cstdint.hpp>
#include <boost/array.hpp>
#include <boost/iterator/iterator_facade.hpp>
#include <boost/fusion/container/map.hpp>
#include <boost/fusion/include/map.hpp>
#include <boost/fusion/include/at_key.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/foreach.hpp>
#include <boost/property_map/property_map.hpp>
@@ -2089,16 +2085,40 @@ public:
private: //--------------------------------------------------- property handling
/// @cond BROKEN_DOC
typedef boost::fusion::map<
boost::fusion::pair< typename Surface_mesh::Vertex_index, Property_container<Vertex_index> (Surface_mesh::*)>,
boost::fusion::pair< typename Surface_mesh::Halfedge_index, Property_container<Halfedge_index> (Surface_mesh::*)>,
boost::fusion::pair< typename Surface_mesh::Edge_index, Property_container<Edge_index> (Surface_mesh::*)>,
boost::fusion::pair< typename Surface_mesh::Face_index, Property_container<Face_index> (Surface_mesh::*)> >
map_type;
// Property_selector maps an index type to a property_container, the
// dummy is necessary to make it a partial specialization (full
// specializations are only allowed at namespace scope).
template<typename, bool = true>
struct Property_selector {};
map_type pmap_;
/// @endcond
template<bool dummy>
struct Property_selector<typename CGAL::Surface_mesh<P>::Vertex_index, dummy> {
CGAL::Surface_mesh<P>* m_;
Property_selector(CGAL::Surface_mesh<P>* m) : m_(m) {}
Property_container<typename CGAL::Surface_mesh<P>::Vertex_index>&
operator()() { return m_->vprops_; }
};
template<bool dummy>
struct Property_selector<typename CGAL::Surface_mesh<P>::Halfedge_index, dummy> {
CGAL::Surface_mesh<P>* m_;
Property_selector(CGAL::Surface_mesh<P>* m) : m_(m) {}
Property_container<typename CGAL::Surface_mesh<P>::Halfedge_index>&
operator()() { return m_->hprops_; }
};
template<bool dummy>
struct Property_selector<typename CGAL::Surface_mesh<P>::Edge_index, dummy> {
CGAL::Surface_mesh<P>* m_;
Property_selector(CGAL::Surface_mesh<P>* m) : m_(m) {}
Property_container<typename CGAL::Surface_mesh<P>::Edge_index>&
operator()() { return m_->eprops_; }
};
template<bool dummy>
struct Property_selector<typename CGAL::Surface_mesh<P>::Face_index, dummy> {
CGAL::Surface_mesh<P>* m_;
Property_selector(CGAL::Surface_mesh<P>* m) : m_(m) {}
Property_container<typename CGAL::Surface_mesh<P>::Face_index>&
operator()() { return m_->fprops_; }
};
public:
@@ -2130,9 +2150,9 @@ private: //--------------------------------------------------- property handling
template<class I, class T>
std::pair<Property_map<I, T>, bool>
std::pair<Property_map<I, T>, bool>
add_property_map(const std::string& name, const T t=T()) {
return (this->*boost::fusion::at_key<I>(pmap_)).template add<T>(name, t);
return Property_selector<I>(this)().template add<T>(name, t);
}
@@ -2143,7 +2163,7 @@ private: //--------------------------------------------------- property handling
template <class I, class T>
std::pair<Property_map<I, T>,bool> property_map(const std::string& name) const
{
return (this->*boost::fusion::at_key<I>(pmap_)).template get<T>(name);
return Property_selector<I>(const_cast<Surface_mesh*>(this))().template get<T>(name);
}
@@ -2152,7 +2172,7 @@ private: //--------------------------------------------------- property handling
template<class I, class T>
void remove_property_map(Property_map<I, T>& p)
{
(this->*boost::fusion::at_key<I>(pmap_)).remove(p);
(Property_selector<I>(this)()).remove(p);
}
/// @cond CGAL_DOCUMENT_INTERNALS
@@ -2165,16 +2185,16 @@ private: //--------------------------------------------------- property handling
template<class I>
const std::type_info& property_type(const std::string& name)
{
return (this->*boost::fusion::at_key<I>(pmap_)).get_type(name);
return Property_selector<I>(this)().get_type(name);
}
/// @endcond
/// @endcond
/// returns a vector with all strings that describe properties with the key type `I`.
/// @tparam I The key type of the properties.
template<class I>
std::vector<std::string> properties() const
{
return (this->*boost::fusion::at_key<I>(pmap_)).properties();
return Property_selector<I>(this)().properties();
}
/// returns the property for the string "v:point".
@@ -2365,10 +2385,6 @@ private: //------------------------------------------------------- private data
template <typename P>
Surface_mesh<P>::
Surface_mesh()
: pmap_(boost::fusion::make_pair< typename Surface_mesh::Vertex_index >(&Surface_mesh::vprops_)
, boost::fusion::make_pair< typename Surface_mesh::Halfedge_index >(&Surface_mesh::hprops_)
, boost::fusion::make_pair< typename Surface_mesh::Edge_index >(&Surface_mesh::eprops_)
, boost::fusion::make_pair< typename Surface_mesh::Face_index >(&Surface_mesh::fprops_))
{
// allocate standard properties
// same list is used in operator=() and assign()
@@ -2394,8 +2410,6 @@ operator=(const Surface_mesh<P>& rhs)
{
if (this != &rhs)
{
pmap_ = rhs.pmap_;
// deep copy of property containers
vprops_ = rhs.vprops_;
hprops_ = rhs.hprops_;
@@ -18,8 +18,6 @@
#ifndef CGAL_SURFACE_MESH_FWD_H
#define CGAL_SURFACE_MESH_FWD_H
#include <string>
/// \file Surface_mesh_fwd.h
/// Forward declarations of the Surface_mesh package.
@@ -312,7 +312,9 @@ public:
Face_handle f1,
Face_handle f2,
Face_handle f3);
void set_adjacency(Face_handle f0, int i0, Face_handle f1, int i1) const;
void delete_face(Face_handle);
void delete_vertex(Vertex_handle);
@@ -353,10 +355,12 @@ public:
// HELPING
private:
typedef std::pair<Vertex_handle,Vertex_handle> Vh_pair;
public:
void set_adjacency(Face_handle fh,
int ih,
std::map< Vh_pair, Edge>& edge_map);
void reorient_faces();
private:
bool dim_down_precondition(Face_handle f, int i);
public:
@@ -2270,24 +2274,24 @@ reorient_faces()
std::set<Face_handle> oriented_set;
std::stack<Face_handle> st;
Face_iterator fit = faces_begin();
int nf = std::distance(faces_begin(),faces_end());
std::ptrdiff_t nf = std::distance(faces_begin(),faces_end());
while (static_cast<int>(oriented_set.size()) != nf) {
while ( oriented_set.find(fit) != oriented_set.end()){
while (0 != nf) {
while ( !oriented_set.insert(fit).second ){
++fit; // find a germ for non oriented components
}
// orient component
oriented_set.insert(fit);
--nf;
st.push(fit);
while ( ! st.empty()) {
Face_handle fh = st.top();
st.pop();
for(int ih = 0 ; ih < 3 ; ++ih){
Face_handle fn = fh->neighbor(ih);
if (oriented_set.find(fn) == oriented_set.end()){
if (oriented_set.insert(fn).second){
int in = fn->index(fh);
if (fn->vertex(cw(in)) != fh->vertex(ccw(ih))) fn->reorient();
oriented_set.insert(fn);
--nf;
st.push(fn);
}
}
@@ -48,6 +48,12 @@ The type for weighted points.
typedef Weighted_point <Bare_point, Weight>
Weighted_point_3;
/*!
The type for points.
*/
typedef Weighted_point <Bare_point, Weight>
Point_3;
/// @}
/// \name Types for Predicate Functors