mirror of https://github.com/CGAL/cgal
Remove trailing whitespace / tabs
This commit is contained in:
parent
fb8463f470
commit
580a1efd5c
|
|
@ -2,13 +2,13 @@
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
\mainpage User Manual
|
\mainpage User Manual
|
||||||
\anchor Chapter_3D_Alpha_Shapes
|
\anchor Chapter_3D_Alpha_Shapes
|
||||||
\cgalAutoToc
|
\cgalAutoToc
|
||||||
\authors Tran Kai Frank Da, Sébastien Loriot, and Mariette Yvinec
|
\authors Tran Kai Frank Da, Sébastien Loriot, and Mariette Yvinec
|
||||||
|
|
||||||
\image html alphashape.png
|
\image html alphashape.png
|
||||||
\image latex alphashape.png
|
\image latex alphashape.png
|
||||||
|
|
||||||
Assume we are given a set \f$ S\f$ of points in 2D or 3D and we would like to
|
Assume we are given a set \f$ S\f$ of points in 2D or 3D and we would like to
|
||||||
have something like "the shape formed by these points". This is
|
have something like "the shape formed by these points". This is
|
||||||
|
|
@ -56,8 +56,8 @@ are based on its generalization, the regular triangulation
|
||||||
replacing the euclidean distance by the power to weighted points.
|
replacing the euclidean distance by the power to weighted points.
|
||||||
|
|
||||||
Let us consider the basic case with a Delaunay triangulation.
|
Let us consider the basic case with a Delaunay triangulation.
|
||||||
We first define the alpha complex of the set of points \f$ S\f$.
|
We first define the alpha complex of the set of points \f$ S\f$.
|
||||||
The alpha complex is a subcomplex
|
The alpha complex is a subcomplex
|
||||||
of the Delaunay triangulation.
|
of the Delaunay triangulation.
|
||||||
For a given value of \f$ \alpha\f$, the alpha complex includes
|
For a given value of \f$ \alpha\f$, the alpha complex includes
|
||||||
all the simplices in the Delaunay triangulation which have
|
all the simplices in the Delaunay triangulation which have
|
||||||
|
|
@ -75,17 +75,17 @@ singular if it is not a facet of a \f$ (k+1)\f$-simplex of the complex.
|
||||||
the alpha shapes correspond strictly to the above definition.
|
the alpha shapes correspond strictly to the above definition.
|
||||||
The regularized mode provides a regularized version of the alpha shapes.
|
The regularized mode provides a regularized version of the alpha shapes.
|
||||||
It corresponds to the domain covered by a regularized version
|
It corresponds to the domain covered by a regularized version
|
||||||
of the alpha complex where singular faces are removed
|
of the alpha complex where singular faces are removed
|
||||||
(See \cgalFigureRef{figgenregex} for an example).
|
(See \cgalFigureRef{figgenregex} for an example).
|
||||||
|
|
||||||
\cgalFigureBegin{figgenregex,gen-reg-ex.png}
|
\cgalFigureBegin{figgenregex,gen-reg-ex.png}
|
||||||
Comparison of general and regularized alpha-shape. <B>Left:</B> Some points are taken on the surface of a torus, three points being taken relatively far from the surface of the torus; <B>Middle:</B> The general alpha-shape (for a large enough alpha value) contains the singular triangle facet of the three isolated points; <B>Right:</B> The regularized version (for the same value of alpha) does not contains any singular facet.
|
Comparison of general and regularized alpha-shape. <B>Left:</B> Some points are taken on the surface of a torus, three points being taken relatively far from the surface of the torus; <B>Middle:</B> The general alpha-shape (for a large enough alpha value) contains the singular triangle facet of the three isolated points; <B>Right:</B> The regularized version (for the same value of alpha) does not contains any singular facet.
|
||||||
\cgalFigureEnd
|
\cgalFigureEnd
|
||||||
|
|
||||||
The alpha shapes of a set of points
|
The alpha shapes of a set of points
|
||||||
\f$ S\f$ form a discrete family, even though they
|
\f$ S\f$ form a discrete family, even though they
|
||||||
are defined for all real numbers \f$ \alpha\f$.
|
are defined for all real numbers \f$ \alpha\f$.
|
||||||
The entire family of alpha shapes can be represented
|
The entire family of alpha shapes can be represented
|
||||||
through the underlying triangulation of \f$ S\f$. In this representation
|
through the underlying triangulation of \f$ S\f$. In this representation
|
||||||
each \f$ k\f$-simplex of the underlying triangulation is associated with an
|
each \f$ k\f$-simplex of the underlying triangulation is associated with an
|
||||||
interval that specifies for which values of \f$ \alpha\f$ the \f$ k\f$-simplex
|
interval that specifies for which values of \f$ \alpha\f$ the \f$ k\f$-simplex
|
||||||
|
|
@ -95,23 +95,23 @@ easily. Furthermore, we can select the optimal value
|
||||||
of \f$ \alpha\f$ to get an alpha shape including all data points
|
of \f$ \alpha\f$ to get an alpha shape including all data points
|
||||||
and having less than a given number of connected components.
|
and having less than a given number of connected components.
|
||||||
Also, the alpha-values allows to define a filtration on the
|
Also, the alpha-values allows to define a filtration on the
|
||||||
faces of the triangulation of a set of points.
|
faces of the triangulation of a set of points.
|
||||||
In this filtration, the faces of the triangulation are output
|
In this filtration, the faces of the triangulation are output
|
||||||
in increasing order of the alpha value
|
in increasing order of the alpha value
|
||||||
for which they appear
|
for which they appear
|
||||||
in the alpha complex. In case of equal alpha values,
|
in the alpha complex. In case of equal alpha values,
|
||||||
lower dimensional faces are output first.
|
lower dimensional faces are output first.
|
||||||
|
|
||||||
The definition is analog in the case of weighted alpha shapes.
|
The definition is analog in the case of weighted alpha shapes.
|
||||||
The input set is now a set of weighted points (which can be regarded
|
The input set is now a set of weighted points (which can be regarded
|
||||||
as spheres) and the underlying triangulation
|
as spheres) and the underlying triangulation
|
||||||
is the regular triangulation of this set.
|
is the regular triangulation of this set.
|
||||||
Two spheres, or two weighted points, with centers \f$ C_1, C_2\f$
|
Two spheres, or two weighted points, with centers \f$ C_1, C_2\f$
|
||||||
and radii \f$ r_1, r_2 \f$ are said to be orthogonal iff
|
and radii \f$ r_1, r_2 \f$ are said to be orthogonal iff
|
||||||
\f$ C_1C_2 ^2 = r_1^2 + r_2^2\f$ and suborthogonal
|
\f$ C_1C_2 ^2 = r_1^2 + r_2^2\f$ and suborthogonal
|
||||||
iff \f$ C_1C_2 ^2 < r_1^2 + r_2^2\f$.
|
iff \f$ C_1C_2 ^2 < r_1^2 + r_2^2\f$.
|
||||||
For a given value of \f$ \alpha\f$,
|
For a given value of \f$ \alpha\f$,
|
||||||
the weighted alpha complex is formed with the simplices of the
|
the weighted alpha complex is formed with the simplices of the
|
||||||
regular triangulation triangulation
|
regular triangulation triangulation
|
||||||
such that there is a sphere orthogonal to the weighted points associated
|
such that there is a sphere orthogonal to the weighted points associated
|
||||||
with the vertices of the simplex and suborthogonal to all the other
|
with the vertices of the simplex and suborthogonal to all the other
|
||||||
|
|
@ -127,7 +127,7 @@ The class `Alpha_shape_3<Dt,ExactAlphaComparisonTag>` represents the whole
|
||||||
family of alpha shapes for a given set of points.
|
family of alpha shapes for a given set of points.
|
||||||
The class includes the underlying triangulation `Dt`
|
The class includes the underlying triangulation `Dt`
|
||||||
of the set, and associates to each \f$ k\f$-face of this triangulation
|
of the set, and associates to each \f$ k\f$-face of this triangulation
|
||||||
an interval specifying
|
an interval specifying
|
||||||
for which values of \f$ \alpha\f$ the face belongs to the
|
for which values of \f$ \alpha\f$ the face belongs to the
|
||||||
alpha complex.
|
alpha complex.
|
||||||
The second template parameter, `ExactAlphaComparisonTag`, is a tag that,
|
The second template parameter, `ExactAlphaComparisonTag`, is a tag that,
|
||||||
|
|
@ -139,11 +139,11 @@ the \f$ \alpha\f$ values where the alpha shape changes.
|
||||||
|
|
||||||
Additionally, the class has a filtration member function that, given
|
Additionally, the class has a filtration member function that, given
|
||||||
an output iterator with `Object`
|
an output iterator with `Object`
|
||||||
as value type, outputs the faces of the triangulation
|
as value type, outputs the faces of the triangulation
|
||||||
according to the
|
according to the
|
||||||
order of apparition in the alpha complex when alpha increases.
|
order of apparition in the alpha complex when alpha increases.
|
||||||
|
|
||||||
Finally, it provides a function to determine
|
Finally, it provides a function to determine
|
||||||
the smallest value \f$ \alpha\f$
|
the smallest value \f$ \alpha\f$
|
||||||
such that the alpha shape satisfies the following two properties: <br>
|
such that the alpha shape satisfies the following two properties: <br>
|
||||||
<ol>
|
<ol>
|
||||||
|
|
@ -157,7 +157,7 @@ points cannot be inserted or removed.
|
||||||
|
|
||||||
\subsection AlphaShape_3DAlphaShapeForAFixedAlpha Alpha Shape for a Fixed Alpha
|
\subsection AlphaShape_3DAlphaShapeForAFixedAlpha Alpha Shape for a Fixed Alpha
|
||||||
|
|
||||||
Given a value of alpha, the class `Fixed_alpha_shape_3<Dt>` represents one
|
Given a value of alpha, the class `Fixed_alpha_shape_3<Dt>` represents one
|
||||||
alpha shape for a given set of points.
|
alpha shape for a given set of points.
|
||||||
The class includes the underlying triangulation `Dt`
|
The class includes the underlying triangulation `Dt`
|
||||||
of the set, and associates to each \f$ k\f$-face of this triangulation
|
of the set, and associates to each \f$ k\f$-face of this triangulation
|
||||||
|
|
@ -168,7 +168,7 @@ points can be inserted or removed.
|
||||||
|
|
||||||
Both classes provide member functions to classify for a (given) value
|
Both classes provide member functions to classify for a (given) value
|
||||||
of \f$ \alpha\f$ the different faces of the triangulation as
|
of \f$ \alpha\f$ the different faces of the triangulation as
|
||||||
`EXTERIOR`, `SINGULAR`, `REGULAR` or
|
`EXTERIOR`, `SINGULAR`, `REGULAR` or
|
||||||
`INTERIOR` with respect
|
`INTERIOR` with respect
|
||||||
to the alpha shape. A \f$ k\f$-face on the boundary of the alpha complex
|
to the alpha shape. A \f$ k\f$-face on the boundary of the alpha complex
|
||||||
is said to be: `REGULAR` if it is a subface of the alpha-complex which
|
is said to be: `REGULAR` if it is a subface of the alpha-complex which
|
||||||
|
|
@ -189,7 +189,7 @@ of its circumscribed circle is larger than alpha.
|
||||||
|
|
||||||
The classes provide also output iterators to get for a given `alpha` value
|
The classes provide also output iterators to get for a given `alpha` value
|
||||||
the vertices, edges, facets and cells of the different types
|
the vertices, edges, facets and cells of the different types
|
||||||
(`EXTERIOR`, `SINGULAR`, `REGULAR` or
|
(`EXTERIOR`, `SINGULAR`, `REGULAR` or
|
||||||
`INTERIOR`).
|
`INTERIOR`).
|
||||||
|
|
||||||
\subsection AlphaShape3DIO Input/Output
|
\subsection AlphaShape3DIO Input/Output
|
||||||
|
|
@ -237,7 +237,7 @@ The triangulation data structure of the triangulation
|
||||||
has to be a model of the concept `TriangulationDataStructure_3`,
|
has to be a model of the concept `TriangulationDataStructure_3`,
|
||||||
and it must be parameterized with vertex and cell classes, which are model of the concepts
|
and it must be parameterized with vertex and cell classes, which are model of the concepts
|
||||||
`FixedAlphaShapeVertex_3` and `FixedAlphaShapeCell_3`.
|
`FixedAlphaShapeVertex_3` and `FixedAlphaShapeCell_3`.
|
||||||
The package provides models `Fixed_alpha_shape_vertex_base_3<Gt>`
|
The package provides models `Fixed_alpha_shape_vertex_base_3<Gt>`
|
||||||
and `Fixed_alpha_shape_cell_base_3<Gt>`, respectively.
|
and `Fixed_alpha_shape_cell_base_3<Gt>`, respectively.
|
||||||
|
|
||||||
\subsection AlphaShape3D_ConceptAndModelsTDS Triangulation data structure
|
\subsection AlphaShape3D_ConceptAndModelsTDS Triangulation data structure
|
||||||
|
|
@ -266,7 +266,7 @@ represents only one alpha shape (for a fixed alpha). When using the same kernel,
|
||||||
`Fixed_alpha_shape_3<Dt>` is a lighter version. It is thus naturally much more efficient
|
`Fixed_alpha_shape_3<Dt>` is a lighter version. It is thus naturally much more efficient
|
||||||
when the alpha-shape is needed for a single given value of alpha.
|
when the alpha-shape is needed for a single given value of alpha.
|
||||||
In addition, note that the class `Alpha_shape_3<Dt,ExactAlphaComparisonTag>`
|
In addition, note that the class `Alpha_shape_3<Dt,ExactAlphaComparisonTag>`
|
||||||
requires constructions (squared radius of simplices) while the
|
requires constructions (squared radius of simplices) while the
|
||||||
class `Fixed_alpha_shape_3<Dt>` uses only predicates.
|
class `Fixed_alpha_shape_3<Dt>` uses only predicates.
|
||||||
This implies that a certified construction of one (several)
|
This implies that a certified construction of one (several)
|
||||||
alpha-shape, using the `Alpha_shape_3<Dt,ExactAlphaComparisonTag>` requires a kernel
|
alpha-shape, using the `Alpha_shape_3<Dt,ExactAlphaComparisonTag>` requires a kernel
|
||||||
|
|
@ -278,13 +278,13 @@ two that supports incremental insertion and removal of points.
|
||||||
|
|
||||||
We give the time spent while computing the alpha shape of a protein (considered
|
We give the time spent while computing the alpha shape of a protein (considered
|
||||||
as a set of weighted points) featuring 4251 atoms (using `gcc 4.3` under Linux with `-O3`
|
as a set of weighted points) featuring 4251 atoms (using `gcc 4.3` under Linux with `-O3`
|
||||||
and `-DNDEBUG` flags, on a 2.27GHz Intel(R) Xeon(R) E5520 CPU):
|
and `-DNDEBUG` flags, on a 2.27GHz Intel(R) Xeon(R) E5520 CPU):
|
||||||
Using `Exact_predicates_inexact_constructions_kernel`, building
|
Using `Exact_predicates_inexact_constructions_kernel`, building
|
||||||
the regular triangulation requires 0.09s, then the class `Fixed_alpha_shape_3<Dt>`
|
the regular triangulation requires 0.09s, then the class `Fixed_alpha_shape_3<Dt>`
|
||||||
required 0.05s while the class `Alpha_shape_3<Dt,ExactAlphaComparisonTag>` requires 0.35s
|
required 0.05s while the class `Alpha_shape_3<Dt,ExactAlphaComparisonTag>` requires 0.35s
|
||||||
if `ExactAlphaComparisonTag` is `Tag_false` (and 0.70s with `Tag_true`).
|
if `ExactAlphaComparisonTag` is `Tag_false` (and 0.70s with `Tag_true`).
|
||||||
Using `Exact_predicates_exact_constructions_kernel`, building
|
Using `Exact_predicates_exact_constructions_kernel`, building
|
||||||
the regular triangulation requires 0.19s and then the class `Alpha_shape_3<Dt,ExactAlphaComparisonTag>`
|
the regular triangulation requires 0.19s and then the class `Alpha_shape_3<Dt,ExactAlphaComparisonTag>`
|
||||||
requires 0.90s.
|
requires 0.90s.
|
||||||
|
|
||||||
\section Alpha_shapes_3Examples Examples
|
\section Alpha_shapes_3Examples Examples
|
||||||
|
|
@ -350,6 +350,6 @@ results will suffer from round-off problems.
|
||||||
|
|
||||||
\cgalExample{Alpha_shapes_3/ex_periodic_alpha_shapes_3.cpp}
|
\cgalExample{Alpha_shapes_3/ex_periodic_alpha_shapes_3.cpp}
|
||||||
|
|
||||||
*/
|
*/
|
||||||
} /* namespace CGAL */
|
} /* namespace CGAL */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
// Copyright (c) 1997
|
// Copyright (c) 1997
|
||||||
// Utrecht University (The Netherlands),
|
// Utrecht University (The Netherlands),
|
||||||
// ETH Zurich (Switzerland),
|
// ETH Zurich (Switzerland),
|
||||||
// INRIA Sophia-Antipolis (France),
|
// INRIA Sophia-Antipolis (France),
|
||||||
// Max-Planck-Institute Saarbruecken (Germany),
|
// Max-Planck-Institute Saarbruecken (Germany),
|
||||||
// and Tel-Aviv University (Israel). All rights reserved.
|
// and Tel-Aviv University (Israel). All rights reserved.
|
||||||
//
|
//
|
||||||
// This file is part of CGAL (www.cgal.org);
|
// This file is part of CGAL (www.cgal.org);
|
||||||
//
|
//
|
||||||
|
|
@ -74,7 +74,7 @@ operator<<(VRML_2_ostream& os,
|
||||||
os << Indent << " ";
|
os << Indent << " ";
|
||||||
for (int i=0; i<4; i++)
|
for (int i=0; i<4; i++)
|
||||||
if (i != (*Flist_it).second){
|
if (i != (*Flist_it).second){
|
||||||
os << V[(*Flist_it).first->vertex(i)];
|
os << V[(*Flist_it).first->vertex(i)];
|
||||||
os << ", ";
|
os << ", ";
|
||||||
}
|
}
|
||||||
if (Flist_it != Flist_end)
|
if (Flist_it != Flist_end)
|
||||||
|
|
|
||||||
|
|
@ -34,12 +34,12 @@ digraph example {
|
||||||
\cgalHeading{Notations}
|
\cgalHeading{Notations}
|
||||||
|
|
||||||
<dl>
|
<dl>
|
||||||
<dt>`G`</dt> <dd>A type that is a model of a graph concept.</dd>
|
<dt>`G`</dt> <dd>A type that is a model of a graph concept.</dd>
|
||||||
<dt>`g`</dt> <dd>An object of type `G`.</dd>
|
<dt>`g`</dt> <dd>An object of type `G`.</dd>
|
||||||
<dt>`u`, `v`</dt> <dd>Objects of type `boost::graph_traits<G>::%vertex_descriptor`.</dd>
|
<dt>`u`, `v`</dt> <dd>Objects of type `boost::graph_traits<G>::%vertex_descriptor`.</dd>
|
||||||
<dt>`h`</dt> <dd>An object of type `boost::graph_traits<G>::%halfedge_descriptor`.</dd>
|
<dt>`h`</dt> <dd>An object of type `boost::graph_traits<G>::%halfedge_descriptor`.</dd>
|
||||||
<dt>`e`</dt> <dd>An object of type `boost::graph_traits<G>::%edge_descriptor`.</dd>
|
<dt>`e`</dt> <dd>An object of type `boost::graph_traits<G>::%edge_descriptor`.</dd>
|
||||||
<dt>`f`</dt> <dd>An object of type `boost::graph_traits<G>::%face_descriptor`.</dd>
|
<dt>`f`</dt> <dd>An object of type `boost::graph_traits<G>::%face_descriptor`.</dd>
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
\cgalHeading{%VertexListGraph}
|
\cgalHeading{%VertexListGraph}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
// $URL$
|
// $URL$
|
||||||
// $Id$
|
// $Id$
|
||||||
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Author(s) : Andreas Fabri, Fernando Cacciola
|
// Author(s) : Andreas Fabri, Fernando Cacciola
|
||||||
|
|
||||||
|
|
@ -90,7 +90,7 @@ using boost::face_external_index;
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
template<typename Polyhedron, typename Handle>
|
template<typename Polyhedron, typename Handle>
|
||||||
struct Index_accessor
|
struct Index_accessor
|
||||||
: boost::put_get_helper< std::size_t&, Index_accessor<Polyhedron,Handle> >
|
: boost::put_get_helper< std::size_t&, Index_accessor<Polyhedron,Handle> >
|
||||||
|
|
|
||||||
|
|
@ -174,7 +174,7 @@ bool read_a_mesh(Polyhedron& p, const std::string& str)
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::vector<T> t_data()
|
std::vector<T> t_data()
|
||||||
{
|
{
|
||||||
std::vector<T> vs;
|
std::vector<T> vs;
|
||||||
for(unsigned int i = 0; i < sizeof(data) / sizeof(data[0]); ++i) {
|
for(unsigned int i = 0; i < sizeof(data) / sizeof(data[0]); ++i) {
|
||||||
|
|
@ -258,7 +258,7 @@ struct Surface_fixture_1 {
|
||||||
f1 = CGAL::is_border(halfedge(u, m),m) ? face(opposite(halfedge(u, m), m), m) : face(halfedge(u, m), m);
|
f1 = CGAL::is_border(halfedge(u, m),m) ? face(opposite(halfedge(u, m), m), m) : face(halfedge(u, m), m);
|
||||||
assert(f1 != boost::graph_traits<Graph>::null_face());
|
assert(f1 != boost::graph_traits<Graph>::null_face());
|
||||||
CGAL::Halfedge_around_face_iterator<Graph> hafib, hafie;
|
CGAL::Halfedge_around_face_iterator<Graph> hafib, hafie;
|
||||||
for(boost::tie(hafib, hafie) = CGAL::halfedges_around_face(halfedge(f1, m), m); hafib != hafie; ++hafib)
|
for(boost::tie(hafib, hafie) = CGAL::halfedges_around_face(halfedge(f1, m), m); hafib != hafie; ++hafib)
|
||||||
{
|
{
|
||||||
if(! CGAL::is_border(opposite(*hafib, m), m))
|
if(! CGAL::is_border(opposite(*hafib, m), m))
|
||||||
f2 = face(opposite(*hafib, m), m);
|
f2 = face(opposite(*hafib, m), m);
|
||||||
|
|
@ -408,7 +408,7 @@ struct Surface_fixture_4 {
|
||||||
h2 = *hb;
|
h2 = *hb;
|
||||||
++found;
|
++found;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert(found == 2);
|
assert(found == 2);
|
||||||
|
|
@ -442,7 +442,7 @@ struct Surface_fixture_5 {
|
||||||
} else if(get(pm, target(*hb,m)) == Point_3(2,-1,0)){
|
} else if(get(pm, target(*hb,m)) == Point_3(2,-1,0)){
|
||||||
h2 = *hb;
|
h2 = *hb;
|
||||||
found++;
|
found++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert(found == 2);
|
assert(found == 2);
|
||||||
|
|
@ -461,9 +461,9 @@ struct Surface_fixture_6 {
|
||||||
assert(CGAL::is_valid_polygon_mesh(m));
|
assert(CGAL::is_valid_polygon_mesh(m));
|
||||||
|
|
||||||
typename boost::graph_traits<Graph>::halfedge_descriptor h;
|
typename boost::graph_traits<Graph>::halfedge_descriptor h;
|
||||||
|
|
||||||
h1 = halfedge(*faces(m).first, m);
|
h1 = halfedge(*faces(m).first, m);
|
||||||
|
|
||||||
h2 = next(next(h1,m),m);
|
h2 = next(next(h1,m),m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -480,7 +480,7 @@ struct Surface_fixture_7 {
|
||||||
assert(is_reading_successful);
|
assert(is_reading_successful);
|
||||||
assert(CGAL::is_valid_polygon_mesh(m));
|
assert(CGAL::is_valid_polygon_mesh(m));
|
||||||
|
|
||||||
h = *(halfedges(m).first);
|
h = *(halfedges(m).first);
|
||||||
}
|
}
|
||||||
|
|
||||||
Graph m;
|
Graph m;
|
||||||
|
|
@ -512,9 +512,9 @@ struct Surface_fixture_8 {
|
||||||
get(pm, target(*hb,m)) == Point_3(0,0,0)){
|
get(pm, target(*hb,m)) == Point_3(0,0,0)){
|
||||||
h3 = *hb;
|
h3 = *hb;
|
||||||
found++;
|
found++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(found == 3);
|
assert(found == 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,16 @@
|
||||||
// Copyright (c) 1997,1998,1999,2000,2001
|
// Copyright (c) 1997,1998,1999,2000,2001
|
||||||
// Utrecht University (The Netherlands),
|
// Utrecht University (The Netherlands),
|
||||||
// ETH Zurich (Switzerland),
|
// ETH Zurich (Switzerland),
|
||||||
// INRIA Sophia-Antipolis (France),
|
// INRIA Sophia-Antipolis (France),
|
||||||
// Max-Planck-Institute Saarbruecken (Germany),
|
// Max-Planck-Institute Saarbruecken (Germany),
|
||||||
// and Tel-Aviv University (Israel). All rights reserved.
|
// and Tel-Aviv University (Israel). All rights reserved.
|
||||||
//
|
//
|
||||||
// This file is part of CGAL (www.cgal.org)
|
// This file is part of CGAL (www.cgal.org)
|
||||||
//
|
//
|
||||||
// $URL$
|
// $URL$
|
||||||
// $Id$
|
// $Id$
|
||||||
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Author(s) : Andreas Fabri, Sylvain Pion
|
// Author(s) : Andreas Fabri, Sylvain Pion
|
||||||
|
|
||||||
|
|
@ -40,8 +40,8 @@ namespace CGAL {
|
||||||
class CGAL_EXPORT Geomview_stream {
|
class CGAL_EXPORT Geomview_stream {
|
||||||
public:
|
public:
|
||||||
Geomview_stream(const Bbox_3 &bbox = Bbox_3(0,0,0, 1,1,1),
|
Geomview_stream(const Bbox_3 &bbox = Bbox_3(0,0,0, 1,1,1),
|
||||||
const char *machine = nullptr,
|
const char *machine = nullptr,
|
||||||
const char *login = nullptr);
|
const char *login = nullptr);
|
||||||
|
|
||||||
bool fail() const { return false; }
|
bool fail() const { return false; }
|
||||||
bool good() const { return true; }
|
bool good() const { return true; }
|
||||||
|
|
@ -90,62 +90,62 @@ public:
|
||||||
|
|
||||||
double get_vertex_radius() const
|
double get_vertex_radius() const
|
||||||
{
|
{
|
||||||
return radius;
|
return radius;
|
||||||
}
|
}
|
||||||
double set_vertex_radius(double r)
|
double set_vertex_radius(double r)
|
||||||
{
|
{
|
||||||
std::swap(r, radius);
|
std::swap(r, radius);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_line_width() const
|
int get_line_width() const
|
||||||
{
|
{
|
||||||
return line_width;
|
return line_width;
|
||||||
}
|
}
|
||||||
int set_line_width(int w)
|
int set_line_width(int w)
|
||||||
{
|
{
|
||||||
std::swap(w, line_width);
|
std::swap(w, line_width);
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool set_wired(bool b)
|
bool set_wired(bool b)
|
||||||
{
|
{
|
||||||
std::swap(b, wired_flag);
|
std::swap(b, wired_flag);
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
bool get_wired() const
|
bool get_wired() const
|
||||||
{
|
{
|
||||||
return wired_flag;
|
return wired_flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool set_echo(bool b)
|
bool set_echo(bool b)
|
||||||
{
|
{
|
||||||
std::swap(b, echo_flag);
|
std::swap(b, echo_flag);
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
bool get_echo() const
|
bool get_echo() const
|
||||||
{
|
{
|
||||||
return echo_flag;
|
return echo_flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool set_raw(bool b)
|
bool set_raw(bool b)
|
||||||
{
|
{
|
||||||
std::swap(b, raw_flag);
|
std::swap(b, raw_flag);
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
bool get_raw() const
|
bool get_raw() const
|
||||||
{
|
{
|
||||||
return raw_flag;
|
return raw_flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool set_trace(bool b)
|
bool set_trace(bool b)
|
||||||
{
|
{
|
||||||
std::swap(b, trace_flag);
|
std::swap(b, trace_flag);
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
bool get_trace() const
|
bool get_trace() const
|
||||||
{
|
{
|
||||||
return trace_flag;
|
return trace_flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
void trace(const std::string s) const
|
void trace(const std::string s) const
|
||||||
|
|
@ -171,27 +171,27 @@ public:
|
||||||
|
|
||||||
bool set_binary_mode(bool b = true)
|
bool set_binary_mode(bool b = true)
|
||||||
{
|
{
|
||||||
std::swap(b, binary_flag);
|
std::swap(b, binary_flag);
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
bool set_ascii_mode(bool b = true)
|
bool set_ascii_mode(bool b = true)
|
||||||
{
|
{
|
||||||
return !set_binary_mode(!b);
|
return !set_binary_mode(!b);
|
||||||
}
|
}
|
||||||
bool get_binary_mode() const
|
bool get_binary_mode() const
|
||||||
{
|
{
|
||||||
return binary_flag;
|
return binary_flag;
|
||||||
}
|
}
|
||||||
bool get_ascii_mode() const
|
bool get_ascii_mode() const
|
||||||
{
|
{
|
||||||
return !binary_flag;
|
return !binary_flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string get_new_id(const std::string & s);
|
std::string get_new_id(const std::string & s);
|
||||||
|
|
||||||
const Bbox_3 & get_bbox()
|
const Bbox_3 & get_bbox()
|
||||||
{
|
{
|
||||||
return bb;
|
return bb;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pickplane()
|
void pickplane()
|
||||||
|
|
@ -201,7 +201,7 @@ public:
|
||||||
|
|
||||||
static char* nth(char* s, int count);
|
static char* nth(char* s, int count);
|
||||||
static void parse_point(const char* pickpoint,
|
static void parse_point(const char* pickpoint,
|
||||||
double &x, double &y, double &z, double &w);
|
double &x, double &y, double &z, double &w);
|
||||||
private:
|
private:
|
||||||
void setup_geomview(const char *machine, const char *login);
|
void setup_geomview(const char *machine, const char *login);
|
||||||
void frame(const Bbox_3 &bbox);
|
void frame(const Bbox_3 &bbox);
|
||||||
|
|
@ -228,9 +228,9 @@ output_point(Geomview_stream &gv, const FT &x, const FT &y, const FT &z)
|
||||||
{
|
{
|
||||||
bool ascii_bak = true; // the initialization value shuts up the compiler.
|
bool ascii_bak = true; // the initialization value shuts up the compiler.
|
||||||
if (!gv.get_raw()) {
|
if (!gv.get_raw()) {
|
||||||
ascii_bak = gv.set_ascii_mode();
|
ascii_bak = gv.set_ascii_mode();
|
||||||
gv << "(geometry " << gv.get_new_id("P")
|
gv << "(geometry " << gv.get_new_id("P")
|
||||||
<< " {appearance {linewidth 5 material {edgecolor "
|
<< " {appearance {linewidth 5 material {edgecolor "
|
||||||
<< gv.vcr() << gv.vcg() << gv.vcb() << "}}{SKEL 1 1 ";
|
<< gv.vcr() << gv.vcg() << gv.vcb() << "}}{SKEL 1 1 ";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -238,7 +238,7 @@ output_point(Geomview_stream &gv, const FT &x, const FT &y, const FT &z)
|
||||||
|
|
||||||
if (!gv.get_raw()) {
|
if (!gv.get_raw()) {
|
||||||
gv << "1 0\n}})";
|
gv << "1 0\n}})";
|
||||||
gv.set_ascii_mode(ascii_bak);
|
gv.set_ascii_mode(ascii_bak);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -363,8 +363,8 @@ Geomview_stream::draw_triangles(InputIterator begin, InputIterator end)
|
||||||
std::vector<Point> points;
|
std::vector<Point> points;
|
||||||
for (Tit i = triangles.begin(); i != triangles.end(); ++i)
|
for (Tit i = triangles.begin(); i != triangles.end(); ++i)
|
||||||
for (int j = 0; j < 3; ++j)
|
for (int j = 0; j < 3; ++j)
|
||||||
if (point_map.insert(typename Point_map::value_type(i->vertex(j),
|
if (point_map.insert(typename Point_map::value_type(i->vertex(j),
|
||||||
points.size())).second)
|
points.size())).second)
|
||||||
points.push_back(i->vertex(j));
|
points.push_back(i->vertex(j));
|
||||||
|
|
||||||
bool ascii_bak = get_ascii_mode();
|
bool ascii_bak = get_ascii_mode();
|
||||||
|
|
@ -383,8 +383,8 @@ Geomview_stream::draw_triangles(InputIterator begin, InputIterator end)
|
||||||
// Triangles vertices indices.
|
// Triangles vertices indices.
|
||||||
for (Tit tit = triangles.begin(); tit != triangles.end(); ++tit) {
|
for (Tit tit = triangles.begin(); tit != triangles.end(); ++tit) {
|
||||||
(*this) << 3;
|
(*this) << 3;
|
||||||
for (int j = 0; j < 3; ++j)
|
for (int j = 0; j < 3; ++j)
|
||||||
(*this) << point_map[tit->vertex(j)];
|
(*this) << point_map[tit->vertex(j)];
|
||||||
(*this) << 0; // without color.
|
(*this) << 0; // without color.
|
||||||
}
|
}
|
||||||
// Footer.
|
// Footer.
|
||||||
|
|
@ -487,14 +487,14 @@ operator<<(Geomview_stream &gv, const Ray_2<R> &r)
|
||||||
// Note: it won't work if double is not convertible to an RT...
|
// Note: it won't work if double is not convertible to an RT...
|
||||||
const Bbox_3 & bb = gv.get_bbox();
|
const Bbox_3 & bb = gv.get_bbox();
|
||||||
Object result = intersection(Iso_rectangle_2<R>(
|
Object result = intersection(Iso_rectangle_2<R>(
|
||||||
Point_2<R>(bb.xmin(), bb.ymin()),
|
Point_2<R>(bb.xmin(), bb.ymin()),
|
||||||
Point_2<R>(bb.xmax(), bb.ymax())), r);
|
Point_2<R>(bb.xmax(), bb.ymax())), r);
|
||||||
Point_2<R> ipoint;
|
Point_2<R> ipoint;
|
||||||
Segment_2<R> iseg;
|
Segment_2<R> iseg;
|
||||||
if (assign(ipoint, result))
|
if (assign(ipoint, result))
|
||||||
gv << ipoint;
|
gv << ipoint;
|
||||||
else if (assign(iseg, result))
|
else if (assign(iseg, result))
|
||||||
gv << iseg;
|
gv << iseg;
|
||||||
return gv;
|
return gv;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -509,14 +509,14 @@ operator<<(Geomview_stream &gv, const Line_2<R> &r)
|
||||||
// Note: it won't work if double is not convertible to an RT...
|
// Note: it won't work if double is not convertible to an RT...
|
||||||
const Bbox_3 & bb = gv.get_bbox();
|
const Bbox_3 & bb = gv.get_bbox();
|
||||||
Object result = intersection(Iso_rectangle_2<R>(
|
Object result = intersection(Iso_rectangle_2<R>(
|
||||||
Point_2<R>(bb.xmin(), bb.ymin()),
|
Point_2<R>(bb.xmin(), bb.ymin()),
|
||||||
Point_2<R>(bb.xmax(), bb.ymax())), r);
|
Point_2<R>(bb.xmax(), bb.ymax())), r);
|
||||||
Point_2<R> ipoint;
|
Point_2<R> ipoint;
|
||||||
Segment_2<R> iseg;
|
Segment_2<R> iseg;
|
||||||
if (assign(ipoint, result))
|
if (assign(ipoint, result))
|
||||||
gv << ipoint;
|
gv << ipoint;
|
||||||
else if (assign(iseg, result))
|
else if (assign(iseg, result))
|
||||||
gv << iseg;
|
gv << iseg;
|
||||||
return gv;
|
return gv;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -563,7 +563,7 @@ Geomview_stream&
|
||||||
operator>>(Geomview_stream &gv, Point_3<R> &point)
|
operator>>(Geomview_stream &gv, Point_3<R> &point)
|
||||||
{
|
{
|
||||||
const char *gclpick =
|
const char *gclpick =
|
||||||
"(pick world pickplane * nil nil nil nil nil nil nil)";
|
"(pick world pickplane * nil nil nil nil nil nil nil)";
|
||||||
|
|
||||||
bool ascii_bak = gv.set_ascii_mode();
|
bool ascii_bak = gv.set_ascii_mode();
|
||||||
gv << "(pickable pickplane yes) (ui-target pickplane yes)"
|
gv << "(pickable pickplane yes) (ui-target pickplane yes)"
|
||||||
|
|
@ -580,7 +580,7 @@ operator>>(Geomview_stream &gv, Point_3<R> &point)
|
||||||
|
|
||||||
// we echo the input
|
// we echo the input
|
||||||
if (gv.get_echo())
|
if (gv.get_echo())
|
||||||
gv << point;
|
gv << point;
|
||||||
|
|
||||||
// we are done and tell geomview to stop sending pick events
|
// we are done and tell geomview to stop sending pick events
|
||||||
gv << "(uninterest " << gclpick << ") (pickable pickplane no)";
|
gv << "(uninterest " << gclpick << ") (pickable pickplane no)";
|
||||||
|
|
|
||||||
|
|
@ -340,7 +340,7 @@ namespace CGAL {
|
||||||
std::ofstream output(filename);
|
std::ofstream output(filename);
|
||||||
if (!output.is_open())
|
if (!output.is_open())
|
||||||
{ return false; }
|
{ return false; }
|
||||||
|
|
||||||
return write_off(alcc, output);
|
return write_off(alcc, output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
\mainpage User Manual
|
\mainpage User Manual
|
||||||
\anchor Chapter_2D_Conforming_Triangulations_and_Meshes
|
\anchor Chapter_2D_Conforming_Triangulations_and_Meshes
|
||||||
\anchor userchapter2DMeshes
|
\anchor userchapter2DMeshes
|
||||||
\cgalAutoToc
|
\cgalAutoToc
|
||||||
|
|
@ -12,9 +12,9 @@ conforming triangulations and 2D meshes. Conforming triangulations will be
|
||||||
described in Section \ref secMesh_2_conforming_triangulation and
|
described in Section \ref secMesh_2_conforming_triangulation and
|
||||||
meshes in Section \ref secMesh_2_meshes.
|
meshes in Section \ref secMesh_2_meshes.
|
||||||
|
|
||||||
\section secMesh_2_conforming_triangulation Conforming Triangulations
|
\section secMesh_2_conforming_triangulation Conforming Triangulations
|
||||||
|
|
||||||
\subsection secMesh_2_conforming_definitions Definitions
|
\subsection secMesh_2_conforming_definitions Definitions
|
||||||
|
|
||||||
A triangulation is a <I>Delaunay triangulation</I> if the circumscribing
|
A triangulation is a <I>Delaunay triangulation</I> if the circumscribing
|
||||||
circle of any facet of the triangulation contains no vertex in its
|
circle of any facet of the triangulation contains no vertex in its
|
||||||
|
|
@ -46,18 +46,18 @@ triangulation by adding vertices, called <I>Steiner vertices</I>, on
|
||||||
constrained edges until they are decomposed into subconstraints small enough
|
constrained edges until they are decomposed into subconstraints small enough
|
||||||
to be Delaunay or Gabriel edges.
|
to be Delaunay or Gabriel edges.
|
||||||
|
|
||||||
\subsection secMesh_2_building_conforming Building Conforming Triangulations
|
\subsection secMesh_2_building_conforming Building Conforming Triangulations
|
||||||
|
|
||||||
Constrained Delaunay triangulations can be refined into
|
Constrained Delaunay triangulations can be refined into
|
||||||
conforming triangulations by the two following global functions:
|
conforming triangulations by the two following global functions:
|
||||||
|
|
||||||
\code{.cpp}
|
\code{.cpp}
|
||||||
template<class CDT>
|
template<class CDT>
|
||||||
void make_conforming_Delaunay_2 (CDT& t)
|
void make_conforming_Delaunay_2 (CDT& t)
|
||||||
\endcode
|
\endcode
|
||||||
|
|
||||||
\code{.cpp}
|
\code{.cpp}
|
||||||
template<class CDT>
|
template<class CDT>
|
||||||
void make_conforming_Gabriel_2 (CDT& t)
|
void make_conforming_Gabriel_2 (CDT& t)
|
||||||
\endcode
|
\endcode
|
||||||
|
|
||||||
|
|
@ -86,7 +86,7 @@ triangulation and then into a conforming Gabriel triangulation. For
|
||||||
additional control of the refinement algorithm, this class also provides
|
additional control of the refinement algorithm, this class also provides
|
||||||
separate functions to insert one Steiner point at a time.
|
separate functions to insert one Steiner point at a time.
|
||||||
|
|
||||||
\subsection secMesh_2_example_making_conforming Example: Making a Triangulation Conforming Delaunay and Then Conforming Gabriel
|
\subsection secMesh_2_example_making_conforming Example: Making a Triangulation Conforming Delaunay and Then Conforming Gabriel
|
||||||
|
|
||||||
This example inserts several segments into a constrained Delaunay
|
This example inserts several segments into a constrained Delaunay
|
||||||
triangulation, makes it conforming Delaunay, and then conforming
|
triangulation, makes it conforming Delaunay, and then conforming
|
||||||
|
|
@ -101,9 +101,9 @@ See \cgalFigureRef{Conformexampleconform}
|
||||||
From left to right: Initial Delaunay triangulation, the corresponding conforming Delaunay, and the corresponding Gabriel triangulation.
|
From left to right: Initial Delaunay triangulation, the corresponding conforming Delaunay, and the corresponding Gabriel triangulation.
|
||||||
\cgalFigureEnd
|
\cgalFigureEnd
|
||||||
|
|
||||||
\section secMesh_2_meshes Meshes
|
\section secMesh_2_meshes Meshes
|
||||||
|
|
||||||
\subsection secMesh_2_meshes_definition Definitions
|
\subsection secMesh_2_meshes_definition Definitions
|
||||||
|
|
||||||
A mesh is a partition of a given region into simplices whose shapes
|
A mesh is a partition of a given region into simplices whose shapes
|
||||||
and sizes satisfy several criteria.
|
and sizes satisfy several criteria.
|
||||||
|
|
@ -121,10 +121,10 @@ boundary or internals constraints. The segments of the <span class="textsc">Pslg
|
||||||
cover the boundary of the domain.
|
cover the boundary of the domain.
|
||||||
|
|
||||||
The <span class="textsc">Pslg</span> divides the plane into several connected components. By
|
The <span class="textsc">Pslg</span> divides the plane into several connected components. By
|
||||||
default, the domain is the union of the bounded connected components.
|
default, the domain is the union of the bounded connected components.
|
||||||
|
|
||||||
See \cgalFigureRef{Domain} for an example of a domain
|
See \cgalFigureRef{Domain} for an example of a domain
|
||||||
defined without using seed points, and a possible mesh of it.
|
defined without using seed points, and a possible mesh of it.
|
||||||
|
|
||||||
\cgalFigureBegin{Domain,domain-domain-mesh.png}
|
\cgalFigureBegin{Domain,domain-domain-mesh.png}
|
||||||
A domain defined without seed points and the generated mesh.
|
A domain defined without seed points and the generated mesh.
|
||||||
|
|
@ -137,7 +137,7 @@ seed points mark components to be meshed or they mark components not to be
|
||||||
meshed (holes).
|
meshed (holes).
|
||||||
|
|
||||||
See
|
See
|
||||||
\cgalFigureRef{Domainseeds} for another domain defined with the same <span class="textsc">Pslg</span> and two seed points used to define holes.
|
\cgalFigureRef{Domainseeds} for another domain defined with the same <span class="textsc">Pslg</span> and two seed points used to define holes.
|
||||||
In the corresponding mesh these
|
In the corresponding mesh these
|
||||||
two holes are triangulated but not meshed.
|
two holes are triangulated but not meshed.
|
||||||
|
|
||||||
|
|
@ -146,7 +146,7 @@ two holes are triangulated but not meshed.
|
||||||
A domain with two seeds points defining holes and the generated mesh.
|
A domain with two seeds points defining holes and the generated mesh.
|
||||||
\cgalFigureEnd
|
\cgalFigureEnd
|
||||||
|
|
||||||
\subsection secMesh_2_criteria Shape and Size Criteria
|
\subsection secMesh_2_criteria Shape and Size Criteria
|
||||||
|
|
||||||
The shape criterion for triangles is a lower bound \f$ B\f$ on the ratio
|
The shape criterion for triangles is a lower bound \f$ B\f$ on the ratio
|
||||||
between the circumradius and the shortest edge length. Such a bound
|
between the circumradius and the shortest edge length. Such a bound
|
||||||
|
|
@ -193,7 +193,7 @@ satisfy size and shape criteria except for the small input angles.
|
||||||
In addition, the algorithm may succeed in producing meshes with a lower
|
In addition, the algorithm may succeed in producing meshes with a lower
|
||||||
angle bound greater than \f$ 20.7\f$ degrees, but there is no such guarantee.
|
angle bound greater than \f$ 20.7\f$ degrees, but there is no such guarantee.
|
||||||
|
|
||||||
\subsection secMesh_2_building_meshes Building Meshes
|
\subsection secMesh_2_building_meshes Building Meshes
|
||||||
|
|
||||||
Meshes are obtained from
|
Meshes are obtained from
|
||||||
constrained Delaunay triangulations by calling the global function :
|
constrained Delaunay triangulations by calling the global function :
|
||||||
|
|
@ -217,14 +217,14 @@ defines criteria that the triangles have to satisfy.
|
||||||
\cgal provides two models for this concept:
|
\cgal provides two models for this concept:
|
||||||
<UL>
|
<UL>
|
||||||
<LI>`Delaunay_mesh_criteria_2<CDT>`, that defines a shape criterion
|
<LI>`Delaunay_mesh_criteria_2<CDT>`, that defines a shape criterion
|
||||||
that bounds the minimum angle of triangles,
|
that bounds the minimum angle of triangles,
|
||||||
<LI>`Delaunay_mesh_size_criteria_2<CDT>`, that adds to the previous
|
<LI>`Delaunay_mesh_size_criteria_2<CDT>`, that adds to the previous
|
||||||
criterion a bound on the maximum edge length.
|
criterion a bound on the maximum edge length.
|
||||||
</UL>
|
</UL>
|
||||||
|
|
||||||
If the function `refine_Delaunay_mesh_2()` is called several times on the
|
If the function `refine_Delaunay_mesh_2()` is called several times on the
|
||||||
same triangulation with different criteria, the algorithm rebuilds the
|
same triangulation with different criteria, the algorithm rebuilds the
|
||||||
internal data structure used for meshing at every call. In order to avoid
|
internal data structure used for meshing at every call. In order to avoid
|
||||||
rebuild the data structure at every call, the advanced user can
|
rebuild the data structure at every call, the advanced user can
|
||||||
use the class `Delaunay_mesher_2<CDT>`. This class provides also step
|
use the class `Delaunay_mesher_2<CDT>`. This class provides also step
|
||||||
by step functions. Those functions insert one vertex at a time.
|
by step functions. Those functions insert one vertex at a time.
|
||||||
|
|
@ -243,8 +243,8 @@ function of the face type (see the concept `DelaunayMeshFaceBase_2`).
|
||||||
|
|
||||||
\subsection secMesh_2_optimization Optimization of Meshes with Lloyd
|
\subsection secMesh_2_optimization Optimization of Meshes with Lloyd
|
||||||
|
|
||||||
The package also provides a global function that runs Lloyd optimization iterations on the
|
The package also provides a global function that runs Lloyd optimization iterations on the
|
||||||
mesh generated by Delaunay refinement. The goal of this mesh optimization is to
|
mesh generated by Delaunay refinement. The goal of this mesh optimization is to
|
||||||
improve the angles inside the mesh, and make them as close as possible to 60 degrees.
|
improve the angles inside the mesh, and make them as close as possible to 60 degrees.
|
||||||
|
|
||||||
\code{.cpp}
|
\code{.cpp}
|
||||||
|
|
@ -257,7 +257,7 @@ Note that this global function has more parameters (see details in reference pag
|
||||||
|
|
||||||
This optimization process alternates relocating vertices to the center of mass
|
This optimization process alternates relocating vertices to the center of mass
|
||||||
of their Voronoi cells, and updating the Delaunay connectivity of the triangulation.
|
of their Voronoi cells, and updating the Delaunay connectivity of the triangulation.
|
||||||
The center of mass is computed with respect to a sizing function that was designed to
|
The center of mass is computed with respect to a sizing function that was designed to
|
||||||
preserve the local density of points in the mesh generated by Delaunay refinement.
|
preserve the local density of points in the mesh generated by Delaunay refinement.
|
||||||
|
|
||||||
See Figure \cgalFigureRef{Lloydfigure} for a mesh generated by `refine_Delaunay_mesh_2()` and optimized
|
See Figure \cgalFigureRef{Lloydfigure} for a mesh generated by `refine_Delaunay_mesh_2()` and optimized
|
||||||
|
|
@ -270,7 +270,7 @@ shows the histogram of angles inside these meshes.
|
||||||
\cgalFigureEnd
|
\cgalFigureEnd
|
||||||
|
|
||||||
\cgalFigureBegin{LloydHistogramfigure,lloyd-histograms.png}
|
\cgalFigureBegin{LloydHistogramfigure,lloyd-histograms.png}
|
||||||
Histograms of angles inside the mesh after Delaunay refinement, and after 10 and 100 iterations
|
Histograms of angles inside the mesh after Delaunay refinement, and after 10 and 100 iterations
|
||||||
of Lloyd optimization.
|
of Lloyd optimization.
|
||||||
After Delaunay refinement, angles are in the interval [28.5; 121.9] degrees.
|
After Delaunay refinement, angles are in the interval [28.5; 121.9] degrees.
|
||||||
After 10 iterations of Lloyd optimization, they are in [29.1; 110.8]. 100 iterations take them to [29.3; 109.9].
|
After 10 iterations of Lloyd optimization, they are in [29.1; 110.8]. 100 iterations take them to [29.3; 109.9].
|
||||||
|
|
@ -316,11 +316,11 @@ faces is used to count them.
|
||||||
|
|
||||||
\subsubsection Mesh_2ExampleLloyd Example Using the Lloyd optimizer
|
\subsubsection Mesh_2ExampleLloyd Example Using the Lloyd optimizer
|
||||||
|
|
||||||
This example uses the global function `lloyd_optimize_mesh_2()`.
|
This example uses the global function `lloyd_optimize_mesh_2()`.
|
||||||
The mesh is generated using the function `refine_Delaunay_mesh_2()` of `CGAL::Delaunay_mesher_2`,
|
The mesh is generated using the function `refine_Delaunay_mesh_2()` of `CGAL::Delaunay_mesher_2`,
|
||||||
and is then optimized using `lloyd_optimize_mesh_2()`. The optimization will stop
|
and is then optimized using `lloyd_optimize_mesh_2()`. The optimization will stop
|
||||||
after 10 (set by `max_iteration_number`) iterations of alternating vertex relocations
|
after 10 (set by `max_iteration_number`) iterations of alternating vertex relocations
|
||||||
and Delaunay connectivity updates. More termination conditions can be used and are detailed
|
and Delaunay connectivity updates. More termination conditions can be used and are detailed
|
||||||
in the Reference Manual.
|
in the Reference Manual.
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -330,6 +330,6 @@ in the Reference Manual.
|
||||||
\section secMesh_2_IO Input/Output
|
\section secMesh_2_IO Input/Output
|
||||||
It is possible to export the result of a meshing in VTU, using the function `write_vtu()`.
|
It is possible to export the result of a meshing in VTU, using the function `write_vtu()`.
|
||||||
For more information about this format, see \ref IOStreamVTK.
|
For more information about this format, see \ref IOStreamVTK.
|
||||||
*/
|
*/
|
||||||
} /* namespace CGAL */
|
} /* namespace CGAL */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,14 +27,14 @@
|
||||||
//todo try to factorize with functors
|
//todo try to factorize with functors
|
||||||
namespace CGAL{
|
namespace CGAL{
|
||||||
// writes the appended data into the .vtu file
|
// writes the appended data into the .vtu file
|
||||||
template <class FT>
|
template <class FT>
|
||||||
void
|
void
|
||||||
write_vector(std::ostream& os,
|
write_vector(std::ostream& os,
|
||||||
const std::vector<FT>& vect)
|
const std::vector<FT>& vect)
|
||||||
{
|
{
|
||||||
const char* buffer = reinterpret_cast<const char*>(&(vect[0]));
|
const char* buffer = reinterpret_cast<const char*>(&(vect[0]));
|
||||||
std::size_t size = vect.size()*sizeof(FT);
|
std::size_t size = vect.size()*sizeof(FT);
|
||||||
|
|
||||||
os.write(reinterpret_cast<const char *>(&size), sizeof(std::size_t)); // number of bytes encoded
|
os.write(reinterpret_cast<const char *>(&size), sizeof(std::size_t)); // number of bytes encoded
|
||||||
os.write(buffer, vect.size()*sizeof(FT)); // encoded data
|
os.write(buffer, vect.size()*sizeof(FT)); // encoded data
|
||||||
}
|
}
|
||||||
|
|
@ -42,7 +42,7 @@ write_vector(std::ostream& os,
|
||||||
// writes the cells tags before binary data is appended
|
// writes the cells tags before binary data is appended
|
||||||
|
|
||||||
template <class CDT>
|
template <class CDT>
|
||||||
void
|
void
|
||||||
write_cells_tag_2(std::ostream& os,
|
write_cells_tag_2(std::ostream& os,
|
||||||
const CDT & tr,
|
const CDT & tr,
|
||||||
std::size_t number_of_triangles,
|
std::size_t number_of_triangles,
|
||||||
|
|
@ -64,18 +64,18 @@ write_cells_tag_2(std::ostream& os,
|
||||||
os << " <Cells>\n"
|
os << " <Cells>\n"
|
||||||
<< " <DataArray Name=\"connectivity\""
|
<< " <DataArray Name=\"connectivity\""
|
||||||
<< formatattribute << typeattribute;
|
<< formatattribute << typeattribute;
|
||||||
|
|
||||||
if (binary) { // if binary output, just write the xml tag
|
if (binary) { // if binary output, just write the xml tag
|
||||||
os << " offset=\"" << offset << "\"/>\n";
|
os << " offset=\"" << offset << "\"/>\n";
|
||||||
// 3 indices (size_t) per triangle + length of the encoded data (size_t)
|
// 3 indices (size_t) per triangle + length of the encoded data (size_t)
|
||||||
offset += (3 * number_of_triangles + 1) * sizeof(std::size_t);
|
offset += (3 * number_of_triangles + 1) * sizeof(std::size_t);
|
||||||
// 2 indices (size_t) per edge (size_t)
|
// 2 indices (size_t) per edge (size_t)
|
||||||
offset += (2 * std::distance(tr.constrained_edges_begin(),
|
offset += (2 * std::distance(tr.constrained_edges_begin(),
|
||||||
tr.constrained_edges_end())) * sizeof(std::size_t);
|
tr.constrained_edges_end())) * sizeof(std::size_t);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
os << "\">\n";
|
os << "\">\n";
|
||||||
for(typename CDT::Finite_faces_iterator
|
for(typename CDT::Finite_faces_iterator
|
||||||
fit = tr.finite_faces_begin(),
|
fit = tr.finite_faces_begin(),
|
||||||
end = tr.finite_faces_end();
|
end = tr.finite_faces_end();
|
||||||
fit != end; ++fit)
|
fit != end; ++fit)
|
||||||
|
|
@ -89,11 +89,11 @@ write_cells_tag_2(std::ostream& os,
|
||||||
}
|
}
|
||||||
os << " </DataArray>\n";
|
os << " </DataArray>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write offsets
|
// Write offsets
|
||||||
os << " <DataArray Name=\"offsets\""
|
os << " <DataArray Name=\"offsets\""
|
||||||
<< formatattribute << typeattribute;
|
<< formatattribute << typeattribute;
|
||||||
|
|
||||||
if (binary) { // if binary output, just write the xml tag
|
if (binary) { // if binary output, just write the xml tag
|
||||||
os << " offset=\"" << offset << "\"/>\n";
|
os << " offset=\"" << offset << "\"/>\n";
|
||||||
offset += (number_of_triangles +std::distance(tr.constrained_edges_begin(),
|
offset += (number_of_triangles +std::distance(tr.constrained_edges_begin(),
|
||||||
|
|
@ -102,9 +102,9 @@ write_cells_tag_2(std::ostream& os,
|
||||||
// 1 offset (size_t) per cell + length of the encoded data (size_t)
|
// 1 offset (size_t) per cell + length of the encoded data (size_t)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
os << "\">\n";
|
os << "\">\n";
|
||||||
std::size_t cells_offset = 0;
|
std::size_t cells_offset = 0;
|
||||||
for(typename CDT::Finite_faces_iterator fit =
|
for(typename CDT::Finite_faces_iterator fit =
|
||||||
tr.finite_faces_begin() ;
|
tr.finite_faces_begin() ;
|
||||||
fit != tr.finite_faces_end() ;
|
fit != tr.finite_faces_end() ;
|
||||||
++fit )
|
++fit )
|
||||||
|
|
@ -114,7 +114,7 @@ write_cells_tag_2(std::ostream& os,
|
||||||
cells_offset += 3;
|
cells_offset += 3;
|
||||||
os << cells_offset << " ";
|
os << cells_offset << " ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
os << " </DataArray>\n";
|
os << " </DataArray>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -126,13 +126,13 @@ write_cells_tag_2(std::ostream& os,
|
||||||
os << " offset=\"" << offset << "\"/>\n";
|
os << " offset=\"" << offset << "\"/>\n";
|
||||||
offset += number_of_triangles
|
offset += number_of_triangles
|
||||||
+ std::distance(tr.constrained_edges_begin(),
|
+ std::distance(tr.constrained_edges_begin(),
|
||||||
tr.constrained_edges_end())
|
tr.constrained_edges_end())
|
||||||
+ sizeof(std::size_t);
|
+ sizeof(std::size_t);
|
||||||
// 1 unsigned char per cell + length of the encoded data (size_t)
|
// 1 unsigned char per cell + length of the encoded data (size_t)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
os << "\">\n";
|
os << "\">\n";
|
||||||
for(typename CDT::Finite_faces_iterator fit =
|
for(typename CDT::Finite_faces_iterator fit =
|
||||||
tr.finite_faces_begin() ;
|
tr.finite_faces_begin() ;
|
||||||
fit != tr.finite_faces_end() ;
|
fit != tr.finite_faces_end() ;
|
||||||
++fit )
|
++fit )
|
||||||
|
|
@ -147,7 +147,7 @@ write_cells_tag_2(std::ostream& os,
|
||||||
os << " </Cells>\n";
|
os << " </Cells>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
// writes the cells appended data at the end of the .vtu file
|
// writes the cells appended data at the end of the .vtu file
|
||||||
template <class CDT>
|
template <class CDT>
|
||||||
void
|
void
|
||||||
write_cells_2(std::ostream& os,
|
write_cells_2(std::ostream& os,
|
||||||
|
|
@ -160,9 +160,9 @@ write_cells_2(std::ostream& os,
|
||||||
std::vector<unsigned char> cell_type(number_of_triangles,5); // triangles == 5
|
std::vector<unsigned char> cell_type(number_of_triangles,5); // triangles == 5
|
||||||
cell_type.resize(cell_type.size() + std::distance(tr.constrained_edges_begin(),
|
cell_type.resize(cell_type.size() + std::distance(tr.constrained_edges_begin(),
|
||||||
tr.constrained_edges_end()), 3); // line == 3
|
tr.constrained_edges_end()), 3); // line == 3
|
||||||
|
|
||||||
std::size_t off = 0;
|
std::size_t off = 0;
|
||||||
for(typename CDT::Finite_faces_iterator
|
for(typename CDT::Finite_faces_iterator
|
||||||
fit = tr.finite_faces_begin(),
|
fit = tr.finite_faces_begin(),
|
||||||
end = tr.finite_faces_end();
|
end = tr.finite_faces_end();
|
||||||
fit != end; ++fit)
|
fit != end; ++fit)
|
||||||
|
|
@ -197,7 +197,7 @@ write_cells_2(std::ostream& os,
|
||||||
|
|
||||||
// writes the points tags before binary data is appended
|
// writes the points tags before binary data is appended
|
||||||
template <class Tr>
|
template <class Tr>
|
||||||
void
|
void
|
||||||
write_cdt_points_tag(std::ostream& os,
|
write_cdt_points_tag(std::ostream& os,
|
||||||
const Tr & tr,
|
const Tr & tr,
|
||||||
std::map<typename Tr::Vertex_handle, std::size_t> & V,
|
std::map<typename Tr::Vertex_handle, std::size_t> & V,
|
||||||
|
|
@ -218,12 +218,12 @@ write_cdt_points_tag(std::ostream& os,
|
||||||
<< format;
|
<< format;
|
||||||
|
|
||||||
if (binary) {
|
if (binary) {
|
||||||
os << "\" offset=\"" << offset << "\"/>\n";
|
os << "\" offset=\"" << offset << "\"/>\n";
|
||||||
offset += 3 * tr.number_of_vertices() * sizeof(FT) + sizeof(std::size_t);
|
offset += 3 * tr.number_of_vertices() * sizeof(FT) + sizeof(std::size_t);
|
||||||
// dim coords per points + length of the encoded data (size_t)
|
// dim coords per points + length of the encoded data (size_t)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
os << "\">\n";
|
os << "\">\n";
|
||||||
for( Finite_vertices_iterator vit = tr.finite_vertices_begin();
|
for( Finite_vertices_iterator vit = tr.finite_vertices_begin();
|
||||||
vit != tr.finite_vertices_end();
|
vit != tr.finite_vertices_end();
|
||||||
++vit)
|
++vit)
|
||||||
|
|
@ -231,7 +231,7 @@ write_cdt_points_tag(std::ostream& os,
|
||||||
V[vit] = inum++;
|
V[vit] = inum++;
|
||||||
os << vit->point()[0] << " ";
|
os << vit->point()[0] << " ";
|
||||||
os << vit->point()[1] << " ";
|
os << vit->point()[1] << " ";
|
||||||
if(dim == 3)
|
if(dim == 3)
|
||||||
os << vit->point()[2] << " ";
|
os << vit->point()[2] << " ";
|
||||||
else
|
else
|
||||||
os << 0.0 << " ";
|
os << 0.0 << " ";
|
||||||
|
|
@ -241,7 +241,7 @@ write_cdt_points_tag(std::ostream& os,
|
||||||
os << " </Points>\n";
|
os << " </Points>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
// writes the points appended data at the end of the .vtu file
|
// writes the points appended data at the end of the .vtu file
|
||||||
template <class Tr>
|
template <class Tr>
|
||||||
void
|
void
|
||||||
write_cdt_points(std::ostream& os,
|
write_cdt_points(std::ostream& os,
|
||||||
|
|
@ -270,37 +270,37 @@ write_cdt_points(std::ostream& os,
|
||||||
|
|
||||||
// writes the attribute tags before binary data is appended
|
// writes the attribute tags before binary data is appended
|
||||||
template <class T>
|
template <class T>
|
||||||
void
|
void
|
||||||
write_attribute_tag_2 (std::ostream& os,
|
write_attribute_tag_2 (std::ostream& os,
|
||||||
const std::string& attr_name,
|
const std::string& attr_name,
|
||||||
const std::vector<T>& attribute,
|
const std::vector<T>& attribute,
|
||||||
bool binary,
|
bool binary,
|
||||||
std::size_t& offset)
|
std::size_t& offset)
|
||||||
{
|
{
|
||||||
std::string format = binary ? "appended" : "ascii";
|
std::string format = binary ? "appended" : "ascii";
|
||||||
std::string type = (sizeof(T) == 8) ? "Float64" : "Float32";
|
std::string type = (sizeof(T) == 8) ? "Float64" : "Float32";
|
||||||
os << " <DataArray type=\"" << type << "\" Name=\"" << attr_name << "\" format=\"" << format;
|
os << " <DataArray type=\"" << type << "\" Name=\"" << attr_name << "\" format=\"" << format;
|
||||||
|
|
||||||
if (binary) {
|
if (binary) {
|
||||||
os << "\" offset=\"" << offset << "\"/>\n";
|
os << "\" offset=\"" << offset << "\"/>\n";
|
||||||
offset += attribute.size() * sizeof(T) + sizeof(std::size_t);
|
offset += attribute.size() * sizeof(T) + sizeof(std::size_t);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
typedef typename std::vector<T>::const_iterator Iterator;
|
typedef typename std::vector<T>::const_iterator Iterator;
|
||||||
os << "\">\n";
|
os << "\">\n";
|
||||||
for (Iterator it = attribute.begin();
|
for (Iterator it = attribute.begin();
|
||||||
it != attribute.end();
|
it != attribute.end();
|
||||||
++it )
|
++it )
|
||||||
os << *it << " ";
|
os << *it << " ";
|
||||||
os << " </DataArray>\n";
|
os << " </DataArray>\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// writes the attributes appended data at the end of the .vtu file
|
// writes the attributes appended data at the end of the .vtu file
|
||||||
template <typename FT>
|
template <typename FT>
|
||||||
void
|
void
|
||||||
write_attributes_2(std::ostream& os,
|
write_attributes_2(std::ostream& os,
|
||||||
const std::vector<FT>& att)
|
const std::vector<FT>& att)
|
||||||
{
|
{
|
||||||
IO::internal::write_vector(os,att);
|
IO::internal::write_vector(os,att);
|
||||||
}
|
}
|
||||||
|
|
@ -321,7 +321,7 @@ void write_vtu_with_attributes(std::ostream& os,
|
||||||
#else // CGAL_BIG_ENDIAN
|
#else // CGAL_BIG_ENDIAN
|
||||||
os << " byte_order=\"BigEndian\"";
|
os << " byte_order=\"BigEndian\"";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
switch(sizeof(std::size_t)) {
|
switch(sizeof(std::size_t)) {
|
||||||
case 4: os << " header_type=\"UInt32\""; break;
|
case 4: os << " header_type=\"UInt32\""; break;
|
||||||
case 8: os << " header_type=\"UInt64\""; break;
|
case 8: os << " header_type=\"UInt64\""; break;
|
||||||
|
|
@ -329,16 +329,16 @@ void write_vtu_with_attributes(std::ostream& os,
|
||||||
}
|
}
|
||||||
os << ">\n"
|
os << ">\n"
|
||||||
<< " <UnstructuredGrid>" << "\n";
|
<< " <UnstructuredGrid>" << "\n";
|
||||||
|
|
||||||
int number_of_triangles = 0;
|
int number_of_triangles = 0;
|
||||||
for(typename CDT::Finite_faces_iterator
|
for(typename CDT::Finite_faces_iterator
|
||||||
fit = tr.finite_faces_begin(),
|
fit = tr.finite_faces_begin(),
|
||||||
end = tr.finite_faces_end();
|
end = tr.finite_faces_end();
|
||||||
fit != end; ++fit)
|
fit != end; ++fit)
|
||||||
{
|
{
|
||||||
if(fit->is_in_domain()) ++number_of_triangles;
|
if(fit->is_in_domain()) ++number_of_triangles;
|
||||||
}
|
}
|
||||||
os << " <Piece NumberOfPoints=\"" << tr.number_of_vertices()
|
os << " <Piece NumberOfPoints=\"" << tr.number_of_vertices()
|
||||||
<< "\" NumberOfCells=\"" << number_of_triangles + std::distance(tr.constrained_edges_begin(), tr.constrained_edges_end()) << "\">\n";
|
<< "\" NumberOfCells=\"" << number_of_triangles + std::distance(tr.constrained_edges_begin(), tr.constrained_edges_end()) << "\">\n";
|
||||||
std::size_t offset = 0;
|
std::size_t offset = 0;
|
||||||
const bool binary = (mode == IO::BINARY);
|
const bool binary = (mode == IO::BINARY);
|
||||||
|
|
@ -356,7 +356,7 @@ void write_vtu_with_attributes(std::ostream& os,
|
||||||
os << " </Piece>\n"
|
os << " </Piece>\n"
|
||||||
<< " </UnstructuredGrid>\n";
|
<< " </UnstructuredGrid>\n";
|
||||||
if (binary) {
|
if (binary) {
|
||||||
os << "<AppendedData encoding=\"raw\">\n_";
|
os << "<AppendedData encoding=\"raw\">\n_";
|
||||||
write_cdt_points(os,tr,V); // write points before cells to fill the std::map V
|
write_cdt_points(os,tr,V); // write points before cells to fill the std::map V
|
||||||
write_cells_2(os,tr, number_of_triangles, V);
|
write_cells_2(os,tr, number_of_triangles, V);
|
||||||
for(std::size_t i = 0; i< attributes.size(); ++i)
|
for(std::size_t i = 0; i< attributes.size(); ++i)
|
||||||
|
|
|
||||||
|
|
@ -27,8 +27,8 @@
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
template <class C3T3>
|
template <class C3T3>
|
||||||
void
|
void
|
||||||
output_to_maya(std::ostream& os,
|
output_to_maya(std::ostream& os,
|
||||||
const C3T3& c3t3,
|
const C3T3& c3t3,
|
||||||
bool surfaceOnly = true)
|
bool surfaceOnly = true)
|
||||||
{
|
{
|
||||||
typedef typename C3T3::Triangulation Tr;
|
typedef typename C3T3::Triangulation Tr;
|
||||||
|
|
@ -44,7 +44,7 @@ output_to_maya(std::ostream& os,
|
||||||
#ifdef CGAL_MESH_3_IO_VERBOSE
|
#ifdef CGAL_MESH_3_IO_VERBOSE
|
||||||
std::cerr << "Output to maya:\n";
|
std::cerr << "Output to maya:\n";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const Tr& tr = c3t3.triangulation();
|
const Tr& tr = c3t3.triangulation();
|
||||||
|
|
||||||
//-------------------------------------------------------
|
//-------------------------------------------------------
|
||||||
|
|
@ -75,13 +75,13 @@ output_to_maya(std::ostream& os,
|
||||||
os << " setAttr \".cuvs\" -type \"string\" \"map1\";" << std::endl;
|
os << " setAttr \".cuvs\" -type \"string\" \"map1\";" << std::endl;
|
||||||
os << " setAttr \".dcol\" yes;" << std::endl;
|
os << " setAttr \".dcol\" yes;" << std::endl;
|
||||||
os << " setAttr \".dcc\" -type \"string\" \"Ambient+Diffuse\";" << std::endl;
|
os << " setAttr \".dcc\" -type \"string\" \"Ambient+Diffuse\";" << std::endl;
|
||||||
|
|
||||||
os << " connectAttr \"" << name << "Shape.iog\" \":initialShadingGroup.dsm\" -na;\n\n";
|
os << " connectAttr \"" << name << "Shape.iog\" \":initialShadingGroup.dsm\" -na;\n\n";
|
||||||
|
|
||||||
//-------------------------------------------------------
|
//-------------------------------------------------------
|
||||||
// Colors
|
// Colors
|
||||||
//------------------------------------------------------
|
//------------------------------------------------------
|
||||||
|
|
||||||
/*os << " setAttr \".ccls\" -type \"string\" \"colorSet\";\n";
|
/*os << " setAttr \".ccls\" -type \"string\" \"colorSet\";\n";
|
||||||
os << " setAttr \".clst[0].clsn\" -type \"string\" \"colorSet\";\n";
|
os << " setAttr \".clst[0].clsn\" -type \"string\" \"colorSet\";\n";
|
||||||
os << " setAttr \".clst[0].rprt\" 3;\n";
|
os << " setAttr \".clst[0].rprt\" 3;\n";
|
||||||
|
|
@ -90,11 +90,11 @@ output_to_maya(std::ostream& os,
|
||||||
os << " 100 250 50" << std::endl;
|
os << " 100 250 50" << std::endl;
|
||||||
os << " 0 200 200" << std::endl;
|
os << " 0 200 200" << std::endl;
|
||||||
os << " ;\n";*/
|
os << " ;\n";*/
|
||||||
|
|
||||||
//-------------------------------------------------------
|
//-------------------------------------------------------
|
||||||
// Vertices
|
// Vertices
|
||||||
//------------------------------------------------------
|
//------------------------------------------------------
|
||||||
|
|
||||||
boost::unordered_map<Vertex_handle, int, Hash_fct> V;
|
boost::unordered_map<Vertex_handle, int, Hash_fct> V;
|
||||||
std::stringstream vertices_sstr;
|
std::stringstream vertices_sstr;
|
||||||
int num_vertices = 0;
|
int num_vertices = 0;
|
||||||
|
|
@ -110,7 +110,7 @@ output_to_maya(std::ostream& os,
|
||||||
vertices_sstr << " " << CGAL::to_double(p.x()) << " " << CGAL::to_double(p.y()) << " " << CGAL::to_double(p.z()) << std::endl;
|
vertices_sstr << " " << CGAL::to_double(p.x()) << " " << CGAL::to_double(p.y()) << " " << CGAL::to_double(p.z()) << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
os << " setAttr -s " << num_vertices << " \".vt[0:" << num_vertices-1 << "]\"" << std::endl;
|
os << " setAttr -s " << num_vertices << " \".vt[0:" << num_vertices-1 << "]\"" << std::endl;
|
||||||
os << vertices_sstr.str();
|
os << vertices_sstr.str();
|
||||||
os << ";\n";
|
os << ";\n";
|
||||||
|
|
@ -134,7 +134,7 @@ output_to_maya(std::ostream& os,
|
||||||
//-------------------------------------------------------
|
//-------------------------------------------------------
|
||||||
|
|
||||||
typename C3T3::size_type number_of_triangles = c3t3.number_of_facets_in_complex();
|
typename C3T3::size_type number_of_triangles = c3t3.number_of_facets_in_complex();
|
||||||
|
|
||||||
std::stringstream facets_sstr;
|
std::stringstream facets_sstr;
|
||||||
//std::stringstream normals_sstr;
|
//std::stringstream normals_sstr;
|
||||||
|
|
||||||
|
|
@ -147,7 +147,7 @@ output_to_maya(std::ostream& os,
|
||||||
// Surface only
|
// Surface only
|
||||||
if (surfaceOnly)
|
if (surfaceOnly)
|
||||||
{
|
{
|
||||||
facets_sstr << " setAttr -s " << number_of_triangles
|
facets_sstr << " setAttr -s " << number_of_triangles
|
||||||
<< " \".fc[0:" << number_of_triangles-1 << "]\" -type \"polyFaces\" \n";
|
<< " \".fc[0:" << number_of_triangles-1 << "]\" -type \"polyFaces\" \n";
|
||||||
int c = 0;
|
int c = 0;
|
||||||
for( Facet_iterator fit = c3t3.facets_in_complex_begin();
|
for( Facet_iterator fit = c3t3.facets_in_complex_begin();
|
||||||
|
|
@ -163,9 +163,9 @@ output_to_maya(std::ostream& os,
|
||||||
indices[j] = V[vh];
|
indices[j] = V[vh];
|
||||||
//points[j] = tr.point(fit->first, i);
|
//points[j] = tr.point(fit->first, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reverse triangle orientation?
|
// Reverse triangle orientation?
|
||||||
bool reverse_triangle =
|
bool reverse_triangle =
|
||||||
(fit->second % 2 == 0 && !c3t3.is_in_complex(fit->first))
|
(fit->second % 2 == 0 && !c3t3.is_in_complex(fit->first))
|
||||||
|| (fit->second % 2 != 0 && c3t3.is_in_complex(fit->first));
|
|| (fit->second % 2 != 0 && c3t3.is_in_complex(fit->first));
|
||||||
if (reverse_triangle)
|
if (reverse_triangle)
|
||||||
|
|
@ -194,7 +194,7 @@ output_to_maya(std::ostream& os,
|
||||||
// ith edge of triangle
|
// ith edge of triangle
|
||||||
facets_sstr << pos << " ";
|
facets_sstr << pos << " ";
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1 triangles
|
// 1 triangles
|
||||||
facets_sstr << std::endl;
|
facets_sstr << std::endl;
|
||||||
// Colors
|
// Colors
|
||||||
|
|
@ -204,7 +204,7 @@ output_to_maya(std::ostream& os,
|
||||||
// Tetrahedra = 4 facets for each
|
// Tetrahedra = 4 facets for each
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
facets_sstr << " setAttr -s " << 4*c3t3.number_of_cells_in_complex()
|
facets_sstr << " setAttr -s " << 4*c3t3.number_of_cells_in_complex()
|
||||||
<< " \".fc[0:" << 4*c3t3.number_of_cells_in_complex()-1 << "]\" -type \"polyFaces\" \n";
|
<< " \".fc[0:" << 4*c3t3.number_of_cells_in_complex()-1 << "]\" -type \"polyFaces\" \n";
|
||||||
int c = 0;
|
int c = 0;
|
||||||
for( Cell_iterator cit = c3t3.cells_in_complex_begin();
|
for( Cell_iterator cit = c3t3.cells_in_complex_begin();
|
||||||
|
|
@ -222,7 +222,7 @@ output_to_maya(std::ostream& os,
|
||||||
indices[j] = V[vh];
|
indices[j] = V[vh];
|
||||||
//points[j] = tr.point(cit, i);
|
//points[j] = tr.point(cit, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reverse triangle orientation?
|
// Reverse triangle orientation?
|
||||||
bool reverse_triangle = (facet_i % 2 != 0 && c3t3.is_in_complex(cit, facet_i));
|
bool reverse_triangle = (facet_i % 2 != 0 && c3t3.is_in_complex(cit, facet_i));
|
||||||
if (reverse_triangle)
|
if (reverse_triangle)
|
||||||
|
|
@ -251,7 +251,7 @@ output_to_maya(std::ostream& os,
|
||||||
// ith edge of triangle
|
// ith edge of triangle
|
||||||
facets_sstr << pos << " ";
|
facets_sstr << pos << " ";
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1 triangles
|
// 1 triangles
|
||||||
facets_sstr << std::endl;
|
facets_sstr << std::endl;
|
||||||
// Colors
|
// Colors
|
||||||
|
|
@ -261,30 +261,30 @@ output_to_maya(std::ostream& os,
|
||||||
}
|
}
|
||||||
facets_sstr << ";\n\n";
|
facets_sstr << ";\n\n";
|
||||||
//normals_sstr << ";\n\n";
|
//normals_sstr << ";\n\n";
|
||||||
|
|
||||||
//-------------------------------------------------------
|
//-------------------------------------------------------
|
||||||
// Edges
|
// Edges
|
||||||
//-------------------------------------------------------
|
//-------------------------------------------------------
|
||||||
os << " setAttr -s " << edges.size() << " \".ed[0:"
|
os << " setAttr -s " << edges.size() << " \".ed[0:"
|
||||||
<< edges.size() - 1 << "]\"" << std::endl;
|
<< edges.size() - 1 << "]\"" << std::endl;
|
||||||
|
|
||||||
for (EdgeList::const_iterator it = edges.begin(), it_end = edges.end() ; it != it_end ; ++it)
|
for (EdgeList::const_iterator it = edges.begin(), it_end = edges.end() ; it != it_end ; ++it)
|
||||||
os << " " << it->first << " " << it->second << " " << 0 << std::endl;
|
os << " " << it->first << " " << it->second << " " << 0 << std::endl;
|
||||||
|
|
||||||
os << ";\n";
|
os << ";\n";
|
||||||
|
|
||||||
//-------------------------------------------------------
|
//-------------------------------------------------------
|
||||||
// Normals
|
// Normals
|
||||||
//-------------------------------------------------------
|
//-------------------------------------------------------
|
||||||
|
|
||||||
//os << normals_sstr.str();
|
//os << normals_sstr.str();
|
||||||
|
|
||||||
//-------------------------------------------------------
|
//-------------------------------------------------------
|
||||||
// Facets
|
// Facets
|
||||||
//-------------------------------------------------------
|
//-------------------------------------------------------
|
||||||
|
|
||||||
os << facets_sstr.str();
|
os << facets_sstr.str();
|
||||||
|
|
||||||
//-------------------------------------------------------
|
//-------------------------------------------------------
|
||||||
// Tetrahedra
|
// Tetrahedra
|
||||||
//-------------------------------------------------------
|
//-------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -126,13 +126,13 @@ private:
|
||||||
else
|
else
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const C3T3& r_c3t3_;
|
const C3T3& r_c3t3_;
|
||||||
Subdomain_map subdomain_map_;
|
Subdomain_map subdomain_map_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Accessor
|
// Accessor
|
||||||
template <typename C3T3>
|
template <typename C3T3>
|
||||||
int
|
int
|
||||||
get(const Rebind_cell_pmap<C3T3>& cmap,
|
get(const Rebind_cell_pmap<C3T3>& cmap,
|
||||||
|
|
@ -146,7 +146,7 @@ unsigned int get_size(const Rebind_cell_pmap<C3T3>& cmap)
|
||||||
{
|
{
|
||||||
return cmap.subdomain_number();
|
return cmap.subdomain_number();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
// No_rebind_cell_pmap
|
// No_rebind_cell_pmap
|
||||||
|
|
@ -157,21 +157,21 @@ class No_rebind_cell_pmap
|
||||||
typedef typename C3T3::Subdomain_index Subdomain_index;
|
typedef typename C3T3::Subdomain_index Subdomain_index;
|
||||||
typedef typename C3T3::Cell_handle Cell_handle;
|
typedef typename C3T3::Cell_handle Cell_handle;
|
||||||
typedef unsigned int size_type;
|
typedef unsigned int size_type;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
No_rebind_cell_pmap(const C3T3& c3t3)
|
No_rebind_cell_pmap(const C3T3& c3t3)
|
||||||
: r_c3t3_(c3t3) {}
|
: r_c3t3_(c3t3) {}
|
||||||
|
|
||||||
int subdomain_index(const Cell_handle& ch) const
|
int subdomain_index(const Cell_handle& ch) const
|
||||||
{
|
{
|
||||||
return static_cast<int>(r_c3t3_.subdomain_index(ch));
|
return static_cast<int>(r_c3t3_.subdomain_index(ch));
|
||||||
}
|
}
|
||||||
|
|
||||||
size_type subdomain_number() const
|
size_type subdomain_number() const
|
||||||
{
|
{
|
||||||
typedef typename C3T3::Cells_in_complex_iterator Cell_iterator;
|
typedef typename C3T3::Cells_in_complex_iterator Cell_iterator;
|
||||||
std::set<Subdomain_index> subdomain_set;
|
std::set<Subdomain_index> subdomain_set;
|
||||||
|
|
||||||
for( Cell_iterator cell_it = r_c3t3_.cells_in_complex_begin();
|
for( Cell_iterator cell_it = r_c3t3_.cells_in_complex_begin();
|
||||||
cell_it != r_c3t3_.cells_in_complex_end();
|
cell_it != r_c3t3_.cells_in_complex_end();
|
||||||
++cell_it)
|
++cell_it)
|
||||||
|
|
@ -179,15 +179,15 @@ public:
|
||||||
// Add subdomain index in set
|
// Add subdomain index in set
|
||||||
subdomain_set.insert(subdomain_index(cell_it));
|
subdomain_set.insert(subdomain_index(cell_it));
|
||||||
}
|
}
|
||||||
|
|
||||||
return subdomain_set.size();
|
return subdomain_set.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const C3T3& r_c3t3_;
|
const C3T3& r_c3t3_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Accessor
|
// Accessor
|
||||||
template <typename C3T3>
|
template <typename C3T3>
|
||||||
int
|
int
|
||||||
get(const No_rebind_cell_pmap<C3T3>& cmap,
|
get(const No_rebind_cell_pmap<C3T3>& cmap,
|
||||||
|
|
@ -195,8 +195,8 @@ get(const No_rebind_cell_pmap<C3T3>& cmap,
|
||||||
{
|
{
|
||||||
return cmap.subdomain_index(ch);
|
return cmap.subdomain_index(ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
// Rebind_facet_pmap
|
// Rebind_facet_pmap
|
||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
|
|
@ -207,17 +207,17 @@ class Rebind_facet_pmap
|
||||||
typedef std::map<Surface_patch_index,int> Surface_map;
|
typedef std::map<Surface_patch_index,int> Surface_map;
|
||||||
typedef typename C3T3::Facet Facet;
|
typedef typename C3T3::Facet Facet;
|
||||||
typedef unsigned int size_type;
|
typedef unsigned int size_type;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Rebind_facet_pmap(const C3T3& c3t3, const Cell_pmap& cell_pmap)
|
Rebind_facet_pmap(const C3T3& c3t3, const Cell_pmap& cell_pmap)
|
||||||
: r_c3t3_(c3t3)
|
: r_c3t3_(c3t3)
|
||||||
, cell_pmap_(cell_pmap)
|
, cell_pmap_(cell_pmap)
|
||||||
{
|
{
|
||||||
typedef typename C3T3::Facets_in_complex_iterator Facet_iterator;
|
typedef typename C3T3::Facets_in_complex_iterator Facet_iterator;
|
||||||
|
|
||||||
int first_index = 1;
|
int first_index = 1;
|
||||||
int index_counter = first_index;
|
int index_counter = first_index;
|
||||||
|
|
||||||
for( Facet_iterator facet_it = r_c3t3_.facets_in_complex_begin();
|
for( Facet_iterator facet_it = r_c3t3_.facets_in_complex_begin();
|
||||||
facet_it != r_c3t3_.facets_in_complex_end();
|
facet_it != r_c3t3_.facets_in_complex_end();
|
||||||
++facet_it)
|
++facet_it)
|
||||||
|
|
@ -229,11 +229,11 @@ public:
|
||||||
if(is_insert_successful.second)
|
if(is_insert_successful.second)
|
||||||
++index_counter;
|
++index_counter;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find cell_pmap_ unused indices
|
// Find cell_pmap_ unused indices
|
||||||
typedef typename C3T3::Cells_in_complex_iterator Cell_iterator;
|
typedef typename C3T3::Cells_in_complex_iterator Cell_iterator;
|
||||||
std::set<int> cell_label_set;
|
std::set<int> cell_label_set;
|
||||||
|
|
||||||
for( Cell_iterator cell_it = r_c3t3_.cells_in_complex_begin();
|
for( Cell_iterator cell_it = r_c3t3_.cells_in_complex_begin();
|
||||||
cell_it != r_c3t3_.cells_in_complex_end();
|
cell_it != r_c3t3_.cells_in_complex_end();
|
||||||
++cell_it)
|
++cell_it)
|
||||||
|
|
@ -241,7 +241,7 @@ public:
|
||||||
// Add subdomain index in set
|
// Add subdomain index in set
|
||||||
cell_label_set.insert(get(cell_pmap_, cell_it));
|
cell_label_set.insert(get(cell_pmap_, cell_it));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rebind indices
|
// Rebind indices
|
||||||
index_counter = get_first_unused_label(cell_label_set,first_index);
|
index_counter = get_first_unused_label(cell_label_set,first_index);
|
||||||
for ( typename Surface_map::iterator mit = surface_map_.begin() ;
|
for ( typename Surface_map::iterator mit = surface_map_.begin() ;
|
||||||
|
|
@ -251,11 +251,11 @@ public:
|
||||||
mit->second = index_counter++;
|
mit->second = index_counter++;
|
||||||
index_counter = get_first_unused_label(cell_label_set,index_counter);
|
index_counter = get_first_unused_label(cell_label_set,index_counter);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CGAL_MESH_3_IO_VERBOSE
|
#ifdef CGAL_MESH_3_IO_VERBOSE
|
||||||
std::cerr << "Nb of surface patches: " << surface_map_.size() << "\n";
|
std::cerr << "Nb of surface patches: " << surface_map_.size() << "\n";
|
||||||
std::cerr << "Surface mapping:\n\t" ;
|
std::cerr << "Surface mapping:\n\t" ;
|
||||||
|
|
||||||
typedef typename Surface_map::iterator Surface_map_iterator;
|
typedef typename Surface_map::iterator Surface_map_iterator;
|
||||||
for ( Surface_map_iterator surf_it = surface_map_.begin() ;
|
for ( Surface_map_iterator surf_it = surface_map_.begin() ;
|
||||||
surf_it != surface_map_.end() ;
|
surf_it != surface_map_.end() ;
|
||||||
|
|
@ -267,17 +267,17 @@ public:
|
||||||
std::cerr << "\n";
|
std::cerr << "\n";
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int surface_index(const Facet& f) const
|
int surface_index(const Facet& f) const
|
||||||
{
|
{
|
||||||
return surface_index(r_c3t3_.surface_patch_index(f));
|
return surface_index(r_c3t3_.surface_patch_index(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
size_type surface_number() const
|
size_type surface_number() const
|
||||||
{
|
{
|
||||||
return surface_map_.size();
|
return surface_map_.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int surface_index(const Surface_patch_index& index) const
|
int surface_index(const Surface_patch_index& index) const
|
||||||
{
|
{
|
||||||
|
|
@ -288,23 +288,23 @@ private:
|
||||||
else
|
else
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_first_unused_label(const std::set<int>& label_set,
|
int get_first_unused_label(const std::set<int>& label_set,
|
||||||
int search_start) const
|
int search_start) const
|
||||||
{
|
{
|
||||||
while ( label_set.end() != label_set.find(search_start) )
|
while ( label_set.end() != label_set.find(search_start) )
|
||||||
++search_start;
|
++search_start;
|
||||||
|
|
||||||
return search_start;
|
return search_start;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const C3T3& r_c3t3_;
|
const C3T3& r_c3t3_;
|
||||||
const Cell_pmap& cell_pmap_;
|
const Cell_pmap& cell_pmap_;
|
||||||
Surface_map surface_map_;
|
Surface_map surface_map_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Accessors
|
// Accessors
|
||||||
template <typename C3T3, typename Cell_pmap>
|
template <typename C3T3, typename Cell_pmap>
|
||||||
int
|
int
|
||||||
|
|
@ -313,7 +313,7 @@ get(const Rebind_facet_pmap<C3T3,Cell_pmap>& fmap,
|
||||||
{
|
{
|
||||||
return fmap.surface_index(f);
|
return fmap.surface_index(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename C3T3, typename Cell_pmap>
|
template <typename C3T3, typename Cell_pmap>
|
||||||
unsigned int
|
unsigned int
|
||||||
get_size(const Rebind_facet_pmap<C3T3,Cell_pmap>& fmap,
|
get_size(const Rebind_facet_pmap<C3T3,Cell_pmap>& fmap,
|
||||||
|
|
@ -322,7 +322,7 @@ get_size(const Rebind_facet_pmap<C3T3,Cell_pmap>& fmap,
|
||||||
return fmap.surface_number(f);
|
return fmap.surface_number(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
// No_rebind_facet_pmap
|
// No_rebind_facet_pmap
|
||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
|
|
@ -332,7 +332,7 @@ class No_rebind_facet_pmap
|
||||||
typedef typename C3T3::Surface_patch_index Surface_patch_index;
|
typedef typename C3T3::Surface_patch_index Surface_patch_index;
|
||||||
typedef typename C3T3::Facet Facet;
|
typedef typename C3T3::Facet Facet;
|
||||||
typedef unsigned int size_type;
|
typedef unsigned int size_type;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
No_rebind_facet_pmap(const C3T3& c3t3, const Cell_pmap& /*cell_pmap*/)
|
No_rebind_facet_pmap(const C3T3& c3t3, const Cell_pmap& /*cell_pmap*/)
|
||||||
: r_c3t3_(c3t3) {}
|
: r_c3t3_(c3t3) {}
|
||||||
|
|
@ -341,7 +341,7 @@ public:
|
||||||
{
|
{
|
||||||
return static_cast<int>(r_c3t3_.surface_patch_index(f));
|
return static_cast<int>(r_c3t3_.surface_patch_index(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const C3T3& r_c3t3_;
|
const C3T3& r_c3t3_;
|
||||||
};
|
};
|
||||||
|
|
@ -365,16 +365,16 @@ class No_rebind_facet_pmap_first
|
||||||
typedef typename C3T3::Surface_patch_index Surface_patch_index;
|
typedef typename C3T3::Surface_patch_index Surface_patch_index;
|
||||||
typedef typename C3T3::Facet Facet;
|
typedef typename C3T3::Facet Facet;
|
||||||
typedef unsigned int size_type;
|
typedef unsigned int size_type;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
No_rebind_facet_pmap_first(const C3T3& c3t3, const Cell_pmap& /*cell_pmap*/)
|
No_rebind_facet_pmap_first(const C3T3& c3t3, const Cell_pmap& /*cell_pmap*/)
|
||||||
: r_c3t3_(c3t3) {}
|
: r_c3t3_(c3t3) {}
|
||||||
|
|
||||||
int surface_index(const Facet& f) const
|
int surface_index(const Facet& f) const
|
||||||
{
|
{
|
||||||
return static_cast<int>(r_c3t3_.surface_patch_index(f).first);
|
return static_cast<int>(r_c3t3_.surface_patch_index(f).first);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const C3T3& r_c3t3_;
|
const C3T3& r_c3t3_;
|
||||||
};
|
};
|
||||||
|
|
@ -388,8 +388,8 @@ get(const No_rebind_facet_pmap_first<C3T3,Cell_pmap>& fmap,
|
||||||
{
|
{
|
||||||
return fmap.surface_index(f);
|
return fmap.surface_index(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
// No_rebind_facet_pmap_second
|
// No_rebind_facet_pmap_second
|
||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
|
|
@ -399,16 +399,16 @@ class No_rebind_facet_pmap_second
|
||||||
typedef typename C3T3::Surface_patch_index Surface_patch_index;
|
typedef typename C3T3::Surface_patch_index Surface_patch_index;
|
||||||
typedef typename C3T3::Facet Facet;
|
typedef typename C3T3::Facet Facet;
|
||||||
typedef unsigned int size_type;
|
typedef unsigned int size_type;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
No_rebind_facet_pmap_second(const C3T3& c3t3, const Cell_pmap& /*cell_pmap*/)
|
No_rebind_facet_pmap_second(const C3T3& c3t3, const Cell_pmap& /*cell_pmap*/)
|
||||||
: r_c3t3_(c3t3) {}
|
: r_c3t3_(c3t3) {}
|
||||||
|
|
||||||
int surface_index(const Facet& f) const
|
int surface_index(const Facet& f) const
|
||||||
{
|
{
|
||||||
return static_cast<int>(r_c3t3_.surface_patch_index(f).second);
|
return static_cast<int>(r_c3t3_.surface_patch_index(f).second);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const C3T3& r_c3t3_;
|
const C3T3& r_c3t3_;
|
||||||
};
|
};
|
||||||
|
|
@ -422,9 +422,9 @@ get(const No_rebind_facet_pmap_second<C3T3,Cell_pmap>& fmap,
|
||||||
{
|
{
|
||||||
return fmap.surface_index(f);
|
return fmap.surface_index(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
// No_patch_facet_pmap_first
|
// No_patch_facet_pmap_first
|
||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
|
|
@ -434,32 +434,32 @@ class No_patch_facet_pmap_first
|
||||||
typedef typename C3T3::Surface_patch_index Surface_patch_index;
|
typedef typename C3T3::Surface_patch_index Surface_patch_index;
|
||||||
typedef typename C3T3::Facet Facet;
|
typedef typename C3T3::Facet Facet;
|
||||||
typedef typename C3T3::Cell_handle Cell_handle;
|
typedef typename C3T3::Cell_handle Cell_handle;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
No_patch_facet_pmap_first(const C3T3&, const Cell_pmap& cell_pmap)
|
No_patch_facet_pmap_first(const C3T3&, const Cell_pmap& cell_pmap)
|
||||||
: cell_pmap_(cell_pmap) { }
|
: cell_pmap_(cell_pmap) { }
|
||||||
|
|
||||||
int surface_index(const Facet& f) const
|
int surface_index(const Facet& f) const
|
||||||
{
|
{
|
||||||
Cell_handle c1 = f.first;
|
Cell_handle c1 = f.first;
|
||||||
Cell_handle c2 = c1->neighbor(f.second);
|
Cell_handle c2 = c1->neighbor(f.second);
|
||||||
|
|
||||||
int label1 = get(cell_pmap_,c1);
|
int label1 = get(cell_pmap_,c1);
|
||||||
int label2 = get(cell_pmap_,c2);
|
int label2 = get(cell_pmap_,c2);
|
||||||
|
|
||||||
if ( 0 == label1 || -1 == label1 )
|
if ( 0 == label1 || -1 == label1 )
|
||||||
label1 = label2;
|
label1 = label2;
|
||||||
if ( 0 == label2 || -1 == label2 )
|
if ( 0 == label2 || -1 == label2 )
|
||||||
label2 = label1;
|
label2 = label1;
|
||||||
|
|
||||||
return (std::min)(label1,label2);
|
return (std::min)(label1,label2);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const Cell_pmap& cell_pmap_;
|
const Cell_pmap& cell_pmap_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Accessors
|
// Accessors
|
||||||
template <typename C3T3, typename Cell_pmap>
|
template <typename C3T3, typename Cell_pmap>
|
||||||
int
|
int
|
||||||
get(const No_patch_facet_pmap_first<C3T3,Cell_pmap>& fmap,
|
get(const No_patch_facet_pmap_first<C3T3,Cell_pmap>& fmap,
|
||||||
|
|
@ -477,32 +477,32 @@ class No_patch_facet_pmap_second
|
||||||
typedef typename C3T3::Surface_patch_index Surface_patch_index;
|
typedef typename C3T3::Surface_patch_index Surface_patch_index;
|
||||||
typedef typename C3T3::Facet Facet;
|
typedef typename C3T3::Facet Facet;
|
||||||
typedef typename C3T3::Cell_handle Cell_handle;
|
typedef typename C3T3::Cell_handle Cell_handle;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
No_patch_facet_pmap_second(const C3T3&, const Cell_pmap& cell_pmap)
|
No_patch_facet_pmap_second(const C3T3&, const Cell_pmap& cell_pmap)
|
||||||
: cell_pmap_(cell_pmap) { }
|
: cell_pmap_(cell_pmap) { }
|
||||||
|
|
||||||
int surface_index(const Facet& f) const
|
int surface_index(const Facet& f) const
|
||||||
{
|
{
|
||||||
Cell_handle c1 = f.first;
|
Cell_handle c1 = f.first;
|
||||||
Cell_handle c2 = c1->neighbor(f.second);
|
Cell_handle c2 = c1->neighbor(f.second);
|
||||||
|
|
||||||
int label1 = get(cell_pmap_,c1);
|
int label1 = get(cell_pmap_,c1);
|
||||||
int label2 = get(cell_pmap_,c2);
|
int label2 = get(cell_pmap_,c2);
|
||||||
|
|
||||||
if ( 0 == label1 || -1 == label1 )
|
if ( 0 == label1 || -1 == label1 )
|
||||||
label1 = label2;
|
label1 = label2;
|
||||||
if ( 0 == label2 || -1 == label2 )
|
if ( 0 == label2 || -1 == label2 )
|
||||||
label2 = label1;
|
label2 = label1;
|
||||||
|
|
||||||
return (std::max)(label1,label2);
|
return (std::max)(label1,label2);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const Cell_pmap& cell_pmap_;
|
const Cell_pmap& cell_pmap_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Accessors
|
// Accessors
|
||||||
template <typename C3T3, typename Cell_pmap>
|
template <typename C3T3, typename Cell_pmap>
|
||||||
int
|
int
|
||||||
get(const No_patch_facet_pmap_second<C3T3,Cell_pmap>& fmap,
|
get(const No_patch_facet_pmap_second<C3T3,Cell_pmap>& fmap,
|
||||||
|
|
@ -510,11 +510,11 @@ get(const No_patch_facet_pmap_second<C3T3,Cell_pmap>& fmap,
|
||||||
{
|
{
|
||||||
return fmap.surface_index(f);
|
return fmap.surface_index(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
// Default_vertex_index_pmap
|
// Default_vertex_index_pmap
|
||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
template <typename C3T3, typename Cell_pmap, typename Facet_pmap>
|
template <typename C3T3, typename Cell_pmap, typename Facet_pmap>
|
||||||
class Default_vertex_pmap
|
class Default_vertex_pmap
|
||||||
{
|
{
|
||||||
|
|
@ -611,26 +611,26 @@ get(const Default_vertex_pmap<C3T3,Cell_pmap,Facet_pmap>& vmap,
|
||||||
|
|
||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
// Null pmap
|
// Null pmap
|
||||||
// -----------------------------------
|
// -----------------------------------
|
||||||
template <typename C3T3, typename Cell_pmap>
|
template <typename C3T3, typename Cell_pmap>
|
||||||
struct Null_facet_pmap
|
struct Null_facet_pmap
|
||||||
{
|
{
|
||||||
Null_facet_pmap(const C3T3&, const Cell_pmap&) {}
|
Null_facet_pmap(const C3T3&, const Cell_pmap&) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename C3T3, typename Cell_pmap>
|
template <typename C3T3, typename Cell_pmap>
|
||||||
int get(const Null_facet_pmap<C3T3,Cell_pmap>&,
|
int get(const Null_facet_pmap<C3T3,Cell_pmap>&,
|
||||||
const typename C3T3::Facet&)
|
const typename C3T3::Facet&)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename C3T3, typename Cell_pmap, typename Facet_pmap>
|
template <typename C3T3, typename Cell_pmap, typename Facet_pmap>
|
||||||
struct Null_vertex_pmap
|
struct Null_vertex_pmap
|
||||||
{
|
{
|
||||||
Null_vertex_pmap(const C3T3&, const Cell_pmap&, const Facet_pmap&) {}
|
Null_vertex_pmap(const C3T3&, const Cell_pmap&, const Facet_pmap&) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename C3T3, typename Cell_pmap, typename Facet_pmap>
|
template <typename C3T3, typename Cell_pmap, typename Facet_pmap>
|
||||||
int get(const Null_vertex_pmap<C3T3, Cell_pmap, Facet_pmap>&,
|
int get(const Null_vertex_pmap<C3T3, Cell_pmap, Facet_pmap>&,
|
||||||
const typename C3T3::Vertex_handle&)
|
const typename C3T3::Vertex_handle&)
|
||||||
|
|
@ -645,7 +645,7 @@ int get(const Null_vertex_pmap<C3T3, Cell_pmap, Facet_pmap>&,
|
||||||
template <typename C3T3, bool rebind, bool no_patch>
|
template <typename C3T3, bool rebind, bool no_patch>
|
||||||
struct Medit_pmap_generator{};
|
struct Medit_pmap_generator{};
|
||||||
|
|
||||||
|
|
||||||
template <typename C3T3>
|
template <typename C3T3>
|
||||||
struct Medit_pmap_generator<C3T3, true, false>
|
struct Medit_pmap_generator<C3T3, true, false>
|
||||||
{
|
{
|
||||||
|
|
@ -653,11 +653,11 @@ struct Medit_pmap_generator<C3T3, true, false>
|
||||||
typedef Rebind_facet_pmap<C3T3, Cell_pmap> Facet_pmap;
|
typedef Rebind_facet_pmap<C3T3, Cell_pmap> Facet_pmap;
|
||||||
typedef Null_facet_pmap<C3T3, Cell_pmap> Facet_pmap_twice;
|
typedef Null_facet_pmap<C3T3, Cell_pmap> Facet_pmap_twice;
|
||||||
typedef Default_vertex_pmap<C3T3, Cell_pmap, Facet_pmap> Vertex_pmap;
|
typedef Default_vertex_pmap<C3T3, Cell_pmap, Facet_pmap> Vertex_pmap;
|
||||||
|
|
||||||
bool print_twice() { return false; }
|
bool print_twice() { return false; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template <typename C3T3>
|
template <typename C3T3>
|
||||||
struct Medit_pmap_generator<C3T3, true, true>
|
struct Medit_pmap_generator<C3T3, true, true>
|
||||||
{
|
{
|
||||||
|
|
@ -665,7 +665,7 @@ struct Medit_pmap_generator<C3T3, true, true>
|
||||||
typedef No_patch_facet_pmap_first<C3T3,Cell_pmap> Facet_pmap;
|
typedef No_patch_facet_pmap_first<C3T3,Cell_pmap> Facet_pmap;
|
||||||
typedef No_patch_facet_pmap_second<C3T3,Cell_pmap> Facet_pmap_twice;
|
typedef No_patch_facet_pmap_second<C3T3,Cell_pmap> Facet_pmap_twice;
|
||||||
typedef Default_vertex_pmap<C3T3, Cell_pmap, Facet_pmap> Vertex_pmap;
|
typedef Default_vertex_pmap<C3T3, Cell_pmap, Facet_pmap> Vertex_pmap;
|
||||||
|
|
||||||
bool print_twice() { return true; }
|
bool print_twice() { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -677,10 +677,10 @@ struct Medit_pmap_generator<C3T3, false, true>
|
||||||
typedef No_patch_facet_pmap_first<C3T3,Cell_pmap> Facet_pmap;
|
typedef No_patch_facet_pmap_first<C3T3,Cell_pmap> Facet_pmap;
|
||||||
typedef No_patch_facet_pmap_second<C3T3,Cell_pmap> Facet_pmap_twice;
|
typedef No_patch_facet_pmap_second<C3T3,Cell_pmap> Facet_pmap_twice;
|
||||||
typedef Default_vertex_pmap<C3T3, Cell_pmap, Facet_pmap> Vertex_pmap;
|
typedef Default_vertex_pmap<C3T3, Cell_pmap, Facet_pmap> Vertex_pmap;
|
||||||
|
|
||||||
bool print_twice() { return true; }
|
bool print_twice() { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename C3T3>
|
template <typename C3T3>
|
||||||
struct Medit_pmap_generator<C3T3, false, false>
|
struct Medit_pmap_generator<C3T3, false, false>
|
||||||
{
|
{
|
||||||
|
|
@ -688,17 +688,17 @@ struct Medit_pmap_generator<C3T3, false, false>
|
||||||
typedef Rebind_facet_pmap<C3T3,Cell_pmap> Facet_pmap;
|
typedef Rebind_facet_pmap<C3T3,Cell_pmap> Facet_pmap;
|
||||||
typedef Null_facet_pmap<C3T3, Cell_pmap> Facet_pmap_twice;
|
typedef Null_facet_pmap<C3T3, Cell_pmap> Facet_pmap_twice;
|
||||||
typedef Null_vertex_pmap<C3T3, Cell_pmap, Facet_pmap> Vertex_pmap;
|
typedef Null_vertex_pmap<C3T3, Cell_pmap, Facet_pmap> Vertex_pmap;
|
||||||
|
|
||||||
bool print_twice() { return false; }
|
bool print_twice() { return false; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------------
|
//-------------------------------------------------------
|
||||||
// IO functions
|
// IO functions
|
||||||
//-------------------------------------------------------
|
//-------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template <class C3T3, bool rebind, bool no_patch>
|
template <class C3T3, bool rebind, bool no_patch>
|
||||||
void
|
void
|
||||||
output_to_medit(std::ostream& os,
|
output_to_medit(std::ostream& os,
|
||||||
|
|
@ -707,18 +707,18 @@ output_to_medit(std::ostream& os,
|
||||||
#ifdef CGAL_MESH_3_IO_VERBOSE
|
#ifdef CGAL_MESH_3_IO_VERBOSE
|
||||||
std::cerr << "Output to medit:\n";
|
std::cerr << "Output to medit:\n";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef Medit_pmap_generator<C3T3,rebind,no_patch> Generator;
|
typedef Medit_pmap_generator<C3T3,rebind,no_patch> Generator;
|
||||||
typedef typename Generator::Cell_pmap Cell_pmap;
|
typedef typename Generator::Cell_pmap Cell_pmap;
|
||||||
typedef typename Generator::Facet_pmap Facet_pmap;
|
typedef typename Generator::Facet_pmap Facet_pmap;
|
||||||
typedef typename Generator::Facet_pmap_twice Facet_pmap_twice;
|
typedef typename Generator::Facet_pmap_twice Facet_pmap_twice;
|
||||||
typedef typename Generator::Vertex_pmap Vertex_pmap;
|
typedef typename Generator::Vertex_pmap Vertex_pmap;
|
||||||
|
|
||||||
Cell_pmap cell_pmap(c3t3);
|
Cell_pmap cell_pmap(c3t3);
|
||||||
Facet_pmap facet_pmap(c3t3,cell_pmap);
|
Facet_pmap facet_pmap(c3t3,cell_pmap);
|
||||||
Facet_pmap_twice facet_pmap_twice(c3t3,cell_pmap);
|
Facet_pmap_twice facet_pmap_twice(c3t3,cell_pmap);
|
||||||
Vertex_pmap vertex_pmap(c3t3,cell_pmap,facet_pmap);
|
Vertex_pmap vertex_pmap(c3t3,cell_pmap,facet_pmap);
|
||||||
|
|
||||||
output_to_medit(os,
|
output_to_medit(os,
|
||||||
c3t3,
|
c3t3,
|
||||||
vertex_pmap,
|
vertex_pmap,
|
||||||
|
|
@ -726,14 +726,14 @@ output_to_medit(std::ostream& os,
|
||||||
cell_pmap,
|
cell_pmap,
|
||||||
facet_pmap_twice,
|
facet_pmap_twice,
|
||||||
Generator().print_twice());
|
Generator().print_twice());
|
||||||
|
|
||||||
#ifdef CGAL_MESH_3_IO_VERBOSE
|
#ifdef CGAL_MESH_3_IO_VERBOSE
|
||||||
std::cerr << "done.\n";
|
std::cerr << "done.\n";
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template <class C3T3,
|
template <class C3T3,
|
||||||
class Vertex_index_property_map,
|
class Vertex_index_property_map,
|
||||||
class Facet_index_property_map,
|
class Facet_index_property_map,
|
||||||
|
|
@ -795,11 +795,11 @@ output_to_medit(std::ostream& os,
|
||||||
// Facets
|
// Facets
|
||||||
//-------------------------------------------------------
|
//-------------------------------------------------------
|
||||||
typename C3T3::size_type number_of_triangles = c3t3.number_of_facets_in_complex();
|
typename C3T3::size_type number_of_triangles = c3t3.number_of_facets_in_complex();
|
||||||
|
|
||||||
if ( print_each_facet_twice )
|
if ( print_each_facet_twice )
|
||||||
number_of_triangles += number_of_triangles;
|
number_of_triangles += number_of_triangles;
|
||||||
|
|
||||||
os << "Triangles\n"
|
os << "Triangles\n"
|
||||||
<< number_of_triangles << '\n';
|
<< number_of_triangles << '\n';
|
||||||
|
|
||||||
for( Facet_iterator fit = c3t3.facets_in_complex_begin();
|
for( Facet_iterator fit = c3t3.facets_in_complex_begin();
|
||||||
|
|
@ -807,7 +807,7 @@ output_to_medit(std::ostream& os,
|
||||||
++fit)
|
++fit)
|
||||||
{
|
{
|
||||||
typename C3T3::Facet f = (*fit);
|
typename C3T3::Facet f = (*fit);
|
||||||
|
|
||||||
// Apply priority among subdomains, to get consistent facet orientation per subdomain-pair interface.
|
// Apply priority among subdomains, to get consistent facet orientation per subdomain-pair interface.
|
||||||
if ( print_each_facet_twice )
|
if ( print_each_facet_twice )
|
||||||
{
|
{
|
||||||
|
|
@ -815,23 +815,23 @@ output_to_medit(std::ostream& os,
|
||||||
if (f.first->subdomain_index() > f.first->neighbor(f.second)->subdomain_index())
|
if (f.first->subdomain_index() > f.first->neighbor(f.second)->subdomain_index())
|
||||||
f = tr.mirror_facet(f);
|
f = tr.mirror_facet(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get facet vertices in CCW order.
|
// Get facet vertices in CCW order.
|
||||||
Vertex_handle vh1 = f.first->vertex((f.second + 1) % 4);
|
Vertex_handle vh1 = f.first->vertex((f.second + 1) % 4);
|
||||||
Vertex_handle vh2 = f.first->vertex((f.second + 2) % 4);
|
Vertex_handle vh2 = f.first->vertex((f.second + 2) % 4);
|
||||||
Vertex_handle vh3 = f.first->vertex((f.second + 3) % 4);
|
Vertex_handle vh3 = f.first->vertex((f.second + 3) % 4);
|
||||||
|
|
||||||
// Facet orientation also depends on parity.
|
// Facet orientation also depends on parity.
|
||||||
if (f.second % 2 != 0)
|
if (f.second % 2 != 0)
|
||||||
std::swap(vh2, vh3);
|
std::swap(vh2, vh3);
|
||||||
|
|
||||||
os << V[vh1] << ' ' << V[vh2] << ' ' << V[vh3] << ' ';
|
os << V[vh1] << ' ' << V[vh2] << ' ' << V[vh3] << ' ';
|
||||||
os << get(facet_pmap, *fit) << '\n';
|
os << get(facet_pmap, *fit) << '\n';
|
||||||
|
|
||||||
// Print triangle again if needed, with opposite orientation
|
// Print triangle again if needed, with opposite orientation
|
||||||
if ( print_each_facet_twice )
|
if ( print_each_facet_twice )
|
||||||
{
|
{
|
||||||
os << V[vh3] << ' ' << V[vh2] << ' ' << V[vh1] << ' ';
|
os << V[vh3] << ' ' << V[vh2] << ' ' << V[vh1] << ' ';
|
||||||
os << get(facet_twice_pmap, *fit) << '\n';
|
os << get(facet_twice_pmap, *fit) << '\n';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@
|
||||||
namespace CGAL{
|
namespace CGAL{
|
||||||
|
|
||||||
template <class C3T3>
|
template <class C3T3>
|
||||||
void
|
void
|
||||||
write_cells_tag(std::ostream& os,
|
write_cells_tag(std::ostream& os,
|
||||||
const C3T3 & c3t3,
|
const C3T3 & c3t3,
|
||||||
std::map<typename C3T3::Triangulation::Vertex_handle, std::size_t> & V,
|
std::map<typename C3T3::Triangulation::Vertex_handle, std::size_t> & V,
|
||||||
|
|
@ -52,7 +52,7 @@ write_cells_tag(std::ostream& os,
|
||||||
os << " <Cells>\n"
|
os << " <Cells>\n"
|
||||||
<< " <DataArray Name=\"connectivity\""
|
<< " <DataArray Name=\"connectivity\""
|
||||||
<< formatattribute << typeattribute;
|
<< formatattribute << typeattribute;
|
||||||
|
|
||||||
if (binary) { // if binary output, just write the xml tag
|
if (binary) { // if binary output, just write the xml tag
|
||||||
os << " offset=\"" << offset << "\"/>\n";
|
os << " offset=\"" << offset << "\"/>\n";
|
||||||
offset += (4 * c3t3.number_of_cells() + 1) * sizeof(std::size_t);
|
offset += (4 * c3t3.number_of_cells() + 1) * sizeof(std::size_t);
|
||||||
|
|
@ -69,11 +69,11 @@ write_cells_tag(std::ostream& os,
|
||||||
}
|
}
|
||||||
os << "\n </DataArray>\n";
|
os << "\n </DataArray>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write offsets
|
// Write offsets
|
||||||
os << " <DataArray Name=\"offsets\""
|
os << " <DataArray Name=\"offsets\""
|
||||||
<< formatattribute << typeattribute;
|
<< formatattribute << typeattribute;
|
||||||
|
|
||||||
if (binary) { // if binary output, just write the xml tag
|
if (binary) { // if binary output, just write the xml tag
|
||||||
os << " offset=\"" << offset << "\"/>\n";
|
os << " offset=\"" << offset << "\"/>\n";
|
||||||
offset += (c3t3.number_of_cells() + 1) * sizeof(std::size_t);
|
offset += (c3t3.number_of_cells() + 1) * sizeof(std::size_t);
|
||||||
|
|
@ -83,12 +83,12 @@ write_cells_tag(std::ostream& os,
|
||||||
os << ">\n";
|
os << ">\n";
|
||||||
std::size_t cells_offset = 0;
|
std::size_t cells_offset = 0;
|
||||||
for( Cell_iterator cit = c3t3.cells_in_complex_begin() ;
|
for( Cell_iterator cit = c3t3.cells_in_complex_begin() ;
|
||||||
cit != c3t3.cells_in_complex_end() ;
|
cit != c3t3.cells_in_complex_end() ;
|
||||||
++cit )
|
++cit )
|
||||||
{
|
{
|
||||||
cells_offset += 4;
|
cells_offset += 4;
|
||||||
os << cells_offset << " ";
|
os << cells_offset << " ";
|
||||||
}
|
}
|
||||||
os << "\n </DataArray>\n";
|
os << "\n </DataArray>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -104,8 +104,8 @@ write_cells_tag(std::ostream& os,
|
||||||
else {
|
else {
|
||||||
os << ">\n";
|
os << ">\n";
|
||||||
for( Cell_iterator cit = c3t3.cells_in_complex_begin() ;
|
for( Cell_iterator cit = c3t3.cells_in_complex_begin() ;
|
||||||
cit != c3t3.cells_in_complex_end() ;
|
cit != c3t3.cells_in_complex_end() ;
|
||||||
++cit )
|
++cit )
|
||||||
os << "10 ";
|
os << "10 ";
|
||||||
os << "\n </DataArray>\n";
|
os << "\n </DataArray>\n";
|
||||||
}
|
}
|
||||||
|
|
@ -131,7 +131,7 @@ write_cells(std::ostream& os,
|
||||||
off += 4;
|
off += 4;
|
||||||
offsets.push_back(off);
|
offsets.push_back(off);
|
||||||
for (int i=0; i<4; i++)
|
for (int i=0; i<4; i++)
|
||||||
connectivity_table.push_back(V[cit->vertex(i)]);
|
connectivity_table.push_back(V[cit->vertex(i)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
IO::internal::write_vector<std::size_t>(os,connectivity_table);
|
IO::internal::write_vector<std::size_t>(os,connectivity_table);
|
||||||
|
|
@ -141,7 +141,7 @@ write_cells(std::ostream& os,
|
||||||
|
|
||||||
|
|
||||||
template <class Tr>
|
template <class Tr>
|
||||||
void
|
void
|
||||||
write_c3t3_points_tag(std::ostream& os,
|
write_c3t3_points_tag(std::ostream& os,
|
||||||
const Tr & tr,
|
const Tr & tr,
|
||||||
std::size_t size_of_vertices,
|
std::size_t size_of_vertices,
|
||||||
|
|
@ -163,12 +163,12 @@ write_c3t3_points_tag(std::ostream& os,
|
||||||
<< format;
|
<< format;
|
||||||
|
|
||||||
if (binary) {
|
if (binary) {
|
||||||
os << "\" offset=\"" << offset << "\"/>\n";
|
os << "\" offset=\"" << offset << "\"/>\n";
|
||||||
offset += 3 * size_of_vertices * sizeof(FT) + sizeof(std::size_t);
|
offset += 3 * size_of_vertices * sizeof(FT) + sizeof(std::size_t);
|
||||||
// dim coords per points + length of the encoded data (size_t)
|
// dim coords per points + length of the encoded data (size_t)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
os << "\">\n";
|
os << "\">\n";
|
||||||
for( Finite_vertices_iterator vit = tr.finite_vertices_begin();
|
for( Finite_vertices_iterator vit = tr.finite_vertices_begin();
|
||||||
vit != tr.finite_vertices_end();
|
vit != tr.finite_vertices_end();
|
||||||
++vit)
|
++vit)
|
||||||
|
|
@ -187,7 +187,7 @@ write_c3t3_points_tag(std::ostream& os,
|
||||||
os << " </Points>\n";
|
os << " </Points>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
// writes the points appended data at the end of the .vtu file
|
// writes the points appended data at the end of the .vtu file
|
||||||
template <class Tr>
|
template <class Tr>
|
||||||
void
|
void
|
||||||
write_c3t3_points(std::ostream& os,
|
write_c3t3_points(std::ostream& os,
|
||||||
|
|
@ -217,12 +217,12 @@ write_c3t3_points(std::ostream& os,
|
||||||
|
|
||||||
// writes the attribute tags before binary data is appended
|
// writes the attribute tags before binary data is appended
|
||||||
template <class T>
|
template <class T>
|
||||||
void
|
void
|
||||||
write_attribute_tag(std::ostream& os,
|
write_attribute_tag(std::ostream& os,
|
||||||
const std::string& attr_name,
|
const std::string& attr_name,
|
||||||
const std::vector<T>& attribute,
|
const std::vector<T>& attribute,
|
||||||
bool binary,
|
bool binary,
|
||||||
std::size_t& offset)
|
std::size_t& offset)
|
||||||
{
|
{
|
||||||
std::string format = binary ? "appended" : "ascii";
|
std::string format = binary ? "appended" : "ascii";
|
||||||
std::string type = "";
|
std::string type = "";
|
||||||
|
|
@ -239,28 +239,28 @@ write_attribute_tag(std::ostream& os,
|
||||||
else
|
else
|
||||||
type = "UInt64";
|
type = "UInt64";
|
||||||
}
|
}
|
||||||
os << " <DataArray type=\"" << type << "\" Name=\"" << attr_name << "\" format=\"" << format;
|
os << " <DataArray type=\"" << type << "\" Name=\"" << attr_name << "\" format=\"" << format;
|
||||||
|
|
||||||
if (binary) {
|
if (binary) {
|
||||||
os << "\" offset=\"" << offset << "\"/>\n";
|
os << "\" offset=\"" << offset << "\"/>\n";
|
||||||
offset += attribute.size() * sizeof(T) + sizeof(std::size_t);
|
offset += attribute.size() * sizeof(T) + sizeof(std::size_t);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
typedef typename std::vector<T>::const_iterator Iterator;
|
typedef typename std::vector<T>::const_iterator Iterator;
|
||||||
os << "\">\n";
|
os << "\">\n";
|
||||||
for (Iterator it = attribute.begin();
|
for (Iterator it = attribute.begin();
|
||||||
it != attribute.end();
|
it != attribute.end();
|
||||||
++it )
|
++it )
|
||||||
os << *it << " ";
|
os << *it << " ";
|
||||||
os << "\n </DataArray>\n";
|
os << "\n </DataArray>\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// writes the attributes appended data at the end of the .vtu file
|
// writes the attributes appended data at the end of the .vtu file
|
||||||
template <typename FT>
|
template <typename FT>
|
||||||
void
|
void
|
||||||
write_attributes(std::ostream& os,
|
write_attributes(std::ostream& os,
|
||||||
const std::vector<FT>& att)
|
const std::vector<FT>& att)
|
||||||
{
|
{
|
||||||
IO::internal::write_vector(os,att);
|
IO::internal::write_vector(os,att);
|
||||||
}
|
}
|
||||||
|
|
@ -292,7 +292,7 @@ void output_to_vtu_with_attributes(std::ostream& os,
|
||||||
#else // CGAL_BIG_ENDIAN
|
#else // CGAL_BIG_ENDIAN
|
||||||
os << " byte_order=\"BigEndian\"";
|
os << " byte_order=\"BigEndian\"";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
switch(sizeof(std::size_t)) {
|
switch(sizeof(std::size_t)) {
|
||||||
case 4: os << " header_type=\"UInt32\""; break;
|
case 4: os << " header_type=\"UInt32\""; break;
|
||||||
case 8: os << " header_type=\"UInt64\""; break;
|
case 8: os << " header_type=\"UInt64\""; break;
|
||||||
|
|
@ -328,7 +328,7 @@ void output_to_vtu_with_attributes(std::ostream& os,
|
||||||
os << " </Piece>\n"
|
os << " </Piece>\n"
|
||||||
<< " </UnstructuredGrid>\n";
|
<< " </UnstructuredGrid>\n";
|
||||||
if (binary) {
|
if (binary) {
|
||||||
os << "<AppendedData encoding=\"raw\">\n_";
|
os << "<AppendedData encoding=\"raw\">\n_";
|
||||||
write_c3t3_points(os,tr,V); // fills V if the mode is BINARY
|
write_c3t3_points(os,tr,V); // fills V if the mode is BINARY
|
||||||
write_cells(os,c3t3,V);
|
write_cells(os,c3t3,V);
|
||||||
for(std::size_t i = 0; i< attributes.size(); ++i)
|
for(std::size_t i = 0; i< attributes.size(); ++i)
|
||||||
|
|
@ -364,7 +364,7 @@ void output_to_vtu(std::ostream& os,
|
||||||
double v = cit->subdomain_index();
|
double v = cit->subdomain_index();
|
||||||
mids.push_back(v);
|
mids.push_back(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::pair<const char*, Vtu_attributes > > atts;
|
std::vector<std::pair<const char*, Vtu_attributes > > atts;
|
||||||
Vtu_attributes v = &mids;
|
Vtu_attributes v = &mids;
|
||||||
atts.push_back(std::make_pair("MeshDomain", v));
|
atts.push_back(std::make_pair("MeshDomain", v));
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
\mainpage User Manual
|
\mainpage User Manual
|
||||||
\anchor Chapter_Point_Set_Processing
|
\anchor Chapter_Point_Set_Processing
|
||||||
\anchor chappoint_set_processing_3
|
\anchor chappoint_set_processing_3
|
||||||
|
|
||||||
|
|
@ -22,12 +22,12 @@ Point set processing. Left: 275K points sampled on the statue of an elephant wit
|
||||||
In the context of surface reconstruction we can position the elements
|
In the context of surface reconstruction we can position the elements
|
||||||
of this component along the common surface reconstruction pipeline
|
of this component along the common surface reconstruction pipeline
|
||||||
(\cgalFigureRef{Point_set_processing_3figpipeline}) which involves the
|
(\cgalFigureRef{Point_set_processing_3figpipeline}) which involves the
|
||||||
following steps:
|
following steps:
|
||||||
-# Scanning and scan registration to produce a set of
|
-# Scanning and scan registration to produce a set of
|
||||||
points or points with normals;
|
points or points with normals;
|
||||||
-# Outlier removal;
|
-# Outlier removal;
|
||||||
-# Simplification to reduce the number of input points;
|
-# Simplification to reduce the number of input points;
|
||||||
-# Smoothing to reduce noise in the input data;
|
-# Smoothing to reduce noise in the input data;
|
||||||
-# Normal estimation and orientation when the normals are not already provided
|
-# Normal estimation and orientation when the normals are not already provided
|
||||||
by the acquisition device; and
|
by the acquisition device; and
|
||||||
-# Surface reconstruction. Chapter \ref Chapter_Poisson_Surface_Reconstruction "Poisson Surface Reconstruction"
|
-# Surface reconstruction. Chapter \ref Chapter_Poisson_Surface_Reconstruction "Poisson Surface Reconstruction"
|
||||||
|
|
@ -84,9 +84,9 @@ The following classes described in Chapter \ref PkgPropertyMap
|
||||||
provide property maps for the implementations of points with normals
|
provide property maps for the implementations of points with normals
|
||||||
listed above:
|
listed above:
|
||||||
|
|
||||||
- `Identity_property_map<T>`
|
- `Identity_property_map<T>`
|
||||||
- `First_of_pair_property_map<Pair>` and `Second_of_pair_property_map<Pair>`
|
- `First_of_pair_property_map<Pair>` and `Second_of_pair_property_map<Pair>`
|
||||||
- `Nth_of_tuple_property_map<N, Tuple>`
|
- `Nth_of_tuple_property_map<N, Tuple>`
|
||||||
|
|
||||||
`Identity_property_map<Point_3>` is the default value of the
|
`Identity_property_map<Point_3>` is the default value of the
|
||||||
position property map expected by all functions in this component.
|
position property map expected by all functions in this component.
|
||||||
|
|
@ -96,7 +96,7 @@ See below examples using pair and tuple property maps.
|
||||||
Users of this package may use other types to represent positions and
|
Users of this package may use other types to represent positions and
|
||||||
normals if they implement the corresponding property maps.
|
normals if they implement the corresponding property maps.
|
||||||
|
|
||||||
Points and normals can even be stored in separate containers
|
Points and normals can even be stored in separate containers
|
||||||
and accessed by their index, as any built-in vector is also
|
and accessed by their index, as any built-in vector is also
|
||||||
a property map.
|
a property map.
|
||||||
|
|
||||||
|
|
@ -128,7 +128,7 @@ parameters (than can be deduced automatically in simple cases) are
|
||||||
moved to the end of the function in a single named parameter object
|
moved to the end of the function in a single named parameter object
|
||||||
(see \ref BGLNamedParameters). The code translated to the current API
|
(see \ref BGLNamedParameters). The code translated to the current API
|
||||||
becomes:
|
becomes:
|
||||||
|
|
||||||
\code
|
\code
|
||||||
std::vector<PointVectorPair> points;
|
std::vector<PointVectorPair> points;
|
||||||
|
|
||||||
|
|
@ -297,7 +297,7 @@ The 4 functions presented here work both with 2D points and 3D points
|
||||||
and they shouldn't be used if the point sets do not sample a curve in
|
and they shouldn't be used if the point sets do not sample a curve in
|
||||||
2D or a surface in 3D.
|
2D or a surface in 3D.
|
||||||
|
|
||||||
\subsection Point_set_processing_3Example_scale_estimation_global Global Scale Example
|
\subsection Point_set_processing_3Example_scale_estimation_global Global Scale Example
|
||||||
|
|
||||||
The following example reads a 3D point set in the `xyz` format and:
|
The following example reads a 3D point set in the `xyz` format and:
|
||||||
|
|
||||||
|
|
@ -340,7 +340,7 @@ one point set w.r.t. another and directly aligns it to it.
|
||||||
|
|
||||||
\subsection Point_set_processing_3Examples_registration_OpenGR OpenGR Example
|
\subsection Point_set_processing_3Examples_registration_OpenGR OpenGR Example
|
||||||
|
|
||||||
The following example reads two point sets and aligns them using the
|
The following example reads two point sets and aligns them using the
|
||||||
\ref thirdpartyOpenGR library, using the Super4PCS algorithm:
|
\ref thirdpartyOpenGR library, using the Super4PCS algorithm:
|
||||||
\cgalExample{Point_set_processing_3/registration_with_OpenGR.cpp}
|
\cgalExample{Point_set_processing_3/registration_with_OpenGR.cpp}
|
||||||
|
|
||||||
|
|
@ -389,7 +389,7 @@ defined by the parameter delta (accuracy).
|
||||||
|
|
||||||
Using too wide values will slow down the algorithm by increasing the size of the congruent set,
|
Using too wide values will slow down the algorithm by increasing the size of the congruent set,
|
||||||
while using to small values prevents to find a solution. This parameter impacts other steps of
|
while using to small values prevents to find a solution. This parameter impacts other steps of
|
||||||
the algorithm, see the paper \cgalCite{cgal:mam-sffgp-14} for more details.
|
the algorithm, see the paper \cgalCite{cgal:mam-sffgp-14} for more details.
|
||||||
|
|
||||||
\subsubsection Point_set_processing_3Examples_registration_OpenGR_parameter_normal Parameter: maximum normal deviation
|
\subsubsection Point_set_processing_3Examples_registration_OpenGR_parameter_normal Parameter: maximum normal deviation
|
||||||
|
|
||||||
|
|
@ -402,7 +402,7 @@ candidates that should indeed have been matched and may thus result in a quality
|
||||||
|
|
||||||
\subsubsection Point_set_processing_3Examples_registration_OpenGR_parameter_overlap Parameter: overlap
|
\subsubsection Point_set_processing_3Examples_registration_OpenGR_parameter_overlap Parameter: overlap
|
||||||
|
|
||||||
Ratio of expected overlap between the two point sets: it is ranging between 0 (no overlap) to 1 (100% overlap).
|
Ratio of expected overlap between the two point sets: it is ranging between 0 (no overlap) to 1 (100% overlap).
|
||||||
|
|
||||||
The overlap parameter controls the size of the basis used for registration, as shown below:
|
The overlap parameter controls the size of the basis used for registration, as shown below:
|
||||||
|
|
||||||
|
|
@ -411,7 +411,7 @@ The effect of varying overlap parameter on the size of the basis used for regist
|
||||||
\cgalFigureEnd
|
\cgalFigureEnd
|
||||||
|
|
||||||
Usually, the larger the overlap, the faster the algorithm.
|
Usually, the larger the overlap, the faster the algorithm.
|
||||||
When the overlap is unknown, a simple way to set this parameter is to start from
|
When the overlap is unknown, a simple way to set this parameter is to start from
|
||||||
100% overlap, and decrease the value until obtaining a good result.
|
100% overlap, and decrease the value until obtaining a good result.
|
||||||
Using too small values will slow down the algorithm, and
|
Using too small values will slow down the algorithm, and
|
||||||
reduce the accuracy of the result.
|
reduce the accuracy of the result.
|
||||||
|
|
@ -424,7 +424,7 @@ randomly, it is recommended to use a large time value to explore the whole space
|
||||||
|
|
||||||
\subsection Point_set_processing_3Examples_registration_PointMatcher PointMatcher Example
|
\subsection Point_set_processing_3Examples_registration_PointMatcher PointMatcher Example
|
||||||
|
|
||||||
The following example reads two point sets and aligns them using the
|
The following example reads two point sets and aligns them using the
|
||||||
\ref thirdpartylibpointmatcher library, using the ICP algorithm. It also shows how
|
\ref thirdpartylibpointmatcher library, using the ICP algorithm. It also shows how
|
||||||
to customize ICP algorithm by using possible configurations:
|
to customize ICP algorithm by using possible configurations:
|
||||||
\cgalExample{Point_set_processing_3/registration_with_pointmatcher.cpp}
|
\cgalExample{Point_set_processing_3/registration_with_pointmatcher.cpp}
|
||||||
|
|
@ -463,7 +463,7 @@ The method used for matching (linking) the points from to the points in the refe
|
||||||
|
|
||||||
Corresponds to `matcher` configuration module of \ref thirdpartylibpointmatcher
|
Corresponds to `matcher` configuration module of \ref thirdpartylibpointmatcher
|
||||||
library. The matcher should be chosen and set from possible components of
|
library. The matcher should be chosen and set from possible components of
|
||||||
the `matcher` configuration module.
|
the `matcher` configuration module.
|
||||||
See <a href="https://libpointmatcher.readthedocs.io/en/latest/Configuration/#configuration-of-an-icp-chain">libpointmatcher documentation</a>
|
See <a href="https://libpointmatcher.readthedocs.io/en/latest/Configuration/#configuration-of-an-icp-chain">libpointmatcher documentation</a>
|
||||||
for possible configurations.
|
for possible configurations.
|
||||||
|
|
||||||
|
|
@ -478,7 +478,7 @@ range.
|
||||||
|
|
||||||
Corresponds to `outlierFilters` configuration module of \ref thirdpartylibpointmatcher
|
Corresponds to `outlierFilters` configuration module of \ref thirdpartylibpointmatcher
|
||||||
library. The filters should be chosen and set from possible components of
|
library. The filters should be chosen and set from possible components of
|
||||||
the `outlierFilters` configuration module.
|
the `outlierFilters` configuration module.
|
||||||
See <a href="https://libpointmatcher.readthedocs.io/en/latest/Configuration/#configuration-of-an-icp-chain">libpointmatcher documentation</a>
|
See <a href="https://libpointmatcher.readthedocs.io/en/latest/Configuration/#configuration-of-an-icp-chain">libpointmatcher documentation</a>
|
||||||
for possible configurations.
|
for possible configurations.
|
||||||
|
|
||||||
|
|
@ -489,7 +489,7 @@ the error between the point sets.
|
||||||
|
|
||||||
Corresponds to `errorMinimizer` configuration module of \ref thirdpartylibpointmatcher
|
Corresponds to `errorMinimizer` configuration module of \ref thirdpartylibpointmatcher
|
||||||
library. The error minimizer should be chosen and set from possible components of
|
library. The error minimizer should be chosen and set from possible components of
|
||||||
the `errorMinimizer` configuration module.
|
the `errorMinimizer` configuration module.
|
||||||
See <a href="https://libpointmatcher.readthedocs.io/en/latest/Configuration/#configuration-of-an-icp-chain">libpointmatcher documentation</a>
|
See <a href="https://libpointmatcher.readthedocs.io/en/latest/Configuration/#configuration-of-an-icp-chain">libpointmatcher documentation</a>
|
||||||
for possible configurations.
|
for possible configurations.
|
||||||
|
|
||||||
|
|
@ -500,7 +500,7 @@ typically provide deeper scrutiny than the logger.
|
||||||
|
|
||||||
Corresponds to `inspector` configuration module of \ref thirdpartylibpointmatcher
|
Corresponds to `inspector` configuration module of \ref thirdpartylibpointmatcher
|
||||||
library. The inspector should be chosen and set from possible components of
|
library. The inspector should be chosen and set from possible components of
|
||||||
the `inspector` configuration module.
|
the `inspector` configuration module.
|
||||||
See <a href="https://libpointmatcher.readthedocs.io/en/latest/Configuration/#configuration-of-an-icp-chain">libpointmatcher documentation</a>
|
See <a href="https://libpointmatcher.readthedocs.io/en/latest/Configuration/#configuration-of-an-icp-chain">libpointmatcher documentation</a>
|
||||||
for possible configurations.
|
for possible configurations.
|
||||||
|
|
||||||
|
|
@ -512,7 +512,7 @@ does not get effected by this configuration.
|
||||||
|
|
||||||
Corresponds to `logger` configuration module of \ref thirdpartylibpointmatcher
|
Corresponds to `logger` configuration module of \ref thirdpartylibpointmatcher
|
||||||
library. The logger should be chosen and set from possible components of
|
library. The logger should be chosen and set from possible components of
|
||||||
the `logger` configuration module.
|
the `logger` configuration module.
|
||||||
See <a href="https://libpointmatcher.readthedocs.io/en/latest/Configuration/#configuration-of-an-icp-chain">libpointmatcher documentation</a>
|
See <a href="https://libpointmatcher.readthedocs.io/en/latest/Configuration/#configuration-of-an-icp-chain">libpointmatcher documentation</a>
|
||||||
for possible configurations.
|
for possible configurations.
|
||||||
|
|
||||||
|
|
@ -526,7 +526,7 @@ The following example reads two point sets and aligns them by using both
|
||||||
\ref thirdpartyOpenGR and \ref thirdpartylibpointmatcher libraries, respectively.
|
\ref thirdpartyOpenGR and \ref thirdpartylibpointmatcher libraries, respectively.
|
||||||
It depicts a use case where a coarse estimation of a registration transformation
|
It depicts a use case where a coarse estimation of a registration transformation
|
||||||
is done using the Super4PCS algorithm. Then, a fine registration from this coarse
|
is done using the Super4PCS algorithm. Then, a fine registration from this coarse
|
||||||
registration using the ICP algorithm.
|
registration using the ICP algorithm.
|
||||||
\cgalExample{Point_set_processing_3/registration_with_opengr_pointmatcher_pipeline.cpp}
|
\cgalExample{Point_set_processing_3/registration_with_opengr_pointmatcher_pipeline.cpp}
|
||||||
|
|
||||||
\cgalFigureRef{Point_set_processing_3tableRegistrationRegistration_visualization_table} demonstrates
|
\cgalFigureRef{Point_set_processing_3tableRegistrationRegistration_visualization_table} demonstrates
|
||||||
|
|
@ -603,7 +603,7 @@ above-mentioned example was used.
|
||||||
\cgalFigureCaptionBegin{Point_set_processing_3tableRegistrationRegistration_visualization_table}
|
\cgalFigureCaptionBegin{Point_set_processing_3tableRegistrationRegistration_visualization_table}
|
||||||
Visualization of registered hippo scans with different registration methods.
|
Visualization of registered hippo scans with different registration methods.
|
||||||
Two scans are used: red as the reference, green as the one for which the transformation
|
Two scans are used: red as the reference, green as the one for which the transformation
|
||||||
is computed and applied. To obtain the results, the example code given in
|
is computed and applied. To obtain the results, the example code given in
|
||||||
\ref Point_set_processing_3Examples_registration_OpenGR ,
|
\ref Point_set_processing_3Examples_registration_OpenGR ,
|
||||||
\ref Point_set_processing_3Examples_registration_PointMatcher ,
|
\ref Point_set_processing_3Examples_registration_PointMatcher ,
|
||||||
\ref Point_set_processing_3Examples_registration_OpenGR_PointMatcher_Pipeline
|
\ref Point_set_processing_3Examples_registration_OpenGR_PointMatcher_Pipeline
|
||||||
|
|
@ -681,7 +681,7 @@ simplification of the point set through local clusters
|
||||||
directly selected by the user or it automatically adapts to the local
|
directly selected by the user or it automatically adapts to the local
|
||||||
variation of the point set.
|
variation of the point set.
|
||||||
|
|
||||||
Function `wlop_simplify_and_regularize_point_set()` not only simplifies,
|
Function `wlop_simplify_and_regularize_point_set()` not only simplifies,
|
||||||
but also regularizes downsampled points. This is an implementation of
|
but also regularizes downsampled points. This is an implementation of
|
||||||
the Weighted Locally Optimal Projection (WLOP) algorithm \cgalCite{wlop-2009}.
|
the Weighted Locally Optimal Projection (WLOP) algorithm \cgalCite{wlop-2009}.
|
||||||
|
|
||||||
|
|
@ -743,7 +743,7 @@ Computing density weights for each point is an optional preprocessing. For examp
|
||||||
|
|
||||||
|
|
||||||
\cgalFigureBegin{Point_set_processing_3figWLOP_parameter_density, WLOP_parameter_density.jpg}
|
\cgalFigureBegin{Point_set_processing_3figWLOP_parameter_density, WLOP_parameter_density.jpg}
|
||||||
Comparison between with and without density: Left: input. Middle: `require_uniform_sampling = false`. Right: `require_uniform_sampling=true`.
|
Comparison between with and without density: Left: input. Middle: `require_uniform_sampling = false`. Right: `require_uniform_sampling=true`.
|
||||||
\cgalFigureEnd
|
\cgalFigureEnd
|
||||||
|
|
||||||
\subsubsection Point_set_processing_3WLOP_parameter_neighborhood_size Parameter: neighbor_radius
|
\subsubsection Point_set_processing_3WLOP_parameter_neighborhood_size Parameter: neighbor_radius
|
||||||
|
|
@ -754,14 +754,14 @@ Comparison between different sizes of neighbor radius.
|
||||||
\cgalFigureEnd
|
\cgalFigureEnd
|
||||||
|
|
||||||
\subsubsection Point_set_processing_3WLOP_parallel_performance Parallel Performance
|
\subsubsection Point_set_processing_3WLOP_parallel_performance Parallel Performance
|
||||||
A parallel version of WLOP is provided and requires the executable to be linked against the
|
A parallel version of WLOP is provided and requires the executable to be linked against the
|
||||||
<a href="https://www.threadingbuildingblocks.org">Intel TBB library</a>.
|
<a href="https://www.threadingbuildingblocks.org">Intel TBB library</a>.
|
||||||
To control the number of threads used, the user may use the tbb::task_scheduler_init class.
|
To control the number of threads used, the user may use the tbb::task_scheduler_init class.
|
||||||
See the <a href="https://www.threadingbuildingblocks.org/documentation">TBB documentation</a>
|
See the <a href="https://www.threadingbuildingblocks.org/documentation">TBB documentation</a>
|
||||||
for more details. We provide below a speed-up chart generated using the parallel version of the WLOP algorithm. The machine used is a PC running Windows 7 64-bits with a 4-core i7-4700HQ@2.40GHz CPU with 8GB of RAM.
|
for more details. We provide below a speed-up chart generated using the parallel version of the WLOP algorithm. The machine used is a PC running Windows 7 64-bits with a 4-core i7-4700HQ@2.40GHz CPU with 8GB of RAM.
|
||||||
|
|
||||||
\cgalFigureBegin{Point_set_processing_3figWLOP_parallel_performance, parallel_WLOP_performance.jpg}
|
\cgalFigureBegin{Point_set_processing_3figWLOP_parallel_performance, parallel_WLOP_performance.jpg}
|
||||||
Parallel WLOP speed-up, compared to the sequential version of the algorithm.
|
Parallel WLOP speed-up, compared to the sequential version of the algorithm.
|
||||||
\cgalFigureEnd
|
\cgalFigureEnd
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -771,11 +771,11 @@ Two smoothing functions are devised to smooth an input point set.
|
||||||
|
|
||||||
Function `jet_smooth_point_set()` smooths the input point set by
|
Function `jet_smooth_point_set()` smooths the input point set by
|
||||||
projecting each point onto a smooth parametric surface patch
|
projecting each point onto a smooth parametric surface patch
|
||||||
(so-called jet surface) fitted over its nearest neighbors.
|
(so-called jet surface) fitted over its nearest neighbors.
|
||||||
|
|
||||||
Function `bilateral_smooth_point_set()` smooths the input point set by
|
Function `bilateral_smooth_point_set()` smooths the input point set by
|
||||||
iteratively projecting each point onto the implicit surface patch fitted over its nearest neighbors.
|
iteratively projecting each point onto the implicit surface patch fitted over its nearest neighbors.
|
||||||
Bilateral projection preserves sharp features according to the normal (gradient) information.
|
Bilateral projection preserves sharp features according to the normal (gradient) information.
|
||||||
Normals are thus required as input. For more details, see section 4 of \cgalCite{ear-2013}.
|
Normals are thus required as input. For more details, see section 4 of \cgalCite{ear-2013}.
|
||||||
|
|
||||||
For both functions, the user can either specify a fixed number of
|
For both functions, the user can either specify a fixed number of
|
||||||
|
|
@ -783,7 +783,7 @@ nearest neighbors or a fixed spherical neighborhood radius.
|
||||||
|
|
||||||
\subsection Point_set_processing_3Example_jet_smoothing Jet Smoothing Example
|
\subsection Point_set_processing_3Example_jet_smoothing Jet Smoothing Example
|
||||||
|
|
||||||
The following example generates a set of 9 points close to the `xy`
|
The following example generates a set of 9 points close to the `xy`
|
||||||
plane and smooths them using 8 nearest neighbors:
|
plane and smooths them using 8 nearest neighbors:
|
||||||
\cgalExample{Point_set_processing_3/jet_smoothing_example.cpp}
|
\cgalExample{Point_set_processing_3/jet_smoothing_example.cpp}
|
||||||
|
|
||||||
|
|
@ -798,14 +798,14 @@ Comparison for two smoothing methods: Left: Input, 250K points, normal-color map
|
||||||
|
|
||||||
\subsubsection Point_set_processing_3Bilateral_smoothing_parallel_performance Parallel
|
\subsubsection Point_set_processing_3Bilateral_smoothing_parallel_performance Parallel
|
||||||
|
|
||||||
Performance:
|
Performance:
|
||||||
A parallel version of bilateral smoothing is provided and requires the executable to be linked against the
|
A parallel version of bilateral smoothing is provided and requires the executable to be linked against the
|
||||||
<a href="https://www.threadingbuildingblocks.org">Intel TBB library</a>.
|
<a href="https://www.threadingbuildingblocks.org">Intel TBB library</a>.
|
||||||
The number of threads used is controlled through the tbb::task_scheduler_init class.
|
The number of threads used is controlled through the tbb::task_scheduler_init class.
|
||||||
See the <a href="https://www.threadingbuildingblocks.org/documentation">TBB documentation</a> for more details. We provide below a speed-up chart generated using the parallel version of the bilateral smoothing algorithm. The machine used is a PC running Windows 7 64-bits with a 4-core i7-4700HQ@2.40GHz CPU with 8GB of RAM.
|
See the <a href="https://www.threadingbuildingblocks.org/documentation">TBB documentation</a> for more details. We provide below a speed-up chart generated using the parallel version of the bilateral smoothing algorithm. The machine used is a PC running Windows 7 64-bits with a 4-core i7-4700HQ@2.40GHz CPU with 8GB of RAM.
|
||||||
|
|
||||||
\cgalFigureBegin{Point_set_processing_3Bilateral_smoothing_parallel_performance, parallel_bilateral_smooth_point_set_performance.jpg}
|
\cgalFigureBegin{Point_set_processing_3Bilateral_smoothing_parallel_performance, parallel_bilateral_smooth_point_set_performance.jpg}
|
||||||
Parallel bilateral smoothing speed-up, compared to the sequential version of the algorithm.
|
Parallel bilateral smoothing speed-up, compared to the sequential version of the algorithm.
|
||||||
\cgalFigureEnd
|
\cgalFigureEnd
|
||||||
|
|
||||||
\section Point_set_processing_3NormalEstimation Normal Estimation
|
\section Point_set_processing_3NormalEstimation Normal Estimation
|
||||||
|
|
@ -837,9 +837,9 @@ of nearest neighbors or a fixed spherical neighborhood radius.
|
||||||
|
|
||||||
Function `mst_orient_normals()` orients the normals of a set of
|
Function `mst_orient_normals()` orients the normals of a set of
|
||||||
points with unoriented normals using the method described by Hoppe et
|
points with unoriented normals using the method described by Hoppe et
|
||||||
al. in <I>Surface reconstruction from unorganized points</I> \cgalCite{cgal:hddms-srup-92}.
|
al. in <I>Surface reconstruction from unorganized points</I> \cgalCite{cgal:hddms-srup-92}.
|
||||||
More specifically, this method constructs a
|
More specifically, this method constructs a
|
||||||
Riemannian graph over the input points (the graph of the
|
Riemannian graph over the input points (the graph of the
|
||||||
nearest neighbor points) and propagates a seed normal orientation
|
nearest neighbor points) and propagates a seed normal orientation
|
||||||
within a minimum spanning tree computed over this graph. The result is
|
within a minimum spanning tree computed over this graph. The result is
|
||||||
an oriented normal vector for each input unoriented normal, except for
|
an oriented normal vector for each input unoriented normal, except for
|
||||||
|
|
@ -873,7 +873,7 @@ The following example reads a point set from a file, upsamples it to get a dense
|
||||||
|
|
||||||
\subsubsection Point_set_processing_3Upsample_Parameter1 Parameter: edge_sensitivity
|
\subsubsection Point_set_processing_3Upsample_Parameter1 Parameter: edge_sensitivity
|
||||||
This parameter controls where the new points are inserted. Larger values of edge-sensitivity give higher priority to inserting points along the sharp features.
|
This parameter controls where the new points are inserted. Larger values of edge-sensitivity give higher priority to inserting points along the sharp features.
|
||||||
For example, as shown in the following figure, high value is preferable when one wants to insert more points on sharp features, where the local gradient is high, e.g., darts, cusps, creases and corners. In contrast, points are evenly inserted when edge_sensitivity is set to 0. The range of possible value is [0, 1].
|
For example, as shown in the following figure, high value is preferable when one wants to insert more points on sharp features, where the local gradient is high, e.g., darts, cusps, creases and corners. In contrast, points are evenly inserted when edge_sensitivity is set to 0. The range of possible value is [0, 1].
|
||||||
|
|
||||||
|
|
||||||
\cgalFigureBegin{Point_set_processing_3figUpsample_edge_sensitivity, upsample_edge_sensitivity.jpg}
|
\cgalFigureBegin{Point_set_processing_3figUpsample_edge_sensitivity, upsample_edge_sensitivity.jpg}
|
||||||
|
|
@ -884,14 +884,14 @@ Upsampling for different edge-sensitivity parameter values. The input containing
|
||||||
This parameter controls the preservation of sharp features.
|
This parameter controls the preservation of sharp features.
|
||||||
|
|
||||||
\cgalFigureBegin{Point_set_processing_3figUpsample_sharpness_angle, upsample_sharpness_angle.jpg}
|
\cgalFigureBegin{Point_set_processing_3figUpsample_sharpness_angle, upsample_sharpness_angle.jpg}
|
||||||
Upsampling for different sharpness_angle parameter values. The input containing 850 points is upsampled to 425K points in all cases depicted.
|
Upsampling for different sharpness_angle parameter values. The input containing 850 points is upsampled to 425K points in all cases depicted.
|
||||||
\cgalFigureEnd
|
\cgalFigureEnd
|
||||||
|
|
||||||
\subsubsection Point_set_processing_3upsample_neighborhood_size Parameter: neighbor_radius
|
\subsubsection Point_set_processing_3upsample_neighborhood_size Parameter: neighbor_radius
|
||||||
Usually, the neighborhood of sample points should include at least one ring of neighboring sample points. Using small neighborhood size may not be able to insert new points. Using big neighborhood size can fill small holes, but points inserted on the edges could be irregular. The function will use a neighborhood size estimation if this parameter value is set to default or smaller than zero.
|
Usually, the neighborhood of sample points should include at least one ring of neighboring sample points. Using small neighborhood size may not be able to insert new points. Using big neighborhood size can fill small holes, but points inserted on the edges could be irregular. The function will use a neighborhood size estimation if this parameter value is set to default or smaller than zero.
|
||||||
|
|
||||||
\cgalFigureBegin{Point_set_processing_3figupsample_neighborhood_size, upsample_neighborhood_size.jpg}
|
\cgalFigureBegin{Point_set_processing_3figupsample_neighborhood_size, upsample_neighborhood_size.jpg}
|
||||||
Comparison between different sizes of neighbor radius.
|
Comparison between different sizes of neighbor radius.
|
||||||
\cgalFigureEnd
|
\cgalFigureEnd
|
||||||
|
|
||||||
\section Point_set_processing_3FeaturesEstimation Feature Edges Estimation
|
\section Point_set_processing_3FeaturesEstimation Feature Edges Estimation
|
||||||
|
|
@ -915,7 +915,7 @@ points that are on sharp edges:
|
||||||
|
|
||||||
The function `structure_point_set()` generates a structured version of
|
The function `structure_point_set()` generates a structured version of
|
||||||
the input point set assigned to a set of planes. Such an input can be
|
the input point set assigned to a set of planes. Such an input can be
|
||||||
produced by a shape detection algorithm (see \ref PkgShapeDetectionRef).
|
produced by a shape detection algorithm (see \ref PkgShapeDetectionRef).
|
||||||
Point set structuring is based on the article \cgalCite{cgal:la-srpss-13}.
|
Point set structuring is based on the article \cgalCite{cgal:la-srpss-13}.
|
||||||
|
|
||||||
- __Planes__: inliers of each detected plane are replaced by sets of
|
- __Planes__: inliers of each detected plane are replaced by sets of
|
||||||
|
|
@ -995,5 +995,5 @@ Started from GSoC'2019, Necip Fazil Yildiran with the help of Nicolas Mellado an
|
||||||
libraries that perform registration on two point sets.
|
libraries that perform registration on two point sets.
|
||||||
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
} /* namespace CGAL */
|
} /* namespace CGAL */
|
||||||
|
|
|
||||||
|
|
@ -414,7 +414,7 @@ compute_face_face_intersection(const FaceRange& face_range1,
|
||||||
|
|
||||||
CGAL::Bbox_3 b1 = CGAL::Polygon_mesh_processing::bbox(tm1, np1),
|
CGAL::Bbox_3 b1 = CGAL::Polygon_mesh_processing::bbox(tm1, np1),
|
||||||
b2 = CGAL::Polygon_mesh_processing::bbox(tm2, np2);
|
b2 = CGAL::Polygon_mesh_processing::bbox(tm2, np2);
|
||||||
|
|
||||||
if(!CGAL::do_overlap(b1, b2))
|
if(!CGAL::do_overlap(b1, b2))
|
||||||
{
|
{
|
||||||
return out;
|
return out;
|
||||||
|
|
@ -643,7 +643,7 @@ compute_face_polylines_intersection(const FaceRange& face_range,
|
||||||
using parameters::get_parameter;
|
using parameters::get_parameter;
|
||||||
|
|
||||||
CGAL_precondition(CGAL::is_triangle_mesh(tm));
|
CGAL_precondition(CGAL::is_triangle_mesh(tm));
|
||||||
|
|
||||||
CGAL::Bbox_3 b1,b2;
|
CGAL::Bbox_3 b1,b2;
|
||||||
b1 = CGAL::Polygon_mesh_processing::bbox(tm, np);
|
b1 = CGAL::Polygon_mesh_processing::bbox(tm, np);
|
||||||
for(std::size_t i =0; i< polyline_range.size(); ++i)
|
for(std::size_t i =0; i< polyline_range.size(); ++i)
|
||||||
|
|
@ -651,10 +651,10 @@ compute_face_polylines_intersection(const FaceRange& face_range,
|
||||||
b2 += CGAL::bbox_3(polyline_range[i].begin(),
|
b2 += CGAL::bbox_3(polyline_range[i].begin(),
|
||||||
polyline_range[i].end());
|
polyline_range[i].end());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!CGAL::do_overlap(b1,b2))
|
if(!CGAL::do_overlap(b1,b2))
|
||||||
return out;
|
return out;
|
||||||
|
|
||||||
typedef TriangleMesh TM;
|
typedef TriangleMesh TM;
|
||||||
typedef typename boost::graph_traits<TM>::face_descriptor face_descriptor;
|
typedef typename boost::graph_traits<TM>::face_descriptor face_descriptor;
|
||||||
typedef typename GetVertexPointMap<TM, NamedParameters>::const_type VertexPointMap;
|
typedef typename GetVertexPointMap<TM, NamedParameters>::const_type VertexPointMap;
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,10 @@
|
||||||
|
|
||||||
#ifdef CGAL_USE_SCIP // defined (or not) by CMake scripts, do not define by hand
|
#ifdef CGAL_USE_SCIP // defined (or not) by CMake scripts, do not define by hand
|
||||||
#include <CGAL/SCIP_mixed_integer_program_traits.h>
|
#include <CGAL/SCIP_mixed_integer_program_traits.h>
|
||||||
typedef CGAL::SCIP_mixed_integer_program_traits<double> MIP_Solver;
|
typedef CGAL::SCIP_mixed_integer_program_traits<double> MIP_Solver;
|
||||||
#elif defined(CGAL_USE_GLPK) // defined (or not) by CMake scripts, do not define by hand
|
#elif defined(CGAL_USE_GLPK) // defined (or not) by CMake scripts, do not define by hand
|
||||||
#include <CGAL/GLPK_mixed_integer_program_traits.h>
|
#include <CGAL/GLPK_mixed_integer_program_traits.h>
|
||||||
typedef CGAL::GLPK_mixed_integer_program_traits<double> MIP_Solver;
|
typedef CGAL::GLPK_mixed_integer_program_traits<double> MIP_Solver;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -20,17 +20,17 @@ typedef CGAL::GLPK_mixed_integer_program_traits<double> MIP_Solver;
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
|
|
||||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
|
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
|
||||||
typedef Kernel::Point_3 Point;
|
typedef Kernel::Point_3 Point;
|
||||||
typedef Kernel::Vector_3 Vector;
|
typedef Kernel::Vector_3 Vector;
|
||||||
typedef CGAL::Polygonal_surface_reconstruction<Kernel> Polygonal_surface_reconstruction;
|
typedef CGAL::Polygonal_surface_reconstruction<Kernel> Polygonal_surface_reconstruction;
|
||||||
typedef CGAL::Surface_mesh<Point> Surface_mesh;
|
typedef CGAL::Surface_mesh<Point> Surface_mesh;
|
||||||
|
|
||||||
// Point with normal, and plane index
|
// Point with normal, and plane index
|
||||||
typedef boost::tuple<Point, Vector, int> PNI;
|
typedef boost::tuple<Point, Vector, int> PNI;
|
||||||
typedef CGAL::Nth_of_tuple_property_map<0, PNI> Point_map;
|
typedef CGAL::Nth_of_tuple_property_map<0, PNI> Point_map;
|
||||||
typedef CGAL::Nth_of_tuple_property_map<1, PNI> Normal_map;
|
typedef CGAL::Nth_of_tuple_property_map<1, PNI> Normal_map;
|
||||||
typedef CGAL::Nth_of_tuple_property_map<2, PNI> Plane_index_map;
|
typedef CGAL::Nth_of_tuple_property_map<2, PNI> Plane_index_map;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The following example shows how to control the model complexity by
|
* The following example shows how to control the model complexity by
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,10 @@
|
||||||
|
|
||||||
#ifdef CGAL_USE_SCIP // defined (or not) by CMake scripts, do not define by hand
|
#ifdef CGAL_USE_SCIP // defined (or not) by CMake scripts, do not define by hand
|
||||||
#include <CGAL/SCIP_mixed_integer_program_traits.h>
|
#include <CGAL/SCIP_mixed_integer_program_traits.h>
|
||||||
typedef CGAL::SCIP_mixed_integer_program_traits<double> MIP_Solver;
|
typedef CGAL::SCIP_mixed_integer_program_traits<double> MIP_Solver;
|
||||||
#elif defined(CGAL_USE_GLPK) // defined (or not) by CMake scripts, do not define by hand
|
#elif defined(CGAL_USE_GLPK) // defined (or not) by CMake scripts, do not define by hand
|
||||||
#include <CGAL/GLPK_mixed_integer_program_traits.h>
|
#include <CGAL/GLPK_mixed_integer_program_traits.h>
|
||||||
typedef CGAL::GLPK_mixed_integer_program_traits<double> MIP_Solver;
|
typedef CGAL::GLPK_mixed_integer_program_traits<double> MIP_Solver;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -20,17 +20,17 @@ typedef CGAL::GLPK_mixed_integer_program_traits<double> MIP_Solver;
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
|
|
||||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
|
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
|
||||||
typedef Kernel::Point_3 Point;
|
typedef Kernel::Point_3 Point;
|
||||||
typedef Kernel::Vector_3 Vector;
|
typedef Kernel::Vector_3 Vector;
|
||||||
typedef CGAL::Polygonal_surface_reconstruction<Kernel> Polygonal_surface_reconstruction;
|
typedef CGAL::Polygonal_surface_reconstruction<Kernel> Polygonal_surface_reconstruction;
|
||||||
typedef CGAL::Surface_mesh<Point> Surface_mesh;
|
typedef CGAL::Surface_mesh<Point> Surface_mesh;
|
||||||
|
|
||||||
// Point with normal, and plane index
|
// Point with normal, and plane index
|
||||||
typedef boost::tuple<Point, Vector, int> PNI;
|
typedef boost::tuple<Point, Vector, int> PNI;
|
||||||
typedef CGAL::Nth_of_tuple_property_map<0, PNI> Point_map;
|
typedef CGAL::Nth_of_tuple_property_map<0, PNI> Point_map;
|
||||||
typedef CGAL::Nth_of_tuple_property_map<1, PNI> Normal_map;
|
typedef CGAL::Nth_of_tuple_property_map<1, PNI> Normal_map;
|
||||||
typedef CGAL::Nth_of_tuple_property_map<2, PNI> Plane_index_map;
|
typedef CGAL::Nth_of_tuple_property_map<2, PNI> Plane_index_map;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The following example shows the reconstruction using user-provided
|
* The following example shows the reconstruction using user-provided
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ typedef CGAL::SCIP_mixed_integer_program_traits<double> MIP_Solver;
|
||||||
#elif defined(CGAL_USE_GLPK) // defined (or not) by CMake scripts, do not define by hand
|
#elif defined(CGAL_USE_GLPK) // defined (or not) by CMake scripts, do not define by hand
|
||||||
|
|
||||||
#include <CGAL/GLPK_mixed_integer_program_traits.h>
|
#include <CGAL/GLPK_mixed_integer_program_traits.h>
|
||||||
typedef CGAL::GLPK_mixed_integer_program_traits<double> MIP_Solver;
|
typedef CGAL::GLPK_mixed_integer_program_traits<double> MIP_Solver;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -23,19 +23,19 @@ typedef CGAL::GLPK_mixed_integer_program_traits<double> MIP_Solver;
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <CGAL/Timer.h>
|
#include <CGAL/Timer.h>
|
||||||
|
|
||||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
|
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
|
||||||
|
|
||||||
typedef Kernel::FT FT;
|
typedef Kernel::FT FT;
|
||||||
typedef Kernel::Point_3 Point;
|
typedef Kernel::Point_3 Point;
|
||||||
typedef Kernel::Vector_3 Vector;
|
typedef Kernel::Vector_3 Vector;
|
||||||
|
|
||||||
// Point with normal, and plane index.
|
// Point with normal, and plane index.
|
||||||
typedef boost::tuple<Point, Vector, int> PNI;
|
typedef boost::tuple<Point, Vector, int> PNI;
|
||||||
typedef std::vector<PNI> Point_vector;
|
typedef std::vector<PNI> Point_vector;
|
||||||
|
|
||||||
typedef CGAL::Nth_of_tuple_property_map<0, PNI> Point_map;
|
typedef CGAL::Nth_of_tuple_property_map<0, PNI> Point_map;
|
||||||
typedef CGAL::Nth_of_tuple_property_map<1, PNI> Normal_map;
|
typedef CGAL::Nth_of_tuple_property_map<1, PNI> Normal_map;
|
||||||
typedef CGAL::Nth_of_tuple_property_map<2, PNI> Plane_index_map;
|
typedef CGAL::Nth_of_tuple_property_map<2, PNI> Plane_index_map;
|
||||||
|
|
||||||
typedef CGAL::Shape_detection::Point_set::
|
typedef CGAL::Shape_detection::Point_set::
|
||||||
Sphere_neighbor_query<Kernel, Point_vector, Point_map> Neighbor_query;
|
Sphere_neighbor_query<Kernel, Point_vector, Point_map> Neighbor_query;
|
||||||
|
|
@ -44,8 +44,8 @@ Least_squares_plane_fit_region<Kernel, Point_vector, Point_map, Normal_map> Regi
|
||||||
typedef CGAL::Shape_detection::
|
typedef CGAL::Shape_detection::
|
||||||
Region_growing<Point_vector, Neighbor_query, Region_type> Region_growing;
|
Region_growing<Point_vector, Neighbor_query, Region_type> Region_growing;
|
||||||
|
|
||||||
typedef CGAL::Surface_mesh<Point> Surface_mesh;
|
typedef CGAL::Surface_mesh<Point> Surface_mesh;
|
||||||
typedef CGAL::Polygonal_surface_reconstruction<Kernel> Polygonal_surface_reconstruction;
|
typedef CGAL::Polygonal_surface_reconstruction<Kernel> Polygonal_surface_reconstruction;
|
||||||
|
|
||||||
class Index_map {
|
class Index_map {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,12 +8,12 @@
|
||||||
#ifdef CGAL_USE_SCIP // defined (or not) by CMake scripts, do not define by hand
|
#ifdef CGAL_USE_SCIP // defined (or not) by CMake scripts, do not define by hand
|
||||||
|
|
||||||
#include <CGAL/SCIP_mixed_integer_program_traits.h>
|
#include <CGAL/SCIP_mixed_integer_program_traits.h>
|
||||||
typedef CGAL::SCIP_mixed_integer_program_traits<double> MIP_Solver;
|
typedef CGAL::SCIP_mixed_integer_program_traits<double> MIP_Solver;
|
||||||
|
|
||||||
#elif defined(CGAL_USE_GLPK) // defined (or not) by CMake scripts, do not define by hand
|
#elif defined(CGAL_USE_GLPK) // defined (or not) by CMake scripts, do not define by hand
|
||||||
|
|
||||||
#include <CGAL/GLPK_mixed_integer_program_traits.h>
|
#include <CGAL/GLPK_mixed_integer_program_traits.h>
|
||||||
typedef CGAL::GLPK_mixed_integer_program_traits<double> MIP_Solver;
|
typedef CGAL::GLPK_mixed_integer_program_traits<double> MIP_Solver;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -25,26 +25,26 @@ typedef CGAL::GLPK_mixed_integer_program_traits<double> MIP_Solver;
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
|
|
||||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
|
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
|
||||||
|
|
||||||
typedef Kernel::Point_3 Point;
|
typedef Kernel::Point_3 Point;
|
||||||
typedef Kernel::Vector_3 Vector;
|
typedef Kernel::Vector_3 Vector;
|
||||||
|
|
||||||
// Point with normal, and plane index
|
// Point with normal, and plane index
|
||||||
typedef boost::tuple<Point, Vector, int> PNI;
|
typedef boost::tuple<Point, Vector, int> PNI;
|
||||||
typedef std::vector<PNI> Point_vector;
|
typedef std::vector<PNI> Point_vector;
|
||||||
typedef CGAL::Nth_of_tuple_property_map<0, PNI> Point_map;
|
typedef CGAL::Nth_of_tuple_property_map<0, PNI> Point_map;
|
||||||
typedef CGAL::Nth_of_tuple_property_map<1, PNI> Normal_map;
|
typedef CGAL::Nth_of_tuple_property_map<1, PNI> Normal_map;
|
||||||
typedef CGAL::Nth_of_tuple_property_map<2, PNI> Plane_index_map;
|
typedef CGAL::Nth_of_tuple_property_map<2, PNI> Plane_index_map;
|
||||||
|
|
||||||
typedef CGAL::Shape_detection::Efficient_RANSAC_traits<Kernel, Point_vector, Point_map, Normal_map> Traits;
|
typedef CGAL::Shape_detection::Efficient_RANSAC_traits<Kernel, Point_vector, Point_map, Normal_map> Traits;
|
||||||
|
|
||||||
typedef CGAL::Shape_detection::Efficient_RANSAC<Traits> Efficient_ransac;
|
typedef CGAL::Shape_detection::Efficient_RANSAC<Traits> Efficient_ransac;
|
||||||
typedef CGAL::Shape_detection::Plane<Traits> Plane;
|
typedef CGAL::Shape_detection::Plane<Traits> Plane;
|
||||||
typedef CGAL::Shape_detection::Point_to_shape_index_map<Traits> Point_to_shape_index_map;
|
typedef CGAL::Shape_detection::Point_to_shape_index_map<Traits> Point_to_shape_index_map;
|
||||||
|
|
||||||
typedef CGAL::Polygonal_surface_reconstruction<Kernel> Polygonal_surface_reconstruction;
|
typedef CGAL::Polygonal_surface_reconstruction<Kernel> Polygonal_surface_reconstruction;
|
||||||
typedef CGAL::Surface_mesh<Point> Surface_mesh;
|
typedef CGAL::Surface_mesh<Point> Surface_mesh;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This example first extracts planes from the input point cloud
|
* This example first extracts planes from the input point cloud
|
||||||
|
|
|
||||||
|
|
@ -30,9 +30,9 @@ class Polyhedron_demo_ply_plugin :
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool isDefaultLoader(const CGAL::Three::Scene_item *item) const override
|
bool isDefaultLoader(const CGAL::Three::Scene_item *item) const override
|
||||||
{
|
{
|
||||||
if(qobject_cast<const Scene_points_with_normal_item*>(item))
|
if(qobject_cast<const Scene_points_with_normal_item*>(item))
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
QString name() const override{ return "ply_plugin"; }
|
QString name() const override{ return "ply_plugin"; }
|
||||||
|
|
@ -66,7 +66,7 @@ load(QFileInfo fileinfo, bool& ok, bool add_to_scene) {
|
||||||
ok = false;
|
ok = false;
|
||||||
return QList<Scene_item*>();
|
return QList<Scene_item*>();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test if input is mesh or point set
|
// Test if input is mesh or point set
|
||||||
bool input_is_mesh = false;
|
bool input_is_mesh = false;
|
||||||
std::string line;
|
std::string line;
|
||||||
|
|
@ -101,7 +101,7 @@ load(QFileInfo fileinfo, bool& ok, bool add_to_scene) {
|
||||||
// First try mesh
|
// First try mesh
|
||||||
SMesh *surface_mesh = new SMesh();
|
SMesh *surface_mesh = new SMesh();
|
||||||
std::string comments;
|
std::string comments;
|
||||||
|
|
||||||
if (CGAL::read_PLY(in, *surface_mesh, comments))
|
if (CGAL::read_PLY(in, *surface_mesh, comments))
|
||||||
{
|
{
|
||||||
Scene_surface_mesh_item* sm_item = new Scene_surface_mesh_item(surface_mesh);
|
Scene_surface_mesh_item* sm_item = new Scene_surface_mesh_item(surface_mesh);
|
||||||
|
|
@ -191,13 +191,13 @@ save(QFileInfo fileinfo,QList<CGAL::Three::Scene_item*>& items)
|
||||||
|
|
||||||
if (!ok)
|
if (!ok)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
std::ofstream out(fileinfo.filePath().toUtf8().data(), std::ios::binary);
|
std::ofstream out(fileinfo.filePath().toUtf8().data(), std::ios::binary);
|
||||||
if (choice == tr("Binary"))
|
if (choice == tr("Binary"))
|
||||||
CGAL::set_binary_mode(out);
|
CGAL::set_binary_mode(out);
|
||||||
else
|
else
|
||||||
out.precision (std::numeric_limits<double>::digits10 + 2);
|
out.precision (std::numeric_limits<double>::digits10 + 2);
|
||||||
|
|
||||||
// This plugin supports point sets
|
// This plugin supports point sets
|
||||||
const Scene_points_with_normal_item* point_set_item =
|
const Scene_points_with_normal_item* point_set_item =
|
||||||
qobject_cast<const Scene_points_with_normal_item*>(item);
|
qobject_cast<const Scene_points_with_normal_item*>(item);
|
||||||
|
|
@ -233,7 +233,7 @@ save(QFileInfo fileinfo,QList<CGAL::Three::Scene_item*>& items)
|
||||||
items.pop_front();
|
items.pop_front();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This plugin supports textured surface meshes
|
// This plugin supports textured surface meshes
|
||||||
const Scene_textured_surface_mesh_item* stm_item =
|
const Scene_textured_surface_mesh_item* stm_item =
|
||||||
qobject_cast<const Scene_textured_surface_mesh_item*>(item);
|
qobject_cast<const Scene_textured_surface_mesh_item*>(item);
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@
|
||||||
#include <CGAL/Polygon_mesh_processing/internal/named_params_helper.h>
|
#include <CGAL/Polygon_mesh_processing/internal/named_params_helper.h>
|
||||||
typedef Scene_surface_mesh_item Scene_facegraph_item;
|
typedef Scene_surface_mesh_item Scene_facegraph_item;
|
||||||
typedef Scene_facegraph_item::Face_graph FaceGraph;
|
typedef Scene_facegraph_item::Face_graph FaceGraph;
|
||||||
typedef boost::property_traits<boost::property_map<FaceGraph,
|
typedef boost::property_traits<boost::property_map<FaceGraph,
|
||||||
CGAL::vertex_point_t>::type>::value_type Point;
|
CGAL::vertex_point_t>::type>::value_type Point;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -206,8 +206,8 @@ public:
|
||||||
return (qobject_cast<const Scene_facegraph_item*>(item)
|
return (qobject_cast<const Scene_facegraph_item*>(item)
|
||||||
|| qobject_cast<const Scene_c3t3_item*>(item));
|
|| qobject_cast<const Scene_c3t3_item*>(item));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool save(QFileInfo fileinfo,QList<CGAL::Three::Scene_item*>& items)
|
bool save(QFileInfo fileinfo,QList<CGAL::Three::Scene_item*>& items)
|
||||||
{
|
{
|
||||||
Scene_item* item = items.front();
|
Scene_item* item = items.front();
|
||||||
|
|
@ -219,7 +219,7 @@ public:
|
||||||
|
|
||||||
const Scene_facegraph_item* poly_item =
|
const Scene_facegraph_item* poly_item =
|
||||||
qobject_cast<const Scene_facegraph_item*>(item);
|
qobject_cast<const Scene_facegraph_item*>(item);
|
||||||
|
|
||||||
if (poly_item)
|
if (poly_item)
|
||||||
{
|
{
|
||||||
if (extension != "vtp")
|
if (extension != "vtp")
|
||||||
|
|
@ -250,11 +250,11 @@ public:
|
||||||
qobject_cast<const Scene_c3t3_item*>(item);
|
qobject_cast<const Scene_c3t3_item*>(item);
|
||||||
if(!c3t3_item || extension != "vtu")
|
if(!c3t3_item || extension != "vtu")
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
std::ofstream os(output_filename.data());
|
std::ofstream os(output_filename.data());
|
||||||
os << std::setprecision(16);
|
os << std::setprecision(16);
|
||||||
const C3t3& c3t3 = c3t3_item->c3t3();
|
const C3t3& c3t3 = c3t3_item->c3t3();
|
||||||
|
|
||||||
CGAL::output_to_vtu(os, c3t3);
|
CGAL::output_to_vtu(os, c3t3);
|
||||||
}
|
}
|
||||||
items.pop_front();
|
items.pop_front();
|
||||||
|
|
@ -286,7 +286,7 @@ public:
|
||||||
CGAL::Three::Three::scene()->addItem(item);
|
CGAL::Three::Three::scene()->addItem(item);
|
||||||
return QList<Scene_item*>()<<item;
|
return QList<Scene_item*>()<<item;
|
||||||
}
|
}
|
||||||
|
|
||||||
vtkSmartPointer<vtkPointSet> data;
|
vtkSmartPointer<vtkPointSet> data;
|
||||||
vtkSmartPointer<CGAL::IO::internal::ErrorObserverVtk> obs =
|
vtkSmartPointer<CGAL::IO::internal::ErrorObserverVtk> obs =
|
||||||
vtkSmartPointer<CGAL::IO::internal::ErrorObserverVtk>::New();
|
vtkSmartPointer<CGAL::IO::internal::ErrorObserverVtk>::New();
|
||||||
|
|
@ -351,7 +351,7 @@ public:
|
||||||
{
|
{
|
||||||
group = new Scene_group_item(fileinfo.baseName());
|
group = new Scene_group_item(fileinfo.baseName());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(is_polygon_mesh)
|
if(is_polygon_mesh)
|
||||||
{
|
{
|
||||||
FaceGraph* poly = new FaceGraph();
|
FaceGraph* poly = new FaceGraph();
|
||||||
|
|
@ -373,7 +373,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_c3t3)
|
if (is_c3t3)
|
||||||
{
|
{
|
||||||
typedef boost::array<int, 3> Facet; // 3 = id
|
typedef boost::array<int, 3> Facet; // 3 = id
|
||||||
|
|
@ -421,7 +421,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CGAL::build_triangulation<Tr, true>(c3t3_item->c3t3().triangulation(), points, finite_cells, border_facets);
|
CGAL::build_triangulation<Tr, true>(c3t3_item->c3t3().triangulation(), points, finite_cells, border_facets);
|
||||||
|
|
||||||
for( C3t3::Triangulation::Finite_cells_iterator
|
for( C3t3::Triangulation::Finite_cells_iterator
|
||||||
cit = c3t3_item->c3t3().triangulation().finite_cells_begin();
|
cit = c3t3_item->c3t3().triangulation().finite_cells_begin();
|
||||||
cit != c3t3_item->c3t3().triangulation().finite_cells_end();
|
cit != c3t3_item->c3t3().triangulation().finite_cells_end();
|
||||||
|
|
@ -437,7 +437,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//if there is no facet in the complex, we add the border facets.
|
//if there is no facet in the complex, we add the border facets.
|
||||||
if(c3t3_item->c3t3().number_of_facets_in_complex() == 0)
|
if(c3t3_item->c3t3().number_of_facets_in_complex() == 0)
|
||||||
{
|
{
|
||||||
|
|
@ -447,10 +447,10 @@ public:
|
||||||
++fit)
|
++fit)
|
||||||
{
|
{
|
||||||
typedef C3t3::Triangulation::Cell_handle Cell_handle;
|
typedef C3t3::Triangulation::Cell_handle Cell_handle;
|
||||||
|
|
||||||
Cell_handle c = fit->first;
|
Cell_handle c = fit->first;
|
||||||
Cell_handle nc = c->neighbor(fit->second);
|
Cell_handle nc = c->neighbor(fit->second);
|
||||||
|
|
||||||
// By definition, Subdomain_index() is supposed to be the id of the exterior
|
// By definition, Subdomain_index() is supposed to be the id of the exterior
|
||||||
if(c->subdomain_index() != C3t3::Triangulation::Cell::Subdomain_index() &&
|
if(c->subdomain_index() != C3t3::Triangulation::Cell::Subdomain_index() &&
|
||||||
nc->subdomain_index() == C3t3::Triangulation::Cell::Subdomain_index())
|
nc->subdomain_index() == C3t3::Triangulation::Cell::Subdomain_index())
|
||||||
|
|
@ -476,7 +476,7 @@ public:
|
||||||
return QList<Scene_item*>()<<c3t3_item;
|
return QList<Scene_item*>()<<c3t3_item;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(is_polyline)
|
if(is_polyline)
|
||||||
{
|
{
|
||||||
std::vector< std::vector<Point> > segments;
|
std::vector< std::vector<Point> > segments;
|
||||||
|
|
@ -498,14 +498,14 @@ public:
|
||||||
return QList<Scene_item*>()<<polyline_item;
|
return QList<Scene_item*>()<<polyline_item;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(group){
|
if(group){
|
||||||
ok = true;
|
ok = true;
|
||||||
if(add_to_scene)
|
if(add_to_scene)
|
||||||
CGAL::Three::Three::scene()->addItem(group);
|
CGAL::Three::Three::scene()->addItem(group);
|
||||||
return QList<Scene_item*>()<<group;
|
return QList<Scene_item*>()<<group;
|
||||||
}
|
}
|
||||||
|
|
||||||
QApplication::restoreOverrideCursor();
|
QApplication::restoreOverrideCursor();
|
||||||
QMessageBox::warning(CGAL::Three::Three::mainWindow(),
|
QMessageBox::warning(CGAL::Three::Three::mainWindow(),
|
||||||
"Problematic file",
|
"Problematic file",
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,7 @@ struct Scene_polygon_soup_item_priv{
|
||||||
Edges = 0,
|
Edges = 0,
|
||||||
NM_edges
|
NM_edges
|
||||||
};
|
};
|
||||||
|
|
||||||
Polygon_soup* soup;
|
Polygon_soup* soup;
|
||||||
bool oriented;
|
bool oriented;
|
||||||
mutable std::vector<float> positions_poly;
|
mutable std::vector<float> positions_poly;
|
||||||
|
|
@ -104,7 +104,7 @@ struct Scene_polygon_soup_item_priv{
|
||||||
bool is_triangle, is_quad, stats_computed;
|
bool is_triangle, is_quad, stats_computed;
|
||||||
double minl, maxl, meanl, midl, mini, maxi, ave;
|
double minl, maxl, meanl, midl, mini, maxi, ave;
|
||||||
std::size_t nb_null_edges, nb_degen_faces;
|
std::size_t nb_null_edges, nb_degen_faces;
|
||||||
|
|
||||||
Scene_polygon_soup_item* item;
|
Scene_polygon_soup_item* item;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
@ -120,7 +120,7 @@ Scene_polygon_soup_item_priv::triangulate_polygon(Polygons_iterator pit, int pol
|
||||||
{
|
{
|
||||||
const CGAL::qglviewer::Vec off = static_cast<CGAL::Three::Viewer_interface*>(CGAL::QGLViewer::QGLViewerPool().first())->offset();
|
const CGAL::qglviewer::Vec off = static_cast<CGAL::Three::Viewer_interface*>(CGAL::QGLViewer::QGLViewerPool().first())->offset();
|
||||||
EPICK::Vector_3 offset(off.x,off.y,off.z);
|
EPICK::Vector_3 offset(off.x,off.y,off.z);
|
||||||
|
|
||||||
//Computes the normal of the facet
|
//Computes the normal of the facet
|
||||||
Traits::Vector_3 normal = CGAL::NULL_VECTOR;
|
Traits::Vector_3 normal = CGAL::NULL_VECTOR;
|
||||||
|
|
||||||
|
|
@ -135,7 +135,7 @@ Scene_polygon_soup_item_priv::triangulate_polygon(Polygons_iterator pit, int pol
|
||||||
}
|
}
|
||||||
if (normal == CGAL::NULL_VECTOR) // No normal could be computed, return
|
if (normal == CGAL::NULL_VECTOR) // No normal could be computed, return
|
||||||
return;
|
return;
|
||||||
|
|
||||||
typedef FacetTriangulator<SMesh, EPICK, std::size_t> FT;
|
typedef FacetTriangulator<SMesh, EPICK, std::size_t> FT;
|
||||||
|
|
||||||
std::size_t it = 0;
|
std::size_t it = 0;
|
||||||
|
|
@ -310,7 +310,7 @@ Scene_polygon_soup_item_priv::compute_normals_and_vertices() const{
|
||||||
positions_nm_lines.push_back(b.y()+offset.y);
|
positions_nm_lines.push_back(b.y()+offset.y);
|
||||||
positions_nm_lines.push_back(b.z()+offset.z);
|
positions_nm_lines.push_back(b.z()+offset.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -333,7 +333,7 @@ Scene_polygon_soup_item::~Scene_polygon_soup_item()
|
||||||
delete d;
|
delete d;
|
||||||
}
|
}
|
||||||
|
|
||||||
Scene_polygon_soup_item*
|
Scene_polygon_soup_item*
|
||||||
Scene_polygon_soup_item::clone() const {
|
Scene_polygon_soup_item::clone() const {
|
||||||
Scene_polygon_soup_item* new_soup = new Scene_polygon_soup_item();
|
Scene_polygon_soup_item* new_soup = new Scene_polygon_soup_item();
|
||||||
new_soup->d->soup = d->soup->clone();
|
new_soup->d->soup = d->soup->clone();
|
||||||
|
|
@ -419,7 +419,7 @@ void Scene_polygon_soup_item::inside_out()
|
||||||
invalidateOpenGLBuffers();
|
invalidateOpenGLBuffers();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Scene_polygon_soup_item::orient()
|
Scene_polygon_soup_item::orient()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
@ -457,7 +457,7 @@ Scene_polygon_soup_item::orient()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Scene_polygon_soup_item::save(std::ostream& out) const
|
Scene_polygon_soup_item::save(std::ostream& out) const
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
@ -506,7 +506,7 @@ Scene_polygon_soup_item::exportAsSurfaceMesh(SMesh *out_surface_mesh)
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
QString
|
QString
|
||||||
Scene_polygon_soup_item::toolTip() const
|
Scene_polygon_soup_item::toolTip() const
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
@ -542,10 +542,10 @@ Scene_polygon_soup_item::draw(CGAL::Three::Viewer_interface* viewer) const {
|
||||||
computeElements();
|
computeElements();
|
||||||
initializeBuffers(viewer);
|
initializeBuffers(viewer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(renderingMode() == Flat || renderingMode() == FlatPlusEdges)
|
if(renderingMode() == Flat || renderingMode() == FlatPlusEdges)
|
||||||
{
|
{
|
||||||
|
|
||||||
if(d->soup->fcolors.empty())
|
if(d->soup->fcolors.empty())
|
||||||
getTriangleContainer(Priv::Flat_facets)->setColor(this->color());
|
getTriangleContainer(Priv::Flat_facets)->setColor(this->color());
|
||||||
getTriangleContainer(Priv::Flat_facets)->draw(viewer, d->soup->fcolors.empty());
|
getTriangleContainer(Priv::Flat_facets)->draw(viewer, d->soup->fcolors.empty());
|
||||||
|
|
@ -560,7 +560,7 @@ Scene_polygon_soup_item::draw(CGAL::Three::Viewer_interface* viewer) const {
|
||||||
|
|
||||||
void
|
void
|
||||||
Scene_polygon_soup_item::drawPoints(CGAL::Three::Viewer_interface* viewer) const {
|
Scene_polygon_soup_item::drawPoints(CGAL::Three::Viewer_interface* viewer) const {
|
||||||
|
|
||||||
if(d->soup == 0) return;
|
if(d->soup == 0) return;
|
||||||
if(!isInit(viewer))
|
if(!isInit(viewer))
|
||||||
initGL(viewer);
|
initGL(viewer);
|
||||||
|
|
@ -639,7 +639,7 @@ void Scene_polygon_soup_item::compute_bbox() const {
|
||||||
bbox.xmax(),bbox.ymax(),bbox.zmax()));
|
bbox.xmax(),bbox.ymax(),bbox.zmax()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Scene_polygon_soup_item::new_vertex(const double& x,
|
Scene_polygon_soup_item::new_vertex(const double& x,
|
||||||
const double& y,
|
const double& y,
|
||||||
const double& z)
|
const double& z)
|
||||||
|
|
@ -647,8 +647,8 @@ Scene_polygon_soup_item::new_vertex(const double& x,
|
||||||
|
|
||||||
d->soup->points.push_back(Point_3(x, y, z));
|
d->soup->points.push_back(Point_3(x, y, z));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Scene_polygon_soup_item::new_triangle(const std::size_t i,
|
Scene_polygon_soup_item::new_triangle(const std::size_t i,
|
||||||
const std::size_t j,
|
const std::size_t j,
|
||||||
const std::size_t k)
|
const std::size_t k)
|
||||||
|
|
@ -694,7 +694,7 @@ void Scene_polygon_soup_item::load(const std::vector<Point>& points, const std::
|
||||||
|
|
||||||
d->soup->fcolors.reserve (fcolors.size());
|
d->soup->fcolors.reserve (fcolors.size());
|
||||||
std::copy (fcolors.begin(), fcolors.end(), std::back_inserter (d->soup->fcolors));
|
std::copy (fcolors.begin(), fcolors.end(), std::back_inserter (d->soup->fcolors));
|
||||||
|
|
||||||
d->soup->vcolors.reserve (vcolors.size());
|
d->soup->vcolors.reserve (vcolors.size());
|
||||||
std::copy (vcolors.begin(), vcolors.end(), std::back_inserter (d->soup->vcolors));
|
std::copy (vcolors.begin(), vcolors.end(), std::back_inserter (d->soup->vcolors));
|
||||||
}
|
}
|
||||||
|
|
@ -732,7 +732,7 @@ void Scene_polygon_soup_item::itemAboutToBeDestroyed(Scene_item *item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const Polygon_soup::Edges&
|
const Polygon_soup::Edges&
|
||||||
Scene_polygon_soup_item::non_manifold_edges() const
|
Scene_polygon_soup_item::non_manifold_edges() const
|
||||||
{
|
{
|
||||||
return d->soup->non_manifold_edges;
|
return d->soup->non_manifold_edges;
|
||||||
|
|
@ -742,19 +742,19 @@ void Scene_polygon_soup_item::initializeBuffers(Viewer_interface *v) const
|
||||||
{
|
{
|
||||||
getTriangleContainer(Priv::Flat_facets)->initializeBuffers(v);
|
getTriangleContainer(Priv::Flat_facets)->initializeBuffers(v);
|
||||||
getTriangleContainer(Priv::Flat_facets)->setFlatDataSize(d->nb_polys);
|
getTriangleContainer(Priv::Flat_facets)->setFlatDataSize(d->nb_polys);
|
||||||
|
|
||||||
getTriangleContainer(Priv::Smooth_facets)->initializeBuffers(v);
|
getTriangleContainer(Priv::Smooth_facets)->initializeBuffers(v);
|
||||||
getTriangleContainer(Priv::Smooth_facets)->setFlatDataSize(d->nb_polys);
|
getTriangleContainer(Priv::Smooth_facets)->setFlatDataSize(d->nb_polys);
|
||||||
|
|
||||||
getEdgeContainer(Priv::Edges)->initializeBuffers(v);
|
getEdgeContainer(Priv::Edges)->initializeBuffers(v);
|
||||||
getEdgeContainer(Priv::Edges)->setFlatDataSize(d->nb_lines);
|
getEdgeContainer(Priv::Edges)->setFlatDataSize(d->nb_lines);
|
||||||
|
|
||||||
getEdgeContainer(Priv::NM_edges)->initializeBuffers(v);
|
getEdgeContainer(Priv::NM_edges)->initializeBuffers(v);
|
||||||
getEdgeContainer(Priv::NM_edges)->setFlatDataSize(d->nb_nm_edges);
|
getEdgeContainer(Priv::NM_edges)->setFlatDataSize(d->nb_nm_edges);
|
||||||
|
|
||||||
getPointContainer(0)->initializeBuffers(v);
|
getPointContainer(0)->initializeBuffers(v);
|
||||||
getPointContainer(0)->setFlatDataSize(d->nb_lines);
|
getPointContainer(0)->setFlatDataSize(d->nb_lines);
|
||||||
|
|
||||||
d->normals.resize(0);
|
d->normals.resize(0);
|
||||||
d->positions_poly.resize(0);
|
d->positions_poly.resize(0);
|
||||||
d->normals.shrink_to_fit();
|
d->normals.shrink_to_fit();
|
||||||
|
|
@ -768,15 +768,15 @@ void Scene_polygon_soup_item::initializeBuffers(Viewer_interface *v) const
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene_polygon_soup_item::computeElements() const
|
void Scene_polygon_soup_item::computeElements() const
|
||||||
{
|
{
|
||||||
QApplication::setOverrideCursor(Qt::WaitCursor);
|
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||||
d->compute_normals_and_vertices();
|
d->compute_normals_and_vertices();
|
||||||
|
|
||||||
getTriangleContainer(Priv::Flat_facets)->allocate(
|
getTriangleContainer(Priv::Flat_facets)->allocate(
|
||||||
Tc::Flat_vertices,
|
Tc::Flat_vertices,
|
||||||
d->positions_poly.data(),
|
d->positions_poly.data(),
|
||||||
static_cast<int>(d->positions_poly.size()*sizeof(float)));
|
static_cast<int>(d->positions_poly.size()*sizeof(float)));
|
||||||
|
|
||||||
getTriangleContainer(Priv::Flat_facets)->allocate(
|
getTriangleContainer(Priv::Flat_facets)->allocate(
|
||||||
Tc::Flat_normals,
|
Tc::Flat_normals,
|
||||||
d->normals.data(),
|
d->normals.data(),
|
||||||
|
|
@ -792,12 +792,12 @@ void Scene_polygon_soup_item::computeElements() const
|
||||||
Tc::Flat_vertices,
|
Tc::Flat_vertices,
|
||||||
d->positions_poly.data(),
|
d->positions_poly.data(),
|
||||||
static_cast<int>(d->positions_poly.size()*sizeof(float)));
|
static_cast<int>(d->positions_poly.size()*sizeof(float)));
|
||||||
|
|
||||||
getTriangleContainer(Priv::Smooth_facets)->allocate(
|
getTriangleContainer(Priv::Smooth_facets)->allocate(
|
||||||
Tc::Flat_normals,
|
Tc::Flat_normals,
|
||||||
d->normals.data(),
|
d->normals.data(),
|
||||||
static_cast<int>(d->normals.size()*sizeof(float)));
|
static_cast<int>(d->normals.size()*sizeof(float)));
|
||||||
|
|
||||||
if(!d->v_colors.empty())
|
if(!d->v_colors.empty())
|
||||||
{
|
{
|
||||||
getTriangleContainer(Priv::Smooth_facets)->allocate(
|
getTriangleContainer(Priv::Smooth_facets)->allocate(
|
||||||
|
|
@ -805,28 +805,28 @@ void Scene_polygon_soup_item::computeElements() const
|
||||||
d->v_colors.data(),
|
d->v_colors.data(),
|
||||||
static_cast<int>(d->v_colors.size()*sizeof(float)));
|
static_cast<int>(d->v_colors.size()*sizeof(float)));
|
||||||
}
|
}
|
||||||
|
|
||||||
d->nb_polys = d->positions_poly.size();
|
d->nb_polys = d->positions_poly.size();
|
||||||
|
|
||||||
getEdgeContainer(Priv::Edges)->allocate(
|
getEdgeContainer(Priv::Edges)->allocate(
|
||||||
Ec::Vertices,
|
Ec::Vertices,
|
||||||
d->positions_lines.data(),
|
d->positions_lines.data(),
|
||||||
static_cast<int>(d->positions_lines.size()*sizeof(float)));
|
static_cast<int>(d->positions_lines.size()*sizeof(float)));
|
||||||
|
|
||||||
getPointContainer(0)->allocate(
|
getPointContainer(0)->allocate(
|
||||||
Pc::Vertices,
|
Pc::Vertices,
|
||||||
d->positions_lines.data(),
|
d->positions_lines.data(),
|
||||||
static_cast<int>(d->positions_lines.size()*sizeof(float)));
|
static_cast<int>(d->positions_lines.size()*sizeof(float)));
|
||||||
|
|
||||||
|
|
||||||
getEdgeContainer(Priv::NM_edges)->allocate(
|
getEdgeContainer(Priv::NM_edges)->allocate(
|
||||||
Ec::Vertices,
|
Ec::Vertices,
|
||||||
d->positions_nm_lines.data(),
|
d->positions_nm_lines.data(),
|
||||||
static_cast<int>(d->positions_nm_lines.size()*sizeof(float)));
|
static_cast<int>(d->positions_nm_lines.size()*sizeof(float)));
|
||||||
|
|
||||||
d->nb_nm_edges = d->positions_nm_lines.size();
|
d->nb_nm_edges = d->positions_nm_lines.size();
|
||||||
d->nb_lines = d->positions_lines.size();
|
d->nb_lines = d->positions_lines.size();
|
||||||
|
|
||||||
setBuffersFilled(true);
|
setBuffersFilled(true);
|
||||||
QApplication::restoreOverrideCursor();
|
QApplication::restoreOverrideCursor();
|
||||||
}
|
}
|
||||||
|
|
@ -858,19 +858,19 @@ CGAL::Three::Scene_item::Header_data Scene_polygon_soup_item::header() const
|
||||||
|
|
||||||
//titles
|
//titles
|
||||||
data.titles.append(QString("#Points"));
|
data.titles.append(QString("#Points"));
|
||||||
|
|
||||||
data.titles.append(QString("#Polygons"));
|
data.titles.append(QString("#Polygons"));
|
||||||
data.titles.append(QString("Pure Triangle"));
|
data.titles.append(QString("Pure Triangle"));
|
||||||
data.titles.append(QString("Pure Quad"));
|
data.titles.append(QString("Pure Quad"));
|
||||||
data.titles.append(QString("#Degenerate Polygons"));
|
data.titles.append(QString("#Degenerate Polygons"));
|
||||||
|
|
||||||
data.titles.append(QString("#Edges"));
|
data.titles.append(QString("#Edges"));
|
||||||
data.titles.append(QString("Minimum Length"));
|
data.titles.append(QString("Minimum Length"));
|
||||||
data.titles.append(QString("Maximum Length"));
|
data.titles.append(QString("Maximum Length"));
|
||||||
data.titles.append(QString("Median Length"));
|
data.titles.append(QString("Median Length"));
|
||||||
data.titles.append(QString("Mean Length"));
|
data.titles.append(QString("Mean Length"));
|
||||||
data.titles.append(QString("#Degenerate Edges"));
|
data.titles.append(QString("#Degenerate Edges"));
|
||||||
|
|
||||||
data.titles.append(QString("Minimum"));
|
data.titles.append(QString("Minimum"));
|
||||||
data.titles.append(QString("Maximum"));
|
data.titles.append(QString("Maximum"));
|
||||||
data.titles.append(QString("Average"));
|
data.titles.append(QString("Average"));
|
||||||
|
|
@ -881,7 +881,7 @@ QString Scene_polygon_soup_item::computeStats(int type)
|
||||||
{
|
{
|
||||||
if(!d->stats_computed)
|
if(!d->stats_computed)
|
||||||
d->compute_stats();
|
d->compute_stats();
|
||||||
|
|
||||||
switch(type)
|
switch(type)
|
||||||
{
|
{
|
||||||
case NB_VERTICES:
|
case NB_VERTICES:
|
||||||
|
|
@ -890,7 +890,7 @@ QString Scene_polygon_soup_item::computeStats(int type)
|
||||||
return QString::number(d->soup->polygons.size());
|
return QString::number(d->soup->polygons.size());
|
||||||
case NB_EDGES:
|
case NB_EDGES:
|
||||||
return QString::number(d->nb_lines/6);
|
return QString::number(d->nb_lines/6);
|
||||||
|
|
||||||
case NB_DEGENERATED_FACES:
|
case NB_DEGENERATED_FACES:
|
||||||
{
|
{
|
||||||
if(d->is_triangle)
|
if(d->is_triangle)
|
||||||
|
|
@ -900,7 +900,7 @@ QString Scene_polygon_soup_item::computeStats(int type)
|
||||||
else
|
else
|
||||||
return QString("n/a");
|
return QString("n/a");
|
||||||
}
|
}
|
||||||
|
|
||||||
case MIN_LENGTH:
|
case MIN_LENGTH:
|
||||||
return QString::number(d->minl);
|
return QString::number(d->minl);
|
||||||
case MAX_LENGTH:
|
case MAX_LENGTH:
|
||||||
|
|
@ -911,14 +911,14 @@ QString Scene_polygon_soup_item::computeStats(int type)
|
||||||
return QString::number(d->meanl);
|
return QString::number(d->meanl);
|
||||||
case NB_NULL_LENGTH:
|
case NB_NULL_LENGTH:
|
||||||
return QString::number(d->nb_null_edges);
|
return QString::number(d->nb_null_edges);
|
||||||
|
|
||||||
case MIN_ANGLE:
|
case MIN_ANGLE:
|
||||||
return QString::number(d->mini);
|
return QString::number(d->mini);
|
||||||
case MAX_ANGLE:
|
case MAX_ANGLE:
|
||||||
return QString::number(d->maxi);
|
return QString::number(d->maxi);
|
||||||
case MEAN_ANGLE:
|
case MEAN_ANGLE:
|
||||||
return QString::number(d->ave);
|
return QString::number(d->ave);
|
||||||
|
|
||||||
case IS_PURE_TRIANGLE:
|
case IS_PURE_TRIANGLE:
|
||||||
if(d->is_triangle)
|
if(d->is_triangle)
|
||||||
return QString("yes");
|
return QString("yes");
|
||||||
|
|
@ -961,8 +961,8 @@ Scene_polygon_soup_item_priv::compute_stats()
|
||||||
accumulator_set< double,
|
accumulator_set< double,
|
||||||
features< tag::min, tag::max, tag::mean > > angles_acc;
|
features< tag::min, tag::max, tag::mean > > angles_acc;
|
||||||
double rad_to_deg = 180. / CGAL_PI;
|
double rad_to_deg = 180. / CGAL_PI;
|
||||||
|
|
||||||
|
|
||||||
for(auto poly : soup->polygons)
|
for(auto poly : soup->polygons)
|
||||||
{
|
{
|
||||||
if(poly.size() != 3)
|
if(poly.size() != 3)
|
||||||
|
|
@ -974,7 +974,7 @@ Scene_polygon_soup_item_priv::compute_stats()
|
||||||
Polygon_soup::Point_3 a(soup->points[poly[i]]),
|
Polygon_soup::Point_3 a(soup->points[poly[i]]),
|
||||||
b(soup->points[poly[(i+1)%poly.size()]]),
|
b(soup->points[poly[(i+1)%poly.size()]]),
|
||||||
c(soup->points[poly[(i+2)%poly.size()]]);
|
c(soup->points[poly[(i+2)%poly.size()]]);
|
||||||
if (a == b)
|
if (a == b)
|
||||||
++nb_null_edges;
|
++nb_null_edges;
|
||||||
edges_acc(CGAL::sqrt(CGAL::squared_distance(a, b)));
|
edges_acc(CGAL::sqrt(CGAL::squared_distance(a, b)));
|
||||||
typename Traits::Vector_3 ba(b, a);
|
typename Traits::Vector_3 ba(b, a);
|
||||||
|
|
@ -994,6 +994,6 @@ Scene_polygon_soup_item_priv::compute_stats()
|
||||||
mini = extract_result< tag::min >(angles_acc);
|
mini = extract_result< tag::min >(angles_acc);
|
||||||
maxi = extract_result< tag::max >(angles_acc);
|
maxi = extract_result< tag::max >(angles_acc);
|
||||||
ave = extract_result< tag::mean >(angles_acc);
|
ave = extract_result< tag::mean >(angles_acc);
|
||||||
|
|
||||||
stats_computed = true;
|
stats_computed = true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -151,7 +151,7 @@ struct Scene_surface_mesh_item_priv{
|
||||||
true));
|
true));
|
||||||
item->setPointContainer(0, new Point_container(VI::PROGRAM_WITHOUT_LIGHT,
|
item->setPointContainer(0, new Point_container(VI::PROGRAM_WITHOUT_LIGHT,
|
||||||
false));
|
false));
|
||||||
|
|
||||||
has_feature_edges = false;
|
has_feature_edges = false;
|
||||||
invalidate_stats();
|
invalidate_stats();
|
||||||
vertices_displayed = false;
|
vertices_displayed = false;
|
||||||
|
|
@ -193,7 +193,7 @@ struct Scene_surface_mesh_item_priv{
|
||||||
void* get_aabb_tree();
|
void* get_aabb_tree();
|
||||||
QList<EPICK::Triangle_3> triangulate_primitive(face_descriptor fit,
|
QList<EPICK::Triangle_3> triangulate_primitive(face_descriptor fit,
|
||||||
EPICK::Vector_3 normal);
|
EPICK::Vector_3 normal);
|
||||||
|
|
||||||
//! \brief triangulate_facet Triangulates a facet.
|
//! \brief triangulate_facet Triangulates a facet.
|
||||||
//! \param fd a face_descriptor of the facet that needs to be triangulated.
|
//! \param fd a face_descriptor of the facet that needs to be triangulated.
|
||||||
//! \param fnormals a property_map containing the normals of the mesh.
|
//! \param fnormals a property_map containing the normals of the mesh.
|
||||||
|
|
@ -310,7 +310,7 @@ void Scene_surface_mesh_item::standard_constructor(SMesh* sm)
|
||||||
d->textFItems = new TextListItem(this);
|
d->textFItems = new TextListItem(this);
|
||||||
are_buffers_filled = false;
|
are_buffers_filled = false;
|
||||||
invalidate(ALL);
|
invalidate(ALL);
|
||||||
|
|
||||||
}
|
}
|
||||||
Scene_surface_mesh_item::Scene_surface_mesh_item(SMesh* sm)
|
Scene_surface_mesh_item::Scene_surface_mesh_item(SMesh* sm)
|
||||||
{
|
{
|
||||||
|
|
@ -393,39 +393,39 @@ void Scene_surface_mesh_item_priv::compute_elements(Scene_item_rendering_helper:
|
||||||
v_colors.clear();
|
v_colors.clear();
|
||||||
idx_data_.clear();
|
idx_data_.clear();
|
||||||
idx_data_.shrink_to_fit();
|
idx_data_.shrink_to_fit();
|
||||||
|
|
||||||
SMesh::Property_map<vertex_descriptor, EPICK::Vector_3 > vnormals =
|
SMesh::Property_map<vertex_descriptor, EPICK::Vector_3 > vnormals =
|
||||||
smesh_->add_property_map<vertex_descriptor, EPICK::Vector_3 >("v:normal").first;
|
smesh_->add_property_map<vertex_descriptor, EPICK::Vector_3 >("v:normal").first;
|
||||||
|
|
||||||
SMesh::Property_map<face_descriptor, EPICK::Vector_3 > fnormals =
|
SMesh::Property_map<face_descriptor, EPICK::Vector_3 > fnormals =
|
||||||
smesh_->add_property_map<face_descriptor, EPICK::Vector_3 >("f:normal").first;
|
smesh_->add_property_map<face_descriptor, EPICK::Vector_3 >("f:normal").first;
|
||||||
CGAL::Polygon_mesh_processing::compute_face_normals(*smesh_,fnormals);
|
CGAL::Polygon_mesh_processing::compute_face_normals(*smesh_,fnormals);
|
||||||
|
|
||||||
typedef boost::graph_traits<SMesh>::face_descriptor face_descriptor;
|
typedef boost::graph_traits<SMesh>::face_descriptor face_descriptor;
|
||||||
CGAL::Polygon_mesh_processing::compute_vertex_normals(*smesh_,vnormals);
|
CGAL::Polygon_mesh_processing::compute_vertex_normals(*smesh_,vnormals);
|
||||||
|
|
||||||
const CGAL::qglviewer::Vec o = static_cast<CGAL::Three::Viewer_interface*>(CGAL::QGLViewer::QGLViewerPool().first())->offset();
|
const CGAL::qglviewer::Vec o = static_cast<CGAL::Three::Viewer_interface*>(CGAL::QGLViewer::QGLViewerPool().first())->offset();
|
||||||
EPICK::Vector_3 offset(o.x, o.y, o.z);
|
EPICK::Vector_3 offset(o.x, o.y, o.z);
|
||||||
|
|
||||||
SMesh::Property_map<vertex_descriptor, SMesh::Point> positions =
|
SMesh::Property_map<vertex_descriptor, SMesh::Point> positions =
|
||||||
smesh_->points();
|
smesh_->points();
|
||||||
|
|
||||||
SMesh::Property_map<vertex_descriptor, CGAL::Color> vcolors =
|
SMesh::Property_map<vertex_descriptor, CGAL::Color> vcolors =
|
||||||
smesh_->property_map<vertex_descriptor, CGAL::Color >("v:color").first;
|
smesh_->property_map<vertex_descriptor, CGAL::Color >("v:color").first;
|
||||||
|
|
||||||
SMesh::Property_map<face_descriptor, CGAL::Color> fcolors =
|
SMesh::Property_map<face_descriptor, CGAL::Color> fcolors =
|
||||||
smesh_->property_map<face_descriptor, CGAL::Color >("f:color").first;
|
smesh_->property_map<face_descriptor, CGAL::Color >("f:color").first;
|
||||||
|
|
||||||
boost::property_map< SMesh, boost::vertex_index_t >::type
|
boost::property_map< SMesh, boost::vertex_index_t >::type
|
||||||
im = get(boost::vertex_index, *smesh_);
|
im = get(boost::vertex_index, *smesh_);
|
||||||
|
|
||||||
idx_data_.reserve(num_faces(*smesh_) * 3);
|
idx_data_.reserve(num_faces(*smesh_) * 3);
|
||||||
|
|
||||||
typedef CGAL::Buffer_for_vao<float, unsigned int> CPF;
|
typedef CGAL::Buffer_for_vao<float, unsigned int> CPF;
|
||||||
typedef boost::graph_traits<SMesh>::face_descriptor face_descriptor;
|
typedef boost::graph_traits<SMesh>::face_descriptor face_descriptor;
|
||||||
typedef boost::graph_traits<SMesh>::halfedge_descriptor halfedge_descriptor;
|
typedef boost::graph_traits<SMesh>::halfedge_descriptor halfedge_descriptor;
|
||||||
typedef boost::graph_traits<SMesh>::edge_descriptor edge_descriptor;
|
typedef boost::graph_traits<SMesh>::edge_descriptor edge_descriptor;
|
||||||
|
|
||||||
if(name.testFlag(Scene_item_rendering_helper::GEOMETRY))
|
if(name.testFlag(Scene_item_rendering_helper::GEOMETRY))
|
||||||
{
|
{
|
||||||
for(face_descriptor fd : faces(*smesh_))
|
for(face_descriptor fd : faces(*smesh_))
|
||||||
|
|
@ -445,7 +445,7 @@ void Scene_surface_mesh_item_priv::compute_elements(Scene_item_rendering_helper:
|
||||||
facet_points.push_back(positions[target(hd, *smesh_)]);
|
facet_points.push_back(positions[target(hd, *smesh_)]);
|
||||||
}
|
}
|
||||||
bool is_convex = CPF::is_facet_convex(facet_points, fnormals[fd]);
|
bool is_convex = CPF::is_facet_convex(facet_points, fnormals[fd]);
|
||||||
|
|
||||||
if(is_convex && is_quad(halfedge(fd,*smesh_),*smesh_) )
|
if(is_convex && is_quad(halfedge(fd,*smesh_),*smesh_) )
|
||||||
{
|
{
|
||||||
halfedge_descriptor hd = halfedge(fd,*smesh_);
|
halfedge_descriptor hd = halfedge(fd,*smesh_);
|
||||||
|
|
@ -453,12 +453,12 @@ void Scene_surface_mesh_item_priv::compute_elements(Scene_item_rendering_helper:
|
||||||
idx_data_.push_back(source(hd, *smesh_));
|
idx_data_.push_back(source(hd, *smesh_));
|
||||||
idx_data_.push_back(source(next(hd, *smesh_), *smesh_));
|
idx_data_.push_back(source(next(hd, *smesh_), *smesh_));
|
||||||
idx_data_.push_back(source(next(next(hd, *smesh_), *smesh_), *smesh_));
|
idx_data_.push_back(source(next(next(hd, *smesh_), *smesh_), *smesh_));
|
||||||
|
|
||||||
//2nd half
|
//2nd half
|
||||||
idx_data_.push_back(source(hd, *smesh_));
|
idx_data_.push_back(source(hd, *smesh_));
|
||||||
idx_data_.push_back(source(next(next(hd, *smesh_), *smesh_), *smesh_));
|
idx_data_.push_back(source(next(next(hd, *smesh_), *smesh_), *smesh_));
|
||||||
idx_data_.push_back(source(prev(hd, *smesh_), *smesh_));
|
idx_data_.push_back(source(prev(hd, *smesh_), *smesh_));
|
||||||
}
|
}
|
||||||
else if(is_convex)
|
else if(is_convex)
|
||||||
{
|
{
|
||||||
triangulate_convex_facet(fd, &fnormals, 0, &im, name, true);
|
triangulate_convex_facet(fd, &fnormals, 0, &im, name, true);
|
||||||
|
|
@ -470,10 +470,10 @@ void Scene_surface_mesh_item_priv::compute_elements(Scene_item_rendering_helper:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(name.testFlag(Scene_item_rendering_helper::COLORS))
|
if(name.testFlag(Scene_item_rendering_helper::COLORS))
|
||||||
{
|
{
|
||||||
|
|
||||||
has_fpatch_id = smesh_->property_map<face_descriptor, int >("f:patch_id").second;
|
has_fpatch_id = smesh_->property_map<face_descriptor, int >("f:patch_id").second;
|
||||||
has_fcolors = smesh_->property_map<face_descriptor, CGAL::Color >("f:color").second;
|
has_fcolors = smesh_->property_map<face_descriptor, CGAL::Color >("f:color").second;
|
||||||
has_vcolors = smesh_->property_map<vertex_descriptor, CGAL::Color >("v:color").second;
|
has_vcolors = smesh_->property_map<vertex_descriptor, CGAL::Color >("v:color").second;
|
||||||
|
|
@ -496,19 +496,19 @@ void Scene_surface_mesh_item_priv::compute_elements(Scene_item_rendering_helper:
|
||||||
}
|
}
|
||||||
idx_edge_data_.shrink_to_fit();
|
idx_edge_data_.shrink_to_fit();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(name.testFlag(Scene_item_rendering_helper::COLORS) &&
|
if(name.testFlag(Scene_item_rendering_helper::COLORS) &&
|
||||||
has_fpatch_id){
|
has_fpatch_id){
|
||||||
initialize_colors();
|
initialize_colors();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//compute the Flat data
|
//compute the Flat data
|
||||||
|
|
||||||
flat_vertices.clear();
|
flat_vertices.clear();
|
||||||
flat_normals.clear();
|
flat_normals.clear();
|
||||||
f_colors.clear();
|
f_colors.clear();
|
||||||
|
|
||||||
for(face_descriptor fd : faces(*smesh_))
|
for(face_descriptor fd : faces(*smesh_))
|
||||||
{
|
{
|
||||||
if(is_triangle(halfedge(fd,*smesh_),*smesh_))
|
if(is_triangle(halfedge(fd,*smesh_),*smesh_))
|
||||||
|
|
@ -531,7 +531,7 @@ void Scene_surface_mesh_item_priv::compute_elements(Scene_item_rendering_helper:
|
||||||
{
|
{
|
||||||
//The sharp features detection produces patch ids >=1, this
|
//The sharp features detection produces patch ids >=1, this
|
||||||
//is meant to insure the wanted id is in the range [min,max]
|
//is meant to insure the wanted id is in the range [min,max]
|
||||||
QColor c = item->color_vector()[fpatch_id_map[fd] - min_patch_id];
|
QColor c = item->color_vector()[fpatch_id_map[fd] - min_patch_id];
|
||||||
CGAL::Color color(c.red(),c.green(),c.blue());
|
CGAL::Color color(c.red(),c.green(),c.blue());
|
||||||
CPF::add_color_in_buffer(color, f_colors);
|
CPF::add_color_in_buffer(color, f_colors);
|
||||||
}
|
}
|
||||||
|
|
@ -560,7 +560,7 @@ void Scene_surface_mesh_item_priv::compute_elements(Scene_item_rendering_helper:
|
||||||
CGAL::Color *c;
|
CGAL::Color *c;
|
||||||
if(has_fpatch_id)
|
if(has_fpatch_id)
|
||||||
{
|
{
|
||||||
QColor color = item->color_vector()[fpatch_id_map[fd] - min_patch_id];
|
QColor color = item->color_vector()[fpatch_id_map[fd] - min_patch_id];
|
||||||
c = new CGAL::Color(color.red(),color.green(),color.blue());
|
c = new CGAL::Color(color.red(),color.green(),color.blue());
|
||||||
}
|
}
|
||||||
else if(has_fcolors)
|
else if(has_fcolors)
|
||||||
|
|
@ -568,13 +568,13 @@ void Scene_surface_mesh_item_priv::compute_elements(Scene_item_rendering_helper:
|
||||||
else
|
else
|
||||||
c = 0;
|
c = 0;
|
||||||
addFlatData(p,n,c, name);
|
addFlatData(p,n,c, name);
|
||||||
|
|
||||||
hd = next(halfedge(fd, *smesh_),*smesh_);
|
hd = next(halfedge(fd, *smesh_),*smesh_);
|
||||||
addFlatData(positions[source(hd, *smesh_)]
|
addFlatData(positions[source(hd, *smesh_)]
|
||||||
,fnormals[fd]
|
,fnormals[fd]
|
||||||
,c
|
,c
|
||||||
,name);
|
,name);
|
||||||
|
|
||||||
hd = next(next(halfedge(fd, *smesh_),*smesh_), *smesh_);
|
hd = next(next(halfedge(fd, *smesh_),*smesh_), *smesh_);
|
||||||
addFlatData(positions[source(hd, *smesh_)]
|
addFlatData(positions[source(hd, *smesh_)]
|
||||||
,fnormals[fd]
|
,fnormals[fd]
|
||||||
|
|
@ -586,13 +586,13 @@ void Scene_surface_mesh_item_priv::compute_elements(Scene_item_rendering_helper:
|
||||||
,fnormals[fd]
|
,fnormals[fd]
|
||||||
,c
|
,c
|
||||||
,name);
|
,name);
|
||||||
|
|
||||||
hd = next(next(halfedge(fd, *smesh_),*smesh_), *smesh_);
|
hd = next(next(halfedge(fd, *smesh_),*smesh_), *smesh_);
|
||||||
addFlatData(positions[source(hd, *smesh_)]
|
addFlatData(positions[source(hd, *smesh_)]
|
||||||
,fnormals[fd]
|
,fnormals[fd]
|
||||||
,c
|
,c
|
||||||
,name);
|
,name);
|
||||||
|
|
||||||
hd = prev(halfedge(fd, *smesh_), *smesh_);
|
hd = prev(halfedge(fd, *smesh_), *smesh_);
|
||||||
addFlatData(positions[source(hd, *smesh_)]
|
addFlatData(positions[source(hd, *smesh_)]
|
||||||
,fnormals[fd]
|
,fnormals[fd]
|
||||||
|
|
@ -611,7 +611,7 @@ void Scene_surface_mesh_item_priv::compute_elements(Scene_item_rendering_helper:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(has_vcolors && name.testFlag(Scene_item_rendering_helper::COLORS))
|
if(has_vcolors && name.testFlag(Scene_item_rendering_helper::COLORS))
|
||||||
{
|
{
|
||||||
for(vertex_descriptor vd : vertices(*smesh_))
|
for(vertex_descriptor vd : vertices(*smesh_))
|
||||||
|
|
@ -622,7 +622,7 @@ void Scene_surface_mesh_item_priv::compute_elements(Scene_item_rendering_helper:
|
||||||
v_colors.push_back((float)c.blue()/255);
|
v_colors.push_back((float)c.blue()/255);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(floated &&
|
if(floated &&
|
||||||
(name.testFlag(Scene_item_rendering_helper::GEOMETRY)|| name.testFlag(Scene_item_rendering_helper::NORMALS)))
|
(name.testFlag(Scene_item_rendering_helper::GEOMETRY)|| name.testFlag(Scene_item_rendering_helper::NORMALS)))
|
||||||
{
|
{
|
||||||
|
|
@ -646,7 +646,7 @@ void Scene_surface_mesh_item_priv::compute_elements(Scene_item_rendering_helper:
|
||||||
idx_feature_edge_data_size = idx_feature_edge_data_.size();
|
idx_feature_edge_data_size = idx_feature_edge_data_.size();
|
||||||
idx_data_size = idx_data_.size();
|
idx_data_size = idx_data_.size();
|
||||||
flat_vertices_size = flat_vertices.size();
|
flat_vertices_size = flat_vertices.size();
|
||||||
|
|
||||||
item->getPointContainer(0)->allocate(Pt::Vertices, smooth_vertices.data(),
|
item->getPointContainer(0)->allocate(Pt::Vertices, smooth_vertices.data(),
|
||||||
static_cast<int>(num_vertices(*smesh_)*3*sizeof(cgal_gl_data)));
|
static_cast<int>(num_vertices(*smesh_)*3*sizeof(cgal_gl_data)));
|
||||||
item->getEdgeContainer(0)->allocate(Ed::Indices, idx_edge_data_.data(),
|
item->getEdgeContainer(0)->allocate(Ed::Indices, idx_edge_data_.data(),
|
||||||
|
|
@ -688,7 +688,7 @@ void Scene_surface_mesh_item_priv::compute_elements(Scene_item_rendering_helper:
|
||||||
else
|
else
|
||||||
item->getTriangleContainer(0)->allocate(Tri::VColors, 0, 0);
|
item->getTriangleContainer(0)->allocate(Tri::VColors, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
QApplication::restoreOverrideCursor();
|
QApplication::restoreOverrideCursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -719,7 +719,7 @@ void Scene_surface_mesh_item_priv::initializeBuffers(CGAL::Three::Viewer_interfa
|
||||||
item->getEdgeContainer(1)->initializeBuffers(viewer);
|
item->getEdgeContainer(1)->initializeBuffers(viewer);
|
||||||
item->getEdgeContainer(0)->initializeBuffers(viewer);
|
item->getEdgeContainer(0)->initializeBuffers(viewer);
|
||||||
item->getPointContainer(0)->initializeBuffers(viewer);
|
item->getPointContainer(0)->initializeBuffers(viewer);
|
||||||
|
|
||||||
////Clean-up
|
////Clean-up
|
||||||
item->getPointContainer(0)->setFlatDataSize(vertices(*smesh_).size()*3);
|
item->getPointContainer(0)->setFlatDataSize(vertices(*smesh_).size()*3);
|
||||||
item->getTriangleContainer(1)->setFlatDataSize(flat_vertices_size);
|
item->getTriangleContainer(1)->setFlatDataSize(flat_vertices_size);
|
||||||
|
|
@ -757,8 +757,8 @@ void Scene_surface_mesh_item::draw(CGAL::Three::Viewer_interface *viewer) const
|
||||||
d->initializeBuffers(viewer);
|
d->initializeBuffers(viewer);
|
||||||
setBuffersInit(viewer, true);
|
setBuffersInit(viewer, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if(renderingMode() == Gouraud ||
|
if(renderingMode() == Gouraud ||
|
||||||
renderingMode() == GouraudPlusEdges)
|
renderingMode() == GouraudPlusEdges)
|
||||||
{
|
{
|
||||||
|
|
@ -872,7 +872,7 @@ void Scene_surface_mesh_item_priv::triangulate_convex_facet(face_descriptor fd,
|
||||||
Point p0,p1,p2;
|
Point p0,p1,p2;
|
||||||
SMesh::Halfedge_around_face_circulator he(halfedge(fd, *smesh_), *smesh_);
|
SMesh::Halfedge_around_face_circulator he(halfedge(fd, *smesh_), *smesh_);
|
||||||
SMesh::Halfedge_around_face_circulator he_end = he;
|
SMesh::Halfedge_around_face_circulator he_end = he;
|
||||||
|
|
||||||
while(next(*he, *smesh_) != prev(*he_end, *smesh_))
|
while(next(*he, *smesh_) != prev(*he_end, *smesh_))
|
||||||
{
|
{
|
||||||
++he;
|
++he;
|
||||||
|
|
@ -887,7 +887,7 @@ void Scene_surface_mesh_item_priv::triangulate_convex_facet(face_descriptor fd,
|
||||||
CGAL::Color* color;
|
CGAL::Color* color;
|
||||||
if(has_fpatch_id)
|
if(has_fpatch_id)
|
||||||
{
|
{
|
||||||
QColor c = item->color_vector()[fpatch_id_map[fd] - min_patch_id];
|
QColor c = item->color_vector()[fpatch_id_map[fd] - min_patch_id];
|
||||||
color = new CGAL::Color(c.red(),c.green(),c.blue());
|
color = new CGAL::Color(c.red(),c.green(),c.blue());
|
||||||
}
|
}
|
||||||
else if(has_fcolors)
|
else if(has_fcolors)
|
||||||
|
|
@ -902,7 +902,7 @@ void Scene_surface_mesh_item_priv::triangulate_convex_facet(face_descriptor fd,
|
||||||
(*fnormals)[fd],
|
(*fnormals)[fd],
|
||||||
color,
|
color,
|
||||||
name);
|
name);
|
||||||
|
|
||||||
addFlatData(p2,
|
addFlatData(p2,
|
||||||
(*fnormals)[fd],
|
(*fnormals)[fd],
|
||||||
color,
|
color,
|
||||||
|
|
@ -926,7 +926,7 @@ Scene_surface_mesh_item_priv::triangulate_facet(face_descriptor fd,
|
||||||
Scene_item_rendering_helper::Gl_data_names name,
|
Scene_item_rendering_helper::Gl_data_names name,
|
||||||
bool index) const
|
bool index) const
|
||||||
{
|
{
|
||||||
|
|
||||||
//Computes the normal of the facet
|
//Computes the normal of the facet
|
||||||
EPICK::Vector_3 normal = get(*fnormals, fd);
|
EPICK::Vector_3 normal = get(*fnormals, fd);
|
||||||
if(normal == CGAL::NULL_VECTOR)
|
if(normal == CGAL::NULL_VECTOR)
|
||||||
|
|
@ -946,7 +946,7 @@ Scene_surface_mesh_item_priv::triangulate_facet(face_descriptor fd,
|
||||||
}
|
}
|
||||||
next_ =next(next_, *smesh_);
|
next_ =next(next_, *smesh_);
|
||||||
}while(next_ != start);
|
}while(next_ != start);
|
||||||
|
|
||||||
if (normal == CGAL::NULL_VECTOR) // No normal could be computed, return
|
if (normal == CGAL::NULL_VECTOR) // No normal could be computed, return
|
||||||
{
|
{
|
||||||
qDebug()<<"Warning : normal is not valid. Facet not displayed";
|
qDebug()<<"Warning : normal is not valid. Facet not displayed";
|
||||||
|
|
@ -959,7 +959,7 @@ Scene_surface_mesh_item_priv::triangulate_facet(face_descriptor fd,
|
||||||
qDebug()<<"Warning : normal is not valid. Facet not displayed";
|
qDebug()<<"Warning : normal is not valid. Facet not displayed";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef FacetTriangulator<SMesh, EPICK, boost::graph_traits<SMesh>::vertex_descriptor> FT;
|
typedef FacetTriangulator<SMesh, EPICK, boost::graph_traits<SMesh>::vertex_descriptor> FT;
|
||||||
const CGAL::qglviewer::Vec off = static_cast<CGAL::Three::Viewer_interface*>(CGAL::QGLViewer::QGLViewerPool().first())->offset();
|
const CGAL::qglviewer::Vec off = static_cast<CGAL::Three::Viewer_interface*>(CGAL::QGLViewer::QGLViewerPool().first())->offset();
|
||||||
EPICK::Vector_3 offset(off.x,off.y,off.z);
|
EPICK::Vector_3 offset(off.x,off.y,off.z);
|
||||||
|
|
@ -979,14 +979,14 @@ Scene_surface_mesh_item_priv::triangulate_facet(face_descriptor fd,
|
||||||
CGAL::Color* color;
|
CGAL::Color* color;
|
||||||
if(has_fpatch_id)
|
if(has_fpatch_id)
|
||||||
{
|
{
|
||||||
QColor c= item->color_vector()[fpatch_id_map[fd] - min_patch_id];
|
QColor c= item->color_vector()[fpatch_id_map[fd] - min_patch_id];
|
||||||
color = new CGAL::Color(c.red(),c.green(),c.blue());
|
color = new CGAL::Color(c.red(),c.green(),c.blue());
|
||||||
}
|
}
|
||||||
else if(has_fcolors)
|
else if(has_fcolors)
|
||||||
color = &(*fcolors)[fd];
|
color = &(*fcolors)[fd];
|
||||||
else
|
else
|
||||||
color = 0;
|
color = 0;
|
||||||
|
|
||||||
addFlatData(ffit->vertex(0)->point()-offset,
|
addFlatData(ffit->vertex(0)->point()-offset,
|
||||||
(*fnormals)[fd],
|
(*fnormals)[fd],
|
||||||
color,
|
color,
|
||||||
|
|
@ -995,7 +995,7 @@ Scene_surface_mesh_item_priv::triangulate_facet(face_descriptor fd,
|
||||||
(*fnormals)[fd],
|
(*fnormals)[fd],
|
||||||
color,
|
color,
|
||||||
name);
|
name);
|
||||||
|
|
||||||
addFlatData(ffit->vertex(2)->point()-offset,
|
addFlatData(ffit->vertex(2)->point()-offset,
|
||||||
(*fnormals)[fd],
|
(*fnormals)[fd],
|
||||||
color,
|
color,
|
||||||
|
|
@ -1013,7 +1013,7 @@ Scene_surface_mesh_item_priv::triangulate_facet(face_descriptor fd,
|
||||||
idx_data_.push_back((*im)[triangulation.v2v[ffit->vertex(2)]]);
|
idx_data_.push_back((*im)[triangulation.v2v[ffit->vertex(2)]]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void delete_aabb_tree(Scene_surface_mesh_item* item)
|
void delete_aabb_tree(Scene_surface_mesh_item* item)
|
||||||
|
|
@ -1116,7 +1116,7 @@ void* Scene_surface_mesh_item_priv::get_aabb_tree()
|
||||||
for(face_descriptor f : faces(*sm))
|
for(face_descriptor f : faces(*sm))
|
||||||
{
|
{
|
||||||
//if face is degenerate, skip it
|
//if face is degenerate, skip it
|
||||||
if (CGAL::is_triangle(halfedge(f, *sm), *sm)
|
if (CGAL::is_triangle(halfedge(f, *sm), *sm)
|
||||||
&& CGAL::Polygon_mesh_processing::is_degenerate_triangle_face(f, *sm))
|
&& CGAL::Polygon_mesh_processing::is_degenerate_triangle_face(f, *sm))
|
||||||
continue;
|
continue;
|
||||||
//if face not triangle, triangulate corresponding primitive before adding it to the tree
|
//if face not triangle, triangulate corresponding primitive before adding it to the tree
|
||||||
|
|
@ -1291,7 +1291,7 @@ void Scene_surface_mesh_item::invalidate(Gl_data_names name)
|
||||||
setBuffersInit(viewer, false);
|
setBuffersInit(viewer, false);
|
||||||
viewer->update();
|
viewer->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
getTriangleContainer(1)->reset_vbos(name);
|
getTriangleContainer(1)->reset_vbos(name);
|
||||||
getTriangleContainer(0)->reset_vbos(name);
|
getTriangleContainer(0)->reset_vbos(name);
|
||||||
getEdgeContainer(1)->reset_vbos(name);
|
getEdgeContainer(1)->reset_vbos(name);
|
||||||
|
|
@ -1810,7 +1810,7 @@ void Scene_surface_mesh_item::zoomToPosition(const QPoint &point, CGAL::Three::V
|
||||||
bool found = false;
|
bool found = false;
|
||||||
CGAL::qglviewer::Vec point_under = viewer->camera()->pointUnderPixel(point,found);
|
CGAL::qglviewer::Vec point_under = viewer->camera()->pointUnderPixel(point,found);
|
||||||
EPICK::Point_3 ray_origin;
|
EPICK::Point_3 ray_origin;
|
||||||
CGAL::qglviewer::Vec dir;
|
CGAL::qglviewer::Vec dir;
|
||||||
if(viewer->camera()->type() == CGAL::qglviewer::Camera::PERSPECTIVE)
|
if(viewer->camera()->type() == CGAL::qglviewer::Camera::PERSPECTIVE)
|
||||||
{
|
{
|
||||||
ray_origin = EPICK::Point_3(viewer->camera()->position().x - offset.x,
|
ray_origin = EPICK::Point_3(viewer->camera()->position().x - offset.x,
|
||||||
|
|
@ -1821,7 +1821,7 @@ void Scene_surface_mesh_item::zoomToPosition(const QPoint &point, CGAL::Three::V
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dir = viewer->camera()->viewDirection();
|
dir = viewer->camera()->viewDirection();
|
||||||
ray_origin = EPICK::Point_3(point_under.x - dir.x,
|
ray_origin = EPICK::Point_3(point_under.x - dir.x,
|
||||||
point_under.y - dir.y,
|
point_under.y - dir.y,
|
||||||
point_under.z - dir.z);
|
point_under.z - dir.z);
|
||||||
}
|
}
|
||||||
|
|
@ -1996,8 +1996,8 @@ QMenu* Scene_surface_mesh_item::contextMenu()
|
||||||
actionZoomToId->setObjectName("actionZoomToId");
|
actionZoomToId->setObjectName("actionZoomToId");
|
||||||
connect(actionZoomToId, &QAction::triggered,
|
connect(actionZoomToId, &QAction::triggered,
|
||||||
this, &Scene_surface_mesh_item::zoomToId);
|
this, &Scene_surface_mesh_item::zoomToId);
|
||||||
|
|
||||||
|
|
||||||
setProperty("menu_changed", true);
|
setProperty("menu_changed", true);
|
||||||
menu->setProperty(prop_name, true);
|
menu->setProperty(prop_name, true);
|
||||||
}
|
}
|
||||||
|
|
@ -2123,7 +2123,7 @@ bool Scene_surface_mesh_item::testDisplayId(double x, double y, double z, CGAL::
|
||||||
EPICK::Point_3 src(x - offset.x,
|
EPICK::Point_3 src(x - offset.x,
|
||||||
y - offset.y,
|
y - offset.y,
|
||||||
z - offset.z);
|
z - offset.z);
|
||||||
|
|
||||||
CGAL::qglviewer::Camera* cam = viewer->camera();
|
CGAL::qglviewer::Camera* cam = viewer->camera();
|
||||||
EPICK::Point_3 dest( cam->position().x - offset.x,
|
EPICK::Point_3 dest( cam->position().x - offset.x,
|
||||||
cam->position().y - offset.y,
|
cam->position().y - offset.y,
|
||||||
|
|
@ -2313,7 +2313,7 @@ void Scene_surface_mesh_item::computeElements()const
|
||||||
const_cast<Scene_surface_mesh_item*>(this)->itemChanged();
|
const_cast<Scene_surface_mesh_item*>(this)->itemChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Scene_surface_mesh_item::initializeBuffers(CGAL::Three::Viewer_interface* viewer)const
|
Scene_surface_mesh_item::initializeBuffers(CGAL::Three::Viewer_interface* viewer)const
|
||||||
{
|
{
|
||||||
const_cast<Scene_surface_mesh_item*>(this)->//temporary, until the drawing pipeline is not const anymore.
|
const_cast<Scene_surface_mesh_item*>(this)->//temporary, until the drawing pipeline is not const anymore.
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
// $URL$
|
// $URL$
|
||||||
// $Id$
|
// $Id$
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Author(s) : Lutz Kettner <kettner@mpi-sb.mpg.de>
|
// Author(s) : Lutz Kettner <kettner@mpi-sb.mpg.de>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
// $URL$
|
// $URL$
|
||||||
// $Id$
|
// $Id$
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Author(s) : Lutz Kettner <kettner@mpi-sb.mpg.de>
|
// Author(s) : Lutz Kettner <kettner@mpi-sb.mpg.de>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
// $URL$
|
// $URL$
|
||||||
// $Id$
|
// $Id$
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Author(s) : Lutz Kettner <kettner@mpi-sb.mpg.de>
|
// Author(s) : Lutz Kettner <kettner@mpi-sb.mpg.de>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
// $URL$
|
// $URL$
|
||||||
// $Id$
|
// $Id$
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Author(s) : Lutz Kettner <kettner@mpi-sb.mpg.de>
|
// Author(s) : Lutz Kettner <kettner@mpi-sb.mpg.de>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -186,7 +186,7 @@ struct Dereference_property_map
|
||||||
|
|
||||||
/// Free function to create a `Dereference_property_map` property map.
|
/// Free function to create a `Dereference_property_map` property map.
|
||||||
///
|
///
|
||||||
/// \relates Dereference_property_map
|
/// \relates Dereference_property_map
|
||||||
template <class Iter> // Type convertible to `key_type`
|
template <class Iter> // Type convertible to `key_type`
|
||||||
Dereference_property_map<typename CGAL::value_type_traits<Iter>::type>
|
Dereference_property_map<typename CGAL::value_type_traits<Iter>::type>
|
||||||
make_dereference_property_map(Iter)
|
make_dereference_property_map(Iter)
|
||||||
|
|
@ -236,7 +236,7 @@ struct Identity_property_map_no_lvalue
|
||||||
|
|
||||||
/// Free function to create a `Identity_property_map` property map.
|
/// Free function to create a `Identity_property_map` property map.
|
||||||
///
|
///
|
||||||
/// \relates Identity_property_map
|
/// \relates Identity_property_map
|
||||||
template <class T> // Key and value type
|
template <class T> // Key and value type
|
||||||
Identity_property_map<T>
|
Identity_property_map<T>
|
||||||
make_identity_property_map(T)
|
make_identity_property_map(T)
|
||||||
|
|
@ -246,8 +246,8 @@ Identity_property_map<T>
|
||||||
|
|
||||||
|
|
||||||
/// \ingroup PkgPropertyMapRef
|
/// \ingroup PkgPropertyMapRef
|
||||||
/// Property map that accesses the first item of a `std::pair`.
|
/// Property map that accesses the first item of a `std::pair`.
|
||||||
/// \tparam Pair Instance of `std::pair`.
|
/// \tparam Pair Instance of `std::pair`.
|
||||||
/// \cgalModels `LvaluePropertyMap`
|
/// \cgalModels `LvaluePropertyMap`
|
||||||
///
|
///
|
||||||
/// \sa `CGAL::Second_of_pair_property_map<Pair>`
|
/// \sa `CGAL::Second_of_pair_property_map<Pair>`
|
||||||
|
|
@ -271,9 +271,9 @@ struct First_of_pair_property_map
|
||||||
/// @}
|
/// @}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Free function to create a `First_of_pair_property_map` property map.
|
/// Free function to create a `First_of_pair_property_map` property map.
|
||||||
///
|
///
|
||||||
/// \relates First_of_pair_property_map
|
/// \relates First_of_pair_property_map
|
||||||
template <class Pair> // Pair type
|
template <class Pair> // Pair type
|
||||||
First_of_pair_property_map<Pair>
|
First_of_pair_property_map<Pair>
|
||||||
make_first_of_pair_property_map(Pair)
|
make_first_of_pair_property_map(Pair)
|
||||||
|
|
@ -282,13 +282,13 @@ First_of_pair_property_map<Pair>
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \ingroup PkgPropertyMapRef
|
/// \ingroup PkgPropertyMapRef
|
||||||
///
|
///
|
||||||
/// Property map that accesses the second item of a `std::pair`.
|
/// Property map that accesses the second item of a `std::pair`.
|
||||||
///
|
///
|
||||||
/// \tparam Pair Instance of `std::pair`.
|
/// \tparam Pair Instance of `std::pair`.
|
||||||
///
|
///
|
||||||
/// \cgalModels `LvaluePropertyMap`
|
/// \cgalModels `LvaluePropertyMap`
|
||||||
///
|
///
|
||||||
/// \sa `CGAL::First_of_pair_property_map<Pair>`
|
/// \sa `CGAL::First_of_pair_property_map<Pair>`
|
||||||
template <typename Pair>
|
template <typename Pair>
|
||||||
struct Second_of_pair_property_map
|
struct Second_of_pair_property_map
|
||||||
|
|
@ -312,7 +312,7 @@ struct Second_of_pair_property_map
|
||||||
|
|
||||||
/// Free function to create a Second_of_pair_property_map property map.
|
/// Free function to create a Second_of_pair_property_map property map.
|
||||||
///
|
///
|
||||||
/// \relates Second_of_pair_property_map
|
/// \relates Second_of_pair_property_map
|
||||||
template <class Pair> // Pair type
|
template <class Pair> // Pair type
|
||||||
Second_of_pair_property_map<Pair>
|
Second_of_pair_property_map<Pair>
|
||||||
make_second_of_pair_property_map(Pair)
|
make_second_of_pair_property_map(Pair)
|
||||||
|
|
@ -321,12 +321,12 @@ Second_of_pair_property_map<Pair>
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \ingroup PkgPropertyMapRef
|
/// \ingroup PkgPropertyMapRef
|
||||||
///
|
///
|
||||||
/// Property map that accesses the Nth item of a `boost::tuple` or a `std::tuple`.
|
/// Property map that accesses the Nth item of a `boost::tuple` or a `std::tuple`.
|
||||||
///
|
///
|
||||||
/// \tparam N %Index of the item to access.
|
/// \tparam N %Index of the item to access.
|
||||||
/// \tparam Tuple Instance of `boost::tuple` or `std::tuple`.
|
/// \tparam Tuple Instance of `boost::tuple` or `std::tuple`.
|
||||||
///
|
///
|
||||||
/// \cgalModels `LvaluePropertyMap`
|
/// \cgalModels `LvaluePropertyMap`
|
||||||
template <int N, typename Tuple>
|
template <int N, typename Tuple>
|
||||||
struct Nth_of_tuple_property_map
|
struct Nth_of_tuple_property_map
|
||||||
|
|
|
||||||
|
|
@ -47,13 +47,13 @@ typedef boost::associative_property_map< Face2Vector_map > Face2Vector_property_
|
||||||
//RIDGES
|
//RIDGES
|
||||||
typedef CGAL::Ridge_line<PolyhedralSurf> Ridge_line;
|
typedef CGAL::Ridge_line<PolyhedralSurf> Ridge_line;
|
||||||
typedef CGAL::Ridge_approximation < PolyhedralSurf,
|
typedef CGAL::Ridge_approximation < PolyhedralSurf,
|
||||||
VertexFT_property_map,
|
VertexFT_property_map,
|
||||||
VertexVector_property_map > Ridge_approximation;
|
VertexVector_property_map > Ridge_approximation;
|
||||||
//UMBILICS
|
//UMBILICS
|
||||||
typedef CGAL::Umbilic<PolyhedralSurf> Umbilic;
|
typedef CGAL::Umbilic<PolyhedralSurf> Umbilic;
|
||||||
typedef CGAL::Umbilic_approximation < PolyhedralSurf,
|
typedef CGAL::Umbilic_approximation < PolyhedralSurf,
|
||||||
VertexFT_property_map,
|
VertexFT_property_map,
|
||||||
VertexVector_property_map > Umbilic_approximation;
|
VertexVector_property_map > Umbilic_approximation;
|
||||||
|
|
||||||
//create property maps
|
//create property maps
|
||||||
VertexFT_map vertex_k1_map, vertex_k2_map,
|
VertexFT_map vertex_k1_map, vertex_k2_map,
|
||||||
|
|
@ -86,8 +86,8 @@ unsigned int min_nb_points = (d_fitting + 1) * (d_fitting + 2) / 2;
|
||||||
*/
|
*/
|
||||||
template <typename VertexPointMap>
|
template <typename VertexPointMap>
|
||||||
void gather_fitting_points(vertex_descriptor v,
|
void gather_fitting_points(vertex_descriptor v,
|
||||||
std::vector<Point_3> &in_points,
|
std::vector<Point_3> &in_points,
|
||||||
Poly_rings& poly_rings,
|
Poly_rings& poly_rings,
|
||||||
VertexPointMap vpm)
|
VertexPointMap vpm)
|
||||||
{
|
{
|
||||||
//container to collect vertices of v on the PolyhedralSurf
|
//container to collect vertices of v on the PolyhedralSurf
|
||||||
|
|
@ -148,7 +148,7 @@ void compute_differential_quantities(PolyhedralSurf& P, Poly_rings& poly_rings)
|
||||||
assert( d_monge >= 3);
|
assert( d_monge >= 3);
|
||||||
// run the main fct : perform the fitting
|
// run the main fct : perform the fitting
|
||||||
monge_form = monge_fit(in_points.begin(), in_points.end(),
|
monge_form = monge_fit(in_points.begin(), in_points.end(),
|
||||||
d_fitting, d_monge);
|
d_fitting, d_monge);
|
||||||
|
|
||||||
//switch min-max ppal curv/dir wrt the mesh orientation
|
//switch min-max ppal curv/dir wrt the mesh orientation
|
||||||
const Vector_3 normal_mesh = computeFacetsAverageUnitNormal(P,v, face2normal_pm, Kernel());
|
const Vector_3 normal_mesh = computeFacetsAverageUnitNormal(P,v, face2normal_pm, Kernel());
|
||||||
|
|
@ -164,18 +164,18 @@ void compute_differential_quantities(PolyhedralSurf& P, Poly_rings& poly_rings)
|
||||||
if ( d_monge >= 4) {
|
if ( d_monge >= 4) {
|
||||||
//= 3*b1^2+(k1-k2)(c0-3k1^3)
|
//= 3*b1^2+(k1-k2)(c0-3k1^3)
|
||||||
vertex_P1_map[v] =
|
vertex_P1_map[v] =
|
||||||
3*monge_form.coefficients()[3]*monge_form.coefficients()[3]
|
3*monge_form.coefficients()[3]*monge_form.coefficients()[3]
|
||||||
+(monge_form.coefficients()[0]-monge_form.coefficients()[1])
|
+(monge_form.coefficients()[0]-monge_form.coefficients()[1])
|
||||||
*(monge_form.coefficients()[6]
|
*(monge_form.coefficients()[6]
|
||||||
-3*monge_form.coefficients()[0]*monge_form.coefficients()[0]
|
-3*monge_form.coefficients()[0]*monge_form.coefficients()[0]
|
||||||
*monge_form.coefficients()[0]);
|
*monge_form.coefficients()[0]);
|
||||||
//= 3*b2^2+(k2-k1)(c4-3k2^3)
|
//= 3*b2^2+(k2-k1)(c4-3k2^3)
|
||||||
vertex_P2_map[v] =
|
vertex_P2_map[v] =
|
||||||
3*monge_form.coefficients()[4]*monge_form.coefficients()[4]
|
3*monge_form.coefficients()[4]*monge_form.coefficients()[4]
|
||||||
+(-monge_form.coefficients()[0]+monge_form.coefficients()[1])
|
+(-monge_form.coefficients()[0]+monge_form.coefficients()[1])
|
||||||
*(monge_form.coefficients()[10]
|
*(monge_form.coefficients()[10]
|
||||||
-3*monge_form.coefficients()[1]*monge_form.coefficients()[1]
|
-3*monge_form.coefficients()[1]*monge_form.coefficients()[1]
|
||||||
*monge_form.coefficients()[1]);
|
*monge_form.coefficients()[1]);
|
||||||
}
|
}
|
||||||
} //END FOR LOOP
|
} //END FOR LOOP
|
||||||
}
|
}
|
||||||
|
|
@ -228,10 +228,10 @@ int main()
|
||||||
if ( int_tag == 3 ) tag_order = CGAL::Ridge_order_3;
|
if ( int_tag == 3 ) tag_order = CGAL::Ridge_order_3;
|
||||||
if ( int_tag == 4 ) tag_order = CGAL::Ridge_order_4;
|
if ( int_tag == 4 ) tag_order = CGAL::Ridge_order_4;
|
||||||
if ( int_tag != 3 && int_tag != 4 )
|
if ( int_tag != 3 && int_tag != 4 )
|
||||||
{std::cerr << "ridge_order must be CGAL::Ridge_order_3 or CGAL::Ridge_order_4";
|
{std::cerr << "ridge_order must be CGAL::Ridge_order_3 or CGAL::Ridge_order_4";
|
||||||
return 1;}
|
return 1;}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
std::cerr << "Command-line options require Boost.ProgramOptions" << std::endl;
|
std::cerr << "Command-line options require Boost.ProgramOptions" << std::endl;
|
||||||
if_name = "data/poly2x^2+y^2-0.062500.off";
|
if_name = "data/poly2x^2+y^2-0.062500.off";
|
||||||
d_fitting = 3;
|
d_fitting = 3;
|
||||||
|
|
@ -261,26 +261,26 @@ int main()
|
||||||
if (of_name[i] == '/') of_name[i]='_';
|
if (of_name[i] == '/') of_name[i]='_';
|
||||||
std::ostringstream str_4ogl;
|
std::ostringstream str_4ogl;
|
||||||
str_4ogl << "data/"
|
str_4ogl << "data/"
|
||||||
<< of_name << "RIDGES"
|
<< of_name << "RIDGES"
|
||||||
<< "-d" << d_fitting
|
<< "-d" << d_fitting
|
||||||
<< "-m" << d_monge
|
<< "-m" << d_monge
|
||||||
<< "-t" << tag_order
|
<< "-t" << tag_order
|
||||||
<< "-a" << nb_rings
|
<< "-a" << nb_rings
|
||||||
<< "-p" << nb_points_to_use
|
<< "-p" << nb_points_to_use
|
||||||
<< ".4ogl.txt";
|
<< ".4ogl.txt";
|
||||||
std::cout << str_4ogl.str() << std::endl ;
|
std::cout << str_4ogl.str() << std::endl ;
|
||||||
std::ofstream out_4ogl(str_4ogl.str().c_str() , std::ios::out);
|
std::ofstream out_4ogl(str_4ogl.str().c_str() , std::ios::out);
|
||||||
|
|
||||||
//if verbose only...
|
//if verbose only...
|
||||||
std::ostringstream str_verb;
|
std::ostringstream str_verb;
|
||||||
str_verb << "data/"
|
str_verb << "data/"
|
||||||
<< of_name << "RIDGES"
|
<< of_name << "RIDGES"
|
||||||
<< "-d" << d_fitting
|
<< "-d" << d_fitting
|
||||||
<< "-m" << d_monge
|
<< "-m" << d_monge
|
||||||
<< "-t" << tag_order
|
<< "-t" << tag_order
|
||||||
<< "-a" << nb_rings
|
<< "-a" << nb_rings
|
||||||
<< "-p" << nb_points_to_use
|
<< "-p" << nb_points_to_use
|
||||||
<< ".verb.txt";
|
<< ".verb.txt";
|
||||||
std::cout << str_verb.str() << std::endl ;
|
std::cout << str_verb.str() << std::endl ;
|
||||||
std::ofstream out_verb(str_verb.str().c_str() , std::ios::out);
|
std::ofstream out_verb(str_verb.str().c_str() , std::ios::out);
|
||||||
|
|
||||||
|
|
@ -288,11 +288,11 @@ int main()
|
||||||
PolyhedralSurf P;
|
PolyhedralSurf P;
|
||||||
CGAL::read_OFF(if_name.c_str(), P);
|
CGAL::read_OFF(if_name.c_str(), P);
|
||||||
fprintf(stderr, "loadMesh %d Ves %d Facets\n",
|
fprintf(stderr, "loadMesh %d Ves %d Facets\n",
|
||||||
(int)num_vertices(P), (int)num_faces(P));
|
(int)num_vertices(P), (int)num_faces(P));
|
||||||
if(verbose)
|
if(verbose)
|
||||||
out_verb << "Polysurf with " << num_vertices(P)
|
out_verb << "Polysurf with " << num_vertices(P)
|
||||||
<< " vertices and " << num_faces(P)
|
<< " vertices and " << num_faces(P)
|
||||||
<< " facets. " << std::endl;
|
<< " facets. " << std::endl;
|
||||||
|
|
||||||
//exit if not enough points in the model
|
//exit if not enough points in the model
|
||||||
if (min_nb_points > num_vertices(P))
|
if (min_nb_points > num_vertices(P))
|
||||||
|
|
@ -313,10 +313,10 @@ int main()
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
std::cout << "Compute ridges..." << std::endl;
|
std::cout << "Compute ridges..." << std::endl;
|
||||||
Ridge_approximation ridge_approximation(P,
|
Ridge_approximation ridge_approximation(P,
|
||||||
vertex_k1_pm, vertex_k2_pm,
|
vertex_k1_pm, vertex_k2_pm,
|
||||||
vertex_b0_pm, vertex_b3_pm,
|
vertex_b0_pm, vertex_b3_pm,
|
||||||
vertex_d1_pm, vertex_d2_pm,
|
vertex_d1_pm, vertex_d2_pm,
|
||||||
vertex_P1_pm, vertex_P2_pm );
|
vertex_P1_pm, vertex_P2_pm );
|
||||||
std::vector<Ridge_line*> ridge_lines;
|
std::vector<Ridge_line*> ridge_lines;
|
||||||
std::back_insert_iterator<std::vector<Ridge_line*> > ii(ridge_lines);
|
std::back_insert_iterator<std::vector<Ridge_line*> > ii(ridge_lines);
|
||||||
|
|
||||||
|
|
@ -327,11 +327,11 @@ int main()
|
||||||
|
|
||||||
// or with the global function
|
// or with the global function
|
||||||
CGAL::compute_max_ridges(P,
|
CGAL::compute_max_ridges(P,
|
||||||
vertex_k1_pm, vertex_k2_pm,
|
vertex_k1_pm, vertex_k2_pm,
|
||||||
vertex_b0_pm, vertex_b3_pm,
|
vertex_b0_pm, vertex_b3_pm,
|
||||||
vertex_d1_pm, vertex_d2_pm,
|
vertex_d1_pm, vertex_d2_pm,
|
||||||
vertex_P1_pm, vertex_P2_pm,
|
vertex_P1_pm, vertex_P2_pm,
|
||||||
ii, tag_order);
|
ii, tag_order);
|
||||||
|
|
||||||
std::vector<Ridge_line*>::iterator iter_lines = ridge_lines.begin(),
|
std::vector<Ridge_line*>::iterator iter_lines = ridge_lines.begin(),
|
||||||
iter_end = ridge_lines.end();
|
iter_end = ridge_lines.end();
|
||||||
|
|
@ -360,14 +360,14 @@ int main()
|
||||||
|
|
||||||
//explicit construction of the class
|
//explicit construction of the class
|
||||||
// Umbilic_approximation umbilic_approximation(P,
|
// Umbilic_approximation umbilic_approximation(P,
|
||||||
// vertex_k1_pm, vertex_k2_pm,
|
// vertex_k1_pm, vertex_k2_pm,
|
||||||
// vertex_d1_pm, vertex_d2_pm);
|
// vertex_d1_pm, vertex_d2_pm);
|
||||||
// umbilic_approximation.compute(umb_it, umb_size);
|
// umbilic_approximation.compute(umb_it, umb_size);
|
||||||
//or global function call
|
//or global function call
|
||||||
CGAL::compute_umbilics(P,
|
CGAL::compute_umbilics(P,
|
||||||
vertex_k1_pm, vertex_k2_pm,
|
vertex_k1_pm, vertex_k2_pm,
|
||||||
vertex_d1_pm, vertex_d2_pm,
|
vertex_d1_pm, vertex_d2_pm,
|
||||||
umb_it, umb_size);
|
umb_it, umb_size);
|
||||||
|
|
||||||
std::vector<Umbilic*>::iterator iter_umb = umbilics.begin(),
|
std::vector<Umbilic*>::iterator iter_umb = umbilics.begin(),
|
||||||
iter_umb_end = umbilics.end();
|
iter_umb_end = umbilics.end();
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ if ( CGAL_FOUND )
|
||||||
|
|
||||||
message(STATUS "This project requires the Boost library, and will not be compiled.")
|
message(STATUS "This project requires the Boost library, and will not be compiled.")
|
||||||
|
|
||||||
return()
|
return()
|
||||||
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
@ -37,10 +37,10 @@ if ( CGAL_FOUND )
|
||||||
create_single_source_cgal_program( "off_bbox.cpp" )
|
create_single_source_cgal_program( "off_bbox.cpp" )
|
||||||
create_single_source_cgal_program( "off_glue.cpp" )
|
create_single_source_cgal_program( "off_glue.cpp" )
|
||||||
create_single_source_cgal_program( "off_transform.cpp" )
|
create_single_source_cgal_program( "off_transform.cpp" )
|
||||||
|
|
||||||
else ()
|
else ()
|
||||||
message(STATUS "This project requires the CGAL library, and will not be compiled.")
|
message(STATUS "This project requires the CGAL library, and will not be compiled.")
|
||||||
return()
|
return()
|
||||||
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
typedef CGAL::Point_2<Kernel> Point;
|
typedef CGAL::Point_2<Kernel> Point;
|
||||||
typedef std::vector<Point> MultiPoint;
|
typedef std::vector<Point> MultiPoint;
|
||||||
|
|
||||||
std::ifstream is((argc>1)?argv[1]:"data/multipoint.wkt");
|
std::ifstream is((argc>1)?argv[1]:"data/multipoint.wkt");
|
||||||
MultiPoint mp;
|
MultiPoint mp;
|
||||||
CGAL::read_multi_point_WKT(is, mp);
|
CGAL::read_multi_point_WKT(is, mp);
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ int main(int argc, char* argv[])
|
||||||
for(Polygon p : polys)
|
for(Polygon p : polys)
|
||||||
std::cout<<p<<std::endl;
|
std::cout<<p<<std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
std::ifstream is((argc>2)?argv[2]:"data/multipolygon.wkt");
|
std::ifstream is((argc>2)?argv[2]:"data/multipolygon.wkt");
|
||||||
MultiPolygon mp;
|
MultiPolygon mp;
|
||||||
|
|
|
||||||
|
|
@ -258,7 +258,7 @@ int main( int argc, char **argv) {
|
||||||
}
|
}
|
||||||
if ( !*p_in) {
|
if ( !*p_in) {
|
||||||
cerr << argv[0] << ": error: cannot open file '"<< iname
|
cerr << argv[0] << ": error: cannot open file '"<< iname
|
||||||
<< "' for reading." <<endl;
|
<< "' for reading." <<endl;
|
||||||
exit( 1);
|
exit( 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,10 +19,10 @@ int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
typedef CGAL::Point_2<Kernel> Point;
|
typedef CGAL::Point_2<Kernel> Point;
|
||||||
typedef std::vector<Point> MultiPoint;
|
typedef std::vector<Point> MultiPoint;
|
||||||
|
|
||||||
typedef std::vector<Point> LineString;
|
typedef std::vector<Point> LineString;
|
||||||
typedef std::vector<LineString> MultiLineString;
|
typedef std::vector<LineString> MultiLineString;
|
||||||
|
|
||||||
typedef CGAL::Polygon_with_holes_2<Kernel> Polygon;
|
typedef CGAL::Polygon_with_holes_2<Kernel> Polygon;
|
||||||
typedef std::vector<Polygon> MultiPolygon;
|
typedef std::vector<Polygon> MultiPolygon;
|
||||||
|
|
||||||
|
|
@ -32,7 +32,7 @@ int main(int argc, char* argv[])
|
||||||
MultiLineString polylines;
|
MultiLineString polylines;
|
||||||
MultiPolygon polygons;
|
MultiPolygon polygons;
|
||||||
CGAL::read_WKT(is, points,polylines,polygons);
|
CGAL::read_WKT(is, points,polylines,polygons);
|
||||||
|
|
||||||
for(Point p : points)
|
for(Point p : points)
|
||||||
std::cout<<p<<std::endl;
|
std::cout<<p<<std::endl;
|
||||||
for(LineString ls : polylines)
|
for(LineString ls : polylines)
|
||||||
|
|
@ -40,7 +40,7 @@ int main(int argc, char* argv[])
|
||||||
std::cout<<p<<std::endl;
|
std::cout<<p<<std::endl;
|
||||||
for(Polygon p : polygons)
|
for(Polygon p : polygons)
|
||||||
std::cout<<p<<std::endl;
|
std::cout<<p<<std::endl;
|
||||||
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,11 +18,11 @@ int main(int argc, char* argv[])
|
||||||
std::vector<Point_3> points;
|
std::vector<Point_3> points;
|
||||||
|
|
||||||
for(boost::property_tree::ptree::value_type& node : tree.get_child("PolySet.Polygon")){
|
for(boost::property_tree::ptree::value_type& node : tree.get_child("PolySet.Polygon")){
|
||||||
boost::property_tree::ptree subtree = node.second;
|
boost::property_tree::ptree subtree = node.second;
|
||||||
if( node.first == "Point" ){
|
if( node.first == "Point" ){
|
||||||
for( boost::property_tree::ptree::value_type const& v : subtree.get_child( "" ) ) {
|
for( boost::property_tree::ptree::value_type const& v : subtree.get_child( "" ) ) {
|
||||||
std::string label = v.first;
|
std::string label = v.first;
|
||||||
|
|
||||||
if ( label == "<xmlattr>" ) {
|
if ( label == "<xmlattr>" ) {
|
||||||
Point_3 p(subtree.get<double>( label+".X"),
|
Point_3 p(subtree.get<double>( label+".X"),
|
||||||
subtree.get<double>( label+".Y"),
|
subtree.get<double>( label+".Y"),
|
||||||
|
|
@ -31,7 +31,7 @@ int main(int argc, char* argv[])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << points.size() << " points read"<< std::endl;
|
std::cout << points.size() << " points read"<< std::endl;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,16 @@
|
||||||
// Copyright (c) 1997
|
// Copyright (c) 1997
|
||||||
// Utrecht University (The Netherlands),
|
// Utrecht University (The Netherlands),
|
||||||
// ETH Zurich (Switzerland),
|
// ETH Zurich (Switzerland),
|
||||||
// INRIA Sophia-Antipolis (France),
|
// INRIA Sophia-Antipolis (France),
|
||||||
// Max-Planck-Institute Saarbruecken (Germany),
|
// Max-Planck-Institute Saarbruecken (Germany),
|
||||||
// and Tel-Aviv University (Israel). All rights reserved.
|
// and Tel-Aviv University (Israel). All rights reserved.
|
||||||
//
|
//
|
||||||
// This file is part of CGAL (www.cgal.org)
|
// This file is part of CGAL (www.cgal.org)
|
||||||
//
|
//
|
||||||
// $URL$
|
// $URL$
|
||||||
// $Id$
|
// $Id$
|
||||||
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Author(s) : Lutz Kettner <kettner@inf.ethz.ch>
|
// Author(s) : Lutz Kettner <kettner@inf.ethz.ch>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,16 @@
|
||||||
// Copyright (c) 1997
|
// Copyright (c) 1997
|
||||||
// Utrecht University (The Netherlands),
|
// Utrecht University (The Netherlands),
|
||||||
// ETH Zurich (Switzerland),
|
// ETH Zurich (Switzerland),
|
||||||
// INRIA Sophia-Antipolis (France),
|
// INRIA Sophia-Antipolis (France),
|
||||||
// Max-Planck-Institute Saarbruecken (Germany),
|
// Max-Planck-Institute Saarbruecken (Germany),
|
||||||
// and Tel-Aviv University (Israel). All rights reserved.
|
// and Tel-Aviv University (Israel). All rights reserved.
|
||||||
//
|
//
|
||||||
// This file is part of CGAL (www.cgal.org);
|
// This file is part of CGAL (www.cgal.org);
|
||||||
//
|
//
|
||||||
// $URL$
|
// $URL$
|
||||||
// $Id$
|
// $Id$
|
||||||
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Author(s) : Lutz Kettner <kettner@mpi-sb.mpg.de>
|
// Author(s) : Lutz Kettner <kettner@mpi-sb.mpg.de>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,16 @@
|
||||||
// Copyright (c) 1997
|
// Copyright (c) 1997
|
||||||
// Utrecht University (The Netherlands),
|
// Utrecht University (The Netherlands),
|
||||||
// ETH Zurich (Switzerland),
|
// ETH Zurich (Switzerland),
|
||||||
// INRIA Sophia-Antipolis (France),
|
// INRIA Sophia-Antipolis (France),
|
||||||
// Max-Planck-Institute Saarbruecken (Germany),
|
// Max-Planck-Institute Saarbruecken (Germany),
|
||||||
// and Tel-Aviv University (Israel). All rights reserved.
|
// and Tel-Aviv University (Israel). All rights reserved.
|
||||||
//
|
//
|
||||||
// This file is part of CGAL (www.cgal.org)
|
// This file is part of CGAL (www.cgal.org)
|
||||||
//
|
//
|
||||||
// $URL$
|
// $URL$
|
||||||
// $Id$
|
// $Id$
|
||||||
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Author(s) : Lutz Kettner <kettner@mpi-sb.mpg.de>
|
// Author(s) : Lutz Kettner <kettner@mpi-sb.mpg.de>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,16 @@
|
||||||
// Copyright (c) 1997,2005
|
// Copyright (c) 1997,2005
|
||||||
// Utrecht University (The Netherlands),
|
// Utrecht University (The Netherlands),
|
||||||
// ETH Zurich (Switzerland),
|
// ETH Zurich (Switzerland),
|
||||||
// INRIA Sophia-Antipolis (France),
|
// INRIA Sophia-Antipolis (France),
|
||||||
// Max-Planck-Institute Saarbruecken (Germany),
|
// Max-Planck-Institute Saarbruecken (Germany),
|
||||||
// and Tel-Aviv University (Israel). All rights reserved.
|
// and Tel-Aviv University (Israel). All rights reserved.
|
||||||
//
|
//
|
||||||
// This file is part of CGAL (www.cgal.org)
|
// This file is part of CGAL (www.cgal.org)
|
||||||
//
|
//
|
||||||
// $URL$
|
// $URL$
|
||||||
// $Id$
|
// $Id$
|
||||||
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Author(s) : Lutz Kettner <kettner@mpi-sb.mpg.de>
|
// Author(s) : Lutz Kettner <kettner@mpi-sb.mpg.de>
|
||||||
// Ralf Osbild <osbild@mpi-sb.mpg.de>
|
// Ralf Osbild <osbild@mpi-sb.mpg.de>
|
||||||
|
|
@ -101,7 +101,7 @@ private:
|
||||||
File_scanner_OFF* m_scan;
|
File_scanner_OFF* m_scan;
|
||||||
std::size_t m_cnt;
|
std::size_t m_cnt;
|
||||||
value_type m_current;
|
value_type m_current;
|
||||||
|
|
||||||
|
|
||||||
void next() {
|
void next() {
|
||||||
CGAL_assertion( m_scan != nullptr);
|
CGAL_assertion( m_scan != nullptr);
|
||||||
|
|
@ -162,7 +162,7 @@ private:
|
||||||
std::size_t no;
|
std::size_t no;
|
||||||
m_scan->scan_facet( no, m_cnt);
|
m_scan->scan_facet( no, m_cnt);
|
||||||
m_indices.reserve( no);
|
m_indices.reserve( no);
|
||||||
std::size_t index = (std::numeric_limits<std::size_t>::max)();
|
std::size_t index = (std::numeric_limits<std::size_t>::max)();
|
||||||
// A huge value helps to detect a potential
|
// A huge value helps to detect a potential
|
||||||
// error in the function scan_facet_vertex_index
|
// error in the function scan_facet_vertex_index
|
||||||
for (std::size_t i = 0; i < no; ++i) {
|
for (std::size_t i = 0; i < no; ++i) {
|
||||||
|
|
@ -177,7 +177,7 @@ private:
|
||||||
public:
|
public:
|
||||||
value_type::size_type size_of_indices () const // RO
|
value_type::size_type size_of_indices () const // RO
|
||||||
{ return m_indices.size(); }
|
{ return m_indices.size(); }
|
||||||
typedef value_type::size_type indices_size_type; // RO
|
typedef value_type::size_type indices_size_type; // RO
|
||||||
public:
|
public:
|
||||||
typedef File_scanner_OFF Scanner;
|
typedef File_scanner_OFF Scanner;
|
||||||
typedef I_Scanner_OFF_facet_iterator Self;
|
typedef I_Scanner_OFF_facet_iterator Self;
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,16 @@
|
||||||
// Copyright (c) 1997
|
// Copyright (c) 1997
|
||||||
// Utrecht University (The Netherlands),
|
// Utrecht University (The Netherlands),
|
||||||
// ETH Zurich (Switzerland),
|
// ETH Zurich (Switzerland),
|
||||||
// INRIA Sophia-Antipolis (France),
|
// INRIA Sophia-Antipolis (France),
|
||||||
// Max-Planck-Institute Saarbruecken (Germany),
|
// Max-Planck-Institute Saarbruecken (Germany),
|
||||||
// and Tel-Aviv University (Israel). All rights reserved.
|
// and Tel-Aviv University (Israel). All rights reserved.
|
||||||
//
|
//
|
||||||
// This file is part of CGAL (www.cgal.org);
|
// This file is part of CGAL (www.cgal.org);
|
||||||
//
|
//
|
||||||
// $URL$
|
// $URL$
|
||||||
// $Id$
|
// $Id$
|
||||||
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Author(s) : Lutz Kettner <kettner@mpi-sb.mpg.de>
|
// Author(s) : Lutz Kettner <kettner@mpi-sb.mpg.de>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,16 @@
|
||||||
// Copyright (c) 1997
|
// Copyright (c) 1997
|
||||||
// Utrecht University (The Netherlands),
|
// Utrecht University (The Netherlands),
|
||||||
// ETH Zurich (Switzerland),
|
// ETH Zurich (Switzerland),
|
||||||
// INRIA Sophia-Antipolis (France),
|
// INRIA Sophia-Antipolis (France),
|
||||||
// Max-Planck-Institute Saarbruecken (Germany),
|
// Max-Planck-Institute Saarbruecken (Germany),
|
||||||
// and Tel-Aviv University (Israel). All rights reserved.
|
// and Tel-Aviv University (Israel). All rights reserved.
|
||||||
//
|
//
|
||||||
// This file is part of CGAL (www.cgal.org)
|
// This file is part of CGAL (www.cgal.org)
|
||||||
//
|
//
|
||||||
// $URL$
|
// $URL$
|
||||||
// $Id$
|
// $Id$
|
||||||
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Author(s) : Lutz Kettner <kettner@mpi-sb.mpg.de>
|
// Author(s) : Lutz Kettner <kettner@mpi-sb.mpg.de>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
// Copyright (c) 1997
|
// Copyright (c) 1997
|
||||||
// Utrecht University (The Netherlands),
|
// Utrecht University (The Netherlands),
|
||||||
// ETH Zurich (Switzerland),
|
// ETH Zurich (Switzerland),
|
||||||
// INRIA Sophia-Antipolis (France),
|
// INRIA Sophia-Antipolis (France),
|
||||||
// Max-Planck-Institute Saarbruecken (Germany),
|
// Max-Planck-Institute Saarbruecken (Germany),
|
||||||
// and Tel-Aviv University (Israel). All rights reserved.
|
// and Tel-Aviv University (Israel). All rights reserved.
|
||||||
//
|
//
|
||||||
// This file is part of CGAL (www.cgal.org);
|
// This file is part of CGAL (www.cgal.org);
|
||||||
//
|
//
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,16 @@
|
||||||
// Copyright (c) 1997
|
// Copyright (c) 1997
|
||||||
// Utrecht University (The Netherlands),
|
// Utrecht University (The Netherlands),
|
||||||
// ETH Zurich (Switzerland),
|
// ETH Zurich (Switzerland),
|
||||||
// INRIA Sophia-Antipolis (France),
|
// INRIA Sophia-Antipolis (France),
|
||||||
// Max-Planck-Institute Saarbruecken (Germany),
|
// Max-Planck-Institute Saarbruecken (Germany),
|
||||||
// and Tel-Aviv University (Israel). All rights reserved.
|
// and Tel-Aviv University (Israel). All rights reserved.
|
||||||
//
|
//
|
||||||
// This file is part of CGAL (www.cgal.org)
|
// This file is part of CGAL (www.cgal.org)
|
||||||
//
|
//
|
||||||
// $URL$
|
// $URL$
|
||||||
// $Id$
|
// $Id$
|
||||||
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Author(s) : Lutz Kettner <kettner@inf.ethz.ch>
|
// Author(s) : Lutz Kettner <kettner@inf.ethz.ch>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,16 @@
|
||||||
// Copyright (c) 1997
|
// Copyright (c) 1997
|
||||||
// Utrecht University (The Netherlands),
|
// Utrecht University (The Netherlands),
|
||||||
// ETH Zurich (Switzerland),
|
// ETH Zurich (Switzerland),
|
||||||
// INRIA Sophia-Antipolis (France),
|
// INRIA Sophia-Antipolis (France),
|
||||||
// Max-Planck-Institute Saarbruecken (Germany),
|
// Max-Planck-Institute Saarbruecken (Germany),
|
||||||
// and Tel-Aviv University (Israel). All rights reserved.
|
// and Tel-Aviv University (Israel). All rights reserved.
|
||||||
//
|
//
|
||||||
// This file is part of CGAL (www.cgal.org)
|
// This file is part of CGAL (www.cgal.org)
|
||||||
//
|
//
|
||||||
// $URL$
|
// $URL$
|
||||||
// $Id$
|
// $Id$
|
||||||
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Author(s) : Lutz Kettner <kettner@mpi-sb.mpg.de>
|
// Author(s) : Lutz Kettner <kettner@mpi-sb.mpg.de>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,16 @@
|
||||||
// Copyright (c) 1997
|
// Copyright (c) 1997
|
||||||
// Utrecht University (The Netherlands),
|
// Utrecht University (The Netherlands),
|
||||||
// ETH Zurich (Switzerland),
|
// ETH Zurich (Switzerland),
|
||||||
// INRIA Sophia-Antipolis (France),
|
// INRIA Sophia-Antipolis (France),
|
||||||
// Max-Planck-Institute Saarbruecken (Germany),
|
// Max-Planck-Institute Saarbruecken (Germany),
|
||||||
// and Tel-Aviv University (Israel). All rights reserved.
|
// and Tel-Aviv University (Israel). All rights reserved.
|
||||||
//
|
//
|
||||||
// This file is part of CGAL (www.cgal.org)
|
// This file is part of CGAL (www.cgal.org)
|
||||||
//
|
//
|
||||||
// $URL$
|
// $URL$
|
||||||
// $Id$
|
// $Id$
|
||||||
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Author(s) : Lutz Kettner <kettner@mpi-sb.mpg.de>
|
// Author(s) : Lutz Kettner <kettner@mpi-sb.mpg.de>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ typedef CGAL::Tetrahedron_3<Kernel> Tetrahedron;
|
||||||
typedef CGAL::Sphere_3<Kernel> Sphere;
|
typedef CGAL::Sphere_3<Kernel> Sphere;
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
Point p1(10, 15, 0), p2(0, 0, 0),
|
Point p1(10, 15, 0), p2(0, 0, 0),
|
||||||
p3(-10, 0, -15), p4(15, 15, 15);
|
p3(-10, 0, -15), p4(15, 15, 15);
|
||||||
Segment s1(p1, p2);
|
Segment s1(p1, p2);
|
||||||
Triangle t1(p1, p2, p3);
|
Triangle t1(p1, p2, p3);
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ namespace CGAL {
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
|
|
||||||
\mainpage User Manual
|
\mainpage User Manual
|
||||||
\anchor Chapter_3D_Surface_mesh
|
\anchor Chapter_3D_Surface_mesh
|
||||||
\anchor chapterSurface_mesh
|
\anchor chapterSurface_mesh
|
||||||
|
|
||||||
|
|
@ -11,8 +11,8 @@ namespace CGAL {
|
||||||
|
|
||||||
\image html clown_fish.jpg
|
\image html clown_fish.jpg
|
||||||
|
|
||||||
The class `Surface_mesh` is an implementation of a halfedge data structure
|
The class `Surface_mesh` is an implementation of a halfedge data structure
|
||||||
and can be used to represent a polyhedral surface.
|
and can be used to represent a polyhedral surface.
|
||||||
It is an alternative to the \cgal packages \ref PkgHalfedgeDS
|
It is an alternative to the \cgal packages \ref PkgHalfedgeDS
|
||||||
and \ref PkgPolyhedron.
|
and \ref PkgPolyhedron.
|
||||||
The main difference is that it is indexed based and not pointer based.
|
The main difference is that it is indexed based and not pointer based.
|
||||||
|
|
@ -26,12 +26,12 @@ As the indices are contiguous, they can be used as index into vectors
|
||||||
which store properties.
|
which store properties.
|
||||||
|
|
||||||
When elements are removed, they are only marked as removed, and a garbage
|
When elements are removed, they are only marked as removed, and a garbage
|
||||||
collection function must be called to really remove them.
|
collection function must be called to really remove them.
|
||||||
|
|
||||||
The class `Surface_mesh` can be used through its class member functions
|
The class `Surface_mesh` can be used through its class member functions
|
||||||
as well as through the BGL API as described in the package \ref PkgBGL,
|
as well as through the BGL API as described in the package \ref PkgBGL,
|
||||||
as it is a model of the concepts `MutableFaceGraph` and `FaceListGraph`.
|
as it is a model of the concepts `MutableFaceGraph` and `FaceListGraph`.
|
||||||
Therefore it is possible to apply the algorithms of the packages
|
Therefore it is possible to apply the algorithms of the packages
|
||||||
\ref PkgSurfaceMeshSimplification,
|
\ref PkgSurfaceMeshSimplification,
|
||||||
\ref PkgSurfaceMeshSegmentation, and \ref PkgSurfaceMeshDeformation on a surface mesh.
|
\ref PkgSurfaceMeshSegmentation, and \ref PkgSurfaceMeshDeformation on a surface mesh.
|
||||||
|
|
||||||
|
|
@ -47,7 +47,7 @@ represent the basic elements of the halfedge data structure:
|
||||||
- `Surface_mesh::Edge_index`
|
- `Surface_mesh::Edge_index`
|
||||||
|
|
||||||
These types are just wrappers for an integer and their
|
These types are just wrappers for an integer and their
|
||||||
main purpose is to guarantee type safety.
|
main purpose is to guarantee type safety.
|
||||||
They are default constructible, which yields an *invalid* element. New
|
They are default constructible, which yields an *invalid* element. New
|
||||||
elements can be added and removed to the `Surface_mesh` through a
|
elements can be added and removed to the `Surface_mesh` through a
|
||||||
set of low-level functions which do not maintain connectivity. One
|
set of low-level functions which do not maintain connectivity. One
|
||||||
|
|
@ -82,7 +82,7 @@ by adding 2 faces, and how to check that a face is correctly added
|
||||||
to the mesh.
|
to the mesh.
|
||||||
|
|
||||||
\cgalExample{Surface_mesh/check_orientation.cpp}
|
\cgalExample{Surface_mesh/check_orientation.cpp}
|
||||||
\section sectionSurfaceMeshConnectivity Connectivity
|
\section sectionSurfaceMeshConnectivity Connectivity
|
||||||
|
|
||||||
A surface mesh is an edge-centered data structure capable of
|
A surface mesh is an edge-centered data structure capable of
|
||||||
maintaining incidence information of vertices, edges, and faces. Each
|
maintaining incidence information of vertices, edges, and faces. Each
|
||||||
|
|
@ -94,9 +94,9 @@ an incident halfedge is stored. Halfedges do not store the index of
|
||||||
the opposite halfedge, as `Surface_mesh` stores opposite halfedges consecutively
|
the opposite halfedge, as `Surface_mesh` stores opposite halfedges consecutively
|
||||||
in memory.
|
in memory.
|
||||||
|
|
||||||
The following figure illustrates the functions which allow to navigate
|
The following figure illustrates the functions which allow to navigate
|
||||||
in a surface mesh: `Surface_mesh::opposite()`, `Surface_mesh::next()`,
|
in a surface mesh: `Surface_mesh::opposite()`, `Surface_mesh::next()`,
|
||||||
`Surface_mesh::prev()`, `Surface_mesh::target()`, and
|
`Surface_mesh::prev()`, `Surface_mesh::target()`, and
|
||||||
`Surface_mesh::face()`. Additionally, the
|
`Surface_mesh::face()`. Additionally, the
|
||||||
functions `Surface_mesh::halfedge()` allows to obtain the halfedge
|
functions `Surface_mesh::halfedge()` allows to obtain the halfedge
|
||||||
associated to a vertex and to a face.
|
associated to a vertex and to a face.
|
||||||
|
|
@ -106,7 +106,7 @@ defined in the package \ref PkgBGL.
|
||||||
\cgalFigureBegin{FigSurfaceMeshConnectivity,connectivity.svg}
|
\cgalFigureBegin{FigSurfaceMeshConnectivity,connectivity.svg}
|
||||||
Connectivity of halfedges and vertices in a surface mesh seen from outside.
|
Connectivity of halfedges and vertices in a surface mesh seen from outside.
|
||||||
\cgalFigureEnd
|
\cgalFigureEnd
|
||||||
|
|
||||||
\anchor SurfaceMeshOrientation
|
\anchor SurfaceMeshOrientation
|
||||||
The halfedges incident to a face form a cycle. Depending on from
|
The halfedges incident to a face form a cycle. Depending on from
|
||||||
which side we look at the surface, the sequence of
|
which side we look at the surface, the sequence of
|
||||||
|
|
@ -124,11 +124,11 @@ The connectivity does not allow to represent faces with holes.
|
||||||
halfedges, edges, and faces. It provides member functions
|
halfedges, edges, and faces. It provides member functions
|
||||||
returning ranges of elements which are compatible with the
|
returning ranges of elements which are compatible with the
|
||||||
<a href="https://www.boost.org/libs/range/doc/html/index.html">Boost.Range</a>
|
<a href="https://www.boost.org/libs/range/doc/html/index.html">Boost.Range</a>
|
||||||
library.
|
library.
|
||||||
|
|
||||||
\subsection iterators_example Example
|
\subsection iterators_example Example
|
||||||
|
|
||||||
The following example shows how to obtain the iterator type from
|
The following example shows how to obtain the iterator type from
|
||||||
a range, alternatives for obtaining the begin and end iterator,
|
a range, alternatives for obtaining the begin and end iterator,
|
||||||
and alternatives for range-based loops.
|
and alternatives for range-based loops.
|
||||||
|
|
||||||
|
|
@ -137,11 +137,11 @@ and alternatives for range-based loops.
|
||||||
|
|
||||||
\section sectionSurfaceMesh_circulators Circulators
|
\section sectionSurfaceMesh_circulators Circulators
|
||||||
|
|
||||||
Circulators around faces and around vertices are provided as class templates
|
Circulators around faces and around vertices are provided as class templates
|
||||||
in the package \ref PkgBGL.
|
in the package \ref PkgBGL.
|
||||||
|
|
||||||
Circulators around faces basically call `Surface_mesh::next()`
|
Circulators around faces basically call `Surface_mesh::next()`
|
||||||
in order to go from halfedge to halfedge counterclockwise around the face, and
|
in order to go from halfedge to halfedge counterclockwise around the face, and
|
||||||
when dereferenced return the halfedge or the incident vertex or the opposite face.
|
when dereferenced return the halfedge or the incident vertex or the opposite face.
|
||||||
|
|
||||||
- `CGAL::Halfedge_around_face_circulator<Mesh>`
|
- `CGAL::Halfedge_around_face_circulator<Mesh>`
|
||||||
|
|
@ -164,7 +164,7 @@ of emptiness.
|
||||||
\subsection circulators_example Example
|
\subsection circulators_example Example
|
||||||
|
|
||||||
The following example shows how to enumerate the vertices around the
|
The following example shows how to enumerate the vertices around the
|
||||||
target of a given halfedge. The second loop shows that each of
|
target of a given halfedge. The second loop shows that each of
|
||||||
these circulator types comes with an equivalent iterator and a free
|
these circulator types comes with an equivalent iterator and a free
|
||||||
function to create an iterator range.
|
function to create an iterator range.
|
||||||
|
|
||||||
|
|
@ -191,42 +191,42 @@ directly accessed using `Surface_mesh::points()` or
|
||||||
When an element is removed, it is only marked as removed, and
|
When an element is removed, it is only marked as removed, and
|
||||||
it gets really removed when `Surface_mesh::collect_garbage()` is called.
|
it gets really removed when `Surface_mesh::collect_garbage()` is called.
|
||||||
Garbage collection will also really remove the properties
|
Garbage collection will also really remove the properties
|
||||||
of these elements.
|
of these elements.
|
||||||
|
|
||||||
The connectivity is also stored in properties, namely the properties named
|
The connectivity is also stored in properties, namely the properties named
|
||||||
"v:connectivity", "h:connectivity", and "f:connectivity".
|
"v:connectivity", "h:connectivity", and "f:connectivity".
|
||||||
It is quite similar for the marker of deleted element, where we have
|
It is quite similar for the marker of deleted element, where we have
|
||||||
"v:removed", "e:removed", and "f:removed".
|
"v:removed", "e:removed", and "f:removed".
|
||||||
|
|
||||||
\subsection properties_example Example
|
\subsection properties_example Example
|
||||||
|
|
||||||
This example shows how to use the most common features of the property system.
|
This example shows how to use the most common features of the property system.
|
||||||
|
|
||||||
\cgalExample{Surface_mesh/sm_properties.cpp}
|
\cgalExample{Surface_mesh/sm_properties.cpp}
|
||||||
|
|
||||||
\section sectionSurfaceMesh_borders Borders
|
\section sectionSurfaceMesh_borders Borders
|
||||||
|
|
||||||
A halfedge stores a reference to a face, its incident face.
|
A halfedge stores a reference to a face, its incident face.
|
||||||
A halfedge `h` is on the border, if it has no incident face, that is if
|
A halfedge `h` is on the border, if it has no incident face, that is if
|
||||||
`sm.face(h) == Surface_mesh::null_face()`. An edge is on the border,
|
`sm.face(h) == Surface_mesh::null_face()`. An edge is on the border,
|
||||||
if any of its halfedges is on the border. A vertex is on the border,
|
if any of its halfedges is on the border. A vertex is on the border,
|
||||||
if any of its incident halfedges is on the border.
|
if any of its incident halfedges is on the border.
|
||||||
|
|
||||||
A vertex has only one associated halfedge. If the user takes care that the
|
A vertex has only one associated halfedge. If the user takes care that the
|
||||||
associated halfedge is a border halfedge, in case the vertex is on the
|
associated halfedge is a border halfedge, in case the vertex is on the
|
||||||
border, there is no need to look at all incident halfedges in the
|
border, there is no need to look at all incident halfedges in the
|
||||||
`is_border()` function for vertices.
|
`is_border()` function for vertices.
|
||||||
In order to only check if the associated halfedge is on the border
|
In order to only check if the associated halfedge is on the border
|
||||||
the function
|
the function
|
||||||
`Surface_mesh::is_border(Vertex_index v, bool check_all_incident_halfedges = true)`
|
`Surface_mesh::is_border(Vertex_index v, bool check_all_incident_halfedges = true)`
|
||||||
must be called with `check_all_incident_halfedges = false`.
|
must be called with `check_all_incident_halfedges = false`.
|
||||||
|
|
||||||
The user is in charge to correctly set the halfedge
|
The user is in charge to correctly set the halfedge
|
||||||
associated to a vertex after having applied an operation that might invalidate
|
associated to a vertex after having applied an operation that might invalidate
|
||||||
this property.
|
this property.
|
||||||
The functions `Surface_mesh::set_vertex_halfedge_to_border_halfedge(Vertex_index v)`,
|
The functions `Surface_mesh::set_vertex_halfedge_to_border_halfedge(Vertex_index v)`,
|
||||||
`Surface_mesh::set_vertex_halfedge_to_border_halfedge(Halfedge_index h)`, and
|
`Surface_mesh::set_vertex_halfedge_to_border_halfedge(Halfedge_index h)`, and
|
||||||
`Surface_mesh::set_vertex_halfedge_to_border_halfedge()` enable to set the border
|
`Surface_mesh::set_vertex_halfedge_to_border_halfedge()` enable to set the border
|
||||||
halfedge for a single vertex `v`, for all vertices on the boundary of the
|
halfedge for a single vertex `v`, for all vertices on the boundary of the
|
||||||
face of `h`, and for all vertices of the surface mesh, respectively.
|
face of `h`, and for all vertices of the surface mesh, respectively.
|
||||||
|
|
||||||
|
|
@ -235,7 +235,7 @@ face of `h`, and for all vertices of the surface mesh, respectively.
|
||||||
|
|
||||||
The class `Surface_mesh` is a model of the concept `IncidenceGraph`
|
The class `Surface_mesh` is a model of the concept `IncidenceGraph`
|
||||||
defined in the Boost Graph Library. This enables to apply algorithms such
|
defined in the Boost Graph Library. This enables to apply algorithms such
|
||||||
as
|
as
|
||||||
[Dijkstra shortest path](https://www.boost.org/libs/graph/doc/dijkstra_shortest_paths.html), or
|
[Dijkstra shortest path](https://www.boost.org/libs/graph/doc/dijkstra_shortest_paths.html), or
|
||||||
[Kruskal minimum spanning tree](https://www.boost.org/libs/graph/doc/kruskal_min_spanning_tree.html)
|
[Kruskal minimum spanning tree](https://www.boost.org/libs/graph/doc/kruskal_min_spanning_tree.html)
|
||||||
directly on a surface mesh.
|
directly on a surface mesh.
|
||||||
|
|
@ -254,7 +254,7 @@ for example
|
||||||
|
|
||||||
It would be nicer to return the number of vertices without
|
It would be nicer to return the number of vertices without
|
||||||
taking removed vertices into account, but this would interact badly with
|
taking removed vertices into account, but this would interact badly with
|
||||||
the underlying vertex/edge index mappings. The index mapping would no longer
|
the underlying vertex/edge index mappings. The index mapping would no longer
|
||||||
fall in the range `[0,num_vertices(g))` which is assumed in many
|
fall in the range `[0,num_vertices(g))` which is assumed in many
|
||||||
of the algorithms.
|
of the algorithms.
|
||||||
|
|
||||||
|
|
@ -267,9 +267,9 @@ Again, there are similar types and functions, for example:
|
||||||
| BGL | %Surface_mesh |
|
| BGL | %Surface_mesh |
|
||||||
| :---- | :---- |
|
| :---- | :---- |
|
||||||
| `boost::graph_traits<G>::%halfedge_descriptor` | `Surface_mesh::Halfedge_index` |
|
| `boost::graph_traits<G>::%halfedge_descriptor` | `Surface_mesh::Halfedge_index` |
|
||||||
| `boost::graph_traits<G>::%face_descriptor` | `Surface_mesh::Face_index` |
|
| `boost::graph_traits<G>::%face_descriptor` | `Surface_mesh::Face_index` |
|
||||||
| `halfedges(const G& g)` | `sm.halfedges()` |
|
| `halfedges(const G& g)` | `sm.halfedges()` |
|
||||||
| `faces(const G& g)` | `sm.faces()` |
|
| `faces(const G& g)` | `sm.faces()` |
|
||||||
| `hd = next(hd, g)` | `hd = sm.next(hd)` |
|
| `hd = next(hd, g)` | `hd = sm.next(hd)` |
|
||||||
| `hd = prev(hd, g)` | `hd = sm.prev(hd)` |
|
| `hd = prev(hd, g)` | `hd = sm.prev(hd)` |
|
||||||
| `hd = opposite(hd,g)` | `hd = sm.opposite(hd)` |
|
| `hd = opposite(hd,g)` | `hd = sm.opposite(hd)` |
|
||||||
|
|
@ -292,18 +292,18 @@ for storing if a vertex has already been visited during a graph traversal.
|
||||||
|
|
||||||
The BGL way of retrieving the vertex index property map of a graph `g` is
|
The BGL way of retrieving the vertex index property map of a graph `g` is
|
||||||
`vipm = get(boost::vertex_index, g)`, and `get(vipm, vd)` in order then
|
`vipm = get(boost::vertex_index, g)`, and `get(vipm, vd)` in order then
|
||||||
to retrieve the index for a vertex descriptor `vd`, and it is
|
to retrieve the index for a vertex descriptor `vd`, and it is
|
||||||
`get(vertex_index, g, vd)` to obtain the vertex index directly.
|
`get(vertex_index, g, vd)` to obtain the vertex index directly.
|
||||||
|
|
||||||
|
|
||||||
\subsection SubsectionSurfaceMeshBglExample Example
|
\subsection SubsectionSurfaceMeshBglExample Example
|
||||||
|
|
||||||
The first example shows that we can apply Kruskal's
|
The first example shows that we can apply Kruskal's
|
||||||
minimum spanning tree algorithm directly on a surface mesh.
|
minimum spanning tree algorithm directly on a surface mesh.
|
||||||
|
|
||||||
\cgalExample{Surface_mesh/sm_kruskal.cpp}
|
\cgalExample{Surface_mesh/sm_kruskal.cpp}
|
||||||
|
|
||||||
The second example shows how we can use property maps for
|
The second example shows how we can use property maps for
|
||||||
algorithms such as Prim's minimum spanning tree.
|
algorithms such as Prim's minimum spanning tree.
|
||||||
The algorithm internally also uses a <em>vertex index property map</em>
|
The algorithm internally also uses a <em>vertex index property map</em>
|
||||||
calling `get(boost::vertex_index_t,sm)`. For the class `Surface_mesh`
|
calling `get(boost::vertex_index_t,sm)`. For the class `Surface_mesh`
|
||||||
|
|
@ -319,30 +319,30 @@ See the \ref IOstreamPolygonMeshIO section for more info.
|
||||||
|
|
||||||
Memory management is semi-automatic. Memory grows as more elements are
|
Memory management is semi-automatic. Memory grows as more elements are
|
||||||
added to the structure but does not shrink when elements are
|
added to the structure but does not shrink when elements are
|
||||||
removed.
|
removed.
|
||||||
|
|
||||||
When you add elements and the capacity of the underlying vector
|
When you add elements and the capacity of the underlying vector
|
||||||
is exhausted, the vector reallocates memory. As descriptors are
|
is exhausted, the vector reallocates memory. As descriptors are
|
||||||
basically indices, they refer to the same element after a reallocation.
|
basically indices, they refer to the same element after a reallocation.
|
||||||
|
|
||||||
When you remove an element it is only marked as removed.
|
When you remove an element it is only marked as removed.
|
||||||
Internally it is put in a free list, and when you add elements to
|
Internally it is put in a free list, and when you add elements to
|
||||||
the surface mesh, they are taken from the free list in case it is
|
the surface mesh, they are taken from the free list in case it is
|
||||||
not empty.
|
not empty.
|
||||||
|
|
||||||
For all elements we offer a function to obtain the number of
|
For all elements we offer a function to obtain the number of
|
||||||
used elements, as well as the number of used and removed elements.
|
used elements, as well as the number of used and removed elements.
|
||||||
For vertices the functions are `Surface_mesh::number_of_vertices()`
|
For vertices the functions are `Surface_mesh::number_of_vertices()`
|
||||||
and `Surface_mesh::number_of_removed_vertices()`, respectively.
|
and `Surface_mesh::number_of_removed_vertices()`, respectively.
|
||||||
The first function is slightly different from the free function
|
The first function is slightly different from the free function
|
||||||
`num_vertices(const G&)` of the BGL package.
|
`num_vertices(const G&)` of the BGL package.
|
||||||
As BGL style algorithms use the indices of elements
|
As BGL style algorithms use the indices of elements
|
||||||
to access data in temporary vectors of size `num_vertices()`
|
to access data in temporary vectors of size `num_vertices()`
|
||||||
this function must return a number larger than the largest index of
|
this function must return a number larger than the largest index of
|
||||||
the elements.
|
the elements.
|
||||||
|
|
||||||
Iterators such as `Surface_mesh::Vertex_iterator` only enumerate
|
Iterators such as `Surface_mesh::Vertex_iterator` only enumerate
|
||||||
elements that are not marked as deleted.
|
elements that are not marked as deleted.
|
||||||
|
|
||||||
|
|
||||||
To really shrink the used memory, `Surface_mesh::collect_garbage()`
|
To really shrink the used memory, `Surface_mesh::collect_garbage()`
|
||||||
|
|
@ -350,8 +350,8 @@ must be called. Garbage collection also compacts the properties
|
||||||
associated with the surface mesh.
|
associated with the surface mesh.
|
||||||
|
|
||||||
Note however that by garbage collecting elements get new indices.
|
Note however that by garbage collecting elements get new indices.
|
||||||
In case you keep vertex descriptors they are most probably no longer
|
In case you keep vertex descriptors they are most probably no longer
|
||||||
refering to the right vertices.
|
refering to the right vertices.
|
||||||
|
|
||||||
\subsection SubsectionSurfaceMeshMemoryManagementExample Example
|
\subsection SubsectionSurfaceMeshMemoryManagementExample Example
|
||||||
\cgalExample{Surface_mesh/sm_memory.cpp}
|
\cgalExample{Surface_mesh/sm_memory.cpp}
|
||||||
|
|
@ -375,8 +375,8 @@ Result of the run of the draw_surface_mesh program. A window shows the surface m
|
||||||
As integer type for the indices we have chosen `boost::uint32_t`. On 64 bit operating systems they
|
As integer type for the indices we have chosen `boost::uint32_t`. On 64 bit operating systems they
|
||||||
take only half the size of a pointer. They still allow to have meshes with 2 billion elements.
|
take only half the size of a pointer. They still allow to have meshes with 2 billion elements.
|
||||||
|
|
||||||
We use `std::vector` for storing properties. So by accessing the address
|
We use `std::vector` for storing properties. So by accessing the address
|
||||||
of the 0th element of a property map you can access the underlying
|
of the 0th element of a property map you can access the underlying
|
||||||
raw array. This may be useful, for example for passing an array
|
raw array. This may be useful, for example for passing an array
|
||||||
of points to OpenGL.
|
of points to OpenGL.
|
||||||
|
|
||||||
|
|
@ -388,10 +388,10 @@ and when iterating over elements they will not be enumerated in the insertion or
|
||||||
|
|
||||||
\section sectionSurfaceMeshHistory Implementation History
|
\section sectionSurfaceMeshHistory Implementation History
|
||||||
|
|
||||||
This package is derived from an early version of Daniel Sieger and Mario Botsch package
|
This package is derived from an early version of Daniel Sieger and Mario Botsch package
|
||||||
<a href="http://graphics.uni-bielefeld.de/publications/imr11/"><em>%Surface_mesh</em></a>
|
<a href="http://graphics.uni-bielefeld.de/publications/imr11/"><em>%Surface_mesh</em></a>
|
||||||
\cgalCite{sieger2011design},
|
\cgalCite{sieger2011design},
|
||||||
which is inspired from the design of <a href="https://www.openmesh.org/">OpenMesh</a> and the \cgal package
|
which is inspired from the design of <a href="https://www.openmesh.org/">OpenMesh</a> and the \cgal package
|
||||||
\ref PkgPolyhedron.
|
\ref PkgPolyhedron.
|
||||||
|
|
||||||
Philipp Moeller and Andreas Fabri worked on the code so that iterators
|
Philipp Moeller and Andreas Fabri worked on the code so that iterators
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ namespace CGAL {
|
||||||
///
|
///
|
||||||
/// @return `true`, if reading succeeded, `false` otherwise
|
/// @return `true`, if reading succeeded, `false` otherwise
|
||||||
///
|
///
|
||||||
#endif
|
#endif
|
||||||
template <typename K>
|
template <typename K>
|
||||||
bool read_mesh(Surface_mesh<K>& mesh, const std::string& filename)
|
bool read_mesh(Surface_mesh<K>& mesh, const std::string& filename)
|
||||||
{
|
{
|
||||||
|
|
@ -97,7 +97,7 @@ bool read_mesh(Surface_mesh<K>& mesh, const std::string& filename)
|
||||||
///
|
///
|
||||||
#endif
|
#endif
|
||||||
template <typename K>
|
template <typename K>
|
||||||
bool write_mesh(const Surface_mesh<K>& mesh, const std::string& filename)
|
bool write_mesh(const Surface_mesh<K>& mesh, const std::string& filename)
|
||||||
{
|
{
|
||||||
// extract file extension
|
// extract file extension
|
||||||
std::string::size_type dot(filename.rfind("."));
|
std::string::size_type dot(filename.rfind("."));
|
||||||
|
|
|
||||||
|
|
@ -9,13 +9,13 @@ reconstructed by `make_surface_mesh()` in the OFF file format.
|
||||||
In case the surface is manifold the triangles can be oriented.
|
In case the surface is manifold the triangles can be oriented.
|
||||||
|
|
||||||
|
|
||||||
\tparam SurfaceMeshComplex_2InTriangulation_3 must be a model of the `SurfaceMeshComplex_2InTriangulation_3` concept.
|
\tparam SurfaceMeshComplex_2InTriangulation_3 must be a model of the `SurfaceMeshComplex_2InTriangulation_3` concept.
|
||||||
|
|
||||||
\returns `true` if the surface is manifold and orientable.
|
\returns `true` if the surface is manifold and orientable.
|
||||||
|
|
||||||
|
|
||||||
\param os stream in which to write.
|
\param os stream in which to write.
|
||||||
\param c2t3 Input surface.
|
\param c2t3 Input surface.
|
||||||
\param options an int that is the binary union of values of `Surface_mesher::IO_option`.
|
\param options an int that is the binary union of values of `Surface_mesher::IO_option`.
|
||||||
|
|
||||||
\returns `true` if the surface could be written to the stream.
|
\returns `true` if the surface could be written to the stream.
|
||||||
|
|
@ -26,9 +26,9 @@ In case the surface is manifold the triangles can be oriented.
|
||||||
|
|
||||||
template <class SurfaceMeshComplex_2InTriangulation_3>
|
template <class SurfaceMeshComplex_2InTriangulation_3>
|
||||||
bool output_surface_facets_to_off (std::ostream& os,
|
bool output_surface_facets_to_off (std::ostream& os,
|
||||||
const SurfaceMeshComplex_2InTriangulation_3& c2t3,
|
const SurfaceMeshComplex_2InTriangulation_3& c2t3,
|
||||||
int options =
|
int options =
|
||||||
Surface_mesher::IO_ORIENT_SURFACE);
|
Surface_mesher::IO_ORIENT_SURFACE);
|
||||||
|
|
||||||
namespace Surface_mesher {
|
namespace Surface_mesher {
|
||||||
/*!
|
/*!
|
||||||
|
|
@ -38,7 +38,7 @@ bool output_surface_facets_to_off (std::ostream& os,
|
||||||
enum IO_option { NO_OPTION = 0,
|
enum IO_option { NO_OPTION = 0,
|
||||||
IO_ORIENT_SURFACE = 1,
|
IO_ORIENT_SURFACE = 1,
|
||||||
IO_VERBOSE = 2 };
|
IO_VERBOSE = 2 };
|
||||||
|
|
||||||
} /* namespace Surface_mesher */
|
} /* namespace Surface_mesher */
|
||||||
} /* namespace CGAL */
|
} /* namespace CGAL */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
\mainpage User Manual
|
\mainpage User Manual
|
||||||
\anchor Chapter_3D_Surface_Mesh_Generation
|
\anchor Chapter_3D_Surface_Mesh_Generation
|
||||||
|
|
||||||
\authors Laurent Rineau and Mariette Yvinec
|
\authors Laurent Rineau and Mariette Yvinec
|
||||||
|
|
@ -11,7 +11,7 @@ namespace CGAL {
|
||||||
\image html segmented_head.png
|
\image html segmented_head.png
|
||||||
\image latex segmented_head.png
|
\image latex segmented_head.png
|
||||||
|
|
||||||
\section SurfaceMesher_section_intro Introduction
|
\section SurfaceMesher_section_intro Introduction
|
||||||
|
|
||||||
This package provides a function template
|
This package provides a function template
|
||||||
to compute a triangular mesh approximating a surface.
|
to compute a triangular mesh approximating a surface.
|
||||||
|
|
@ -57,7 +57,7 @@ surface, and is within a small bounded distance
|
||||||
The algorithm can also be used for non smooth surfaces
|
The algorithm can also be used for non smooth surfaces
|
||||||
but then there is no guarantee.
|
but then there is no guarantee.
|
||||||
|
|
||||||
\section SurfaceMesher_section_interface The Surface Mesh Generator Interface for Smooth Surfaces
|
\section SurfaceMesher_section_interface The Surface Mesh Generator Interface for Smooth Surfaces
|
||||||
|
|
||||||
The meshing process is launched through a call to a function template.
|
The meshing process is launched through a call to a function template.
|
||||||
There are two overloaded versions of the meshing function
|
There are two overloaded versions of the meshing function
|
||||||
|
|
@ -236,7 +236,7 @@ Surface mesh of an iso-contour extracted from a gray level 3D image
|
||||||
|
|
||||||
\cgalExample{Surface_mesher/mesh_a_3d_gray_image.cpp}
|
\cgalExample{Surface_mesher/mesh_a_3d_gray_image.cpp}
|
||||||
|
|
||||||
\section SurfaceMesher_section_criteria Meshing Criteria, Guarantees and Variations
|
\section SurfaceMesher_section_criteria Meshing Criteria, Guarantees and Variations
|
||||||
|
|
||||||
\anchor SurfaceMesher_section_variations
|
\anchor SurfaceMesher_section_variations
|
||||||
|
|
||||||
|
|
@ -283,7 +283,7 @@ with the size of the mesh expected by the user,
|
||||||
and still have a guarantee that
|
and still have a guarantee that
|
||||||
the output mesh forms a manifold surface.
|
the output mesh forms a manifold surface.
|
||||||
The function `make_surface_mesh()` has specialized versions
|
The function `make_surface_mesh()` has specialized versions
|
||||||
for the following tag types:
|
for the following tag types:
|
||||||
|
|
||||||
`Manifold_tag`: the output mesh is guaranteed to be a manifold
|
`Manifold_tag`: the output mesh is guaranteed to be a manifold
|
||||||
surface without boundary.
|
surface without boundary.
|
||||||
|
|
@ -296,10 +296,10 @@ guarantees nothing else.
|
||||||
|
|
||||||
\section Surface_mesherOutput Output
|
\section Surface_mesherOutput Output
|
||||||
|
|
||||||
This \cgal component also provides functions to write the reconstructed surface mesh to the %Object File Format (OFF) \cgalCite{cgal:p-gmgv16-96} and to convert it to a `FaceGraph` (when it is manifold):
|
This \cgal component also provides functions to write the reconstructed surface mesh to the %Object File Format (OFF) \cgalCite{cgal:p-gmgv16-96} and to convert it to a `FaceGraph` (when it is manifold):
|
||||||
|
|
||||||
- `output_surface_facets_to_off()`
|
- `output_surface_facets_to_off()`
|
||||||
- `output_surface_facets_to_polyhedron()`
|
- `output_surface_facets_to_polyhedron()`
|
||||||
- `facets_in_complex_2_to_triangle_mesh()`
|
- `facets_in_complex_2_to_triangle_mesh()`
|
||||||
|
|
||||||
\section Surface_mesherUndocumented Undocumented Features Available in Demos
|
\section Surface_mesherUndocumented Undocumented Features Available in Demos
|
||||||
|
|
@ -308,12 +308,12 @@ The Polyhedron demo has a feature that allows to remesh a polyhedral
|
||||||
surface, using the 3D Surface Mesh Generator. That has been implemented as
|
surface, using the 3D Surface Mesh Generator. That has been implemented as
|
||||||
a special model of `SurfaceMeshTraits_3`, for polyhedra. That traits
|
a special model of `SurfaceMeshTraits_3`, for polyhedra. That traits
|
||||||
class is not yet documented because its interface and code have not yet
|
class is not yet documented because its interface and code have not yet
|
||||||
been stabilized.
|
been stabilized.
|
||||||
|
|
||||||
The Surface Mesh Generator demo allows to mesh not only gray level images,
|
The Surface Mesh Generator demo allows to mesh not only gray level images,
|
||||||
but also segmented images, when voxels are labelled with a domain
|
but also segmented images, when voxels are labelled with a domain
|
||||||
index. Such images are for example the result of a segmentation of 3D
|
index. Such images are for example the result of a segmentation of 3D
|
||||||
medical images.
|
medical images.
|
||||||
|
|
||||||
\section Surface_mesherDesign Design and Implementation History
|
\section Surface_mesherDesign Design and Implementation History
|
||||||
|
|
||||||
|
|
@ -327,6 +327,6 @@ described in \cgalCite{cgal:ry-gsddrm-06}.
|
||||||
David Rey, Steve Oudot and Andreas Fabri have participated
|
David Rey, Steve Oudot and Andreas Fabri have participated
|
||||||
in the development of this package.
|
in the development of this package.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
} /* namespace CGAL */
|
} /* namespace CGAL */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ namespace CGAL { namespace Surface_mesher {
|
||||||
typename Tr::size_type number_of_facets_on_surface(const Tr& T);
|
typename Tr::size_type number_of_facets_on_surface(const Tr& T);
|
||||||
|
|
||||||
template <class Triangulation>
|
template <class Triangulation>
|
||||||
class Write_to_OFF_file
|
class Write_to_OFF_file
|
||||||
{
|
{
|
||||||
CGAL::File_writer_OFF off;
|
CGAL::File_writer_OFF off;
|
||||||
std::ostream& os;
|
std::ostream& os;
|
||||||
|
|
@ -46,13 +46,13 @@ namespace CGAL { namespace Surface_mesher {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool write_header(const typename Tr::size_type number_of_vertices,
|
bool write_header(const typename Tr::size_type number_of_vertices,
|
||||||
const typename Tr::size_type number_of_facets)
|
const typename Tr::size_type number_of_facets)
|
||||||
{
|
{
|
||||||
off.header().set_no_comments(true);
|
off.header().set_no_comments(true);
|
||||||
off.write_header(os,
|
off.write_header(os,
|
||||||
number_of_vertices,
|
number_of_vertices,
|
||||||
0, // fake number of halfedges, not used.
|
0, // fake number of halfedges, not used.
|
||||||
number_of_facets);
|
number_of_facets);
|
||||||
return os.good();
|
return os.good();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -70,8 +70,8 @@ namespace CGAL { namespace Surface_mesher {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool write_facet(const int index1,
|
bool write_facet(const int index1,
|
||||||
const int index2,
|
const int index2,
|
||||||
const int index3)
|
const int index3)
|
||||||
{
|
{
|
||||||
off.write_facet_begin(3);
|
off.write_facet_begin(3);
|
||||||
off.write_facet_vertex_index(index1);
|
off.write_facet_vertex_index(index1);
|
||||||
|
|
@ -89,7 +89,7 @@ namespace CGAL { namespace Surface_mesher {
|
||||||
}; // end class Write_to_OFF_file
|
}; // end class Write_to_OFF_file
|
||||||
|
|
||||||
template <class Triangulation, class HDS>
|
template <class Triangulation, class HDS>
|
||||||
class Write_to_HDS
|
class Write_to_HDS
|
||||||
{
|
{
|
||||||
CGAL::Polyhedron_incremental_builder_3<HDS> builder;
|
CGAL::Polyhedron_incremental_builder_3<HDS> builder;
|
||||||
|
|
||||||
|
|
@ -101,10 +101,10 @@ namespace CGAL { namespace Surface_mesher {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool write_header(const typename Tr::size_type number_of_vertices,
|
bool write_header(const typename Tr::size_type number_of_vertices,
|
||||||
const typename Tr::size_type number_of_facets)
|
const typename Tr::size_type number_of_facets)
|
||||||
{
|
{
|
||||||
builder.begin_surface(number_of_vertices,
|
builder.begin_surface(number_of_vertices,
|
||||||
number_of_facets);
|
number_of_facets);
|
||||||
return !builder.error();
|
return !builder.error();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -121,8 +121,8 @@ namespace CGAL { namespace Surface_mesher {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool write_facet(const int index1,
|
bool write_facet(const int index1,
|
||||||
const int index2,
|
const int index2,
|
||||||
const int index3)
|
const int index3)
|
||||||
{
|
{
|
||||||
int indices[3];
|
int indices[3];
|
||||||
indices[0]=index1;
|
indices[0]=index1;
|
||||||
|
|
@ -140,16 +140,16 @@ namespace CGAL { namespace Surface_mesher {
|
||||||
}; // end class Write_to_HDS
|
}; // end class Write_to_HDS
|
||||||
|
|
||||||
enum IO_option { NO_OPTION = 0,
|
enum IO_option { NO_OPTION = 0,
|
||||||
IO_ORIENT_SURFACE = 1,
|
IO_ORIENT_SURFACE = 1,
|
||||||
IO_VERBOSE = 2 };
|
IO_VERBOSE = 2 };
|
||||||
|
|
||||||
} // end namespace Surface_mesher
|
} // end namespace Surface_mesher
|
||||||
|
|
||||||
template <class C2t3>
|
template <class C2t3>
|
||||||
bool output_surface_facets_to_off (std::ostream& os,
|
bool output_surface_facets_to_off (std::ostream& os,
|
||||||
const C2t3& c2t3,
|
const C2t3& c2t3,
|
||||||
int options =
|
int options =
|
||||||
Surface_mesher::IO_ORIENT_SURFACE)
|
Surface_mesher::IO_ORIENT_SURFACE)
|
||||||
{
|
{
|
||||||
using CGAL::Surface_mesher::number_of_facets_on_surface;
|
using CGAL::Surface_mesher::number_of_facets_on_surface;
|
||||||
|
|
||||||
|
|
@ -165,14 +165,14 @@ bool output_surface_facets_to_off (std::ostream& os,
|
||||||
|
|
||||||
bool success = true;
|
bool success = true;
|
||||||
|
|
||||||
Surface_mesher::Write_to_OFF_file<Tr>
|
Surface_mesher::Write_to_OFF_file<Tr>
|
||||||
off(os, (options & Surface_mesher::IO_VERBOSE) != 0);
|
off(os, (options & Surface_mesher::IO_VERBOSE) != 0);
|
||||||
|
|
||||||
success &= off.write_header(tr.number_of_vertices(),
|
success &= off.write_header(tr.number_of_vertices(),
|
||||||
c2t3.number_of_facets());
|
c2t3.number_of_facets());
|
||||||
|
|
||||||
CGAL_assertion(c2t3.number_of_facets() == number_of_facets_on_surface(tr));
|
CGAL_assertion(c2t3.number_of_facets() == number_of_facets_on_surface(tr));
|
||||||
|
|
||||||
// Finite vertices coordinates.
|
// Finite vertices coordinates.
|
||||||
std::map<Vertex_handle, int> V;
|
std::map<Vertex_handle, int> V;
|
||||||
int inum = 0;
|
int inum = 0;
|
||||||
|
|
@ -186,19 +186,19 @@ bool output_surface_facets_to_off (std::ostream& os,
|
||||||
|
|
||||||
success &= off.begin_facets();
|
success &= off.begin_facets();
|
||||||
|
|
||||||
if((options & Surface_mesher::IO_ORIENT_SURFACE) == 0)
|
if((options & Surface_mesher::IO_ORIENT_SURFACE) == 0)
|
||||||
{
|
{
|
||||||
for( Finite_facets_iterator fit = tr.finite_facets_begin();
|
for( Finite_facets_iterator fit = tr.finite_facets_begin();
|
||||||
fit != tr.finite_facets_end(); ++fit)
|
fit != tr.finite_facets_end(); ++fit)
|
||||||
{
|
{
|
||||||
const typename Tr::Cell_handle cell = fit->first;
|
const typename Tr::Cell_handle cell = fit->first;
|
||||||
const int& index = fit->second;
|
const int& index = fit->second;
|
||||||
if (cell->is_facet_on_surface(index)==true)
|
if (cell->is_facet_on_surface(index)==true)
|
||||||
{
|
{
|
||||||
const int index1 = V[cell->vertex(tr.vertex_triple_index(index, 0))];
|
const int index1 = V[cell->vertex(tr.vertex_triple_index(index, 0))];
|
||||||
const int index2 = V[cell->vertex(tr.vertex_triple_index(index, 1))];
|
const int index2 = V[cell->vertex(tr.vertex_triple_index(index, 1))];
|
||||||
const int index3 = V[cell->vertex(tr.vertex_triple_index(index, 2))];
|
const int index3 = V[cell->vertex(tr.vertex_triple_index(index, 2))];
|
||||||
success &= off.write_facet(index1, index2, index3);
|
success &= off.write_facet(index1, index2, index3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -213,52 +213,52 @@ bool output_surface_facets_to_off (std::ostream& os,
|
||||||
|
|
||||||
CGAL_assertion_code(typename Tr::size_type nb_facets = 0; )
|
CGAL_assertion_code(typename Tr::size_type nb_facets = 0; )
|
||||||
|
|
||||||
while (oriented_set.size() != number_of_facets)
|
while (oriented_set.size() != number_of_facets)
|
||||||
{
|
{
|
||||||
while ( fit->first->is_facet_on_surface(fit->second) == false ||
|
while ( fit->first->is_facet_on_surface(fit->second) == false ||
|
||||||
oriented_set.find(*fit) != oriented_set.end() ||
|
oriented_set.find(*fit) != oriented_set.end() ||
|
||||||
|
|
||||||
oriented_set.find(c2t3.opposite_facet(*fit)) !=
|
|
||||||
oriented_set.end() )
|
|
||||||
{
|
|
||||||
++fit;
|
|
||||||
}
|
|
||||||
oriented_set.insert(*fit);
|
|
||||||
stack.push(*fit);
|
|
||||||
while(! stack.empty() )
|
|
||||||
{
|
|
||||||
Facet f = stack.top();
|
|
||||||
stack.pop();
|
|
||||||
for(int ih = 0 ; ih < 3 ; ++ih) {
|
|
||||||
const int i1 = tr.vertex_triple_index(f.second, tr. cw(ih));
|
|
||||||
const int i2 = tr.vertex_triple_index(f.second, tr.ccw(ih));
|
|
||||||
|
|
||||||
const typename C2t3::Face_status face_status
|
oriented_set.find(c2t3.opposite_facet(*fit)) !=
|
||||||
= c2t3.face_status(Edge(f.first, i1, i2));
|
oriented_set.end() )
|
||||||
if(face_status == C2t3::REGULAR) {
|
{
|
||||||
Facet fn = c2t3.neighbor(f, ih);
|
++fit;
|
||||||
if (oriented_set.find(fn) == oriented_set.end()) {
|
}
|
||||||
if(oriented_set.find(c2t3.opposite_facet(fn)) == oriented_set.end())
|
oriented_set.insert(*fit);
|
||||||
{
|
stack.push(*fit);
|
||||||
oriented_set.insert(fn);
|
while(! stack.empty() )
|
||||||
stack.push(fn);
|
{
|
||||||
}
|
Facet f = stack.top();
|
||||||
else {
|
stack.pop();
|
||||||
success = false; // non-orientable
|
for(int ih = 0 ; ih < 3 ; ++ih) {
|
||||||
}
|
const int i1 = tr.vertex_triple_index(f.second, tr. cw(ih));
|
||||||
}
|
const int i2 = tr.vertex_triple_index(f.second, tr.ccw(ih));
|
||||||
}
|
|
||||||
else if(face_status != C2t3::BOUNDARY) {
|
const typename C2t3::Face_status face_status
|
||||||
success = false; // non manifold, thus non-orientable
|
= c2t3.face_status(Edge(f.first, i1, i2));
|
||||||
}
|
if(face_status == C2t3::REGULAR) {
|
||||||
} // end "for each neighbor of f"
|
Facet fn = c2t3.neighbor(f, ih);
|
||||||
} // end "stack non empty"
|
if (oriented_set.find(fn) == oriented_set.end()) {
|
||||||
|
if(oriented_set.find(c2t3.opposite_facet(fn)) == oriented_set.end())
|
||||||
|
{
|
||||||
|
oriented_set.insert(fn);
|
||||||
|
stack.push(fn);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
success = false; // non-orientable
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(face_status != C2t3::BOUNDARY) {
|
||||||
|
success = false; // non manifold, thus non-orientable
|
||||||
|
}
|
||||||
|
} // end "for each neighbor of f"
|
||||||
|
} // end "stack non empty"
|
||||||
} // end "oriented_set not full"
|
} // end "oriented_set not full"
|
||||||
|
|
||||||
for(typename std::set<Facet>::const_iterator fit =
|
for(typename std::set<Facet>::const_iterator fit =
|
||||||
oriented_set.begin();
|
oriented_set.begin();
|
||||||
fit != oriented_set.end();
|
fit != oriented_set.end();
|
||||||
++fit)
|
++fit)
|
||||||
{
|
{
|
||||||
const typename Tr::Cell_handle cell = fit->first;
|
const typename Tr::Cell_handle cell = fit->first;
|
||||||
const int& index = fit->second;
|
const int& index = fit->second;
|
||||||
|
|
@ -288,90 +288,90 @@ bool output_surface_facets_to_off (std::ostream& os,
|
||||||
// void operator()( HalfedgeDS& hds) {
|
// void operator()( HalfedgeDS& hds) {
|
||||||
// CGAL::Polyhedron_incremental_builder_3<HalfedgeDS> builder(hds, true);
|
// CGAL::Polyhedron_incremental_builder_3<HalfedgeDS> builder(hds, true);
|
||||||
// const typename Tr::size_type number_of_facets = c2t3.number_of_facets();
|
// const typename Tr::size_type number_of_facets = c2t3.number_of_facets();
|
||||||
// builder.begin_surface(tr.number_of_vertices(),
|
// builder.begin_surface(tr.number_of_vertices(),
|
||||||
// number_of_facets);
|
// number_of_facets);
|
||||||
// {
|
// {
|
||||||
// // Finite vertices coordinates.
|
// // Finite vertices coordinates.
|
||||||
// std::map<Vertex_handle, int> V;
|
// std::map<Vertex_handle, int> V;
|
||||||
// int inum = 0;
|
// int inum = 0;
|
||||||
// for(Finite_vertices_iterator vit = tr.finite_vertices_begin();
|
// for(Finite_vertices_iterator vit = tr.finite_vertices_begin();
|
||||||
// vit != tr.finite_vertices_end();
|
// vit != tr.finite_vertices_end();
|
||||||
// ++vit)
|
// ++vit)
|
||||||
// {
|
// {
|
||||||
// V[vit] = inum++;
|
// V[vit] = inum++;
|
||||||
// Point p = static_cast<Point>(vit->point());
|
// Point p = static_cast<Point>(vit->point());
|
||||||
// builder.add_vertex(p);
|
// builder.add_vertex(p);
|
||||||
// }
|
// }
|
||||||
// Finite_facets_iterator fit = tr.finite_facets_begin();
|
// Finite_facets_iterator fit = tr.finite_facets_begin();
|
||||||
// std::set<Facet> oriented_set;
|
// std::set<Facet> oriented_set;
|
||||||
// std::stack<Facet> stack;
|
// std::stack<Facet> stack;
|
||||||
|
|
||||||
// CGAL_assertion_code(typename Tr::size_type nb_facets = 0; )
|
// CGAL_assertion_code(typename Tr::size_type nb_facets = 0; )
|
||||||
|
|
||||||
// while (oriented_set.size() != number_of_facets) {
|
// while (oriented_set.size() != number_of_facets) {
|
||||||
// while ( fit->first->is_facet_on_surface(fit->second) == false ||
|
// while ( fit->first->is_facet_on_surface(fit->second) == false ||
|
||||||
// oriented_set.find(*fit) != oriented_set.end() ||
|
// oriented_set.find(*fit) != oriented_set.end() ||
|
||||||
|
|
||||||
// oriented_set.find(c2t3.opposite_facet(*fit)) !=
|
// oriented_set.find(c2t3.opposite_facet(*fit)) !=
|
||||||
// oriented_set.end() ) {
|
// oriented_set.end() ) {
|
||||||
// ++fit;
|
// ++fit;
|
||||||
// }
|
// }
|
||||||
// oriented_set.insert(*fit);
|
// oriented_set.insert(*fit);
|
||||||
// stack.push(*fit);
|
// stack.push(*fit);
|
||||||
// while(! stack.empty() ) {
|
// while(! stack.empty() ) {
|
||||||
// Facet f = stack.top();
|
// Facet f = stack.top();
|
||||||
// stack.pop();
|
// stack.pop();
|
||||||
// for(int ih = 0 ; ih < 3 ; ++ih) {
|
// for(int ih = 0 ; ih < 3 ; ++ih) {
|
||||||
// const int i1 = tr.vertex_triple_index(f.second, tr. cw(ih));
|
// const int i1 = tr.vertex_triple_index(f.second, tr. cw(ih));
|
||||||
// const int i2 = tr.vertex_triple_index(f.second, tr.ccw(ih));
|
// const int i2 = tr.vertex_triple_index(f.second, tr.ccw(ih));
|
||||||
// if( c2t3.face_status(Edge(f.first, i1, i2)) == C2t3::REGULAR ) {
|
// if( c2t3.face_status(Edge(f.first, i1, i2)) == C2t3::REGULAR ) {
|
||||||
// Facet fn = c2t3.neighbor(f, ih);
|
// Facet fn = c2t3.neighbor(f, ih);
|
||||||
// if (oriented_set.find(fn) == oriented_set.end() &&
|
// if (oriented_set.find(fn) == oriented_set.end() &&
|
||||||
// oriented_set.find(c2t3.opposite_facet(fn)) == oriented_set.end())
|
// oriented_set.find(c2t3.opposite_facet(fn)) == oriented_set.end())
|
||||||
// {
|
// {
|
||||||
// oriented_set.insert(fn);
|
// oriented_set.insert(fn);
|
||||||
// stack.push(fn);
|
// stack.push(fn);
|
||||||
// }
|
// }
|
||||||
// } // end "if the edge is regular"
|
// } // end "if the edge is regular"
|
||||||
// } // end "for each neighbor of f"
|
// } // end "for each neighbor of f"
|
||||||
// } // end "stack non empty"
|
// } // end "stack non empty"
|
||||||
// } // end "oriented_set not full"
|
// } // end "oriented_set not full"
|
||||||
|
|
||||||
// for(typename std::set<Facet>::const_iterator fit =
|
// for(typename std::set<Facet>::const_iterator fit =
|
||||||
// oriented_set.begin();
|
// oriented_set.begin();
|
||||||
// fit != oriented_set.end();
|
// fit != oriented_set.end();
|
||||||
// ++fit)
|
// ++fit)
|
||||||
// {
|
// {
|
||||||
// int indices[3];
|
// int indices[3];
|
||||||
// int index = 0;
|
// int index = 0;
|
||||||
// for (int i=0; i<3; i++)
|
// for (int i=0; i<3; i++)
|
||||||
// indices[index++] =
|
// indices[index++] =
|
||||||
// V[fit->first->vertex(tr.vertex_triple_index(fit->second, i))];
|
// V[fit->first->vertex(tr.vertex_triple_index(fit->second, i))];
|
||||||
// builder.add_facet(indices+0, indices+3);
|
// builder.add_facet(indices+0, indices+3);
|
||||||
// CGAL_assertion_code(++nb_facets);
|
// CGAL_assertion_code(++nb_facets);
|
||||||
// }
|
// }
|
||||||
// CGAL_assertion(nb_facets == number_of_facets);
|
// CGAL_assertion(nb_facets == number_of_facets);
|
||||||
// // for( Finite_facets_iterator fit = tr.finite_facets_begin();
|
// // for( Finite_facets_iterator fit = tr.finite_facets_begin();
|
||||||
// // fit != tr.finite_facets_end(); ++fit)
|
// // fit != tr.finite_facets_end(); ++fit)
|
||||||
// // if ((*fit).first->is_facet_on_surface((*fit).second)==true)
|
// // if ((*fit).first->is_facet_on_surface((*fit).second)==true)
|
||||||
// // {
|
// // {
|
||||||
// // int indices[3];
|
// // int indices[3];
|
||||||
// // int index = 0;
|
// // int index = 0;
|
||||||
// // for (int i=0; i<3; i++)
|
// // for (int i=0; i<3; i++)
|
||||||
// // std::cerr << ( indices[index++] = V[(*fit).first->vertex(tr.vertex_triple_index(fit->second, i))] ) << ", ";
|
// // std::cerr << ( indices[index++] = V[(*fit).first->vertex(tr.vertex_triple_index(fit->second, i))] ) << ", ";
|
||||||
// // std::cerr << "\n";
|
// // std::cerr << "\n";
|
||||||
// // if( builder.test_facet(indices+0, indices+3) )
|
// // if( builder.test_facet(indices+0, indices+3) )
|
||||||
// // builder.add_facet(indices+0, indices+3);
|
// // builder.add_facet(indices+0, indices+3);
|
||||||
// // else
|
// // else
|
||||||
// // {
|
// // {
|
||||||
// // builder.begin_facet();
|
// // builder.begin_facet();
|
||||||
// // builder.add_vertex_to_facet(indices[2]);
|
// // builder.add_vertex_to_facet(indices[2]);
|
||||||
// // builder.add_vertex_to_facet(indices[1]);
|
// // builder.add_vertex_to_facet(indices[1]);
|
||||||
// // builder.add_vertex_to_facet(indices[0]);
|
// // builder.add_vertex_to_facet(indices[0]);
|
||||||
// // builder.end_facet();
|
// // builder.end_facet();
|
||||||
// // }
|
// // }
|
||||||
// // CGAL_assertion_code(++nb_facets);
|
// // CGAL_assertion_code(++nb_facets);
|
||||||
// // }
|
// // }
|
||||||
// }
|
// }
|
||||||
// builder.end_surface();
|
// builder.end_surface();
|
||||||
// }
|
// }
|
||||||
|
|
@ -417,17 +417,17 @@ output_oriented_surface_facets_to_off (std::ostream& os, const Tr & T) {
|
||||||
fit != T.finite_facets_end(); ++fit)
|
fit != T.finite_facets_end(); ++fit)
|
||||||
if ((*fit).first->is_facet_on_surface((*fit).second)==true)
|
if ((*fit).first->is_facet_on_surface((*fit).second)==true)
|
||||||
{
|
{
|
||||||
typename Tr::Facet f = *fit;
|
typename Tr::Facet f = *fit;
|
||||||
typename Tr::Facet opposite = T.mirror_facet(f);
|
typename Tr::Facet opposite = T.mirror_facet(f);
|
||||||
CGAL_assertion (f.first->is_in_domain() !=
|
CGAL_assertion (f.first->is_in_domain() !=
|
||||||
opposite.first->is_in_domain());
|
opposite.first->is_in_domain());
|
||||||
if(!f.first->is_in_domain())
|
if(!f.first->is_in_domain())
|
||||||
f = T.mirror_facet(f);
|
f = T.mirror_facet(f);
|
||||||
os << "3 "
|
os << "3 "
|
||||||
<< V[f.first->vertex(T.vertex_triple_index(f.second,0))] << " "
|
<< V[f.first->vertex(T.vertex_triple_index(f.second,0))] << " "
|
||||||
<< V[f.first->vertex(T.vertex_triple_index(f.second,1))] << " "
|
<< V[f.first->vertex(T.vertex_triple_index(f.second,1))] << " "
|
||||||
<< V[f.first->vertex(T.vertex_triple_index(f.second,2))] << " "
|
<< V[f.first->vertex(T.vertex_triple_index(f.second,2))] << " "
|
||||||
<< "\n"; // without color.
|
<< "\n"; // without color.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -435,8 +435,8 @@ output_oriented_surface_facets_to_off (std::ostream& os, const Tr & T) {
|
||||||
template < class Tr>
|
template < class Tr>
|
||||||
void
|
void
|
||||||
output_surface_facets_to_ghs (std::ostream& os_points,
|
output_surface_facets_to_ghs (std::ostream& os_points,
|
||||||
std::ostream& os_faces,
|
std::ostream& os_faces,
|
||||||
const Tr & T) {
|
const Tr & T) {
|
||||||
typedef typename Tr::Finite_facets_iterator Finite_facets_iterator;
|
typedef typename Tr::Finite_facets_iterator Finite_facets_iterator;
|
||||||
typedef typename Tr::Finite_vertices_iterator Finite_vertices_iterator;
|
typedef typename Tr::Finite_vertices_iterator Finite_vertices_iterator;
|
||||||
typedef typename Tr::Vertex_handle Vertex_handle;
|
typedef typename Tr::Vertex_handle Vertex_handle;
|
||||||
|
|
@ -466,15 +466,15 @@ output_surface_facets_to_ghs (std::ostream& os_points,
|
||||||
fit != T.finite_facets_end(); ++fit)
|
fit != T.finite_facets_end(); ++fit)
|
||||||
if ((*fit).first->is_facet_on_surface((*fit).second)==true)
|
if ((*fit).first->is_facet_on_surface((*fit).second)==true)
|
||||||
{
|
{
|
||||||
Facet f = *fit;
|
Facet f = *fit;
|
||||||
if(!f.first->is_in_domain())
|
if(!f.first->is_in_domain())
|
||||||
f = T.mirror_facet(f);
|
f = T.mirror_facet(f);
|
||||||
os_faces
|
os_faces
|
||||||
<< "3 "
|
<< "3 "
|
||||||
<< V[f.first->vertex(T.vertex_triple_index(f.second,0))] << " "
|
<< V[f.first->vertex(T.vertex_triple_index(f.second,0))] << " "
|
||||||
<< V[f.first->vertex(T.vertex_triple_index(f.second,1))] << " "
|
<< V[f.first->vertex(T.vertex_triple_index(f.second,1))] << " "
|
||||||
<< V[f.first->vertex(T.vertex_triple_index(f.second,2))] << " "
|
<< V[f.first->vertex(T.vertex_triple_index(f.second,2))] << " "
|
||||||
<< "0 0 0 0\n";
|
<< "0 0 0 0\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -485,7 +485,7 @@ int number_of_facets_in_domain(const Tr& T) {
|
||||||
fit != T.finite_facets_end(); ++fit) {
|
fit != T.finite_facets_end(); ++fit) {
|
||||||
typename Tr::Cell_handle neighb = fit->first->neighbor (fit->second);
|
typename Tr::Cell_handle neighb = fit->first->neighbor (fit->second);
|
||||||
if ((fit->first->is_in_domain () || neighb->is_in_domain()) &&
|
if ((fit->first->is_in_domain () || neighb->is_in_domain()) &&
|
||||||
!fit->first->is_facet_on_surface (fit->second))
|
!fit->first->is_facet_on_surface (fit->second))
|
||||||
++result;
|
++result;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -522,14 +522,14 @@ output_interior_facets_to_off (std::ostream& os, const Tr & T) {
|
||||||
fit != T.finite_facets_end(); ++fit){
|
fit != T.finite_facets_end(); ++fit){
|
||||||
typename Tr::Cell_handle neighb = fit->first->neighbor (fit->second);
|
typename Tr::Cell_handle neighb = fit->first->neighbor (fit->second);
|
||||||
if ((fit->first->is_in_domain () || neighb->is_in_domain()) &&
|
if ((fit->first->is_in_domain () || neighb->is_in_domain()) &&
|
||||||
!fit->first->is_facet_on_surface (fit->second))
|
!fit->first->is_facet_on_surface (fit->second))
|
||||||
{
|
{
|
||||||
os << "3 ";
|
os << "3 ";
|
||||||
for (int i=0; i<4; i++)
|
for (int i=0; i<4; i++)
|
||||||
if (i != (*fit).second)
|
if (i != (*fit).second)
|
||||||
os << V[(*fit).first->vertex(i)] << " ";
|
os << V[(*fit).first->vertex(i)] << " ";
|
||||||
|
|
||||||
os << "\n"; // without color.
|
os << "\n"; // without color.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -32,12 +32,12 @@ A simplex \f$ s\in S\f$ is <I>maximal</I> if it is not a proper subset of some o
|
||||||
set in \f$ S\f$.
|
set in \f$ S\f$.
|
||||||
A simplex having \f$ k+1 \f$ vertices is said of dimension \f$ k \f$.
|
A simplex having \f$ k+1 \f$ vertices is said of dimension \f$ k \f$.
|
||||||
An \f$ k\f$-face denotes a \f$ k\f$-dimensional simplex, i.e., a simplex with \f$ k+1\f$
|
An \f$ k\f$-face denotes a \f$ k\f$-dimensional simplex, i.e., a simplex with \f$ k+1\f$
|
||||||
vertices.
|
vertices.
|
||||||
The simplicial complex is <I>pure</I> if all the maximal simplices
|
The simplicial complex is <I>pure</I> if all the maximal simplices
|
||||||
have the same dimension.
|
have the same dimension.
|
||||||
|
|
||||||
A <i>triangulation</i> is a simplicial complex
|
A <i>triangulation</i> is a simplicial complex
|
||||||
that is pure, connected and without boundaries nor singularities. The
|
that is pure, connected and without boundaries nor singularities. The
|
||||||
<i>dimension</i> of the triangulation is the dimension of its maximal
|
<i>dimension</i> of the triangulation is the dimension of its maximal
|
||||||
simplices.
|
simplices.
|
||||||
|
|
||||||
|
|
@ -48,7 +48,7 @@ A <I>proper face</I> of a simplex is a strict subset of this simplex.
|
||||||
Two faces \f$ \sigma\f$ and \f$ \sigma'\f$ are <I>incident</I> if and only if
|
Two faces \f$ \sigma\f$ and \f$ \sigma'\f$ are <I>incident</I> if and only if
|
||||||
\f$ \sigma'\f$ is a proper face of \f$ \sigma\f$ or <I>vice versa</I>.
|
\f$ \sigma'\f$ is a proper face of \f$ \sigma\f$ or <I>vice versa</I>.
|
||||||
|
|
||||||
A complex has <i>no boundaries</i> if any proper face of a simplex is also a
|
A complex has <i>no boundaries</i> if any proper face of a simplex is also a
|
||||||
proper face of another simplex.
|
proper face of another simplex.
|
||||||
|
|
||||||
If the triangulation is of dimension \f$ d \f$, we use the following terminology:<UL>
|
If the triangulation is of dimension \f$ d \f$, we use the following terminology:<UL>
|
||||||
|
|
@ -60,7 +60,7 @@ If the triangulation is of dimension \f$ d \f$, we use the following terminology
|
||||||
<LI><I>full cell</I>: a \f$ d\f$-face.
|
<LI><I>full cell</I>: a \f$ d\f$-face.
|
||||||
</UL>
|
</UL>
|
||||||
|
|
||||||
If the vertices are embedded into Euclidean space \f$ \mathbb{R}^n\f$,
|
If the vertices are embedded into Euclidean space \f$ \mathbb{R}^n\f$,
|
||||||
we deal with
|
we deal with
|
||||||
<I>finite simplicial complexes</I>, which have slightly different simplices
|
<I>finite simplicial complexes</I>, which have slightly different simplices
|
||||||
and additional requirements:
|
and additional requirements:
|
||||||
|
|
@ -77,28 +77,28 @@ simplices (the empty set counts).
|
||||||
This \cgal package provides four main classes
|
This \cgal package provides four main classes
|
||||||
for creating and manipulating triangulations.
|
for creating and manipulating triangulations.
|
||||||
|
|
||||||
The class `CGAL::Triangulation_data_structure<Dimensionality, TriangulationDSVertex_, TriangulationDSFullCell_>`
|
The class `CGAL::Triangulation_data_structure<Dimensionality, TriangulationDSVertex_, TriangulationDSFullCell_>`
|
||||||
models an <I>abstract triangulation</I>: vertices in this
|
models an <I>abstract triangulation</I>: vertices in this
|
||||||
class are not embedded in Euclidean space but are only of combinatorial
|
class are not embedded in Euclidean space but are only of combinatorial
|
||||||
nature.
|
nature.
|
||||||
|
|
||||||
The class `CGAL::Triangulation<TriangulationTraits_, TriangulationDataStructure_>`
|
The class `CGAL::Triangulation<TriangulationTraits_, TriangulationDataStructure_>`
|
||||||
describes an embedded triangulation that has as vertices a given set of points.
|
describes an embedded triangulation that has as vertices a given set of points.
|
||||||
Methods are provided for the insertion of points in the triangulation, the
|
Methods are provided for the insertion of points in the triangulation, the
|
||||||
traversal of various elements of the triangulation, as well as the location of a
|
traversal of various elements of the triangulation, as well as the location of a
|
||||||
query point inside the triangulation.
|
query point inside the triangulation.
|
||||||
The triangulation covers the convex hull of the set of points.
|
The triangulation covers the convex hull of the set of points.
|
||||||
|
|
||||||
The class `CGAL::Delaunay_triangulation<DelaunayTriangulationTraits_, TriangulationDataStructure_>`
|
The class `CGAL::Delaunay_triangulation<DelaunayTriangulationTraits_, TriangulationDataStructure_>`
|
||||||
builds the Delaunay triangulation of a set of points.
|
builds the Delaunay triangulation of a set of points.
|
||||||
In a Delaunay triangulation, each face has the so-called
|
In a Delaunay triangulation, each face has the so-called
|
||||||
<I>Delaunay</I> or <I>empty-ball</I> property: there exists a
|
<I>Delaunay</I> or <I>empty-ball</I> property: there exists a
|
||||||
circumscribing ball whose interior does not contain
|
circumscribing ball whose interior does not contain
|
||||||
any vertex of the triangulation.
|
any vertex of the triangulation.
|
||||||
|
|
||||||
The class `CGAL::Regular_triangulation<RegularTriangulationTraits_, TriangulationDataStructure_>`
|
The class `CGAL::Regular_triangulation<RegularTriangulationTraits_, TriangulationDataStructure_>`
|
||||||
builds the regular triangulation
|
builds the regular triangulation
|
||||||
-- also known as weighted Delaunay triangulation -- of a set of points.
|
-- also known as weighted Delaunay triangulation -- of a set of points.
|
||||||
A detailed definition of such a triangulation is available in section
|
A detailed definition of such a triangulation is available in section
|
||||||
\ref TriangulationSecRT.
|
\ref TriangulationSecRT.
|
||||||
|
|
||||||
|
|
@ -109,10 +109,10 @@ which \cgal provides one model class:
|
||||||
`CGAL::Triangulation_data_structure<Dimensionality, TriangulationDSVertex_, TriangulationDSFullCell_>`.
|
`CGAL::Triangulation_data_structure<Dimensionality, TriangulationDSVertex_, TriangulationDSFullCell_>`.
|
||||||
|
|
||||||
A triangulation data structure can represent an abstract triangulation.
|
A triangulation data structure can represent an abstract triangulation.
|
||||||
|
|
||||||
The <I>maximal dimension</I> of a triangulation data structure is a
|
The <I>maximal dimension</I> of a triangulation data structure is a
|
||||||
positive integer equal to the maximum dimension a full cell can have.
|
positive integer equal to the maximum dimension a full cell can have.
|
||||||
This maximal dimension can be chosen by the user at the creation of the
|
This maximal dimension can be chosen by the user at the creation of the
|
||||||
triangulation data structure and can then be obtained using the method `tds.maximal_dimension()`.
|
triangulation data structure and can then be obtained using the method `tds.maximal_dimension()`.
|
||||||
A triangulation data structure also knows the <I>current dimension</I> of its full cells,
|
A triangulation data structure also knows the <I>current dimension</I> of its full cells,
|
||||||
which can be obtained using `tds.current_dimension()`. In the sequel, let
|
which can be obtained using `tds.current_dimension()`. In the sequel, let
|
||||||
|
|
@ -122,8 +122,8 @@ The special meaning of negative values for \f$d\f$ is explained below.
|
||||||
|
|
||||||
## The Set of Faces ##
|
## The Set of Faces ##
|
||||||
|
|
||||||
The set of faces of a triangulation data structure with
|
The set of faces of a triangulation data structure with
|
||||||
current dimension \f$ d \f$ forms a triangulation of the
|
current dimension \f$ d \f$ forms a triangulation of the
|
||||||
topological sphere \f$ \mathbb{S}^d\f$.
|
topological sphere \f$ \mathbb{S}^d\f$.
|
||||||
|
|
||||||
Two full cells \f$ \sigma\f$ and \f$ \sigma'\f$ sharing a facet are called
|
Two full cells \f$ \sigma\f$ and \f$ \sigma'\f$ sharing a facet are called
|
||||||
|
|
@ -134,10 +134,10 @@ Possible values of \f$d\f$ (the <I>current dimension</I> of the triangulation) i
|
||||||
<DL>
|
<DL>
|
||||||
<DT><B>\f$d=-2\f$</B><DD> This corresponds to an empty
|
<DT><B>\f$d=-2\f$</B><DD> This corresponds to an empty
|
||||||
triangulation data structure.
|
triangulation data structure.
|
||||||
<DT><B>\f$d=-1\f$</B><DD> This corresponds to an abstract simplicial
|
<DT><B>\f$d=-1\f$</B><DD> This corresponds to an abstract simplicial
|
||||||
complex reduced to a single vertex.
|
complex reduced to a single vertex.
|
||||||
<!--- and a single full cell. In a geometric triangulation, this vertex corresponds to the vertex at infinity.--->
|
<!--- and a single full cell. In a geometric triangulation, this vertex corresponds to the vertex at infinity.--->
|
||||||
<DT><B>\f$d=0\f$</B><DD> This corresponds to an abstract simplicial
|
<DT><B>\f$d=0\f$</B><DD> This corresponds to an abstract simplicial
|
||||||
complex including two vertices, each corresponding to a full cell;
|
complex including two vertices, each corresponding to a full cell;
|
||||||
the two full cells being neighbors of each other. This is the unique
|
the two full cells being neighbors of each other. This is the unique
|
||||||
triangulation of the \f$ 0\f$-sphere.
|
triangulation of the \f$ 0\f$-sphere.
|
||||||
|
|
@ -145,7 +145,7 @@ triangulation of the \f$ 0\f$-sphere.
|
||||||
<DT><B>\f$ 0< d \le D\f$</B><DD> This corresponds to a triangulation of
|
<DT><B>\f$ 0< d \le D\f$</B><DD> This corresponds to a triangulation of
|
||||||
the sphere \f$ \mathbb{S}^d\f$.
|
the sphere \f$ \mathbb{S}^d\f$.
|
||||||
</DL>
|
</DL>
|
||||||
</BLOCKQUOTE>
|
</BLOCKQUOTE>
|
||||||
|
|
||||||
## The `Triangulation_data_structure` Class ##
|
## The `Triangulation_data_structure` Class ##
|
||||||
|
|
||||||
|
|
@ -176,7 +176,7 @@ Indexing the vertices and neighbors of a full cell \f$ c\f$ in dimension \f$ d=2
|
||||||
\cgalFigureEnd
|
\cgalFigureEnd
|
||||||
|
|
||||||
Faces of dimension between 0 and \f$ d-1 \f$ can be accessed as
|
Faces of dimension between 0 and \f$ d-1 \f$ can be accessed as
|
||||||
subfaces of a full cell, through the nested type `Face`. The `Face` instance
|
subfaces of a full cell, through the nested type `Face`. The `Face` instance
|
||||||
corresponding to a face \f$ f \f$ stores a reference to a full cell `c`
|
corresponding to a face \f$ f \f$ stores a reference to a full cell `c`
|
||||||
containing \f$ f \f$, and the indices of the vertices of `c` that belong
|
containing \f$ f \f$, and the indices of the vertices of `c` that belong
|
||||||
to \f$ f \f$.
|
to \f$ f \f$.
|
||||||
|
|
@ -212,7 +212,7 @@ template parameter and
|
||||||
</UL>
|
</UL>
|
||||||
|
|
||||||
The last two parameters have default values and are thus not necessary, unless
|
The last two parameters have default values and are thus not necessary, unless
|
||||||
the user needs custom types (see `Triangulation_data_structure`).
|
the user needs custom types (see `Triangulation_data_structure`).
|
||||||
The first template parameter, `Dimensionality`, must be one of the following:
|
The first template parameter, `Dimensionality`, must be one of the following:
|
||||||
<UL>
|
<UL>
|
||||||
<LI>`CGAL::Dimension_tag<D>` for some integer \f$ D \f$. This
|
<LI>`CGAL::Dimension_tag<D>` for some integer \f$ D \f$. This
|
||||||
|
|
@ -234,11 +234,11 @@ some nested types in `TriangulationDataStructure_`.
|
||||||
|
|
||||||
The default values are `CGAL::Triangulation_ds_vertex<TDS>`
|
The default values are `CGAL::Triangulation_ds_vertex<TDS>`
|
||||||
and `CGAL::Triangulation_ds_full_cell<TDS>`
|
and `CGAL::Triangulation_ds_full_cell<TDS>`
|
||||||
where `TDS` is the current class
|
where `TDS` is the current class
|
||||||
`Triangulation_data_structure<Dimensionality, TriangulationDSVertex_, TriangulationDSFullCell_>`.
|
`Triangulation_data_structure<Dimensionality, TriangulationDSVertex_, TriangulationDSFullCell_>`.
|
||||||
<I>This creates a circular dependency</I>, which we resolve in the same way
|
<I>This creates a circular dependency</I>, which we resolve in the same way
|
||||||
as in the \cgal `Triangulation_2` and `Triangulation_3` packages (see
|
as in the \cgal `Triangulation_2` and `Triangulation_3` packages (see
|
||||||
Chapters \ref Chapter_2D_Triangulation_Data_Structure, \ref Chapter_2D_Triangulations,
|
Chapters \ref Chapter_2D_Triangulation_Data_Structure, \ref Chapter_2D_Triangulations,
|
||||||
\ref Chapter_3D_Triangulation_Data_Structure, and \ref Chapter_3D_Triangulations).
|
\ref Chapter_3D_Triangulation_Data_Structure, and \ref Chapter_3D_Triangulations).
|
||||||
In particular, models of the concepts `TriangulationDSVertex` and
|
In particular, models of the concepts `TriangulationDSVertex` and
|
||||||
`TriangulationDSFullCell` must provide a nested template `Rebind_TDS`
|
`TriangulationDSFullCell` must provide a nested template `Rebind_TDS`
|
||||||
|
|
@ -254,7 +254,7 @@ class. The user is encouraged to read the documentation of the \cgal
|
||||||
|
|
||||||
The following examples shows how to construct a triangulation data structure by
|
The following examples shows how to construct a triangulation data structure by
|
||||||
inserting vertices. Its main interest is that it demonstrates most of the API
|
inserting vertices. Its main interest is that it demonstrates most of the API
|
||||||
to insert new vertices into the triangulation.
|
to insert new vertices into the triangulation.
|
||||||
<!---
|
<!---
|
||||||
Therefore, the reader will make
|
Therefore, the reader will make
|
||||||
the best use of this example by reading it slowly, together with the reference
|
the best use of this example by reading it slowly, together with the reference
|
||||||
|
|
@ -287,20 +287,20 @@ Barycentric subdivision in dimension \f$ d=2\f$.
|
||||||
|
|
||||||
\section TriangulationSecTriangulations Triangulations
|
\section TriangulationSecTriangulations Triangulations
|
||||||
|
|
||||||
The class `CGAL::Triangulation<TriangulationTraits_, TriangulationDataStructure_>`
|
The class `CGAL::Triangulation<TriangulationTraits_, TriangulationDataStructure_>`
|
||||||
maintains a triangulation embedded in Euclidean space. The triangulation
|
maintains a triangulation embedded in Euclidean space. The triangulation
|
||||||
covers the convex hull of the input points (the embedded vertices of the
|
covers the convex hull of the input points (the embedded vertices of the
|
||||||
triangulation).
|
triangulation).
|
||||||
|
|
||||||
To store this triangulation in a triangulation data structure, we turn the set
|
To store this triangulation in a triangulation data structure, we turn the set
|
||||||
of its faces into a topological sphere by adding a
|
of its faces into a topological sphere by adding a
|
||||||
fictitious vertex, called the <i>infinite vertex</i>, as well as infinite
|
fictitious vertex, called the <i>infinite vertex</i>, as well as infinite
|
||||||
simplices incident to boundary faces of the convex hull.
|
simplices incident to boundary faces of the convex hull.
|
||||||
Each infinite \f$ i\f$-simplex is
|
Each infinite \f$ i\f$-simplex is
|
||||||
incident to the infinite vertex and to an \f$ (i-1)\f$-simplex of the
|
incident to the infinite vertex and to an \f$ (i-1)\f$-simplex of the
|
||||||
convex hull boundary.
|
convex hull boundary.
|
||||||
|
|
||||||
See Chapters \ref Chapter_2D_Triangulations "2D Triangulations" or
|
See Chapters \ref Chapter_2D_Triangulations "2D Triangulations" or
|
||||||
\ref Chapter_3D_Triangulations "3D Triangulations" for more details
|
\ref Chapter_3D_Triangulations "3D Triangulations" for more details
|
||||||
about infinite vertices and cells.
|
about infinite vertices and cells.
|
||||||
|
|
||||||
|
|
@ -311,22 +311,22 @@ as well as the location of a query point inside the triangulation.
|
||||||
The ordering of the vertices of a full cell defines an orientation of
|
The ordering of the vertices of a full cell defines an orientation of
|
||||||
that full cell.
|
that full cell.
|
||||||
As long as no <I>advanced</I> class method is called, it is guaranteed
|
As long as no <I>advanced</I> class method is called, it is guaranteed
|
||||||
that all finite full cells have positive orientation. Each infinite full
|
that all finite full cells have positive orientation. Each infinite full
|
||||||
cell is oriented as if its infinite vertex was on the side of
|
cell is oriented as if its infinite vertex was on the side of
|
||||||
the hyperplane supported by its finite facet where there is no other point.
|
the hyperplane supported by its finite facet where there is no other point.
|
||||||
|
|
||||||
## Implementation ##
|
## Implementation ##
|
||||||
|
|
||||||
The class `CGAL::Triangulation<TriangulationTraits_, TriangulationDataStructure_>`
|
The class `CGAL::Triangulation<TriangulationTraits_, TriangulationDataStructure_>`
|
||||||
stores a model of the concept `TriangulationDataStructure` that is
|
stores a model of the concept `TriangulationDataStructure` that is
|
||||||
instantiated with a vertex type that stores a point.
|
instantiated with a vertex type that stores a point.
|
||||||
|
|
||||||
The template parameter `TriangulationTraits_` must be a model of the concept
|
The template parameter `TriangulationTraits_` must be a model of the concept
|
||||||
`TriangulationTraits`, which provides the point type as well
|
`TriangulationTraits`, which provides the point type as well
|
||||||
as various geometric predicates used by the `Triangulation` class.
|
as various geometric predicates used by the `Triangulation` class.
|
||||||
|
|
||||||
The `TriangulationTraits` concept includes a nested type
|
The `TriangulationTraits` concept includes a nested type
|
||||||
`TriangulationTraits::Dimension`. This dimension governs the number of points
|
`TriangulationTraits::Dimension`. This dimension governs the number of points
|
||||||
given as arguments to the predicates. This type is either
|
given as arguments to the predicates. This type is either
|
||||||
`CGAL::Dimension_tag<D>` or `CGAL::Dynamic_dimension_tag`.
|
`CGAL::Dimension_tag<D>` or `CGAL::Dynamic_dimension_tag`.
|
||||||
In any case, the dimension of the traits
|
In any case, the dimension of the traits
|
||||||
|
|
@ -348,7 +348,7 @@ ask the triangulation to construct the set of edges
|
||||||
these edges are in bijection with the vertices on the convex hull of the
|
these edges are in bijection with the vertices on the convex hull of the
|
||||||
points. This gives us a handy way to count the convex hull vertices
|
points. This gives us a handy way to count the convex hull vertices
|
||||||
(include files <tt>triangulation1.cpp</tt> and
|
(include files <tt>triangulation1.cpp</tt> and
|
||||||
<tt>triangulation2.cpp</tt> are given and commented below).
|
<tt>triangulation2.cpp</tt> are given and commented below).
|
||||||
|
|
||||||
\cgalExample{triangulation.cpp}
|
\cgalExample{triangulation.cpp}
|
||||||
|
|
||||||
|
|
@ -356,7 +356,7 @@ points. This gives us a handy way to count the convex hull vertices
|
||||||
|
|
||||||
Remember that a triangulation covers the convex hull of its
|
Remember that a triangulation covers the convex hull of its
|
||||||
vertices.
|
vertices.
|
||||||
Each facet of the convex hull is incident
|
Each facet of the convex hull is incident
|
||||||
to one finite full cell and one infinite
|
to one finite full cell and one infinite
|
||||||
full cell. In fact there is a bijection between the infinite full cells and the
|
full cell. In fact there is a bijection between the infinite full cells and the
|
||||||
facets of the convex hull.
|
facets of the convex hull.
|
||||||
|
|
@ -392,17 +392,17 @@ A <I>circumscribing ball</I> of a simplex is a ball
|
||||||
having all vertices of the simplex on its boundary.
|
having all vertices of the simplex on its boundary.
|
||||||
In a Delaunay triangulation, each face has the so-called
|
In a Delaunay triangulation, each face has the so-called
|
||||||
<I>Delaunay</I> or <I>empty-ball</I> property: there exists a
|
<I>Delaunay</I> or <I>empty-ball</I> property: there exists a
|
||||||
circumscribing ball whose interior does not contain
|
circumscribing ball whose interior does not contain
|
||||||
any vertex of the triangulation.
|
any vertex of the triangulation.
|
||||||
|
|
||||||
In case of degeneracies (co-spherical points) the triangulation is not
|
In case of degeneracies (co-spherical points) the triangulation is not
|
||||||
uniquely defined. Note however that the CGAL implementation computes a
|
uniquely defined. Note however that the CGAL implementation computes a
|
||||||
unique triangulation even in these cases.
|
unique triangulation even in these cases.
|
||||||
|
|
||||||
When a new point `p` is inserted into a Delaunay triangulation, the
|
When a new point `p` is inserted into a Delaunay triangulation, the
|
||||||
full cells whose circumscribing ball contains `p` are said to
|
full cells whose circumscribing ball contains `p` are said to
|
||||||
<I>be in conflict</I> with point `p`. Note that the circumscribing ball
|
<I>be in conflict</I> with point `p`. Note that the circumscribing ball
|
||||||
of an infinite full cell is the empty half-space bounded by the affine hull
|
of an infinite full cell is the empty half-space bounded by the affine hull
|
||||||
of the finite facet of this cell. The set of full cells that are in
|
of the finite facet of this cell. The set of full cells that are in
|
||||||
conflict with `p` form the <I>conflict zone</I>. The full cells
|
conflict with `p` form the <I>conflict zone</I>. The full cells
|
||||||
in the conflict zone are removed, leaving a hole that contains `p`. That
|
in the conflict zone are removed, leaving a hole that contains `p`. That
|
||||||
|
|
@ -451,9 +451,9 @@ Regular triangulations are also known as weighted Delaunay triangulations.
|
||||||
|
|
||||||
Let \f$ {S}^{(w)}\f$ be a set of weighted points in \f$ \mathbb{R}^D\f$. Let
|
Let \f$ {S}^{(w)}\f$ be a set of weighted points in \f$ \mathbb{R}^D\f$. Let
|
||||||
\f$ {p}^{(w)}=(p,w_p), p\in\mathbb{R}^D, w_p\in\mathbb{R}\f$ and
|
\f$ {p}^{(w)}=(p,w_p), p\in\mathbb{R}^D, w_p\in\mathbb{R}\f$ and
|
||||||
\f$ {z}^{(w)}=(z,w_z), z\in\mathbb{R}^D, w_z\in\mathbb{R}\f$
|
\f$ {z}^{(w)}=(z,w_z), z\in\mathbb{R}^D, w_z\in\mathbb{R}\f$
|
||||||
be two weighted points.
|
be two weighted points.
|
||||||
A weighted point \f$ {p}^{(w)}=(p,w_p)\f$ can also be seen as a sphere of
|
A weighted point \f$ {p}^{(w)}=(p,w_p)\f$ can also be seen as a sphere of
|
||||||
center \f$ p\f$ and radius \f$ \sqrt{w_p}\f$.
|
center \f$ p\f$ and radius \f$ \sqrt{w_p}\f$.
|
||||||
The <I>power product</I> (or <I>power distance</I> )
|
The <I>power product</I> (or <I>power distance</I> )
|
||||||
between \f$ {p}^{(w)}\f$ and \f$ {z}^{(w)}\f$ is
|
between \f$ {p}^{(w)}\f$ and \f$ {z}^{(w)}\f$ is
|
||||||
|
|
@ -464,7 +464,7 @@ where \f$ \|{p-z}\|\f$ is the Euclidean distance between \f$ p\f$ and \f$ z\f$.
|
||||||
are said to be <I>orthogonal</I> if \f$ \Pi({p}^{(w)},{z}^{(w)})
|
are said to be <I>orthogonal</I> if \f$ \Pi({p}^{(w)},{z}^{(w)})
|
||||||
= 0\f$.
|
= 0\f$.
|
||||||
|
|
||||||
\f$D + 1\f$ weighted points have a unique common orthogonal weighted point
|
\f$D + 1\f$ weighted points have a unique common orthogonal weighted point
|
||||||
called the <I>power sphere</I>. A sphere \f$ {z}^{(w)}\f$ is said to be
|
called the <I>power sphere</I>. A sphere \f$ {z}^{(w)}\f$ is said to be
|
||||||
<I>regular</I> if \f$ \forall {p}^{(w)}\in{S}^{(w)},
|
<I>regular</I> if \f$ \forall {p}^{(w)}\in{S}^{(w)},
|
||||||
\Pi({p}^{(w)},{z}^{(w)})\geq 0\f$.
|
\Pi({p}^{(w)},{z}^{(w)})\geq 0\f$.
|
||||||
|
|
@ -475,10 +475,10 @@ of all simplices are regular.
|
||||||
Note that as a result, some points can be hidden and do not result in vertices
|
Note that as a result, some points can be hidden and do not result in vertices
|
||||||
in the triangulation. Those points are discarded and cannot be retrieved.
|
in the triangulation. Those points are discarded and cannot be retrieved.
|
||||||
|
|
||||||
A weighted point `p` is said to be in conflict
|
A weighted point `p` is said to be in conflict
|
||||||
with a simplex `s` if it has a negative power distance to the power sphere of `s`.
|
with a simplex `s` if it has a negative power distance to the power sphere of `s`.
|
||||||
|
|
||||||
Regular triangulations support insertion of weighted points,
|
Regular triangulations support insertion of weighted points,
|
||||||
and location of a query point inside the triangulation.
|
and location of a query point inside the triangulation.
|
||||||
Note that inserting a large set of points at once is much faster
|
Note that inserting a large set of points at once is much faster
|
||||||
than inserting the same points one by one.
|
than inserting the same points one by one.
|
||||||
|
|
@ -493,8 +493,8 @@ the concept `TriangulationDataStructure_` which is instantiated with a vertex
|
||||||
type that stores a weighted point and allows its retrieval.
|
type that stores a weighted point and allows its retrieval.
|
||||||
|
|
||||||
The template parameter `RegularTriangulationTraits_` must be a model of the concept
|
The template parameter `RegularTriangulationTraits_` must be a model of the concept
|
||||||
`RegularTriangulationTraits`. It must provide the `%Weighted_point_d`
|
`RegularTriangulationTraits`. It must provide the `%Weighted_point_d`
|
||||||
type as well as various geometric predicates used by the
|
type as well as various geometric predicates used by the
|
||||||
`Regular_triangulation` class.
|
`Regular_triangulation` class.
|
||||||
The concept `RegularTriangulationTraits` refines the concept
|
The concept `RegularTriangulationTraits` refines the concept
|
||||||
`TriangulationTraits`.
|
`TriangulationTraits`.
|
||||||
|
|
@ -507,12 +507,12 @@ This simple example shows how to create a regular triangulation.
|
||||||
|
|
||||||
\section TriangulationSecPerf Complexity and Performances
|
\section TriangulationSecPerf Complexity and Performances
|
||||||
|
|
||||||
When inserting a batch of points into a Delaunay triangulation,
|
When inserting a batch of points into a Delaunay triangulation,
|
||||||
the current implementation starts by spatially sorting the points.
|
the current implementation starts by spatially sorting the points.
|
||||||
Then, for each point to insert, it locates it by walking in the triangulation,
|
Then, for each point to insert, it locates it by walking in the triangulation,
|
||||||
using the previously inserted vertex as a "hint". Finally, the point is
|
using the previously inserted vertex as a "hint". Finally, the point is
|
||||||
inserted.
|
inserted.
|
||||||
In the worst case scenario, without spatial sort, the expected complexity is
|
In the worst case scenario, without spatial sort, the expected complexity is
|
||||||
\f$ O(n^{\lceil\frac{d}{2}\rceil+1}) \f$.
|
\f$ O(n^{\lceil\frac{d}{2}\rceil+1}) \f$.
|
||||||
When the algorithm is run on uniformly distributed points, the localization complexity is
|
When the algorithm is run on uniformly distributed points, the localization complexity is
|
||||||
\f$ O(n^{\frac{1}{d}}) \f$ and the size of the triangulation is \f$ O(n) \f$, which gives
|
\f$ O(n^{\frac{1}{d}}) \f$ and the size of the triangulation is \f$ O(n) \f$, which gives
|
||||||
|
|
@ -520,11 +520,11 @@ a complexity of \f$ O(n^{1+\frac{1}{d}}) \f$ for the insertion.
|
||||||
With spatial sort and random points, one can expect a complexity of \f$ O(n\log n) \f$.
|
With spatial sort and random points, one can expect a complexity of \f$ O(n\log n) \f$.
|
||||||
Please refer to \cgalCite{boissonnat2009Delaunay} for more details.
|
Please refer to \cgalCite{boissonnat2009Delaunay} for more details.
|
||||||
|
|
||||||
We provide below (\cgalFigureRef{Triangulationfigbenchmarks100},
|
We provide below (\cgalFigureRef{Triangulationfigbenchmarks100},
|
||||||
\cgalFigureRef{Triangulationfigbenchmarks1000} and
|
\cgalFigureRef{Triangulationfigbenchmarks1000} and
|
||||||
\cgalFigureRef{triangulationfigbenchmarkchart}) the
|
\cgalFigureRef{triangulationfigbenchmarkchart}) the
|
||||||
performance of the Delaunay triangulation on randomly distributed points.
|
performance of the Delaunay triangulation on randomly distributed points.
|
||||||
The machine used is a PC running
|
The machine used is a PC running
|
||||||
Windows 7 64-bits with an Intel Xeon CPU clocked at 2.80 GHz with 32GB of RAM.
|
Windows 7 64-bits with an Intel Xeon CPU clocked at 2.80 GHz with 32GB of RAM.
|
||||||
The program has been compiled with Microsoft Visual C++ 2013 in Release mode.
|
The program has been compiled with Microsoft Visual C++ 2013 in Release mode.
|
||||||
|
|
||||||
|
|
@ -581,7 +581,7 @@ instead.
|
||||||
This package is heavily inspired by the works of
|
This package is heavily inspired by the works of
|
||||||
Monique Teillaud and Sylvain Pion (`Triangulation_3`)
|
Monique Teillaud and Sylvain Pion (`Triangulation_3`)
|
||||||
and Mariette Yvinec (`Triangulation_2`).
|
and Mariette Yvinec (`Triangulation_2`).
|
||||||
The first version was written by Samuel Hornus. The final version is a joint
|
The first version was written by Samuel Hornus. The final version is a joint
|
||||||
work by Samuel Hornus, Olivier Devillers and Clément Jamin. In 2017, Clément
|
work by Samuel Hornus, Olivier Devillers and Clément Jamin. In 2017, Clément
|
||||||
Jamin added the regular triangulations.
|
Jamin added the regular triangulations.
|
||||||
|
|
||||||
|
|
@ -590,6 +590,6 @@ Clément Jamin's work was supported by the
|
||||||
(Geometric Understanding in Higher Dimensions).
|
(Geometric Understanding in Higher Dimensions).
|
||||||
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
} /* namespace CGAL */
|
} /* namespace CGAL */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -57,36 +57,36 @@ int main( int argc, char **argv) {
|
||||||
for (int i = 1; i < argc; i++) { // check commandline options
|
for (int i = 1; i < argc; i++) { // check commandline options
|
||||||
if ( strcmp( "-v", argv[i]) == 0)
|
if ( strcmp( "-v", argv[i]) == 0)
|
||||||
verbose = true;
|
verbose = true;
|
||||||
else if ( strcmp( "-b", argv[i]) == 0)
|
else if ( strcmp( "-b", argv[i]) == 0)
|
||||||
binary = true;
|
binary = true;
|
||||||
else if ( strcmp( "-noc", argv[i]) == 0)
|
else if ( strcmp( "-noc", argv[i]) == 0)
|
||||||
noc = true;
|
noc = true;
|
||||||
else if ( strcmp( "-delaunay", argv[i]) == 0)
|
else if ( strcmp( "-delaunay", argv[i]) == 0)
|
||||||
delaunay = true;
|
delaunay = true;
|
||||||
else if ( strcmp( "-incr", argv[i]) == 0)
|
else if ( strcmp( "-incr", argv[i]) == 0)
|
||||||
incr = true;
|
incr = true;
|
||||||
else if ( (strcmp( "-h", argv[i]) == 0) ||
|
else if ( (strcmp( "-h", argv[i]) == 0) ||
|
||||||
(strcmp( "-help", argv[i]) == 0))
|
(strcmp( "-help", argv[i]) == 0))
|
||||||
help = true;
|
help = true;
|
||||||
else if ( n < 2 ) {
|
else if ( n < 2 ) {
|
||||||
filename[ n++] = argv[i];
|
filename[ n++] = argv[i];
|
||||||
} else {
|
} else {
|
||||||
++n;
|
++n;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((n > 2) || help) {
|
if ((n > 2) || help) {
|
||||||
if ( ! help)
|
if ( ! help)
|
||||||
cerr << "Error: in parameter list" << endl;
|
cerr << "Error: in parameter list" << endl;
|
||||||
cerr << "Usage: " << argv[0] << " [<options>] [<infile> [<outfile>]]"
|
cerr << "Usage: " << argv[0] << " [<options>] [<infile> [<outfile>]]"
|
||||||
<< endl;
|
<< endl;
|
||||||
cerr << " Terrain triangulation in the xy-plane." << endl;
|
cerr << " Terrain triangulation in the xy-plane." << endl;
|
||||||
cerr << " -delaunay Delaunay triangulation (default)." << endl;
|
cerr << " -delaunay Delaunay triangulation (default)." << endl;
|
||||||
cerr << " -incr Incremental insertion (no flips)." << endl;
|
cerr << " -incr Incremental insertion (no flips)." << endl;
|
||||||
cerr << " -b binary output (default is ASCII)." << endl;
|
cerr << " -b binary output (default is ASCII)." << endl;
|
||||||
cerr << " -noc no comments in file." << endl;
|
cerr << " -noc no comments in file." << endl;
|
||||||
cerr << " -v verbose." << endl;
|
cerr << " -v verbose." << endl;
|
||||||
exit( ! help);
|
exit( ! help);
|
||||||
}
|
}
|
||||||
|
|
||||||
CGAL::Verbose_ostream vout( verbose);
|
CGAL::Verbose_ostream vout( verbose);
|
||||||
|
|
@ -96,77 +96,77 @@ int main( int argc, char **argv) {
|
||||||
istream* p_in = &cin;
|
istream* p_in = &cin;
|
||||||
ifstream in;
|
ifstream in;
|
||||||
if ( n > 0) {
|
if ( n > 0) {
|
||||||
in.open( filename[0]);
|
in.open( filename[0]);
|
||||||
p_in = ∈
|
p_in = ∈
|
||||||
iname = filename[0];
|
iname = filename[0];
|
||||||
}
|
}
|
||||||
if ( !*p_in) {
|
if ( !*p_in) {
|
||||||
cerr << argv[0] << ": error: cannot open file '" << iname
|
cerr << argv[0] << ": error: cannot open file '" << iname
|
||||||
<< "' for reading." <<endl;
|
<< "' for reading." <<endl;
|
||||||
exit( 1);
|
exit( 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
CGAL::File_scanner_OFF scanner( * p_in, true);
|
CGAL::File_scanner_OFF scanner( * p_in, true);
|
||||||
if ( !*p_in)
|
if ( !*p_in)
|
||||||
exit( 1);
|
exit( 1);
|
||||||
|
|
||||||
const char* oname = "cout";
|
const char* oname = "cout";
|
||||||
ostream* p_out = &cout;
|
ostream* p_out = &cout;
|
||||||
ofstream out;
|
ofstream out;
|
||||||
if ( n > 1) {
|
if ( n > 1) {
|
||||||
out.open( filename[1]);
|
out.open( filename[1]);
|
||||||
p_out = &out;
|
p_out = &out;
|
||||||
oname = filename[1];
|
oname = filename[1];
|
||||||
}
|
}
|
||||||
if ( !*p_out) {
|
if ( !*p_out) {
|
||||||
cerr << argv[0] << ": error: cannot open file '"<< oname
|
cerr << argv[0] << ": error: cannot open file '"<< oname
|
||||||
<< "' for writing." <<endl;
|
<< "' for writing." <<endl;
|
||||||
exit( 1);
|
exit( 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// index array.
|
// index array.
|
||||||
int* indices = new int[ scanner.size_of_vertices()];
|
int* indices = new int[ scanner.size_of_vertices()];
|
||||||
for ( std::size_t k = 0; k < scanner.size_of_vertices(); k++)
|
for ( std::size_t k = 0; k < scanner.size_of_vertices(); k++)
|
||||||
indices[k] = -1;
|
indices[k] = -1;
|
||||||
|
|
||||||
if ( delaunay || ! incr) {
|
if ( delaunay || ! incr) {
|
||||||
Delaunay_triangulation triang;
|
Delaunay_triangulation triang;
|
||||||
vout << "Scanning and triangulating ..." << endl;
|
vout << "Scanning and triangulating ..." << endl;
|
||||||
for ( std::size_t j = 0; j < scanner.size_of_vertices(); j++) {
|
for ( std::size_t j = 0; j < scanner.size_of_vertices(); j++) {
|
||||||
double x, y, z;
|
double x, y, z;
|
||||||
scanner.scan_vertex( x, y, z);
|
scanner.scan_vertex( x, y, z);
|
||||||
IPoint p( x, y, z, indices + j);
|
IPoint p( x, y, z, indices + j);
|
||||||
triang.insert( p);
|
triang.insert( p);
|
||||||
}
|
}
|
||||||
vout << " .... done." << endl;
|
vout << " .... done." << endl;
|
||||||
vout << "write_triangulation( " << oname
|
vout << "write_triangulation( " << oname
|
||||||
<< (binary ? ", binary" : ", ASCII") << ") ...." << endl;
|
<< (binary ? ", binary" : ", ASCII") << ") ...." << endl;
|
||||||
CGAL::triangulation_print_OFF( *p_out, triang, binary, noc, verbose);
|
CGAL::triangulation_print_OFF( *p_out, triang, binary, noc, verbose);
|
||||||
vout << " .... done." << endl;
|
vout << " .... done." << endl;
|
||||||
} else {
|
} else {
|
||||||
Triangulation triang;
|
Triangulation triang;
|
||||||
vout << "Scanning and triangulating ..." << endl;
|
vout << "Scanning and triangulating ..." << endl;
|
||||||
for ( std::size_t j = 0; j < scanner.size_of_vertices(); j++) {
|
for ( std::size_t j = 0; j < scanner.size_of_vertices(); j++) {
|
||||||
double x, y, z;
|
double x, y, z;
|
||||||
scanner.scan_vertex( x, y, z);
|
scanner.scan_vertex( x, y, z);
|
||||||
IPoint p( x, y, z, indices + j);
|
IPoint p( x, y, z, indices + j);
|
||||||
triang.insert( p);
|
triang.insert( p);
|
||||||
}
|
}
|
||||||
vout << " .... done." << endl;
|
vout << " .... done." << endl;
|
||||||
vout << "write_triangulation( " << oname
|
vout << "write_triangulation( " << oname
|
||||||
<< (binary ? ", binary" : ", ASCII") << ") ...." << endl;
|
<< (binary ? ", binary" : ", ASCII") << ") ...." << endl;
|
||||||
CGAL::triangulation_print_OFF( *p_out, triang, binary, noc, verbose);
|
CGAL::triangulation_print_OFF( *p_out, triang, binary, noc, verbose);
|
||||||
vout << " .... done." << endl;
|
vout << " .... done." << endl;
|
||||||
}
|
}
|
||||||
if ( !*p_in) {
|
if ( !*p_in) {
|
||||||
cerr << argv[0] << " read error: while reading file '"<< iname << "'."
|
cerr << argv[0] << " read error: while reading file '"<< iname << "'."
|
||||||
<< endl;
|
<< endl;
|
||||||
exit( 1);
|
exit( 1);
|
||||||
}
|
}
|
||||||
if ( !*p_out) {
|
if ( !*p_out) {
|
||||||
cerr << argv[0] << " write error: while writing file '"<< oname << "'."
|
cerr << argv[0] << " write error: while writing file '"<< oname << "'."
|
||||||
<< endl;
|
<< endl;
|
||||||
exit( 1);
|
exit( 1);
|
||||||
}
|
}
|
||||||
delete[] indices;
|
delete[] indices;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue