mirror of https://github.com/CGAL/cgal
Merge branch 'Advancing_front_surface_reconstruction-afabri-old' into Advancing_front_surface_reconstruction-afabri
This commit is contained in:
commit
4e9eefd891
|
|
@ -0,0 +1,260 @@
|
|||
|
||||
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 by selecting the triangles sequentially, that
|
||||
is by using previous selected triangles to select a new triangle for
|
||||
advancing the front. At each advancing step the most plausible
|
||||
triangle is selected, and the triangles are selected in a way that
|
||||
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 Delaunay triangle with the
|
||||
smallest radius is the starting point for the greedy algorithm. 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 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 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.
|
||||
|
||||
|
||||
We denote by \f$ \beta_t\f$ the angle between the normal of a triangle
|
||||
\f$ t\f$ incident on a boundary edge \f$ e \f$ and the normal of the
|
||||
triangle on the surface incident to \f$ e \f$.
|
||||
|
||||
The *candidate* triangle of an edge \f$ e \f$ is the triangle
|
||||
with the smallest radius, that is valid for \f$ e \f$
|
||||
and that has \f$ \beta_t < \alpha_\mathrm{sliver} \f$.
|
||||
There may be no such triangle. In the implementation
|
||||
of the algorithm \f$ \alpha_\mathrm{sliver} = 5\pi/6 \f$.
|
||||
|
||||
|
||||
We define the *plausibility* grade \f$ p(t) \f$ as \f$ 1/r_t \f$, if
|
||||
\f$ \beta_t < \beta \f$, and \f$ -\beta_t \f$ else. The parameter \f$
|
||||
\beta \f$ can be 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 Example for Global Function
|
||||
|
||||
The global function `advancing_front_surface_reconstruction()`
|
||||
takes an iterator range of points as input and writes for each face of the
|
||||
reconstructed surface a 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}
|
||||
|
||||
|
||||
\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,246 @@
|
|||
|
||||
namespace CGAL {
|
||||
|
||||
/*!
|
||||
\ingroup PkgAdvancingFrontSurfaceReconstruction
|
||||
|
||||
The class `Advancing_front_surface_reconstruction` enables advanced users to provide the unstructured
|
||||
point cloud in a 3D Delaunay triangulation. The reconstruction algorithm then marks vertices and faces
|
||||
in the triangulation as being on the 2D surface embedded in 3D space, and constructs a 2D triangulation
|
||||
data structure that describes the surface. The vertices and facets of the 2D triangulation data structure
|
||||
store handles to the vertices and faces of the 3D triangulation, which enables the user to explore the
|
||||
2D as well as 3D neighborhood of vertices and facets of the surface.
|
||||
|
||||
\tparam Gt must be a model of `Kernel`.
|
||||
\tparam Dt must be a `Delaunay_triangulation_3` with
|
||||
`Advancing_front_surface_reconstruction_vertex_base_3` and `Advancing_front_surface_reconstruction_cell_base_3` blended into the vertex and cell type, and the geometric traits class must be the `Exact_predicates_inexact_constructions_kernel`.
|
||||
|
||||
\tparam Filter must be a functor with `bool operator()(Gt::Point_3,Gt::Point_3,Gt::Point_3)` that allows the user to filter candidate triangles, for example based on its size.
|
||||
It defaults to a functor that always returns `false`.
|
||||
|
||||
*/
|
||||
|
||||
template< typename Gt, typename Dt, typename Filter>
|
||||
class Advancing_front_surface_reconstruction {
|
||||
public:
|
||||
|
||||
/// \name Types
|
||||
/// @{
|
||||
|
||||
/*!
|
||||
The type of the 2D triangulation data structure describing the reconstructed surface.
|
||||
The type `Triangulation_data_structure_2::Vertex` is model of the concept `TriangulationDataStructure_2::Vertex` and has additionally the
|
||||
method `vertex_3()` that returns a `Vertex_handle` to the associated 3D vertex.
|
||||
The type `Triangulation_data_structure_2::Face` is model of the concept `TriangulationDataStructure_2::Face` and has additionally the
|
||||
method `facet()` that returns the associated `Facet`, and a method `bool is_on_surface()`
|
||||
for testing if a face is part of the reconstructed surface or a face incident to a boundary edge.
|
||||
In case the surface has boundaries, the 2D surface has one vertex which is associated to the infinite
|
||||
vertex of the 3D triangulation.
|
||||
*/
|
||||
typedef unspecified_type Triangulation_data_structure_2;
|
||||
|
||||
|
||||
/*!
|
||||
The type of the 3D triangulation.
|
||||
|
||||
*/
|
||||
typedef Dt Triangulation_3;
|
||||
|
||||
/*!
|
||||
The point type.
|
||||
|
||||
*/
|
||||
typedef typename Triangulation_3::Point Point;
|
||||
/*!
|
||||
The vertex handle type of the 3D triangulation.
|
||||
|
||||
*/
|
||||
typedef typename Triangulation_3::Vertex_handle Vertex_handle;
|
||||
|
||||
/*!
|
||||
The cell handle type of the 3D triangulation.
|
||||
|
||||
*/
|
||||
typedef typename Triangulation_3::Cell_handle Cell_handle;
|
||||
|
||||
/*!
|
||||
The facet type of the 3D triangulation.
|
||||
|
||||
*/
|
||||
typedef typename Triangulation_3::Facet Facet;
|
||||
|
||||
|
||||
/*!
|
||||
A bidirectional iterator range which enables to enumerate all points that were removed
|
||||
from the 3D Delaunay triangulation during the surface reconstruction. The value type
|
||||
of the iterator is `Point`.
|
||||
*/
|
||||
typedef unspecified_type Outlier_range;
|
||||
|
||||
#if 0
|
||||
/*!
|
||||
A forward iterator which enables to visit all boundaries. It
|
||||
visits the entry point of each boundary twice. This allows to
|
||||
detect that the traversal of a boundary is finished. One more increment
|
||||
brings us to the vertex on the next boundary.
|
||||
The value type of the iterator is `Vertex_handle`.
|
||||
*/
|
||||
|
||||
#endif
|
||||
/*!
|
||||
A bidirectional iterator range which enables to visit all boundaries.
|
||||
The value type of the iterator is `Vertex_on_boundary_range`.
|
||||
*/
|
||||
typedef unspecified_type Boundary_range;
|
||||
|
||||
/*!
|
||||
A bidirectional iterator range which enables to visit all vertices on a boundary.
|
||||
The value type of the iterator is `Vertex_handle`
|
||||
*/
|
||||
typedef unspecified_type Vertex_on_boundary_range;
|
||||
|
||||
|
||||
/// @}
|
||||
|
||||
/// \name Creation
|
||||
/// @{
|
||||
|
||||
/*!
|
||||
Constructor for the unstructured point cloud given as 3D Delaunay triangulation.
|
||||
*/
|
||||
Advancing_front_surface_reconstruction(Dt& dt);
|
||||
|
||||
|
||||
/// @}
|
||||
|
||||
/// \name Operations
|
||||
/// @{
|
||||
|
||||
/*!
|
||||
runs the surface reconstruction function.
|
||||
|
||||
\param radius_ratio_bound candidates incident to surface triangles which are not in the beta-wedge
|
||||
are discarded, if the ratio of their radius and the radius of the surface triangle is larger than `radius_ratio_bound`.
|
||||
Described in Section \ref AFSR_Boundaries
|
||||
\param beta half the angle of the wedge in which only the radius of triangles counts for the plausibility of candidates.
|
||||
Described in Section \ref AFSR_Selection
|
||||
|
||||
*/
|
||||
void run(double radius_ratio_bound =5 , double beta = 0.52);
|
||||
|
||||
/*!
|
||||
returns the reconstructed surface.
|
||||
*/
|
||||
const Triangulation_data_structure_2&
|
||||
triangulation_data_structure_2() const;
|
||||
|
||||
/*!
|
||||
returns the underlying 3D Delaunay triangulation.
|
||||
*/
|
||||
const Triangulation_3&
|
||||
triangulation_3();
|
||||
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
returns an iterator range over the outliers.
|
||||
*/
|
||||
Outlier_range outliers();
|
||||
|
||||
|
||||
/*!
|
||||
returns an iterator range over the boundaries.
|
||||
*/
|
||||
Boundary_range boundaries();
|
||||
|
||||
|
||||
/// @}
|
||||
|
||||
/// \name Predicates
|
||||
/// @{
|
||||
|
||||
/*!
|
||||
returns `true` if the reconstructed surface has boundaries.
|
||||
*/
|
||||
bool
|
||||
has_boundaries() const;
|
||||
|
||||
|
||||
/*!
|
||||
returns `true` if the facet is on the surface.
|
||||
*/
|
||||
bool
|
||||
has_on_surface(Facet f) const;
|
||||
|
||||
/*!
|
||||
returns `true` if the facet `f2` is on the surface.
|
||||
*/
|
||||
bool
|
||||
has_on_surface(Triangulation_data_structure_2::Face_handle f2) const;
|
||||
|
||||
/*!
|
||||
returns `true` if the vertex `v2` is on the surface.
|
||||
*/
|
||||
bool
|
||||
has_on_surface(Triangulation_data_structure_2::Vertex_handle v2) const;
|
||||
/// @}
|
||||
|
||||
|
||||
|
||||
|
||||
}; /* end Advancing_front_surface_reconstruction */
|
||||
|
||||
|
||||
/*!
|
||||
\ingroup PkgAdvancingFrontSurfaceReconstruction
|
||||
|
||||
For a sequence of points computes a sequence of index triples
|
||||
describing the faces of the reconstructed surface.
|
||||
|
||||
\tparam PointInputIterator must be an input iterator with 3D points from the `Exact_predicates_inexact_constructions_kernel` as value type.
|
||||
\tparam IndicesOutputIterator must be an output iterator to which
|
||||
`CGAL::cpp11::tuple<std::size_t,std::size_t,std::size_t>` can be assigned.
|
||||
|
||||
\param b iterator on the first point of the sequence
|
||||
\param e past the end iterator of the point sequence
|
||||
\param out output iterator
|
||||
\param radius_ratio_bound candidates incident to surface triangles which are not in the beta-wedge
|
||||
are discarded, if the ratio of their radius and the radius of the surface triangle is larger than `radius_ratio_bound`.
|
||||
Described in Section \ref AFSR_Boundaries
|
||||
\param beta half the angle of the wedge in which only the radius of triangles counts for the plausibility of candidates.
|
||||
Described in Section \ref AFSR_Selection
|
||||
|
||||
*/
|
||||
template <class PointInputIterator, IndicesOutputIterator>
|
||||
IndicesOutputIterator advancing_front_surface_reconstruction(PointInputIterator b, PointInputIterator e, IndicesOutputIterator out, double radius_ratio_bound = 5, double beta= 0.52 );
|
||||
|
||||
|
||||
/*!
|
||||
\ingroup PkgAdvancingFrontSurfaceReconstruction
|
||||
|
||||
For a sequence of points computes a sequence of index triples
|
||||
describing the faces of the reconstructed surface.
|
||||
|
||||
\tparam PointInputIterator must be an input iterator with 3D points from the `Exact_predicates_inexact_constructions_kernel` as value type.
|
||||
\tparam IndicesOutputIterator must be an output iterator to which
|
||||
`CGAL::cpp11::tuple<std::size_t,std::size_t,std::size_t>` can be assigned.
|
||||
\tparam Filter must be a functor with `bool operator()(Gt::Point_3,Gt::Point_3,Gt::Point_3)`.
|
||||
|
||||
\param b iterator on the first point of the sequence
|
||||
\param e past the end iterator of the point sequence
|
||||
\param out output iterator
|
||||
\param radius_ratio_bound candidates incident to surface triangles which are not in the beta-wedge
|
||||
are discarded, if the ratio of their radius and the radius of the surface triangle is larger than `radius_ratio_bound`.
|
||||
Described in Section \ref AFSR_Boundaries
|
||||
\param beta half the angle of the wedge in which only the radius of triangles counts for the plausibility of candidates.
|
||||
Described in Section \ref AFSR_Selection
|
||||
\param filter allows the user to filter candidate triangles, for example based on their size.
|
||||
|
||||
*/
|
||||
template <class PointInputIterator, IndicesOutputIterator, class Filter>
|
||||
IndicesOutputIterator advancing_front_surface_reconstruction(PointInputIterator b, PointInputIterator e, IndicesOutputIterator out, Filter filter, double radius_ratio_bound = 5, double beta= 0.52 );
|
||||
|
||||
|
||||
|
||||
} /* end namespace CGAL */
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
|
||||
namespace CGAL {
|
||||
|
||||
/*!
|
||||
\ingroup PkgAdvancingFrontSurfaceReconstruction
|
||||
|
||||
The class `Advancing_front_surface_reconstruction_cell_base_3` is the default
|
||||
cell type for the class `Advancing_front_surface_reconstruction`.
|
||||
|
||||
\tparam Traits has to be a model of `DelaunayTriangulationTraits_3`.
|
||||
|
||||
\tparam Cb has to be a model of `TriangulationCellBase_3`.
|
||||
|
||||
*/
|
||||
template< typename Traits, typename Cb = Triangulation_cell_base_3<Traits> >
|
||||
class Advancing_front_surface_reconstruction_cell_base_3 : public Cb {
|
||||
public:
|
||||
|
||||
/// @}
|
||||
|
||||
}; /* end Advancing_front_surface_reconstruction_cell_base_3 */
|
||||
} /* end namespace CGAL */
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
|
||||
namespace CGAL {
|
||||
|
||||
/*!
|
||||
\ingroup PkgAdvancingFrontSurfaceReconstruction
|
||||
|
||||
The class `Advancing_front_surface_reconstruction_vertex_base_3` is the default
|
||||
vertex type for the class `Advancing_front_surface_reconstruction`.
|
||||
|
||||
\tparam Traits has to be a model of `DelaunayTriangulationTraits_3`.
|
||||
|
||||
\tparam Vb has to be a model of `TriangulationVertexBase_3`.
|
||||
|
||||
|
||||
*/
|
||||
template< typename Traits, typename Vb = Triangulation_vertex_base_3<Traits> >
|
||||
class Advancing_front_surface_reconstruction_vertex_base_3 : public Vb {
|
||||
public:
|
||||
|
||||
/// @}
|
||||
|
||||
}; /* end Advancing_front_surface_reconstruction_vertex_base_3 */
|
||||
} /* end namespace CGAL */
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
@INCLUDE = ${CGAL_DOC_PACKAGE_DEFAULTS}
|
||||
|
||||
PROJECT_NAME = "CGAL ${CGAL_CREATED_VERSION_NUM} - Advancing Front Surface Reconstruction"
|
||||
|
||||
|
||||
INPUT = ${CMAKE_SOURCE_DIR}/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/
|
||||
|
||||
|
||||
|
||||
MULTILINE_CPP_IS_BRIEF = YES
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
/// \defgroup PkgAdvancingFrontSurfaceReconstruction Advancing Front Surface Reconstruction Reference
|
||||
|
||||
/*!
|
||||
\addtogroup PkgAdvancingFrontSurfaceReconstruction
|
||||
|
||||
\cgalPkgDescriptionBegin{Advancing Front Surface Reconstruction,PkgAdvancingFrontSurfaceReconstructionSummary}
|
||||
\cgalPkgPicture{afsr-detail.png}
|
||||
\cgalPkgSummaryBegin
|
||||
\cgalPkgAuthors{Tran Kai Frank Da, David Cohen-Steiner}
|
||||
\cgalPkgDesc{This package provides a greedy algorithm for surface reconstruction from an
|
||||
unorganized point set. Starting from a seed facet, a piecewise linear
|
||||
surface is grown by adding Delaunay triangles one by one. The most
|
||||
plausible triangles are added first, in a way that avoids the appearance
|
||||
of topological singularities. }
|
||||
\cgalPkgManuals{Chapter_Advancing_Front_Surface_Reconstruction,PkgAdvancingFrontSurfaceReconstruction}
|
||||
\cgalPkgSummaryEnd
|
||||
\cgalPkgShortInfoBegin
|
||||
\cgalPkgSince{4.7}
|
||||
\cgalPkgDependsOn{\ref PkgTriangulation3Summary}
|
||||
\cgalPkgBib{cgal:dc-afsr}
|
||||
\cgalPkgLicense{\ref licensesGPL "GPL"}
|
||||
\cgalPkgShortInfoEnd
|
||||
\cgalPkgDescriptionEnd
|
||||
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
Manual
|
||||
Kernel_23
|
||||
STL_Extension
|
||||
Algebraic_foundations
|
||||
Circulator
|
||||
Stream_support
|
||||
Triangulation_2
|
||||
Triangulation_3
|
||||
Number_types
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
/*!
|
||||
\example Advancing_front_surface_reconstruction/reconstruction_fct.cpp
|
||||
\example Advancing_front_surface_reconstruction/reconstruction_class.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,37 @@
|
|||
# Created by the script cgal_create_cmake_script
|
||||
# This is the CMake script for compiling a CGAL application.
|
||||
|
||||
|
||||
project( Advancing_front_surface_reconstruction_example )
|
||||
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.4.5)
|
||||
|
||||
set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true)
|
||||
|
||||
if ( COMMAND cmake_policy )
|
||||
cmake_policy( SET CMP0003 NEW )
|
||||
endif()
|
||||
|
||||
find_package(CGAL QUIET COMPONENTS Core )
|
||||
|
||||
if ( CGAL_FOUND )
|
||||
|
||||
include( ${CGAL_USE_FILE} )
|
||||
|
||||
include( CGAL_CreateSingleSourceCGALProgram )
|
||||
|
||||
include_directories (BEFORE ../../include)
|
||||
# include_directories (BEFORE ../../../../../trunk/Triangulation_2/include)
|
||||
|
||||
create_single_source_cgal_program( "extract.cpp" )
|
||||
create_single_source_cgal_program( "reconstruction_fct.cpp" )
|
||||
create_single_source_cgal_program( "reconstruction_class.cpp" )
|
||||
create_single_source_cgal_program( "reconstruction_polyhedron.cpp" )
|
||||
create_single_source_cgal_program( "boundaries.cpp" )
|
||||
|
||||
else()
|
||||
|
||||
message(STATUS "This program requires the CGAL library, and will not be compiled.")
|
||||
|
||||
endif()
|
||||
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/Advancing_front_surface_reconstruction.h>
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
|
||||
typedef CGAL::Advancing_front_surface_reconstruction<K> 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;
|
||||
|
||||
Triangulation_3 dt(begin, end);
|
||||
Reconstruction reconstruction(dt);
|
||||
|
||||
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,464 @@
|
|||
#define NOLAZY
|
||||
#define BLIND
|
||||
|
||||
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/iterator/transform_iterator.hpp>
|
||||
|
||||
// Kernel
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/Triangulation_data_structure_3.h>
|
||||
#include <CGAL/Delaunay_triangulation_3.h>
|
||||
|
||||
#include <CGAL/Advancing_front_surface_reconstruction.h>
|
||||
#include <CGAL/AFSR_options.h>
|
||||
#include <CGAL/AFSR/write_triple_indices.h>
|
||||
#include <CGAL/IO/Advancing_front_surface_reconstruction.h>
|
||||
|
||||
#include <CGAL/Timer.h>
|
||||
|
||||
|
||||
|
||||
|
||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
|
||||
|
||||
typedef Kernel::Point_3 Point;
|
||||
|
||||
typedef CGAL::Advancing_front_surface_reconstruction_vertex_base_3<Kernel> LVb;
|
||||
typedef CGAL::Advancing_front_surface_reconstruction_cell_base_3<Kernel> LCb;
|
||||
|
||||
typedef CGAL::Triangulation_data_structure_3<LVb,LCb> Tds;
|
||||
typedef CGAL::Delaunay_triangulation_3<Kernel,Tds> Triangulation_3;
|
||||
|
||||
typedef Triangulation_3::Vertex_handle Vertex_handle;
|
||||
|
||||
typedef CGAL::Advancing_front_surface_reconstruction<Kernel,Triangulation_3> Surface;
|
||||
typedef CGAL::AFSR_options Options;
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
struct Auto_count : public std::unary_function<const Point&,std::pair<Point,int> >{
|
||||
mutable int i;
|
||||
Auto_count() : i(0){}
|
||||
std::pair<Point,int> operator()(const Point& p) const {
|
||||
return std::make_pair(p,i++);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
bool
|
||||
file_input(const Options& opt, std::vector<Point>& points)
|
||||
{
|
||||
const char* finput = opt.finname;
|
||||
bool xyz = opt.xyz;
|
||||
|
||||
std::ios::openmode mode = (opt.binary) ? std::ios::binary : std::ios::in;
|
||||
std::ifstream is(finput, mode);
|
||||
|
||||
if(opt.binary){
|
||||
CGAL::set_binary_mode(is);
|
||||
}
|
||||
if(is.fail())
|
||||
{
|
||||
std::cerr << "+++unable to open file for input" << std::endl;
|
||||
exit(0);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
std::cerr << "Input from file : " << finput << std::endl;
|
||||
|
||||
std::size_t n;
|
||||
if(! xyz){
|
||||
is >> n;
|
||||
std::cerr << " reading " << n << " points" << std::endl;
|
||||
points.reserve(n);
|
||||
CGAL::cpp11::copy_n(std::istream_iterator<Point>(is), n, std::back_inserter(points));
|
||||
} else {
|
||||
// we do not know beforehand how many points we will read
|
||||
std::istream_iterator<Point> it(is), eof;
|
||||
char ignore[256];
|
||||
while(it!= eof){
|
||||
points.push_back(*it);
|
||||
is.getline(ignore,256); // ignore what comes after 3 doubles in a line
|
||||
it++;
|
||||
}
|
||||
n = points.size();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void usage(char* program)
|
||||
{
|
||||
std::cerr << std::endl << "NAME " << std::endl
|
||||
<< program << " - surface extension -" << std::endl << std::endl;
|
||||
|
||||
std::cerr << std::endl << "OPTIONS" << std::endl
|
||||
<< " -xyz : input data in xyz format" << std::endl
|
||||
<< " -no_border -nb : " << std::endl
|
||||
<< " -in fname : reads points from file fname" << std::endl
|
||||
<< " -out fname : writes points to file fname" << std::endl
|
||||
<< " -out_format -of : choose file format for output (iv, wrl, off, medit," << std::endl
|
||||
<< " ply, stl, all, none)" << std::endl
|
||||
<< " -rgb r g b : color of the surface" << std::endl
|
||||
<< " -no_header : The Vrml header and footer are not written" << std::endl
|
||||
<< " -area a : No faces larger than area * average_area" << std::endl
|
||||
<< " -perimeter p : No faces larger than perimeter * average_perimeter" << std::endl
|
||||
<< " -abs_area a : No faces larger than abs_area" << std::endl
|
||||
<< " -abs_perimeter p : No faces with perimeter longer than abs_perimeter" << std::endl
|
||||
<< "\n Options for internal use" << std::endl
|
||||
|
||||
<< " -binary : binary I/O" << std::endl
|
||||
<< " -delta x : set the delta constant" << std::endl
|
||||
<< " -ki x y : set the K interval (default : [1.1 5])" << std::endl
|
||||
<< " -ks x : set the K step (default : .1)" << std::endl
|
||||
<< " -k x : set the K constant (only one pass)" << std::endl
|
||||
<< " -Delaunay : display the underlying Delaunay triangulation" << std::endl
|
||||
<< " -max_of_connected_components x : set the max of connected components" << std::endl
|
||||
<< " (default : non-active)" << std::endl
|
||||
<< " -post x : set a number for the post process" << std::endl
|
||||
<< " -contours : display contours" << std::endl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
parse(int argc, char* argv[], Options &opt)
|
||||
{
|
||||
std::strcpy(opt.program, argv[0]);
|
||||
--argc;
|
||||
argv++;
|
||||
if(argc == 0)
|
||||
std::cerr << "nothing ???" << std::endl;
|
||||
|
||||
while ((argc > 0) && (argv[0][0] == '-')){
|
||||
if ((!std::strcmp(argv[0], "-D")) || (!std::strcmp(argv[0], "-Delaunay"))) {
|
||||
opt.Delaunay = true;
|
||||
argv++;
|
||||
argc--;
|
||||
std::cerr << "-D ";
|
||||
}
|
||||
else if ((!std::strcmp(argv[0], "-c")) || (!std::strcmp(argv[0], "-contours"))) {
|
||||
opt.contour = true;
|
||||
argv++;
|
||||
argc--;
|
||||
std::cerr << "-c ";
|
||||
}
|
||||
else if ((!std::strcmp(argv[0], "-b")) || (!std::strcmp(argv[0], "-binary"))) {
|
||||
opt.binary = true;
|
||||
argv++;
|
||||
argc--;
|
||||
std::cerr << "-b ";
|
||||
}
|
||||
else if ((!std::strcmp(argv[0], "-x")) || (!std::strcmp(argv[0], "-xyz"))) {
|
||||
opt.xyz = true;
|
||||
argv++;
|
||||
argc--;
|
||||
std::cerr << "-x ";
|
||||
}
|
||||
else if ((!std::strcmp(argv[0], "-nb")) || (!std::strcmp(argv[0], "-no_border"))) {
|
||||
opt.K = HUGE_VAL;
|
||||
opt.K_init = opt.K;
|
||||
argv++;
|
||||
argc--;
|
||||
std::cerr << "-nb ";
|
||||
}
|
||||
else if ((!std::strcmp(argv[0], "-nh")) || (!std::strcmp(argv[0], "-no_header"))) {
|
||||
opt.no_header = true;
|
||||
argv++;
|
||||
argc--;
|
||||
std::cerr << "-nh ";
|
||||
}
|
||||
else if ((!std::strcmp(argv[0], "-d")) || (!std::strcmp(argv[0], "-delta"))){
|
||||
if (sscanf(argv[1], "%lf", &opt.delta) != 1) {
|
||||
std::cerr << "Argument for delta must be a number"
|
||||
<< std::endl;
|
||||
}
|
||||
argv += 2;
|
||||
argc -= 2;
|
||||
std::cerr << "-d " << opt.delta << " ";
|
||||
}
|
||||
else if ((!std::strcmp(argv[0], "-a")) || (!std::strcmp(argv[0], "-area"))){
|
||||
if (sscanf(argv[1], "%lf", &opt.area) != 1) {
|
||||
std::cerr << "Argument for area must be a number"
|
||||
<< std::endl;
|
||||
}
|
||||
argv += 2;
|
||||
argc -= 2;
|
||||
std::cerr << "-a " << opt.area << " ";
|
||||
}
|
||||
else if ((!std::strcmp(argv[0], "-pe")) || (!std::strcmp(argv[0], "-perimeter"))){
|
||||
if (sscanf(argv[1], "%lf", &opt.perimeter) != 1) {
|
||||
std::cerr << "Argument for perimeter must be a number"
|
||||
<< std::endl;
|
||||
}
|
||||
argv += 2;
|
||||
argc -= 2;
|
||||
std::cerr << "-perimeter " << opt.perimeter << " ";
|
||||
}
|
||||
else if ((!std::strcmp(argv[0], "-aa")) || (!std::strcmp(argv[0], "-abs_area"))){
|
||||
if (sscanf(argv[1], "%lf", &opt.abs_area) != 1) {
|
||||
std::cerr << "Argument for abs_area must be a number"
|
||||
<< std::endl;
|
||||
}
|
||||
argv += 2;
|
||||
argc -= 2;
|
||||
std::cerr << "-abs_area " << opt.abs_area << " ";
|
||||
}
|
||||
else if ((!std::strcmp(argv[0], "-ae")) || (!std::strcmp(argv[0], "-abs_perimeter"))){
|
||||
if (sscanf(argv[1], "%lf", &opt.abs_perimeter) != 1) {
|
||||
std::cerr << "Argument for abs_perimeter must be a number"
|
||||
<< std::endl;
|
||||
}
|
||||
argv += 2;
|
||||
argc -= 2;
|
||||
std::cerr << "-abs_perimeter " << opt.abs_perimeter << " ";
|
||||
}
|
||||
else if ((!std::strcmp(argv[0], "-ki"))){
|
||||
if ((sscanf(argv[1], "%lf", &opt.K_init) != 1)||
|
||||
(sscanf(argv[2], "%lf", &opt.K) != 1)){
|
||||
std::cerr << "Argument for K must be a number"
|
||||
<< std::endl;
|
||||
}
|
||||
argv += 3;
|
||||
argc -= 3;
|
||||
std::cerr << "-ki " << opt.K_init << " " << opt.K << " ";
|
||||
}
|
||||
else if ((!std::strcmp(argv[0], "-rgb"))){
|
||||
if ((sscanf(argv[1], "%lf", &opt.red) != 1)||
|
||||
(sscanf(argv[2], "%lf", &opt.green) != 1) ||
|
||||
(sscanf(argv[3], "%lf", &opt.blue) != 1)){
|
||||
std::cerr << "Argument for rgb must be three numbers"
|
||||
<< std::endl;
|
||||
}
|
||||
argv += 4;
|
||||
argc -= 4;
|
||||
std::cerr << "-rgb " << opt.red << " " << opt.green << " " << opt.blue << " " ;
|
||||
}
|
||||
else if ((!std::strcmp(argv[0], "-ks"))){
|
||||
if (sscanf(argv[1], "%lf", &opt.K_step) != 1) {
|
||||
std::cerr << "Argument for K must be a number"
|
||||
<< std::endl;
|
||||
}
|
||||
argv += 2;
|
||||
argc -= 2;
|
||||
std::cerr << "-ks " << opt.K_step << " ";
|
||||
}
|
||||
else if ((!std::strcmp(argv[0], "-k"))){
|
||||
if (sscanf(argv[1], "%lf", &opt.K) != 1) {
|
||||
std::cerr << "Argument for K must be a number"
|
||||
<< std::endl;
|
||||
}
|
||||
opt.K_init = opt.K;
|
||||
argv += 2;
|
||||
argc -= 2;
|
||||
std::cerr << "-k " << opt.K_init << " ";
|
||||
}
|
||||
else if ((!std::strcmp(argv[0], "-m")) || (!std::strcmp(argv[0], "-max_of_connected_components"))){
|
||||
if (sscanf(argv[1], "%d", &opt.max_connected_comp) != 1) {
|
||||
std::cerr << "Argument for the number of connected components must be a number"
|
||||
<< std::endl;
|
||||
}
|
||||
/*
|
||||
if(opt.max_connected_comp < 1) {
|
||||
std::cerr << "Argument for the number of connected components must be a positive number"
|
||||
<< "It is set to 1" << std::endl;
|
||||
opt.max_connected_comp = 1;
|
||||
}
|
||||
*/
|
||||
argv += 2;
|
||||
argc -= 2;
|
||||
std::cerr << "-m " << opt.max_connected_comp << " ";
|
||||
}
|
||||
else if ((!std::strcmp(argv[0], "-p")) || (!std::strcmp(argv[0], "-post"))){
|
||||
if (sscanf(argv[1], "%d", &opt.NB_BORDER_MAX) != 1) {
|
||||
std::cerr << "Argument for post process must be a number"
|
||||
<< std::endl;
|
||||
}
|
||||
argv += 2;
|
||||
argc -= 2;
|
||||
std::cerr << "-p " << opt.NB_BORDER_MAX << " ";
|
||||
}
|
||||
else if ((!std::strcmp(argv[0], "-i")) || (!std::strcmp(argv[0], "-in"))) {
|
||||
std::strcpy(opt.finname, argv[1]);
|
||||
opt.file_input = true;
|
||||
argv += 2;
|
||||
argc -= 2;
|
||||
std::cerr << "-i " << opt.finname << " ";
|
||||
}
|
||||
else if ((!std::strcmp(argv[0], "-s")) || (!std::strcmp(argv[0], "-sect_in"))) {
|
||||
std::strcpy(opt.finname, argv[1]);
|
||||
opt.Section_file = true;
|
||||
opt.file_input = true;
|
||||
argv += 2;
|
||||
argc -= 2;
|
||||
std::cerr << "-s " << opt.finname << " ";
|
||||
}
|
||||
else if ((!std::strcmp(argv[0], "-o")) || (!std::strcmp(argv[0], "-out"))) {
|
||||
std::strcpy(opt.foutname, argv[1]);
|
||||
opt.file_output = true;
|
||||
argv += 2;
|
||||
argc -= 2;
|
||||
std::cerr << "-o " << opt.foutname << " ";
|
||||
}
|
||||
else if ((!std::strcmp(argv[0], "-of")) || (!std::strcmp(argv[0], "-out_format"))) {
|
||||
if (!std::strcmp(argv[1], "wrl"))
|
||||
opt.out_format = 0;
|
||||
else if (!std::strcmp(argv[1], "off"))
|
||||
opt.out_format = 1;
|
||||
else if (!std::strcmp(argv[1], "medit"))
|
||||
opt.out_format = 2;
|
||||
else if (!std::strcmp(argv[1], "ply"))
|
||||
opt.out_format = 3;
|
||||
else if(!std::strcmp(argv[1], "iv"))
|
||||
opt.out_format = 4;
|
||||
else if(!std::strcmp(argv[1], "stl"))
|
||||
opt.out_format = 5;
|
||||
else if (!std::strcmp(argv[1], "all"))
|
||||
opt.out_format = -1;
|
||||
else if (!std::strcmp(argv[1], "none"))
|
||||
opt.out_format = -2;
|
||||
else
|
||||
std::cerr << "unrecognized file format." << std::endl;
|
||||
opt.file_output = true;
|
||||
std::cerr << "-of " << argv[1] << " ";
|
||||
argv += 2;
|
||||
argc -= 2;
|
||||
}
|
||||
else if ((!std::strcmp(argv[0], "-?")) ||
|
||||
(!std::strcmp(argv[0], "-h")) ||
|
||||
(!std::strcmp(argv[0], "-help"))) {
|
||||
usage(opt.program);
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
std::cerr << "unrecognized option " << argv[0] << std::endl;
|
||||
usage(opt.program);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(argc > 0){
|
||||
std::cerr << "unrecognized option " << argv[0] << std::endl;
|
||||
usage(opt.program);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class PointIterator, class TripleOutputIterator>
|
||||
void reconstruction_test(PointIterator point_begin, PointIterator
|
||||
point_end, TripleOutputIterator out, bool filter_input_points=false,
|
||||
double perimeter=0)
|
||||
{
|
||||
Options opt;
|
||||
opt.abs_perimeter = perimeter;
|
||||
std::cerr << "Compute Delaunay Tetrahedrization " << std::endl;
|
||||
CGAL::Timer t1;
|
||||
t1.start();
|
||||
|
||||
Triangulation_3 dt( boost::make_transform_iterator(point_begin, Auto_count()),
|
||||
boost::make_transform_iterator(point_end, Auto_count() ) );
|
||||
t1.stop();
|
||||
std::cerr << " Inserted " << dt.number_of_vertices() << " points, "
|
||||
<< dt.number_of_cells() << " cells computed in "
|
||||
<< t1.time() << " sec." << std::endl;
|
||||
|
||||
t1.reset();
|
||||
t1.start();
|
||||
Surface S(dt, opt);
|
||||
t1.stop();
|
||||
std::cerr << "Reconstruction takes " << t1.time() << " sec.\n";
|
||||
std::cerr << " " << S.number_of_outliers() << " outliers.\n";
|
||||
std::cerr << " Reconstructed surface: " << S.number_of_facets() <<
|
||||
" facets, " << S.number_of_vertices() << " vertices.\n";
|
||||
std::cerr << " " << S.number_of_border_edges() <<
|
||||
" border edges.\n";
|
||||
std::cerr << " number of connected components <= "
|
||||
<< (std::max)(1, S.number_of_connected_components()-1)
|
||||
<< std::endl;
|
||||
write_triple_indices(out, S);
|
||||
}
|
||||
|
||||
|
||||
//___________________________________________
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
CGAL::Timer timer, total;
|
||||
total.start();
|
||||
timer.start();
|
||||
//parse command line
|
||||
Options opt;
|
||||
std::cerr << "Option line for this execution is :" << std::endl;
|
||||
if (!parse(argc, argv, opt))
|
||||
exit(0);
|
||||
std::cerr << std::endl << std::endl;
|
||||
|
||||
std::vector<Point> points;
|
||||
|
||||
file_input(opt, points);
|
||||
|
||||
#if 0
|
||||
std::cerr << "Time for reading " << timer.time() << " sec." << std::endl;
|
||||
std::vector<CGAL::cpp11::tuple<std::size_t,std::size_t,std::size_t> > triples;
|
||||
reconstruction_test(points.begin(), points.end(), std::back_inserter(triples));
|
||||
|
||||
|
||||
std::cout << triples.size() << std::endl;
|
||||
for(int i = 0; i < triples.size(); ++i){
|
||||
std::cout << "3 " << get<0>(triples[i]) << " " << get<1>(triples[i]) << " " << get<2>(triples[i]) << " " << std::endl;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
std::cerr << "Compute Delaunay Tetrahedrization " << std::endl;
|
||||
CGAL::Timer t1;
|
||||
t1.start();
|
||||
|
||||
Triangulation_3 dt( boost::make_transform_iterator(points.begin(),Auto_count()),
|
||||
boost::make_transform_iterator(points.end(), Auto_count() ) );
|
||||
t1.stop();
|
||||
std::cerr << " Inserted " << dt.number_of_vertices() << " points, "
|
||||
<< dt.number_of_cells() << " cells computed in "
|
||||
<< t1.time() << " sec." << std::endl;
|
||||
|
||||
if (dt.dimension() < 3) {
|
||||
std::cerr << "-- 2D sample of points ???" << std::endl;
|
||||
exit(0);
|
||||
}
|
||||
|
||||
points.clear();
|
||||
|
||||
|
||||
Surface S(dt, opt);
|
||||
S.run();
|
||||
|
||||
std::cerr << "Total time: " << timer.time() << " sec." << std::endl;
|
||||
// write_to_file_vrml2(opt.foutname, S, opt.contour, opt.red, opt.green, opt.blue, opt.no_header);
|
||||
write_to_file(opt.foutname, S, opt.contour, opt.out_format, opt.red, opt.green, opt.blue, opt.no_header);
|
||||
|
||||
std::cerr << " " << S.number_of_outliers()
|
||||
<< " outliers." << std::endl;
|
||||
std::cerr << " Reconstructed surface: " << S.number_of_facets() <<
|
||||
" facets, " << S.number_of_vertices() << " vertices." << std::endl;
|
||||
std::cerr << " " << S.number_of_border_edges() <<
|
||||
" border edges." << std::endl;
|
||||
std::cerr << " number of connected components <= "
|
||||
<< (std::max)(1, S.number_of_connected_components()-1)
|
||||
<< std::endl << std::endl;
|
||||
|
||||
#endif
|
||||
total.stop();
|
||||
std::cerr << "Total = " << total.time() << " sec." << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
#include <CGAL/basic.h>
|
||||
#include <CGAL/Simple_cartesian.h>
|
||||
#include <CGAL/Filtered_kernel.h>
|
||||
#include <CGAL/algorithm.h>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
typedef double NT;
|
||||
|
||||
struct K : public CGAL::Filtered_kernel<CGAL::Simple_cartesian<NT> > {};
|
||||
typedef K::Point_3 Point;
|
||||
typedef K::Vector_3 Vector;
|
||||
typedef K::Segment_3 Segment;
|
||||
typedef K::Triangle_3 Triangle;
|
||||
|
||||
NT
|
||||
weight(const Point& p, const Point& q, const Point& r){
|
||||
NT area = std::sqrt(Triangle(p,q,r).squared_area());
|
||||
NT l1 = std::sqrt((p-q) * (p-q));
|
||||
NT l2 = std::sqrt((p-r) * (p-r));
|
||||
NT l3 = std::sqrt((q-r) * (q-r));
|
||||
if(l1>l2) std::swap(l1,l2);
|
||||
if(l2>l3) std::swap(l2,l3);
|
||||
if(l1>l2) std::swap(l1,l2);
|
||||
if(l2>l3) std::swap(l2,l3);
|
||||
|
||||
// Taken from Piecewise-Linear Interpolation between Polygonal Slices
|
||||
// from Gill Barequet and Micha Sharir
|
||||
return 0.85 * area + 0.05 * (l1 +l2 + l3) + 0.1 * l3/l1;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
insert(std::set<CGAL::Triple<int,int,int> >& triangles, int i, int j, int k){
|
||||
std::cout << i << ", " << j << ", " << k << std::endl;
|
||||
if(i>j) std::swap(i,j);
|
||||
if(j>k) std::swap(j,k);
|
||||
if(i>j) std::swap(i,j);
|
||||
if(j>k) std::swap(j,k);
|
||||
std::cout << i << ", " << j << ", " << k << std::endl;
|
||||
triangles.insert(CGAL::make_triple(i,j,k));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
collect(int i, int k, int n, const std::vector<NT>& O, std::set<CGAL::Triple<int,int,int> >& triangles){
|
||||
|
||||
std::cout << "collect(" << i << ", " << k << ")" << std::endl;
|
||||
if((i+2) == k){
|
||||
insert(triangles, i, i+1, k);
|
||||
}else {
|
||||
int o = O[i*n+k];
|
||||
|
||||
if(o != (i+1)){
|
||||
collect(i, o, n, O, triangles);
|
||||
}
|
||||
insert(triangles, i, o, k);
|
||||
if(o != (k-1)){
|
||||
collect(o, k, n, O, triangles);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
main(){
|
||||
|
||||
int n;
|
||||
std::cin >> n;
|
||||
|
||||
std::vector<Point> points(n);
|
||||
CGAL::copy_n(std::istream_iterator<Point>(std::cin), n, points.begin());
|
||||
|
||||
|
||||
std::set<CGAL::Triple<int,int,int> > triangles;
|
||||
|
||||
std::vector<NT> W(n*n);
|
||||
std::vector<NT> O(n*n);
|
||||
|
||||
for(int i = 0; i <= n-2; i++){
|
||||
W[i*n + i + 1] = 0;
|
||||
}
|
||||
for(int i = 0; i <= n-3; i++){
|
||||
W[i*n + i + 2] = weight(points[i], points[i+1], points[i+3]);
|
||||
}
|
||||
|
||||
for(int j = 3; j <= n-1; j++){
|
||||
for(int i=0; i <= n - j - 1; i++){
|
||||
int k = i + j;
|
||||
double lmin = -1;
|
||||
int lmin_index;
|
||||
for(int m = i+1; m < k; m++){
|
||||
double d = W[i*n + m] + W[m*n + k] + weight(points[i], points[m], points[k]);
|
||||
if( (lmin == -1) || (d < lmin )){
|
||||
lmin = d;
|
||||
lmin_index = m;
|
||||
}
|
||||
}
|
||||
W[i*n + k] = lmin;
|
||||
O[i*n + k] = lmin_index;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
collect(0, n-1, n, O, triangles);
|
||||
|
||||
std::cout << "Shape {\n"
|
||||
"appearance Appearance {\n"
|
||||
"material Material { diffuseColor .9 .5 .1}}\n"
|
||||
"geometry\n"
|
||||
"IndexedFaceSet {\n"
|
||||
"coord DEF def_coords Coordinate {\n"
|
||||
"point [ \n" ;
|
||||
|
||||
for (int i = 0; i < n; i++){
|
||||
std::cout << points[i].x() << " " << points[i].y() << " " << points[i].z() << ",\n ";
|
||||
}
|
||||
std::cout << "]\n"
|
||||
"}\n"
|
||||
"solid FALSE\n"
|
||||
"coordIndex [ \n";
|
||||
|
||||
for(std::set<CGAL::Triple<int,int,int> >::iterator it = triangles.begin();
|
||||
it != triangles.end();
|
||||
it++){
|
||||
std::cout << it->first << ", " << it->second << ", " << it->third << ", -1,\n ";
|
||||
}
|
||||
std::cout << "]\n"
|
||||
"}# IndexedFaceSet\n"
|
||||
"}# Shape\n";
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
#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<K> 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++, j++){
|
||||
if(ci != i){
|
||||
points[j] = ch->vertex(i)->point();
|
||||
}
|
||||
}
|
||||
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,66 @@
|
|||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <algorithm>
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/Advancing_front_surface_reconstruction.h>
|
||||
#include <CGAL/tuple.h>
|
||||
|
||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
|
||||
typedef Kernel::Point_3 Point_3;
|
||||
|
||||
typedef CGAL::cpp11::tuple<std::size_t,std::size_t,std::size_t> Facet;
|
||||
|
||||
namespace std {
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const Facet& f)
|
||||
{
|
||||
os << "3 " << get<0>(f) << " " << get<1>(f) << " " << get<2>(f);
|
||||
return os;
|
||||
}
|
||||
}
|
||||
|
||||
struct Perimeter {
|
||||
|
||||
double bound;
|
||||
|
||||
Perimeter(double bound)
|
||||
: bound(bound)
|
||||
{}
|
||||
|
||||
bool operator()(const Point_3& p, const Point_3& q, const Point_3& r) const
|
||||
{
|
||||
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.5);
|
||||
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,32 @@
|
|||
|
||||
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/Advancing_front_surface_reconstruction.h>
|
||||
#include <CGAL/Polyhedron_3.h>
|
||||
#include <CGAL/IO/Polyhedron_iostream.h>
|
||||
|
||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
|
||||
typedef Kernel::Point_3 Point_3;
|
||||
|
||||
typedef CGAL::Polyhedron_3<Kernel> Polyhedron;
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
std::vector<Point_3> points;
|
||||
Polyhedron P;
|
||||
|
||||
std::copy(std::istream_iterator<Point_3>(std::cin),
|
||||
std::istream_iterator<Point_3>(),
|
||||
std::back_inserter(points));
|
||||
|
||||
CGAL::advancing_front_surface_reconstruction(points.begin(),
|
||||
points.end(),
|
||||
P);
|
||||
|
||||
std::cout << P << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
#ifndef CGAL_AFSR_SURFACE_FACE_BASE_2_H
|
||||
#define CGAL_AFSR_SURFACE_FACE_BASE_2_H
|
||||
|
||||
// This face class stores a facet in the tetrahedrization
|
||||
// When it gets reoriented by the TDS, it also changes the facet
|
||||
|
||||
namespace CGAL {
|
||||
namespace AFSR {
|
||||
|
||||
template < typename GT,
|
||||
typename F3,
|
||||
typename Fb = CGAL::Triangulation_ds_face_base_2<> >
|
||||
class Surface_face_base_2
|
||||
: public Fb
|
||||
{
|
||||
typedef typename Fb::Triangulation_data_structure Tds;
|
||||
|
||||
public:
|
||||
typedef typename Tds::Face_handle Face_handle;
|
||||
typedef typename Tds::Vertex_handle Vertex_handle;
|
||||
|
||||
template < typename TDS2 >
|
||||
struct Rebind_TDS {
|
||||
typedef typename Fb::template Rebind_TDS<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,76 @@
|
|||
// Copyright (c) 2005 GeometryFactory Sarl
|
||||
// All rights reserved.
|
||||
//
|
||||
// This file is part of CGAL (www.cgal.org); you may redistribute it under
|
||||
// the terms of the Q Public License version 1.0.
|
||||
// See the file LICENSE.QPL distributed with CGAL.
|
||||
//
|
||||
// Licensees holding a valid commercial license may use this file in
|
||||
// accordance with the commercial license agreement provided with the software.
|
||||
//
|
||||
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
//
|
||||
// Author(s) : Andreas Fabri
|
||||
|
||||
|
||||
#ifndef CGAL_AFSR_SURFACE_VERTEX_BASE_2_H
|
||||
#define CGAL_AFSR_SURFACE_VERTEX_BASE_2_H
|
||||
|
||||
#include <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,74 @@
|
|||
#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 Kernel, 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 HDS::Vertex Vertex;
|
||||
typedef typename Vertex::Point Point;
|
||||
|
||||
typedef typename Surface::TDS_2 TDS_2;
|
||||
typedef typename TDS_2::Face_iterator Face_iterator;
|
||||
typedef typename TDS_2::Vertex_iterator Vertex_iterator;
|
||||
typedef typename Surface::Cell_handle Cell_handle;
|
||||
|
||||
const TDS_2& tds = s.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,128 @@
|
|||
#ifndef CGAL_AFSR_CONSTRUCT_SURFACE_2
|
||||
#define CGAL_AFSR_CONSTRUCT_SURFACE_2
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
template <class Kernel, class Triangulation, class Filter>
|
||||
class Advancing_front_surface_reconstruction;
|
||||
|
||||
namespace AFSR {
|
||||
|
||||
|
||||
template <class Kernel, class Triangulation, class TDS, class Filter>
|
||||
typename TDS::Vertex_handle
|
||||
construct_surface(TDS& tds, const CGAL::Advancing_front_surface_reconstruction<Kernel,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_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,120 @@
|
|||
#ifndef CGAL_AFSR_ORIENT
|
||||
|
||||
namespace CGAL {
|
||||
namespace AFSR {
|
||||
|
||||
|
||||
template <class Kernel, class Triangulation, class TDS, class Filter>
|
||||
typename TDS::Vertex_handle
|
||||
orient(TDS& tds, const Advancing_front_surface_reconstruction<Kernel,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,42 @@
|
|||
#ifndef CGAL_AFSR_WRITE_TRIPLE_INDICES_H
|
||||
#define CGAL_AFSR_WRITE_TRIPLE_INDICES_H
|
||||
|
||||
#include <CGAL/tuple.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
template <class Kernel, class Triangulation, class Filter>
|
||||
class Advancing_front_surface_reconstruction;
|
||||
|
||||
|
||||
|
||||
template <class OutputIterator, class Kernel, class Triangulation, class Filter>
|
||||
OutputIterator
|
||||
write_triple_indices(OutputIterator out, const Advancing_front_surface_reconstruction<Kernel,Triangulation,Filter>& S)
|
||||
{
|
||||
typedef Advancing_front_surface_reconstruction<Kernel,Triangulation,Filter> Surface;
|
||||
typedef typename Surface::TDS_2 TDS_2;
|
||||
typedef typename TDS_2::Face_iterator Face_iterator;
|
||||
typedef typename Surface::Cell_handle Cell_handle;
|
||||
|
||||
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::cpp11::tuple<std::size_t,std::size_t,std::size_t>(fit->vertex(0)->vertex_3()->id(),
|
||||
fit->vertex(1)->vertex_3()->id(),
|
||||
fit->vertex(2)->vertex_3()->id());
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
#ifndef CGAL_AFSR_OPTIONS_H
|
||||
#define CGAL_AFSR_OPTIONS_H
|
||||
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
class AFSR_options {
|
||||
public:
|
||||
AFSR_options()
|
||||
: file_input(true), file_output(false),
|
||||
Delaunay(false), contour(false), binary(false), xyz(false),
|
||||
Section_file(false), max_connected_comp(-1),
|
||||
delta(.86), K_init(1.1), K_step(.1), K(5), out_format(0),
|
||||
NB_BORDER_MAX(15), red(0), green(0), blue(0), no_header(false)
|
||||
{
|
||||
std::strcpy(finname,"finput");
|
||||
std::strcpy(foutname,"foutput");
|
||||
}
|
||||
|
||||
char program[100];
|
||||
char finname[100];
|
||||
char foutname[100];
|
||||
bool file_input;
|
||||
bool file_output;
|
||||
bool Delaunay;
|
||||
bool contour;
|
||||
bool binary;
|
||||
bool xyz;
|
||||
bool Section_file;
|
||||
int max_connected_comp;
|
||||
double delta;
|
||||
double K_init;
|
||||
double K_step;
|
||||
double K;
|
||||
int out_format;
|
||||
int NB_BORDER_MAX;
|
||||
double red, green, blue;
|
||||
bool no_header;
|
||||
};
|
||||
|
||||
|
||||
} // namespace CGAL
|
||||
|
||||
#endif // CGAL_AFSR_OPTIONS_H
|
||||
|
|
@ -0,0 +1,473 @@
|
|||
#ifndef CGAL_AFSR_VERTEX_BASE_3_H
|
||||
#define CGAL_AFSR_VERTEX_BASE_3_H
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
#include <CGAL/Triangulation_vertex_base_3.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
template <class K, class VertexBase = Triangulation_vertex_base_3<K> >
|
||||
class AFSR_vertex_base_3 : public VertexBase
|
||||
{
|
||||
public:
|
||||
|
||||
template < typename TDS2 >
|
||||
struct Rebind_TDS {
|
||||
typedef typename VertexBase::template Rebind_TDS<TDS2>::Other Vb2;
|
||||
typedef AFSR_vertex_base_3<K,Vb2> Other;
|
||||
};
|
||||
|
||||
|
||||
typedef VertexBase Base;
|
||||
typedef typename Base::Vertex_handle Vertex_handle;
|
||||
typedef typename Base::Cell_handle Cell_handle;
|
||||
typedef typename VertexBase::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;
|
||||
|
||||
private:
|
||||
|
||||
//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;
|
||||
|
||||
// typedef std::set< void* > Interior_edge_set_type;
|
||||
|
||||
//-------------------- DATA MEMBERS ---------------------------------
|
||||
|
||||
private:
|
||||
|
||||
int _mark;
|
||||
int _post_mark;
|
||||
Intern_successors_type* _incident_border;
|
||||
|
||||
// Instead of having a set per vertex, there is a global list.
|
||||
static std::list<Vertex_handle> interior_edges;
|
||||
// and two iterators per vertex in this list
|
||||
// Note that ie_last is not past the end
|
||||
// ie_first == ie_last == interior_edge.end() iff the set is empty
|
||||
typename std::list<Vertex_handle>::iterator ie_first, ie_last;
|
||||
|
||||
|
||||
// We do the same for the incidence requests
|
||||
static std::list< Incidence_request_elt > incidence_requests;
|
||||
typename std::list< Incidence_request_elt >::iterator ir_first, ir_last;
|
||||
//-------------------- CONSTRUCTORS ---------------------------------
|
||||
|
||||
public:
|
||||
|
||||
AFSR_vertex_base_3()
|
||||
: VertexBase(), _mark(-1),
|
||||
_post_mark(-1),
|
||||
ie_first(interior_edges.end()), ie_last(interior_edges.end()),
|
||||
ir_first(incidence_requests.end()), ir_last(incidence_requests.end())
|
||||
{
|
||||
_incident_border = new Intern_successors_type(new Next_border_elt(),
|
||||
new Next_border_elt());
|
||||
_incident_border->first->first = NULL;
|
||||
_incident_border->second->first = NULL;
|
||||
}
|
||||
|
||||
AFSR_vertex_base_3(const Point & p)
|
||||
: VertexBase(p), _mark(-1),
|
||||
_post_mark(-1),
|
||||
ie_first(interior_edges.end()), ie_last(interior_edges.end()),
|
||||
ir_first(incidence_requests.end()), ir_last(incidence_requests.end())
|
||||
{
|
||||
_incident_border = new Intern_successors_type(new Next_border_elt(),
|
||||
new Next_border_elt());
|
||||
_incident_border->first->first = NULL;
|
||||
_incident_border->second->first = NULL;
|
||||
}
|
||||
|
||||
AFSR_vertex_base_3(const Point & p, Cell_handle f)
|
||||
: VertexBase(p, f), _mark(-1),
|
||||
_post_mark(-1),
|
||||
ie_first(interior_edges.end()), ie_last(interior_edges.end()),
|
||||
ir_first(incidence_requests.end()), ir_last(incidence_requests.end())
|
||||
{
|
||||
_incident_border = new Intern_successors_type(new Next_border_elt(),
|
||||
new Next_border_elt());
|
||||
_incident_border->first->first = NULL;
|
||||
_incident_border->second->first = NULL;
|
||||
}
|
||||
|
||||
AFSR_vertex_base_3(Cell_handle f)
|
||||
: VertexBase(f), _mark(-1),
|
||||
_post_mark(-1),
|
||||
ie_first(interior_edges.end()), ie_last(interior_edges.end()),
|
||||
ir_first(incidence_requests.end()), ir_last(incidence_requests.end())
|
||||
{
|
||||
_incident_border = new Intern_successors_type(new Next_border_elt(),
|
||||
new Next_border_elt());
|
||||
_incident_border->first->first = NULL;
|
||||
_incident_border->second->first = NULL;
|
||||
}
|
||||
|
||||
AFSR_vertex_base_3(const AFSR_vertex_base_3& other)
|
||||
: VertexBase(), _mark(-1),
|
||||
_post_mark(-1),
|
||||
ie_first(interior_edges.end()), ie_last(interior_edges.end()),
|
||||
ir_first(incidence_requests.end()), ir_last(incidence_requests.end())
|
||||
{
|
||||
_incident_border = new Intern_successors_type(new Next_border_elt(),
|
||||
new Next_border_elt());
|
||||
_incident_border->first->first = NULL;
|
||||
_incident_border->second->first = NULL;
|
||||
}
|
||||
//-------------------- DESTRUCTOR -----------------------------------
|
||||
|
||||
~AFSR_vertex_base_3()
|
||||
{
|
||||
if (_incident_border != NULL)
|
||||
{
|
||||
delete _incident_border->first;
|
||||
delete _incident_border->second;
|
||||
delete _incident_border;
|
||||
}
|
||||
if(ir_first != incidence_requests.end()){
|
||||
assert(ir_last != incidence_requests.end());
|
||||
typename std::list< Incidence_request_elt >::iterator b(ir_first), e(ir_last);
|
||||
e++;
|
||||
incidence_requests.erase(b, e);
|
||||
}
|
||||
|
||||
if(ie_first != interior_edges.end()){
|
||||
assert(ie_last != interior_edges.end());
|
||||
typename std::list<Vertex_handle>::iterator b(ie_first), e(ie_last);
|
||||
e++;
|
||||
interior_edges.erase(b, e);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------- MEMBER FUNCTIONS -----------------------------
|
||||
|
||||
inline void re_init()
|
||||
{
|
||||
if (_incident_border != NULL)
|
||||
{
|
||||
delete _incident_border->first;
|
||||
delete _incident_border->second;
|
||||
delete _incident_border;
|
||||
}
|
||||
|
||||
if(ir_first != incidence_requests.end()){
|
||||
assert(ir_last != incidence_requests.end());
|
||||
typename std::list< Incidence_request_elt >::iterator b(ir_first), e(ir_last);
|
||||
e++;
|
||||
incidence_requests.erase(b, e);
|
||||
ir_first = incidence_requests.end();
|
||||
ir_last = incidence_requests.end();
|
||||
}
|
||||
|
||||
_incident_border = new Intern_successors_type(new Next_border_elt(),
|
||||
new Next_border_elt());
|
||||
_incident_border->first->first = NULL;
|
||||
_incident_border->second->first = NULL;
|
||||
_mark = -1;
|
||||
_post_mark = -1;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
inline bool is_on_border(const int& i) const
|
||||
{
|
||||
if (_incident_border == NULL) return false; //vh is interior
|
||||
if (_incident_border->first->first != NULL)
|
||||
{
|
||||
if (_incident_border->second->first != NULL)
|
||||
return ((_incident_border->first->second.second == i)||
|
||||
(_incident_border->second->second.second == i));
|
||||
return (_incident_border->first->second.second == i);
|
||||
}
|
||||
return false; //vh is still exterior
|
||||
}
|
||||
|
||||
inline Next_border_elt* get_next_on_border(const int& i) const
|
||||
{
|
||||
if (_incident_border == NULL) return NULL; //vh is interior
|
||||
if (_incident_border->first->first != NULL)
|
||||
if (_incident_border->first->second.second == i)
|
||||
return _incident_border->first;
|
||||
if (_incident_border->second->first != NULL)
|
||||
if (_incident_border->second->second.second == i)
|
||||
return _incident_border->second;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
inline void remove_border_edge(Vertex_handle v)
|
||||
{
|
||||
if (_incident_border != NULL)
|
||||
{
|
||||
if (_incident_border->second->first == v)
|
||||
{
|
||||
_incident_border->second->first = NULL;
|
||||
set_interior_edge(v);
|
||||
return;
|
||||
}
|
||||
if (_incident_border->first->first == v)
|
||||
{
|
||||
if (_incident_border->second->first != NULL)
|
||||
{
|
||||
Next_border_elt* tmp = _incident_border->first;
|
||||
_incident_border->first = _incident_border->second;
|
||||
_incident_border->second = tmp;
|
||||
_incident_border->second->first = NULL;
|
||||
set_interior_edge(v);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
_incident_border->first->first = NULL;
|
||||
set_interior_edge(v);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline bool is_border_edge(Vertex_handle v) const
|
||||
{
|
||||
if (_incident_border == NULL) return false;
|
||||
return ((_incident_border->first->first == v)||
|
||||
(_incident_border->second->first == v));
|
||||
}
|
||||
|
||||
inline Next_border_elt* get_border_elt(Vertex_handle v) const
|
||||
{
|
||||
if (_incident_border == NULL) return NULL;
|
||||
if (_incident_border->first->first == v) return _incident_border->first;
|
||||
if (_incident_border->second->first == v) return _incident_border->second;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
inline Next_border_elt* first_incident() const
|
||||
{
|
||||
if (_incident_border == NULL) return NULL;
|
||||
return _incident_border->first;
|
||||
}
|
||||
|
||||
inline Next_border_elt* second_incident() const
|
||||
{
|
||||
if (_incident_border == NULL) return NULL;
|
||||
return _incident_border->second;
|
||||
}
|
||||
|
||||
|
||||
inline void set_next_border_elt(const Next_border_elt& elt)
|
||||
{
|
||||
if (_incident_border->first->first == NULL)
|
||||
*_incident_border->first = elt;
|
||||
else
|
||||
{
|
||||
if (_incident_border->second->first != NULL)
|
||||
std::cerr << "+++probleme de MAJ du bord <Vertex_base>" << std::endl;
|
||||
*_incident_border->second = elt;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// pour gerer certaines aretes interieures: a savoir celle encore connectee au
|
||||
// bord (en fait seule, les aretes interieures reliant 2 bords nous
|
||||
// interressent...)
|
||||
|
||||
inline bool is_interior_edge(Vertex_handle v) const
|
||||
{
|
||||
|
||||
bool r1;
|
||||
if(ie_first == interior_edges.end()){
|
||||
r1 = false;
|
||||
}else {
|
||||
typename std::list<Vertex_handle>::iterator b(ie_first), e(ie_last);
|
||||
e++;
|
||||
typename std::list<Vertex_handle>::iterator r = std::find(b, e, v);
|
||||
r1 = ( r != e);
|
||||
}
|
||||
|
||||
return r1;
|
||||
}
|
||||
|
||||
inline void set_interior_edge(Vertex_handle v)
|
||||
{
|
||||
if(ie_last == interior_edges.end()){ // empty set
|
||||
assert(ie_first == ie_last);
|
||||
ie_last = interior_edges.insert(ie_last, v);
|
||||
ie_first = ie_last;
|
||||
} else {
|
||||
typename std::list<Vertex_handle>::iterator e(ie_last);
|
||||
e++;
|
||||
#ifdef DEBUG
|
||||
typename std::list<Vertex_handle>::iterator r = std::find(ie_first, e, v);
|
||||
#endif
|
||||
assert(r == e);
|
||||
ie_last = interior_edges.insert(e, v);
|
||||
}
|
||||
}
|
||||
|
||||
inline void remove_interior_edge(Vertex_handle v)
|
||||
{
|
||||
if(ie_first == interior_edges.end()){
|
||||
assert(ie_last == ie_first);
|
||||
} else if(ie_first == ie_last){ // there is only one element
|
||||
if(*ie_first == v){
|
||||
interior_edges.erase(ie_first);
|
||||
ie_last = interior_edges.end();
|
||||
ie_first = ie_last;
|
||||
}
|
||||
} else {
|
||||
typename std::list<Vertex_handle>::iterator b(ie_first), e(ie_last);
|
||||
e++;
|
||||
typename std::list<Vertex_handle>::iterator r = std::find(b, e, v);
|
||||
if(r != e){
|
||||
if(r == ie_first){
|
||||
ie_first++;
|
||||
}
|
||||
if(r == ie_last){
|
||||
ie_last--;
|
||||
}
|
||||
interior_edges.erase(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
inline void set_incidence_request(const Incidence_request_elt& ir)
|
||||
{
|
||||
if(ir_last == incidence_requests.end()){
|
||||
assert(ir_first == ir_last);
|
||||
ir_last = incidence_requests.insert(ir_last, ir);
|
||||
ir_first = ir_last;
|
||||
} else {
|
||||
typename std::list<Incidence_request_elt>::iterator e(ir_last);
|
||||
e++;
|
||||
ir_last = incidence_requests.insert(e, ir);
|
||||
}
|
||||
}
|
||||
|
||||
inline bool is_incidence_requested() const
|
||||
{
|
||||
if(ir_last == incidence_requests.end()){
|
||||
assert(ir_first == incidence_requests.end());
|
||||
}
|
||||
return (ir_last != incidence_requests.end());
|
||||
}
|
||||
|
||||
inline Incidence_request_iterator incidence_request_begin()
|
||||
{
|
||||
return ir_first;
|
||||
}
|
||||
|
||||
inline Incidence_request_iterator get_incidence_request_end()
|
||||
{
|
||||
if(ir_last != incidence_requests.end()){
|
||||
assert(ir_first != incidence_requests.end());
|
||||
Incidence_request_iterator it(ir_last);
|
||||
it++;
|
||||
return it;
|
||||
}
|
||||
return ir_last;
|
||||
}
|
||||
|
||||
inline void erase_incidence_request()
|
||||
{
|
||||
if(ir_last != incidence_requests.end()){
|
||||
assert(ir_first != incidence_requests.end());
|
||||
ir_last++;
|
||||
incidence_requests.erase(ir_first, ir_last);
|
||||
ir_first = incidence_requests.end();
|
||||
ir_last = incidence_requests.end();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
inline bool is_on_border() const
|
||||
{
|
||||
return (_mark > 0);
|
||||
}
|
||||
|
||||
inline bool not_interior() const
|
||||
{
|
||||
return (_mark != 0);
|
||||
}
|
||||
|
||||
inline int number_of_incident_border() const
|
||||
{
|
||||
return _mark;
|
||||
}
|
||||
|
||||
inline bool is_exterior() const
|
||||
{
|
||||
return (_mark < 0);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
inline void inc_mark()
|
||||
{
|
||||
if (_mark==-1)
|
||||
_mark=1;
|
||||
else
|
||||
_mark++;
|
||||
}
|
||||
|
||||
inline void dec_mark()
|
||||
{
|
||||
_mark--;
|
||||
if(_mark == 0)
|
||||
{
|
||||
delete _incident_border->first;
|
||||
delete _incident_border->second;
|
||||
delete _incident_border;
|
||||
_incident_border = NULL;
|
||||
erase_incidence_request();
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
inline void set_post_mark(const int& i)
|
||||
{
|
||||
_post_mark = i;
|
||||
}
|
||||
|
||||
inline bool is_post_marked(const int& i)
|
||||
{
|
||||
return (_post_mark == i);
|
||||
}
|
||||
};
|
||||
|
||||
template <class K, class VertexBase>
|
||||
std::list<typename AFSR_vertex_base_3<K,VertexBase>::Vertex_handle> AFSR_vertex_base_3<K,VertexBase>::interior_edges;
|
||||
|
||||
template <class K, class VertexBase>
|
||||
std::list<typename AFSR_vertex_base_3<K,VertexBase>::Incidence_request_elt> AFSR_vertex_base_3<K,VertexBase>::incidence_requests;
|
||||
|
||||
} // namespace CGAL
|
||||
|
||||
#endif //CGAL_AFSR_VERTEX_BASE_3_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,226 @@
|
|||
#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 {
|
||||
|
||||
template < class Kernel, class CellBase = Triangulation_cell_base_3<Kernel> >
|
||||
class Advancing_front_surface_reconstruction_cell_base_3 : public CellBase
|
||||
{
|
||||
|
||||
public:
|
||||
template < typename TDS2 >
|
||||
struct Rebind_TDS {
|
||||
typedef typename CellBase::template Rebind_TDS<TDS2>::Other Cb2;
|
||||
typedef Advancing_front_surface_reconstruction_cell_base_3<Kernel,Cb2> Other;
|
||||
};
|
||||
|
||||
typedef typename CellBase::Vertex_handle Vertex_handle;
|
||||
typedef typename CellBase::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()
|
||||
: CellBase(),
|
||||
_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)
|
||||
: CellBase( 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)
|
||||
: CellBase(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,257 @@
|
|||
#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 A, class B, class C> class Advancing_front_surface_reconstruction;
|
||||
|
||||
template <class K, class VertexBase = Triangulation_vertex_base_3<K> >
|
||||
class Advancing_front_surface_reconstruction_vertex_base_3 : public VertexBase
|
||||
{
|
||||
public:
|
||||
|
||||
template < typename TDS2 >
|
||||
struct Rebind_TDS {
|
||||
typedef typename VertexBase::template Rebind_TDS<TDS2>::Other Vb2;
|
||||
typedef Advancing_front_surface_reconstruction_vertex_base_3<K,Vb2> Other;
|
||||
};
|
||||
|
||||
|
||||
template <class A, class B,class C> friend class Advancing_front_surface_reconstruction;
|
||||
|
||||
|
||||
typedef VertexBase Base;
|
||||
typedef typename Base::Vertex_handle Vertex_handle;
|
||||
typedef typename Base::Cell_handle Cell_handle;
|
||||
typedef typename VertexBase::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()
|
||||
: VertexBase(), m_mark(-1),
|
||||
m_post_mark(-1)
|
||||
{}
|
||||
|
||||
Advancing_front_surface_reconstruction_vertex_base_3(const Point & p)
|
||||
: VertexBase(p), m_mark(-1),
|
||||
m_post_mark(-1)
|
||||
{}
|
||||
|
||||
Advancing_front_surface_reconstruction_vertex_base_3(const Point & p, Cell_handle f)
|
||||
: VertexBase(p, f), m_mark(-1),
|
||||
m_post_mark(-1)
|
||||
{}
|
||||
|
||||
Advancing_front_surface_reconstruction_vertex_base_3(Cell_handle f)
|
||||
: VertexBase(f), m_mark(-1),
|
||||
m_post_mark(-1)
|
||||
{}
|
||||
|
||||
Advancing_front_surface_reconstruction_vertex_base_3(const Advancing_front_surface_reconstruction_vertex_base_3& other)
|
||||
: VertexBase(), 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,68 @@
|
|||
#ifndef CGAL_AFSR_VRML_H
|
||||
#define CGAL_AFSR_VRML_H
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
template < class Vb, class Fb>
|
||||
void
|
||||
afsr_vrml_output(const Triangulation_data_structure_2<Vb,Fb>& tds,
|
||||
std::ostream& os, double r, double g, double b,
|
||||
typename Triangulation_data_structure_2<Vb,Fb>::Vertex_handle v, bool skip_infinite)
|
||||
{
|
||||
typedef typename Triangulation_data_structure_2<Vb,Fb>::Vertex_handle Vertex_handle;
|
||||
typedef typename Triangulation_data_structure_2<Vb,Fb>::Vertex_iterator Vertex_iterator;
|
||||
typedef typename Triangulation_data_structure_2<Vb,Fb>::Face_iterator Face_iterator;
|
||||
|
||||
// ouput to a vrml file style
|
||||
// Point are assumed to be 3d points with a stream operator <<
|
||||
// if non NULL, v is the vertex to be output first
|
||||
// if skip_inf is true, the point in the first vertex is not output
|
||||
// and the faces incident to v are not output
|
||||
// (it may be for instance the infinite vertex of the terrain)
|
||||
|
||||
os << "#VRML V2.0 utf8" << std::endl;
|
||||
os << "Shape {\n"
|
||||
<< "appearance Appearance {\n"
|
||||
<< "material Material { diffuseColor " << r << " " << g << " " << b << "}}\n";
|
||||
os << "\tgeometry IndexedFaceSet {" << std::endl;
|
||||
os << "\t\tcoord Coordinate {" << std::endl;
|
||||
os << "\t\t\tpoint [" << std::endl;
|
||||
|
||||
std::map<Vertex_handle,int> vmap;
|
||||
Vertex_iterator vit;
|
||||
Face_iterator fit;
|
||||
|
||||
int inum = 0;
|
||||
for( vit= tds.vertices_begin(); vit != tds.vertices_end() ; ++vit) {
|
||||
if ( v != vit) {
|
||||
vmap[vit] = inum++;
|
||||
os << "\t\t\t\t" << *vit << ","<< std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
os << "\t\t\t]" << std::endl;
|
||||
os << "\t\t}" << std::endl;
|
||||
os << "\t\tsolid FALSE\n"
|
||||
"\t\tcoordIndex [" << std::endl;
|
||||
|
||||
// faces
|
||||
for(fit= tds.faces_begin(); fit != tds.faces_end(); ++fit) {
|
||||
if (!skip_infinite || !fit->has_vertex(v)) {
|
||||
os << "\t\t\t";
|
||||
os << vmap[(*fit).vertex(0)] << ", ";
|
||||
os << vmap[(*fit).vertex(1)] << ", ";
|
||||
os << vmap[(*fit).vertex(2)] << ", ";
|
||||
os << "-1, " << std::endl;
|
||||
}
|
||||
}
|
||||
os << "\t\t]" << std::endl;
|
||||
os << "\t}" << std::endl;
|
||||
os << "}" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
} // namespace CGAL
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,94 @@
|
|||
// Copyright (c) 1997 INRIA Sophia-Antipolis (France).
|
||||
// All rights reserved.
|
||||
//
|
||||
// This file is part of CGAL (www.cgal.org); you may redistribute it under
|
||||
// the terms of the Q Public License version 1.0.
|
||||
// See the file LICENSE.QPL distributed with CGAL.
|
||||
//
|
||||
// Licensees holding a valid commercial license may use this file in
|
||||
// accordance with the commercial license agreement provided with the software.
|
||||
//
|
||||
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// $Source: /CVSROOT/CGAL/Packages/Triangulation_2/include/CGAL/Triangulation_vertex_base_2.h,v $
|
||||
// $Revision$ $Date$
|
||||
// $Name: current_submission $
|
||||
//
|
||||
// Author(s) : Mariette Yvinec
|
||||
|
||||
|
||||
#ifndef CGAL_TVB_3_2_H
|
||||
#define CGAL_TVB_3_2_H
|
||||
|
||||
#include <CGAL/basic.h>
|
||||
#include <CGAL/Triangulation_ds_vertex_base_2.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
template < typename GT,
|
||||
typename Vb = Triangulation_ds_vertex_base_2<> >
|
||||
class Tvb_3_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 Tvb_3_2<GT, Vb2> Other;
|
||||
};
|
||||
|
||||
private:
|
||||
Point _p;
|
||||
|
||||
public:
|
||||
Tvb_3_2 () : Vb() {}
|
||||
Tvb_3_2(const Point & p) : Vb(), _p(p) {}
|
||||
Tvb_3_2(const Point & p, Face_handle f)
|
||||
: Vb(f), _p(p) {}
|
||||
Tvb_3_2(Face_handle f) : Vb(f) {}
|
||||
|
||||
void set_point(const Point & p) { _p = p; }
|
||||
const Point& point() const { return _p; }
|
||||
|
||||
// the non const version of point() is undocument
|
||||
// but needed to make the point iterator works
|
||||
// using Lutz projection scheme
|
||||
Point& point() { return _p; }
|
||||
|
||||
//the following trivial is_valid to allow
|
||||
// the user of derived face base classes
|
||||
// to add their own purpose checking
|
||||
bool is_valid(bool /* verbose */ = false, int /* level */ = 0) const
|
||||
{return true;}
|
||||
};
|
||||
|
||||
template < class GT, class Vb >
|
||||
std::istream&
|
||||
operator>>(std::istream &is, Tvb_3_2<GT, Vb> &v)
|
||||
// non combinatorial information. Default = point
|
||||
{
|
||||
return is >> static_cast<Vb&>(v) >> v.point();
|
||||
}
|
||||
|
||||
template < class GT, class Vb >
|
||||
std::ostream&
|
||||
operator<<(std::ostream &os, const Tvb_3_2<GT, Vb> &v)
|
||||
// non combinatorial information. Default = point
|
||||
{
|
||||
return os << static_cast<const Vb&>(v) << v.point();
|
||||
}
|
||||
|
||||
|
||||
|
||||
} //namespace CGAL
|
||||
|
||||
#endif //CGAL_TVB_3_2_H
|
||||
|
|
@ -0,0 +1 @@
|
|||
INRIA Sophia-Antipolis (France)
|
||||
|
|
@ -0,0 +1 @@
|
|||
Surface reconstruction using an advancing front method.
|
||||
|
|
@ -0,0 +1 @@
|
|||
GPL (v3 or later)
|
||||
|
|
@ -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 @@
|
|||
1 2 3
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
0 0 0
|
||||
1 1 1
|
||||
|
|
@ -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
|
||||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -119,3 +119,5 @@ IMAGE_PATH = ${CMAKE_SOURCE_DIR}/Documentation/doc/Documentation/fig \
|
|||
${CMAKE_SOURCE_DIR}/Stream_support/doc/Stream_support/fig \
|
||||
${CMAKE_SOURCE_DIR}/Surface_modeling/doc/Surface_modeling/fig \
|
||||
${CMAKE_SOURCE_DIR}/Barycentric_coordinates_2/doc/Barycentric_coordinates_2/fig \
|
||||
${CMAKE_SOURCE_DIR}/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/fig \
|
||||
|
||||
|
|
|
|||
|
|
@ -85,4 +85,5 @@ Stream_support
|
|||
Surface_modeling
|
||||
Barycentric_coordinates_2
|
||||
Surface_mesh
|
||||
Advancing_front_surface_reconstruction
|
||||
|
||||
|
|
|
|||
|
|
@ -95,6 +95,7 @@ h1 {
|
|||
\package_listing{Scale_space_reconstruction_3}
|
||||
\package_listing{Skin_surface_3}
|
||||
\package_listing{Mesh_3}
|
||||
\package_listing{Advancing_front_surface_reconstruction}
|
||||
|
||||
\section PartGeometryProcessing Geometry Processing
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
||||
|
|
@ -357,6 +357,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() const {
|
||||
return qobject_cast<Scene_points_with_normal_item*>(scene->item(scene->mainSelectionIndex()));
|
||||
}
|
||||
|
||||
QList<QAction*> actions() const {
|
||||
return QList<QAction*>() << actionAdvancingFrontReconstruction;
|
||||
}
|
||||
|
||||
public 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_reconstructionP((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;
|
||||
}
|
||||
|
||||
|
|
@ -311,6 +311,7 @@ QMenu* Scene_points_with_normal_item::contextMenu()
|
|||
actionSelectDuplicatedPoints->setObjectName("actionSelectDuplicatedPoints");
|
||||
connect(actionSelectDuplicatedPoints, SIGNAL(triggered()),this, SLOT(selectDuplicates()));
|
||||
|
||||
|
||||
menu->setProperty(prop_name, true);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -306,16 +306,18 @@ 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)
|
||||
{
|
||||
if(!soup)
|
||||
soup = new Polygon_soup;
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue