mirror of https://github.com/CGAL/cgal
Merge branch 'master' into CGAL-Prepare_CHANGES.md_6.1-GF
This commit is contained in:
commit
6efa5d932a
|
|
@ -16,7 +16,7 @@
|
||||||
*.py text
|
*.py text
|
||||||
*.xml text
|
*.xml text
|
||||||
*.js text
|
*.js text
|
||||||
*.hmtl text
|
*.html text
|
||||||
*.bib text
|
*.bib text
|
||||||
*.css text
|
*.css text
|
||||||
*.ui text
|
*.ui text
|
||||||
|
|
|
||||||
|
|
@ -106,7 +106,7 @@ it is used only for distance computations.
|
||||||
\warning Having degenerate primitives in the AABB-tree is not recommended as the underlying
|
\warning Having degenerate primitives in the AABB-tree is not recommended as the underlying
|
||||||
predicates and constructions of the traits class might not be able to handle them.
|
predicates and constructions of the traits class might not be able to handle them.
|
||||||
For example if one is using `CGAL::AABB_traits` with a Kernel from \cgal,
|
For example if one is using `CGAL::AABB_traits` with a Kernel from \cgal,
|
||||||
having degenerate triangles or segments in the AABB-tree will results in an undefined
|
having degenerate triangles or segments in the AABB-tree will result in an undefined
|
||||||
behavior or a crash.
|
behavior or a crash.
|
||||||
|
|
||||||
\section aabb_tree_examples Examples
|
\section aabb_tree_examples Examples
|
||||||
|
|
@ -197,9 +197,9 @@ The AABB tree example folder contains three examples of trees
|
||||||
constructed with custom primitives. In \ref AABB_tree/AABB_custom_example.cpp "AABB_custom_example.cpp"
|
constructed with custom primitives. In \ref AABB_tree/AABB_custom_example.cpp "AABB_custom_example.cpp"
|
||||||
the primitive contains triangles which are defined by three pointers
|
the primitive contains triangles which are defined by three pointers
|
||||||
to custom points. In \ref AABB_tree/AABB_custom_triangle_soup_example.cpp "AABB_custom_triangle_soup_example.cpp" all input
|
to custom points. In \ref AABB_tree/AABB_custom_triangle_soup_example.cpp "AABB_custom_triangle_soup_example.cpp" all input
|
||||||
triangles are stored into a single array so as to form a triangle
|
triangles are stored into a single array as to form a triangle
|
||||||
soup. The primitive internally uses a `boost::iterator_adaptor` so as
|
soup. The primitive internally uses a `boost::iterator_adaptor`
|
||||||
to provide the three functions `AABBPrimitive::id()`, `AABBPrimitive::datum()`,
|
as to provide the three functions `AABBPrimitive::id()`, `AABBPrimitive::datum()`,
|
||||||
and `AABBPrimitive::reference_point()`) required by the primitive concept. In
|
and `AABBPrimitive::reference_point()`) required by the primitive concept. In
|
||||||
\ref AABB_tree/AABB_custom_indexed_triangle_set_example.cpp "AABB_custom_indexed_triangle_set_example.cpp" the input is an indexed
|
\ref AABB_tree/AABB_custom_indexed_triangle_set_example.cpp "AABB_custom_indexed_triangle_set_example.cpp" the input is an indexed
|
||||||
triangle set stored through two arrays: one array of points and one
|
triangle set stored through two arrays: one array of points and one
|
||||||
|
|
@ -213,7 +213,7 @@ contains a set of polyhedron triangle facets. We measure the tree
|
||||||
construction time, the memory occupancy and the number of queries per
|
construction time, the memory occupancy and the number of queries per
|
||||||
second for a variety of intersection and distance queries. The machine
|
second for a variety of intersection and distance queries. The machine
|
||||||
used is a PC running Windows XP64 with an Intel CPU Core2 Extreme
|
used is a PC running Windows XP64 with an Intel CPU Core2 Extreme
|
||||||
clocked at 3.06 GHz with 4GB of RAM. By default the kernel used is
|
clocked at 3.06 GHz with 4GB of RAM. By default, the kernel used is
|
||||||
`Simple_cartesian<double>` (the fastest in our experiments). The
|
`Simple_cartesian<double>` (the fastest in our experiments). The
|
||||||
program has been compiled with Visual C++ 2005 compiler with the O2
|
program has been compiled with Visual C++ 2005 compiler with the O2
|
||||||
option which maximizes speed.
|
option which maximizes speed.
|
||||||
|
|
@ -244,7 +244,7 @@ internal KD-tree). It increases to approximately 150 bytes per
|
||||||
primitive when constructing the internal KD-tree with one reference
|
primitive when constructing the internal KD-tree with one reference
|
||||||
point per primitive (the default mode when calling the function
|
point per primitive (the default mode when calling the function
|
||||||
`AABB_tree::accelerate_distance_queries()`). Note that the polyhedron
|
`AABB_tree::accelerate_distance_queries()`). Note that the polyhedron
|
||||||
facet primitive primitive stores only one facet handle as primitive id
|
facet primitive stores only one facet handle as primitive id
|
||||||
and computes on the fly a 3D triangle from the facet handle stored
|
and computes on the fly a 3D triangle from the facet handle stored
|
||||||
internally. When explicitly storing a 3D triangle in the primitive the
|
internally. When explicitly storing a 3D triangle in the primitive the
|
||||||
tree occupies approximately 140 bytes per primitive instead of 60
|
tree occupies approximately 140 bytes per primitive instead of 60
|
||||||
|
|
@ -340,7 +340,7 @@ inside the bounding box.
|
||||||
|
|
||||||
The experiments described above are neither exhaustive nor conclusive
|
The experiments described above are neither exhaustive nor conclusive
|
||||||
as we have chosen one specific case where the input primitives are the
|
as we have chosen one specific case where the input primitives are the
|
||||||
facets of a triangle surface polyhedron. Nevertheless we now provide
|
facets of a triangle surface polyhedron. Nevertheless, we now provide
|
||||||
some general observations and advises about how to put the AABB tree
|
some general observations and advises about how to put the AABB tree
|
||||||
to use with satisfactory performances. While the tree construction
|
to use with satisfactory performances. While the tree construction
|
||||||
times and memory occupancy do not fluctuate much in our experiments
|
times and memory occupancy do not fluctuate much in our experiments
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ As a consequence types representing polynomials, algebraic extensions and
|
||||||
finite fields play a more important role in related implementations.
|
finite fields play a more important role in related implementations.
|
||||||
This package has been introduced to stay abreast of these changes.
|
This package has been introduced to stay abreast of these changes.
|
||||||
Since in particular polynomials must be supported by the introduced framework
|
Since in particular polynomials must be supported by the introduced framework
|
||||||
the package avoids the term <I>number type</I>. Instead the package distinguishes
|
the package avoids the term <I>number type</I>. Instead, the package distinguishes
|
||||||
between the <I>algebraic structure</I> of a type and whether a type is embeddable on
|
between the <I>algebraic structure</I> of a type and whether a type is embeddable on
|
||||||
the real axis, or <I>real embeddable</I> for short.
|
the real axis, or <I>real embeddable</I> for short.
|
||||||
Moreover, the package introduces the notion of <I>interoperable</I> types which
|
Moreover, the package introduces the notion of <I>interoperable</I> types which
|
||||||
|
|
@ -45,11 +45,11 @@ the operations 'sqrt', 'k-th root' and 'real root of a polynomial',
|
||||||
respectively. The concept `IntegralDomainWithoutDivision` also
|
respectively. The concept `IntegralDomainWithoutDivision` also
|
||||||
corresponds to integral domains in the algebraic sense, the
|
corresponds to integral domains in the algebraic sense, the
|
||||||
distinction results from the fact that some implementations of
|
distinction results from the fact that some implementations of
|
||||||
integral domains lack the (algebraically always well defined) integral
|
integral domains lack the (algebraically always well-defined) integral
|
||||||
division.
|
division.
|
||||||
Note that `Field` refines `IntegralDomain`. This is because
|
Note that `Field` refines `IntegralDomain`. This is because
|
||||||
most ring-theoretic notions like greatest common divisors become trivial for
|
most ring-theoretic notions like greatest common divisors become trivial for
|
||||||
`Field`s. Hence we see `Field` as a refinement of
|
`Field`s. Hence, we see `Field` as a refinement of
|
||||||
`IntegralDomain` and not as a
|
`IntegralDomain` and not as a
|
||||||
refinement of one of the more advanced ring concepts.
|
refinement of one of the more advanced ring concepts.
|
||||||
If an algorithm wants to rely on gcd or remainder computation, it is trying
|
If an algorithm wants to rely on gcd or remainder computation, it is trying
|
||||||
|
|
@ -119,7 +119,7 @@ Conversely, types as `leda_real` or `CORE::Expr` are exact but sensitive
|
||||||
to numerical issues due to the internal use of multi precision floating point
|
to numerical issues due to the internal use of multi precision floating point
|
||||||
arithmetic. We expect that `Is_numerical_sensitive` is used for dispatching
|
arithmetic. We expect that `Is_numerical_sensitive` is used for dispatching
|
||||||
of algorithms, while `Is_exact` is useful to enable assertions that can be
|
of algorithms, while `Is_exact` is useful to enable assertions that can be
|
||||||
check for exact types only.
|
checked for exact types only.
|
||||||
|
|
||||||
Tags are very useful to dispatch between alternative implementations.
|
Tags are very useful to dispatch between alternative implementations.
|
||||||
The following example illustrates a dispatch for `Field`s using overloaded
|
The following example illustrates a dispatch for `Field`s using overloaded
|
||||||
|
|
@ -134,7 +134,7 @@ category tags reflect the algebraic structure hierarchy.
|
||||||
|
|
||||||
Most number types represent some subset of the real numbers. From those types
|
Most number types represent some subset of the real numbers. From those types
|
||||||
we expect functionality to compute the sign, absolute value or double
|
we expect functionality to compute the sign, absolute value or double
|
||||||
approximations. In particular we can expect an order on such a type that
|
approximations. In particular, we can expect an order on such a type that
|
||||||
reflects the order along the real axis.
|
reflects the order along the real axis.
|
||||||
All these properties are gathered in the concept `::RealEmbeddable`.
|
All these properties are gathered in the concept `::RealEmbeddable`.
|
||||||
The concept is orthogonal to the algebraic structure concepts,
|
The concept is orthogonal to the algebraic structure concepts,
|
||||||
|
|
@ -190,12 +190,12 @@ In general mixed operations are provided by overloaded operators and
|
||||||
functions or just via implicit constructor calls.
|
functions or just via implicit constructor calls.
|
||||||
This level of interoperability is reflected by the concept
|
This level of interoperability is reflected by the concept
|
||||||
`ImplicitInteroperable`. However, within template code the result type,
|
`ImplicitInteroperable`. However, within template code the result type,
|
||||||
or so called coercion type, of a mixed arithmetic operation may be unclear.
|
or so-called coercion type, of a mixed arithmetic operation may be unclear.
|
||||||
Therefore, the package introduces `Coercion_traits`
|
Therefore, the package introduces `Coercion_traits`
|
||||||
giving access to the coercion type via \link Coercion_traits::Type `Coercion_traits<A,B>::Type` \endlink
|
giving access to the coercion type via \link Coercion_traits::Type `Coercion_traits<A,B>::Type` \endlink
|
||||||
for two interoperable types `A` and `B`.
|
for two interoperable types `A` and `B`.
|
||||||
|
|
||||||
Some trivial example are `int` and `double` with coercion type double
|
Some trivial examples are `int` and `double` with coercion type double
|
||||||
or `Gmpz` and `Gmpq` with coercion type `Gmpq`.
|
or `Gmpz` and `Gmpq` with coercion type `Gmpq`.
|
||||||
However, the coercion type is not necessarily one of the input types,
|
However, the coercion type is not necessarily one of the input types,
|
||||||
e.g. the coercion type of a polynomial
|
e.g. the coercion type of a polynomial
|
||||||
|
|
@ -269,7 +269,7 @@ The package is part of \cgal since release 3.3. Of course the package is based
|
||||||
on the former Number type support of CGAL. This goes back to Stefan Schirra and Andreas Fabri. But on the other hand the package is to a large extend influenced
|
on the former Number type support of CGAL. This goes back to Stefan Schirra and Andreas Fabri. But on the other hand the package is to a large extend influenced
|
||||||
by the experience with the number type support in \exacus \cgalCite{beh-eeeafcs-05},
|
by the experience with the number type support in \exacus \cgalCite{beh-eeeafcs-05},
|
||||||
which in the main goes back to
|
which in the main goes back to
|
||||||
Lutz Kettner, Susan Hert, Arno Eigenwillig and Michael Hemmer.
|
Lutz Kettner, Susan Hert, Arno Eigenwillig, and Michael Hemmer.
|
||||||
However, the package abstracts from the pure support for
|
However, the package abstracts from the pure support for
|
||||||
number types that are embedded on the real axis which allows the support of
|
number types that are embedded on the real axis which allows the support of
|
||||||
polynomials, finite fields, and algebraic extensions as well. See also related
|
polynomials, finite fields, and algebraic extensions as well. See also related
|
||||||
|
|
|
||||||
|
|
@ -146,8 +146,8 @@ polynomial is not computed yet.
|
||||||
This is in particular relevant in relation to the `AlgebraicKernel_d_2`,
|
This is in particular relevant in relation to the `AlgebraicKernel_d_2`,
|
||||||
where `AlgebraicKernel_d_1::Algebraic_real_1` is used to represent coordinates of solutions of bivariate systems.
|
where `AlgebraicKernel_d_1::Algebraic_real_1` is used to represent coordinates of solutions of bivariate systems.
|
||||||
Hence, the design does
|
Hence, the design does
|
||||||
not allow a direct access to any, seemingly obvious, members of an
|
not allow direct access to any, seemingly obvious, members of an
|
||||||
`AlgebraicKernel_d_1::Algebraic_real_1`. Instead there is, e.g.,
|
`AlgebraicKernel_d_1::Algebraic_real_1`. Instead, there is, e.g.,
|
||||||
`AlgebraicKernel_d_1::Compute_polynomial_1` which emphasizes
|
`AlgebraicKernel_d_1::Compute_polynomial_1` which emphasizes
|
||||||
that the requested polynomial may not be computed yet. Similarly,
|
that the requested polynomial may not be computed yet. Similarly,
|
||||||
there is no way to directly ask for the refinement of the current
|
there is no way to directly ask for the refinement of the current
|
||||||
|
|
|
||||||
|
|
@ -35,8 +35,8 @@ of this process in 2D (where our ice-cream spoon is simply a circle).
|
||||||
|
|
||||||
Alpha shapes depend on a parameter \f$ \alpha\f$ after which they are named.
|
Alpha shapes depend on a parameter \f$ \alpha\f$ after which they are named.
|
||||||
In the ice-cream analogy above, \f$ \alpha\f$ is the squared radius of the
|
In the ice-cream analogy above, \f$ \alpha\f$ is the squared radius of the
|
||||||
carving spoon. A very small value will allow us to eat up all of the
|
carving spoon. A very small value will allow us to eat up all the
|
||||||
ice-cream except the chocolate points themselves. Thus we already see
|
ice-cream except the chocolate points themselves. Thus, we already see
|
||||||
that the \f$ \alpha\f$-shape degenerates to the point-set \f$ S\f$ for
|
that the \f$ \alpha\f$-shape degenerates to the point-set \f$ S\f$ for
|
||||||
\f$ \alpha \rightarrow 0\f$. On the other hand, a huge value of \f$ \alpha\f$
|
\f$ \alpha \rightarrow 0\f$. On the other hand, a huge value of \f$ \alpha\f$
|
||||||
will prevent us even from moving the spoon between two points since
|
will prevent us even from moving the spoon between two points since
|
||||||
|
|
@ -53,7 +53,7 @@ We distinguish two versions of alpha shapes. <I>Basic alpha shapes</I>
|
||||||
are based on the Delaunay triangulation. <I>Weighted alpha shapes</I>
|
are based on the Delaunay triangulation. <I>Weighted alpha shapes</I>
|
||||||
are based on its generalization, the regular triangulation
|
are based on its generalization, the regular triangulation
|
||||||
(cf. Section \ref Section_2D_Triangulations_Regular "Regular Triangulations"),
|
(cf. Section \ref Section_2D_Triangulations_Regular "Regular Triangulations"),
|
||||||
replacing the euclidean distance by the power to weighted points.
|
replacing the Euclidean distance by the power to weighted points.
|
||||||
|
|
||||||
There is a close connection between alpha shapes and the underlying
|
There is a close connection between alpha shapes and the underlying
|
||||||
triangulations. More precisely, the \f$ \alpha\f$-complex of \f$ S\f$ is a
|
triangulations. More precisely, the \f$ \alpha\f$-complex of \f$ S\f$ is a
|
||||||
|
|
@ -100,7 +100,7 @@ It provides iterators to enumerate the vertices and edges that are in
|
||||||
the \f$ \alpha\f$-shape, and functions that allow to classify vertices,
|
the \f$ \alpha\f$-shape, and functions that allow to classify vertices,
|
||||||
edges and faces with respect to the \f$ \alpha\f$-shape. They can be in
|
edges and faces with respect to the \f$ \alpha\f$-shape. They can be in
|
||||||
the interior of a face that belongs or does not belong to the \f$ \alpha\f$-shape.
|
the interior of a face that belongs or does not belong to the \f$ \alpha\f$-shape.
|
||||||
They can be singular/regular, that is be on the boundary of the \f$ \alpha\f$-shape,
|
They can be singular/regular, that is, they can be on the boundary of the \f$ \alpha\f$-shape,
|
||||||
but not incident/incident to a triangle of the \f$ \alpha\f$-complex.
|
but not incident/incident to a triangle of the \f$ \alpha\f$-complex.
|
||||||
|
|
||||||
Finally, it provides a function to determine the \f$ \alpha\f$-value
|
Finally, it provides a function to determine the \f$ \alpha\f$-value
|
||||||
|
|
@ -213,7 +213,7 @@ cube will be chosen and no optimizations will be used.
|
||||||
It is also recommended to switch the triangulation to 1-sheeted
|
It is also recommended to switch the triangulation to 1-sheeted
|
||||||
covering if possible. Note that a periodic triangulation in 9-sheeted
|
covering if possible. Note that a periodic triangulation in 9-sheeted
|
||||||
covering space is degenerate. In this case, an exact constructions
|
covering space is degenerate. In this case, an exact constructions
|
||||||
kernel needs to be used to compute the alpha shapes. Otherwise the
|
kernel needs to be used to compute the alpha shapes. Otherwise, the
|
||||||
results will suffer from round-off problems.
|
results will suffer from round-off problems.
|
||||||
|
|
||||||
\cgalExample{Alpha_shapes_2/ex_periodic_alpha_shapes_2.cpp}
|
\cgalExample{Alpha_shapes_2/ex_periodic_alpha_shapes_2.cpp}
|
||||||
|
|
|
||||||
|
|
@ -34,8 +34,8 @@ of this process in 2D (where our ice-cream spoon is simply a circle).
|
||||||
|
|
||||||
Alpha shapes depend on a parameter \f$ \alpha\f$ after which they are named.
|
Alpha shapes depend on a parameter \f$ \alpha\f$ after which they are named.
|
||||||
In the ice-cream analogy above, \f$ \alpha\f$ is the squared radius of the
|
In the ice-cream analogy above, \f$ \alpha\f$ is the squared radius of the
|
||||||
carving spoon. A very small value will allow us to eat up all of the
|
carving spoon. A very small value will allow us to eat up all the
|
||||||
ice-cream except the chocolate points themselves. Thus we already see
|
ice-cream except the chocolate points themselves. Thus, we already see
|
||||||
that the alpha shape degenerates to the point-set \f$ S\f$ for
|
that the alpha shape degenerates to the point-set \f$ S\f$ for
|
||||||
\f$ \alpha \rightarrow 0\f$. On the other hand, a huge value of \f$ \alpha\f$
|
\f$ \alpha \rightarrow 0\f$. On the other hand, a huge value of \f$ \alpha\f$
|
||||||
will prevent us even from moving the spoon between two points since
|
will prevent us even from moving the spoon between two points since
|
||||||
|
|
@ -53,7 +53,7 @@ We distinguish two versions of alpha shapes. <I>Basic alpha shapes</I>
|
||||||
are based on the Delaunay triangulation. <I>Weighted alpha shapes</I>
|
are based on the Delaunay triangulation. <I>Weighted alpha shapes</I>
|
||||||
are based on its generalization, the regular triangulation
|
are based on its generalization, the regular triangulation
|
||||||
(cf. Section \ref Triangulation3secclassRegulartriangulation "Regular Triangulations"),
|
(cf. Section \ref Triangulation3secclassRegulartriangulation "Regular Triangulations"),
|
||||||
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$.
|
||||||
|
|
@ -79,7 +79,7 @@ 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 contain any singular facet.
|
||||||
\cgalFigureEnd
|
\cgalFigureEnd
|
||||||
|
|
||||||
The alpha shapes of a set of points
|
The alpha shapes of a set of points
|
||||||
|
|
@ -112,11 +112,11 @@ and radii \f$ r_1, r_2 \f$ are said to be orthogonal iff
|
||||||
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 such that there is a sphere
|
||||||
such that there is a sphere orthogonal to the weighted points associated
|
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
|
||||||
input weighted points. Once again the alpha shape is then defined as
|
input weighted points. Once again the alpha shape is then defined as
|
||||||
the domain covered by a the alpha complex and comes in general and
|
the domain covered by the alpha complex and comes in general and
|
||||||
regularized versions.
|
regularized versions.
|
||||||
|
|
||||||
\section Alpha_Shape_3Functionality Functionality
|
\section Alpha_Shape_3Functionality Functionality
|
||||||
|
|
@ -273,7 +273,7 @@ alpha-shape, using the `Alpha_shape_3<Dt,ExactAlphaComparisonTag>` requires a ke
|
||||||
with exact predicates and exact constructions (or setting `ExactAlphaComparisonTag` to `Tag_true`)
|
with exact predicates and exact constructions (or setting `ExactAlphaComparisonTag` to `Tag_true`)
|
||||||
while using a kernel with exact predicates is sufficient for the class `Fixed_alpha_shape_3<Dt>`.
|
while using a kernel with exact predicates is sufficient for the class `Fixed_alpha_shape_3<Dt>`.
|
||||||
This makes the class `Fixed_alpha_shape_3<Dt>` even more efficient in this setting.
|
This makes the class `Fixed_alpha_shape_3<Dt>` even more efficient in this setting.
|
||||||
In addition, note that the `Fixed` version is the only of the
|
In addition, note that the `Fixed` version is the only one of the
|
||||||
two that supports incremental insertion and removal of points.
|
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
|
||||||
|
|
@ -345,7 +345,7 @@ cube will be chosen and no optimizations will be used.
|
||||||
It is also recommended to switch the triangulation to 1-sheeted
|
It is also recommended to switch the triangulation to 1-sheeted
|
||||||
covering if possible. Note that a periodic triangulation in 27-sheeted
|
covering if possible. Note that a periodic triangulation in 27-sheeted
|
||||||
covering space is degenerate. In this case, an exact constructions
|
covering space is degenerate. In this case, an exact constructions
|
||||||
kernel needs to be used to compute the alpha shapes. Otherwise the
|
kernel needs to be used to compute the alpha shapes. Otherwise, the
|
||||||
results will suffer from round-off problems.
|
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}
|
||||||
|
|
|
||||||
|
|
@ -264,7 +264,7 @@ Secondly, the farther the isosurface is from the input, the more new points are
|
||||||
through the first criterion (i.e., through intersection with dual Voronoi edge, see Section \ref aw3_algorithm);
|
through the first criterion (i.e., through intersection with dual Voronoi edge, see Section \ref aw3_algorithm);
|
||||||
thus, the quality of the output improves in terms of angles of the triangle elements.
|
thus, the quality of the output improves in terms of angles of the triangle elements.
|
||||||
Finally, and depending on the value of the alpha parameter, a large offset can also offer defeaturing capabilities.
|
Finally, and depending on the value of the alpha parameter, a large offset can also offer defeaturing capabilities.
|
||||||
However using a small offset parameter will tend to better preserve sharp features as projection
|
However, using a small offset parameter will tend to better preserve sharp features as projection
|
||||||
Steiner points tend to project onto convex sharp features.
|
Steiner points tend to project onto convex sharp features.
|
||||||
|
|
||||||
\cgalFigureAnchor{6}
|
\cgalFigureAnchor{6}
|
||||||
|
|
@ -278,7 +278,7 @@ Impact of the offset parameter on the output.
|
||||||
The offset parameter is decreasing from left to right, to respectively 1/50, 1/200 and 1/1000 of the longest diagonal of the input bounding box.
|
The offset parameter is decreasing from left to right, to respectively 1/50, 1/200 and 1/1000 of the longest diagonal of the input bounding box.
|
||||||
The alpha parameter is equal to 1/50 of the longest diagonal of the input bounding box for all level of details.
|
The alpha parameter is equal to 1/50 of the longest diagonal of the input bounding box for all level of details.
|
||||||
A larger offset will produce an output less complex with better triangle quality.
|
A larger offset will produce an output less complex with better triangle quality.
|
||||||
However the sharp features (red edges) are well preserved when the offset parameter is small.
|
However, the sharp features (red edges) are well-preserved when the offset parameter is small.
|
||||||
\cgalFigureCaptionEnd
|
\cgalFigureCaptionEnd
|
||||||
|
|
||||||
\cgalFigureAnchor{7}
|
\cgalFigureAnchor{7}
|
||||||
|
|
@ -346,15 +346,15 @@ The charts below plots the computation times of the wrapping algorithm on the Th
|
||||||
\cgalFigureCaptionBegin{9}
|
\cgalFigureCaptionBegin{9}
|
||||||
Execution times and output complexity for different values of alpha on the Thingi10k data set.
|
Execution times and output complexity for different values of alpha on the Thingi10k data set.
|
||||||
Alpha increases from 1/20 to 1/200 of the length of bounding box diagonal.
|
Alpha increases from 1/20 to 1/200 of the length of bounding box diagonal.
|
||||||
The x axis represents the complexity of the output wrap mesh in number of triangle facets.
|
The x-axis represents the complexity of the output wrap mesh in number of triangle facets.
|
||||||
The y axis represents the total computation time, in seconds.
|
The y-axis represents the total computation time, in seconds.
|
||||||
The color and diameter of the dots represent the number of faces in the input triangle soup,
|
The color and diameter of the dots represent the number of faces in the input triangle soup,
|
||||||
ranging from 10 (green) to 3154000 (blue).
|
ranging from 10 (green) to 3154000 (blue).
|
||||||
\cgalFigureCaptionEnd
|
\cgalFigureCaptionEnd
|
||||||
|
|
||||||
\section aw3_examples Examples
|
\section aw3_examples Examples
|
||||||
|
|
||||||
Here is an example with an input triangle mesh, with alpha set to 1/20 of the bounding box longest diagonal edge length,
|
Here is an example with an input triangle mesh, with alpha set to 1/20 of the bounding box's longest diagonal edge length,
|
||||||
and offset set to 1/30 of alpha (i.e., 1/600 of the bounding box diagonal edge length).
|
and offset set to 1/30 of alpha (i.e., 1/600 of the bounding box diagonal edge length).
|
||||||
|
|
||||||
\cgalExample{Alpha_wrap_3/triangle_mesh_wrap.cpp}
|
\cgalExample{Alpha_wrap_3/triangle_mesh_wrap.cpp}
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ returns one of the halfedges corresponding to `e`.
|
||||||
*/
|
*/
|
||||||
template <typename HalfedgeGraph>
|
template <typename HalfedgeGraph>
|
||||||
boost::graph_traits<HalfedgeGraph>::halfedge_descriptor
|
boost::graph_traits<HalfedgeGraph>::halfedge_descriptor
|
||||||
halfedge(boost::graph_traits<HalfedgeGraph>::edge_descriptor f, const HalfedgeGraph& g);
|
halfedge(boost::graph_traits<HalfedgeGraph>::edge_descriptor e, const HalfedgeGraph& g);
|
||||||
|
|
||||||
/*! \relates HalfedgeGraph
|
/*! \relates HalfedgeGraph
|
||||||
returns a halfedge with target `v`.
|
returns a halfedge with target `v`.
|
||||||
|
|
|
||||||
|
|
@ -278,7 +278,9 @@ def main():
|
||||||
encoding="utf-8",
|
encoding="utf-8",
|
||||||
)
|
)
|
||||||
k = 2
|
k = 2
|
||||||
|
citeDic = {}
|
||||||
for line in f:
|
for line in f:
|
||||||
|
foundDouble=False
|
||||||
match = pattern.match(line)
|
match = pattern.match(line)
|
||||||
if match:
|
if match:
|
||||||
pkg = match.group(1)
|
pkg = match.group(1)
|
||||||
|
|
@ -304,6 +306,10 @@ def main():
|
||||||
match = pattern_bib.match(pkg_line)
|
match = pattern_bib.match(pkg_line)
|
||||||
if match:
|
if match:
|
||||||
bib = match.group(1)
|
bib = match.group(1)
|
||||||
|
if bib in citeDic:
|
||||||
|
foundDouble=True
|
||||||
|
else:
|
||||||
|
citeDic[bib] = pkg
|
||||||
continue
|
continue
|
||||||
assert len(bib) > 0, "Did you forget a \\cgalPkgBib{} in %r?" % filename
|
assert len(bib) > 0, "Did you forget a \\cgalPkgBib{} in %r?" % filename
|
||||||
assert len(authors) > 0, (
|
assert len(authors) > 0, (
|
||||||
|
|
@ -313,6 +319,11 @@ def main():
|
||||||
"Did you forget the anchor in \\cgalPkgDescriptionBegin{} in %r?"
|
"Did you forget the anchor in \\cgalPkgDescriptionBegin{} in %r?"
|
||||||
% filename
|
% filename
|
||||||
)
|
)
|
||||||
|
assert not foundDouble, (
|
||||||
|
"""Multiple use of citation name '{}' package '{}'
|
||||||
|
first occurence package '{}'
|
||||||
|
""".format(bib,pkg,citeDic[bib])
|
||||||
|
)
|
||||||
result_txt += gen_txt_entry(title, authors, bib, anchor, k)
|
result_txt += gen_txt_entry(title, authors, bib, anchor, k)
|
||||||
# convert title and author to bibtex format
|
# convert title and author to bibtex format
|
||||||
title = protect_upper_case(title)
|
title = protect_upper_case(title)
|
||||||
|
|
|
||||||
|
|
@ -192,7 +192,7 @@ i.e.\ \f$ |*g| < r\f$. Two random numbers are needed from
|
||||||
`rnd` for each point.
|
`rnd` for each point.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
Random_points_in_disc_2( double r, Random& rnd =
|
Random_points_in_disc_2( double r = 1.0, Random& rnd =
|
||||||
get_default_random());
|
get_default_random());
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
@ -527,7 +527,7 @@ i.e.\ \f$ |*g| == r\f$. A single random number is needed from
|
||||||
`rnd` for each point.
|
`rnd` for each point.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
Random_points_on_circle_2( double r, Random& rnd =
|
Random_points_on_circle_2( double r=1.0, Random& rnd =
|
||||||
get_default_random());
|
get_default_random());
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
|
||||||
|
|
@ -153,7 +153,7 @@ i.e.\ \f$ |*g| < r\f$ . Three random numbers are needed from
|
||||||
`rnd` for each point.
|
`rnd` for each point.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
Random_points_in_sphere_3( double r, Random& rnd =
|
Random_points_in_sphere_3( double r = 1.0, Random& rnd =
|
||||||
get_default_random());
|
get_default_random());
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
@ -719,7 +719,7 @@ i.e.\ \f$ |*g| == r\f$ . Two random numbers are needed from
|
||||||
`rnd` for each point.
|
`rnd` for each point.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
Random_points_on_sphere_3( double r, Random& rnd =
|
Random_points_on_sphere_3( double r=1.0, Random& rnd =
|
||||||
get_default_random());
|
get_default_random());
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,7 @@ i.e.\ \f$ |*g| < r\f$ . \f$ 2\cdot dim+1\f$ random numbers are needed from
|
||||||
`rnd` for each point.
|
`rnd` for each point.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
Random_points_in_ball_d(int dim, double r);
|
Random_points_in_ball_d(int dim, double r=1.0, Random& rnd = get_default_random());
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
|
|
@ -227,7 +227,7 @@ i.e.\ \f$ |*g| == r\f$ . \f$ 2\cdot dim\f$ random numbers are needed from
|
||||||
`rnd` for each point.
|
`rnd` for each point.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
Random_points_on_sphere_d(int dim, double r, Random& rnd =
|
Random_points_on_sphere_d(int dim, double r=1.0, Random& rnd =
|
||||||
get_default_random());
|
get_default_random());
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ public:
|
||||||
typedef Random_points_in_sphere_3<P,Creator> This;
|
typedef Random_points_in_sphere_3<P,Creator> This;
|
||||||
Random_points_in_sphere_3( double r = 1, Random& rnd = CGAL::get_default_random())
|
Random_points_in_sphere_3( double r = 1, Random& rnd = CGAL::get_default_random())
|
||||||
// g is an input iterator creating points of type `P' uniformly
|
// g is an input iterator creating points of type `P' uniformly
|
||||||
// distributed in the open sphere with radius r, i.e. |`*g'| < r .
|
// distributed in the open sphere with radius r, i.e., |`*g'| < r .
|
||||||
// Three random numbers are needed from `rnd' for each point
|
// Three random numbers are needed from `rnd' for each point
|
||||||
: Random_generator_base<P>( r, rnd) { generate_point(); }
|
: Random_generator_base<P>( r, rnd) { generate_point(); }
|
||||||
This& operator++() {
|
This& operator++() {
|
||||||
|
|
|
||||||
|
|
@ -109,6 +109,10 @@ Release date: _______ 2025
|
||||||
enables the user to specify a `Range` of initial points.
|
enables the user to specify a `Range` of initial points.
|
||||||
- Added a new meshing parameter [`surface_only`](https://doc.cgal.org/6.1/Mesh_3/group__PkgMesh3Parameters.html#gaa2618c09b6117d7caab12dccca16ee58),
|
- Added a new meshing parameter [`surface_only`](https://doc.cgal.org/6.1/Mesh_3/group__PkgMesh3Parameters.html#gaa2618c09b6117d7caab12dccca16ee58),
|
||||||
which can be used to improve performance when only surface mesh generation is sought.
|
which can be used to improve performance when only surface mesh generation is sought.
|
||||||
|
- Added a new mesh domain [`Poisson_mesh_domain_3`](), which should be used when generating a mesh from a Poisson surface
|
||||||
|
obtained with the package [Poisson Surface Reconstruction](https://doc.cgal.org/6.1/Manual/packages.html#PkgPoissonSurfaceReconstruction3).
|
||||||
|
This mesh domain re-integrates some optimizations for Poisson surface mesh generation that were lost
|
||||||
|
when the package [3D Mesh Generation](https://doc.cgal.org/6.1/Manual/packages.html#PkgMesh3) had to be replaced instead of the deprecated package [3D Surface Mesh Generation](https://doc.cgal.org/latest/Manual/packages.html#PkgSurfaceMesher3).
|
||||||
|
|
||||||
### [3D Subdivision Methods](https://doc.cgal.org/6.1/Manual/packages.html#PkgSurfaceSubdivisionMethod3)
|
### [3D Subdivision Methods](https://doc.cgal.org/6.1/Manual/packages.html#PkgSurfaceSubdivisionMethod3)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
//| a derived class. The workaround is to write a forwarder or not use using.
|
//| a derived class. The workaround is to write a forwarder or not use using.
|
||||||
//| At least SunPro CC 5.3 has this bug where the typical error message is :
|
//| At least SunPro CC 5.3 has this bug where the typical error message is :
|
||||||
//| "Error: The function B<int>::g() has not had a body defined."
|
//| "Error: The function B<int>::g() has not had a body defined."
|
||||||
//| Note that the subtlely is that the error message does not mention
|
//| Note that the subtility is that the error message does not mention
|
||||||
//| "Member"...
|
//| "Member"...
|
||||||
//| This test is updated (hijacked) to detect an issue with sunpro 5.9
|
//| This test is updated (hijacked) to detect an issue with sunpro 5.9
|
||||||
//| that instantiates a function twice.
|
//| that instantiates a function twice.
|
||||||
|
|
|
||||||
|
|
@ -7,13 +7,8 @@
|
||||||
// $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) : Stéphane Tayeb, Aymeric PELLE
|
// Author(s) : Stéphane Tayeb, Aymeric PELLE
|
||||||
//
|
|
||||||
//******************************************************************************
|
|
||||||
// File Description :
|
|
||||||
// class Labeled_mesh_domain_3. See class description.
|
|
||||||
//******************************************************************************
|
|
||||||
|
|
||||||
#ifndef CGAL_LABELED_MESH_DOMAIN_3_H
|
#ifndef CGAL_LABELED_MESH_DOMAIN_3_H
|
||||||
#define CGAL_LABELED_MESH_DOMAIN_3_H
|
#define CGAL_LABELED_MESH_DOMAIN_3_H
|
||||||
|
|
@ -875,17 +870,15 @@ public:
|
||||||
* function. The domain to be discretized is assumed to be the domain where
|
* function. The domain to be discretized is assumed to be the domain where
|
||||||
* the function has negative values.
|
* the function has negative values.
|
||||||
*
|
*
|
||||||
* The method takes as argument a bounding sphere which is required to
|
|
||||||
* circumscribe the surface and to have its center inside the domain.
|
|
||||||
*
|
|
||||||
* \tparam Function a type compatible with the signature `FT(Point_3)`: it takes a point as argument,
|
* \tparam Function a type compatible with the signature `FT(Point_3)`: it takes a point as argument,
|
||||||
* and returns a scalar value. That object must be model of `CopyConstructible`
|
* and returns a scalar value. That object must be model of `CopyConstructible`
|
||||||
* \tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters"
|
* \tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters"
|
||||||
* \tparam Bounding_object either a bounding sphere (of type `Sphere_3`), a bounding box (type `Bbox_3`),
|
* \tparam Bounding_object either a bounding sphere (of type `Sphere_3`), a bounding box (type `Bbox_3`),
|
||||||
* or a bounding `Iso_cuboid_3`
|
* or a bounding `Iso_cuboid_3` which is required to circumscribe
|
||||||
|
* the surface and to have its center inside the domain.
|
||||||
*
|
*
|
||||||
* \param function the implicit function
|
* \param function the implicit function
|
||||||
* \param bounding_object object boundint the meshable domain and its center is inside the domain.
|
* \param bounding_object object bounding the meshable domain and its center is inside the domain.
|
||||||
* \param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below:
|
* \param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below:
|
||||||
*
|
*
|
||||||
* \cgalNamedParamsBegin
|
* \cgalNamedParamsBegin
|
||||||
|
|
@ -936,12 +929,11 @@ public:
|
||||||
/// @}
|
/// @}
|
||||||
#ifndef DOXYGEN_RUNNING
|
#ifndef DOXYGEN_RUNNING
|
||||||
template<typename CGAL_NP_TEMPLATE_PARAMETERS>
|
template<typename CGAL_NP_TEMPLATE_PARAMETERS>
|
||||||
static Labeled_mesh_domain_3 create_implicit_mesh_domain(const CGAL_NP_CLASS& np = parameters::default_values())
|
static Labeled_mesh_domain_3 create_implicit_mesh_domain(const CGAL_NP_CLASS &np)
|
||||||
{
|
{
|
||||||
static_assert(!parameters::is_default_parameter<CGAL_NP_CLASS, internal_np::function_param_t>::value, "Value for required parameter not found");
|
static_assert(!parameters::is_default_parameter<CGAL_NP_CLASS, internal_np::function_param_t>::value, "Value for required parameter not found");
|
||||||
static_assert(!parameters::is_default_parameter<CGAL_NP_CLASS, internal_np::bounding_object_param_t>::value, "Value for required parameter not found");
|
static_assert(!parameters::is_default_parameter<CGAL_NP_CLASS, internal_np::bounding_object_param_t>::value, "Value for required parameter not found");
|
||||||
|
|
||||||
using parameters::get_parameter;
|
|
||||||
return create_implicit_mesh_domain(parameters::get_parameter(np, internal_np::function_param),
|
return create_implicit_mesh_domain(parameters::get_parameter(np, internal_np::function_param),
|
||||||
parameters::get_parameter(np, internal_np::bounding_object_param),
|
parameters::get_parameter(np, internal_np::bounding_object_param),
|
||||||
np);
|
np);
|
||||||
|
|
@ -1139,11 +1131,7 @@ public:
|
||||||
/*
|
/*
|
||||||
* Returns a point in the intersection of the primitive `type`
|
* Returns a point in the intersection of the primitive `type`
|
||||||
* with some boundary surface.
|
* with some boundary surface.
|
||||||
* `Type1` is either `Segment_3`, `Ray_3` or `Line_3`.
|
* `Type` is either `Segment_3`, `Ray_3` or `Line_3`.
|
||||||
* The integer `dimension` is set to the dimension of the lowest
|
|
||||||
* dimensional face in the input complex containing the returned point, and
|
|
||||||
* `index` is set to the index to be stored at a mesh vertex lying
|
|
||||||
* on this face.
|
|
||||||
*/
|
*/
|
||||||
struct Construct_intersection
|
struct Construct_intersection
|
||||||
{
|
{
|
||||||
|
|
@ -1170,10 +1158,10 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*
|
/*
|
||||||
* Returns a point in the intersection of [a,b] with the surface
|
* Returns a point in the intersection of `[a,b]` with the surface
|
||||||
* `a` must be the source point, and `b` the out point. It's important
|
* `a` must be the source point, and `b` the out point. It is important
|
||||||
* because it drives bisection cuts.
|
* because it drives bisection cuts.
|
||||||
* Indeed, the returned point is the first intersection from `[a,b]`
|
* Indeed, the returned point is the first intersection of `[a,b]`
|
||||||
* with a subdomain surface.
|
* with a subdomain surface.
|
||||||
*/
|
*/
|
||||||
Intersection operator()(const Point_3& a, const Point_3& b) const
|
Intersection operator()(const Point_3& a, const Point_3& b) const
|
||||||
|
|
@ -1196,7 +1184,7 @@ public:
|
||||||
|
|
||||||
// If both extremities are in the same subdomain,
|
// If both extremities are in the same subdomain,
|
||||||
// there is no intersection.
|
// there is no intersection.
|
||||||
// This should not happen...
|
// Should only be able to happen during initial point generation.
|
||||||
if( value_at_p1 == value_at_p2 )
|
if( value_at_p1 == value_at_p2 )
|
||||||
{
|
{
|
||||||
return Intersection();
|
return Intersection();
|
||||||
|
|
|
||||||
|
|
@ -275,7 +275,7 @@ Nef_polyhedron_2<T> difference(const Nef_polyhedron_2<T>& N1) ;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
||||||
returns the symmectric difference `N - T` \f$ \cup\f$ `T - N`.
|
returns the symmetric difference `N - T` \f$ \cup\f$ `T - N`.
|
||||||
*/
|
*/
|
||||||
Nef_polyhedron_2<T> symmetric_difference(const Nef_polyhedron_2<T>& N1) ;
|
Nef_polyhedron_2<T> symmetric_difference(const Nef_polyhedron_2<T>& N1) ;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -773,7 +773,7 @@ public:
|
||||||
|
|
||||||
Nef_polyhedron_2<T,Items,Mark> symmetric_difference(
|
Nef_polyhedron_2<T,Items,Mark> symmetric_difference(
|
||||||
const Nef_polyhedron_2<T,Items,Mark>& N1) const
|
const Nef_polyhedron_2<T,Items,Mark>& N1) const
|
||||||
/*{\Mop returns the symmectric difference |\Mvar - T| $\cup$
|
/*{\Mop returns the symmetric difference |\Mvar - T| $\cup$
|
||||||
|T - \Mvar|. }*/
|
|T - \Mvar|. }*/
|
||||||
{ Nef_polyhedron_2<T,Items,Mark> res(pm(),false); // empty, no frame
|
{ Nef_polyhedron_2<T,Items,Mark> res(pm(),false); // empty, no frame
|
||||||
Overlayer D(res.pm());
|
Overlayer D(res.pm());
|
||||||
|
|
|
||||||
|
|
@ -1541,7 +1541,7 @@ protected:
|
||||||
|
|
||||||
Nef_polyhedron_3<Kernel,Items, Mark>
|
Nef_polyhedron_3<Kernel,Items, Mark>
|
||||||
symmetric_difference(const Nef_polyhedron_3<Kernel,Items, Mark>& N1) const
|
symmetric_difference(const Nef_polyhedron_3<Kernel,Items, Mark>& N1) const
|
||||||
/*{\Mop returns the symmectric difference |\Mvar - T| $\cup$
|
/*{\Mop returns the symmetric difference |\Mvar - T| $\cup$
|
||||||
|T - \Mvar|. }*/ {
|
|T - \Mvar|. }*/ {
|
||||||
CGAL_NEF_TRACEN(" symmetric difference between nef3 "<<&*this<<" and "<<&N1);
|
CGAL_NEF_TRACEN(" symmetric difference between nef3 "<<&*this<<" and "<<&N1);
|
||||||
if (is_empty()) return N1;
|
if (is_empty()) return N1;
|
||||||
|
|
|
||||||
|
|
@ -1072,7 +1072,7 @@ Nef_polyhedron_S2<K> difference(const Nef_polyhedron_S2<K>&
|
||||||
N1) ;
|
N1) ;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
returns the symmectric difference
|
returns the symmetric difference
|
||||||
`N - T` \f$ \cup\f$ `T - N`.
|
`N - T` \f$ \cup\f$ `T - N`.
|
||||||
*/
|
*/
|
||||||
Nef_polyhedron_S2<K> symmetric_difference( const
|
Nef_polyhedron_S2<K> symmetric_difference( const
|
||||||
|
|
|
||||||
|
|
@ -479,7 +479,7 @@ public:
|
||||||
|
|
||||||
Self symmetric_difference(
|
Self symmetric_difference(
|
||||||
const Self& N1) const
|
const Self& N1) const
|
||||||
/*{\Mop returns the symmectric difference |\Mvar - T| $\cup$
|
/*{\Mop returns the symmetric difference |\Mvar - T| $\cup$
|
||||||
|T - \Mvar|. }*/
|
|T - \Mvar|. }*/
|
||||||
{ Self res(sphere_map(),false); // empty
|
{ Self res(sphere_map(),false); // empty
|
||||||
Overlayer D(&res.sphere_map());
|
Overlayer D(&res.sphere_map());
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,7 @@ This \cgal component implements a surface reconstruction method which
|
||||||
takes as input point sets with oriented normals and computes an
|
takes as input point sets with oriented normals and computes an
|
||||||
implicit function. We assume that the input points contain no outliers
|
implicit function. We assume that the input points contain no outliers
|
||||||
and little noise. The output surface mesh is generated by extracting
|
and little noise. The output surface mesh is generated by extracting
|
||||||
an isosurface of this function with the \cgal Surface Mesh Generator
|
an isosurface of this function with the \ref PkgMesh3 or potentially with any other surface
|
||||||
\cgalCite{cgal:ry-gsddrm-06} or potentially with any other surface
|
|
||||||
contouring algorithm.
|
contouring algorithm.
|
||||||
|
|
||||||
\cgalFigureBegin{Poisson_surface_reconstruction_3figintroduction,introduction.jpg}
|
\cgalFigureBegin{Poisson_surface_reconstruction_3figintroduction,introduction.jpg}
|
||||||
|
|
@ -75,8 +74,8 @@ during refinement is set to zero. It then solves for a scalar
|
||||||
indicator function \f$ f\f$ represented as a piecewise linear function
|
indicator function \f$ f\f$ represented as a piecewise linear function
|
||||||
over the refined triangulation. More specifically, it solves for the
|
over the refined triangulation. More specifically, it solves for the
|
||||||
Poisson equation \f$ \Delta f = div(\mathbf{n})\f$ at each vertex of
|
Poisson equation \f$ \Delta f = div(\mathbf{n})\f$ at each vertex of
|
||||||
the triangulation using a sparse linear solver. Eventually, the \cgal
|
the triangulation using a sparse linear solver. Eventually, the \ref PkgMesh3
|
||||||
surface mesh generator extracts an isosurface with function value set
|
extracts an isosurface with function value set
|
||||||
by default to be the median value of \f$ f\f$ at all input points.
|
by default to be the median value of \f$ f\f$ at all input points.
|
||||||
|
|
||||||
\section Poisson_surface_reconstruction_3Function Reconstruction Function
|
\section Poisson_surface_reconstruction_3Function Reconstruction Function
|
||||||
|
|
@ -86,9 +85,7 @@ provided. It takes points with normals as input and handles the whole
|
||||||
reconstruction pipeline :
|
reconstruction pipeline :
|
||||||
|
|
||||||
- it computes the implicit function
|
- it computes the implicit function
|
||||||
- it reconstructs the surface with a given precision using the \cgal
|
- it reconstructs the surface with a given precision using the \ref PkgMesh3
|
||||||
surface mesh generator based on Delaunay refinement
|
|
||||||
\cgalCite{cgal:ry-gsddrm-06} \cgalCite{cgal:bo-pgsms-05}
|
|
||||||
- it outputs the result in a polygon mesh.
|
- it outputs the result in a polygon mesh.
|
||||||
|
|
||||||
This function aims at providing a quick and user-friendly API for
|
This function aims at providing a quick and user-friendly API for
|
||||||
|
|
@ -118,26 +115,19 @@ The following example reads a point set, creates a Poisson implicit function and
|
||||||
|
|
||||||
\subsection Poisson_surface_reconstruction_3Contouring Contouring
|
\subsection Poisson_surface_reconstruction_3Contouring Contouring
|
||||||
|
|
||||||
|
|
||||||
The computed implicit functions can be iso-contoured to reconstruct a
|
The computed implicit functions can be iso-contoured to reconstruct a
|
||||||
surface by using the \cgal surface mesh generator
|
surface by using the \ref PkgMesh3 component, and in particular the function
|
||||||
\cgalCite{cgal:ry-gsddrm-06} \cgalCite{cgal:bo-pgsms-05} :
|
`make_mesh_3()` with the `surface_only()` parameter to only mesh the surface.
|
||||||
|
|
||||||
`make_surface_mesh()`
|
The following `Tag` parameters affect the behavior of `make_mesh_3()`:
|
||||||
|
|
||||||
The parameter `Tag` affects the behavior of `make_surface_mesh()`:
|
|
||||||
- `Manifold_tag`: the output mesh is guaranteed to be a manifold surface without boundary.
|
- `Manifold_tag`: the output mesh is guaranteed to be a manifold surface without boundary.
|
||||||
- `Manifold_with_boundary_tag`: the output mesh is guaranteed to be manifold and may have boundaries.
|
- `Manifold_with_boundary_tag`: the output mesh is guaranteed to be manifold and may have boundaries.
|
||||||
- `Non_manifold_tag`: the output mesh has no guarantee and hence is outputted as a polygon soup.
|
- `Non_manifold_tag`: the output mesh has no guarantee and hence is outputted as a polygon soup.
|
||||||
|
|
||||||
\subsection Poisson_surface_reconstruction_3Output Output
|
\subsection Poisson_surface_reconstruction_3Output Output
|
||||||
|
|
||||||
The surface reconstructed by `make_surface_mesh()` is required to be a
|
The surface reconstructed by `make_mesh_3()` is required to be a model of the concept
|
||||||
model of the concept `SurfaceMeshComplex_2InTriangulation_3`, a data
|
`MeshComplex_3InTriangulation_3`, a data structure devised to represent a three dimensional complex embedded into a three dimensional triangulation. The surface facets can then be extracted into a face graph by `facets_in_complex_3_to_triangle_mesh()`.
|
||||||
structure devised to represent a two dimensional complex embedded into
|
|
||||||
a three dimensional triangulation.
|
|
||||||
|
|
||||||
`SurfaceMeshComplex_2InTriangulation_3` defines the methods to traverse the reconstructed surface, and e.g. convert it to a triangle soup.
|
|
||||||
|
|
||||||
Other \cgal components provide functions to write the reconstructed
|
Other \cgal components provide functions to write the reconstructed
|
||||||
surface mesh to the %Object File Format (OFF) \cgalCite{cgal:p-gmgv16-96}
|
surface mesh to the %Object File Format (OFF) \cgalCite{cgal:p-gmgv16-96}
|
||||||
|
|
@ -218,7 +208,7 @@ function over the tetrahedra of a 3D Delaunay triangulation
|
||||||
constructed from the input points then refined through Delaunay
|
constructed from the input points then refined through Delaunay
|
||||||
refinement. For this reason, any iso-surface is also piecewise linear
|
refinement. For this reason, any iso-surface is also piecewise linear
|
||||||
and hence may contain sharp creases. As the contouring algorithm
|
and hence may contain sharp creases. As the contouring algorithm
|
||||||
`make_surface_mesh()` expects a smooth implicit function these
|
`make_mesh_3()` expects a smooth implicit function these
|
||||||
sharp creases may create spurious clusters of vertices in the final
|
sharp creases may create spurious clusters of vertices in the final
|
||||||
reconstructed surface mesh when setting a small mesh sizing or surface
|
reconstructed surface mesh when setting a small mesh sizing or surface
|
||||||
approximation error parameter (see
|
approximation error parameter (see
|
||||||
|
|
@ -339,136 +329,238 @@ Left: 5K points sampled on a mechanical piece with sharp features (creases, dart
|
||||||
|
|
||||||
We provide some performance numbers for scanning data. We measure the Poisson implicit function computation time,
|
We provide some performance numbers for scanning data. We measure the Poisson implicit function computation time,
|
||||||
the contouring time for a range of approximation distances, the memory occupancy as well as the influence of
|
the contouring time for a range of approximation distances, the memory occupancy as well as the influence of
|
||||||
the point set simplification. The machine used is a PC running Windows 7 64 bits with an Intel CPU Core 2 Duo
|
the point set simplification. The machine used is a PC running Windows 10 64 bits with an Intel CPU Core i7-11850H
|
||||||
processor clocked at 2.81 GHz and with 8 GB of RAM. The software is compiled with Visual \CC 2010 (VC9) compiler
|
processor with 8 cores and 32 GB of RAM. The software is compiled with Visual \CC 2022 compiler
|
||||||
with the 03 option which maximizes speed. All measurements were done using the \ref thirdpartyEigen "Eigen" library.
|
with the 03 option which maximizes speed. All measurements were done using the \ref thirdpartyEigen "Eigen" library.
|
||||||
|
|
||||||
|
|
||||||
\subsection SurfReconstPerfPIF Poisson Implicit Function
|
\subsection SurfReconstPerfPIF Poisson Implicit Function
|
||||||
|
|
||||||
The point set chosen for benchmarking the Poisson implicit function is the Bimba con Nastrino point set
|
The point set chosen for benchmarking the Poisson implicit function is the Lucy statue point set from the
|
||||||
(1.6 million points) depicted by \cgalFigureRef{Poisson_surface_reconstruction_3-fig-contouring_bench}.
|
<a href="https://graphics.stanford.edu/data/3Dscanrep/">The Stanford 3D Scanning Repository</a>
|
||||||
|
(originally 14 million points, here downsampled to 2.9 million points) depicted by \cgalFigureRef{Poisson_surface_reconstruction_3-fig-contouring_bench}.
|
||||||
We measure the Poisson implicit function computation (i.e., the call to
|
We measure the Poisson implicit function computation (i.e., the call to
|
||||||
`Poisson_reconstruction_function::compute_implicit_function()` denoted by Poisson solve hereafter)
|
`Poisson_reconstruction_function::compute_implicit_function()` denoted by Poisson solve hereafter)
|
||||||
for this point set as well as for simplified versions obtained through random simplification.
|
for this point set as well as for simplified versions obtained through random simplification.
|
||||||
The following table provides Poisson solve computation times in seconds for an increasing number of points.
|
The following table provides Poisson solve computation times in seconds for an increasing number of points.
|
||||||
|
|
||||||
|
<CENTER>
|
||||||
<TABLE CELLSPACING=5 >
|
<TABLE CELLSPACING=5 >
|
||||||
<TR><TD ALIGN=LEFT NOWRAP COLSPAN=2><HR>
|
<TR><TD ALIGN=LEFT NOWRAP COLSPAN=2><HR>
|
||||||
<TR>
|
<TR>
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
|
|
||||||
Number of points (x1000)
|
Number of points (x1000)
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
Poisson solve duration (in s)
|
Poisson solve duration (in s)
|
||||||
<TR><TD ALIGN=LEFT NOWRAP COLSPAN=2><HR>
|
<TR><TD ALIGN=LEFT NOWRAP COLSPAN=2><HR>
|
||||||
<TR>
|
<TR>
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
|
30
|
||||||
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
|
3.3
|
||||||
|
<TR>
|
||||||
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
60
|
60
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
15
|
7.7
|
||||||
<TR>
|
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
|
||||||
100
|
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
|
||||||
25
|
|
||||||
<TR>
|
<TR>
|
||||||
|
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
250
|
120
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
96
|
18.1
|
||||||
<TR>
|
<TR>
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
500
|
237.5
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
150
|
35.1
|
||||||
<TR>
|
<TR>
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
1,000
|
375
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
249
|
64
|
||||||
<TR>
|
<TR>
|
||||||
|
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
1,800
|
750
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
478
|
129
|
||||||
<TR><TD ALIGN=LEFT NOWRAP COLSPAN=2><HR>
|
<TR>
|
||||||
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
|
1,500
|
||||||
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
|
303
|
||||||
|
<TR>
|
||||||
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
|
2,900
|
||||||
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
|
486
|
||||||
|
<TR><TD ALIGN=CENTER NOWRAP COLSPAN=2><HR>
|
||||||
</TABLE>
|
</TABLE>
|
||||||
|
</CENTER>
|
||||||
|
|
||||||
\subsection SurfReconstPerfCont Contouring
|
\subsection SurfReconstPerfCont Contouring
|
||||||
|
|
||||||
The point set chosen for benchmarking the contouring stage is the Bimba con Nastrino point
|
The point set chosen for benchmarking the contouring stage is the Lucy point
|
||||||
set simplified to 100k points. We measure the contouring (i.e.\ the call to `make_surface_mesh()`)
|
set simplified to 2.9M points. We measure the contouring (i.e., the calls to `make_mesh_3()` and `facets_in_complex_3_to_triangle_mesh()`)
|
||||||
duration and the reconstruction error for a range of approximation distances.
|
duration and the reconstruction error for a range of approximation distances.
|
||||||
The reconstruction error is expressed as the average distance from input points to the reconstructed surface
|
The reconstruction error is expressed as the average distance from input points to the reconstructed surface in mm (the Lucy statue is 1597 mm tall).
|
||||||
in mm (the Bimba con Nastrino statue is 324 mm tall).
|
|
||||||
|
|
||||||
|
<CENTER>
|
||||||
<TABLE CELLSPACING=5 >
|
<TABLE CELLSPACING=5 >
|
||||||
<TR><TD ALIGN=LEFT NOWRAP COLSPAN=3><HR>
|
<TR><TD ALIGN=CENTER NOWRAP COLSPAN=4><HR>
|
||||||
<TR>
|
<TR>
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
Approx. distance (*average spacing)
|
Approx. distance (*average spacing)
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
Contouring duration (in s)
|
Contouring duration single-thread (in s)
|
||||||
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
|
Contouring duration parallel (in s)
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
Reconstruction error (mm)
|
Reconstruction error (mm)
|
||||||
<TR><TD ALIGN=LEFT NOWRAP COLSPAN=3><HR>
|
<TR><TD ALIGN=CENTER NOWRAP COLSPAN=4><HR>
|
||||||
|
<TR>
|
||||||
|
|
||||||
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
|
0.05
|
||||||
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
|
582
|
||||||
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
|
112
|
||||||
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
|
0.114
|
||||||
<TR>
|
<TR>
|
||||||
|
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
0.1
|
0.1
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
19.2
|
221
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
0.055
|
26
|
||||||
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
|
0.119
|
||||||
<TR>
|
<TR>
|
||||||
|
|
||||||
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
|
0.15
|
||||||
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
|
104
|
||||||
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
|
25
|
||||||
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
|
0.129
|
||||||
|
<TR>
|
||||||
|
|
||||||
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
|
0.2
|
||||||
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
|
69.4
|
||||||
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
|
9.2
|
||||||
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
|
0.14
|
||||||
|
<TR>
|
||||||
|
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
0.25
|
0.25
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
6.9
|
53.6
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
0.106
|
7.0
|
||||||
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
|
0.151
|
||||||
<TR>
|
<TR>
|
||||||
|
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
0.5
|
0.5
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
3.2
|
25.2
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
0.18
|
3.6
|
||||||
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
|
0.209
|
||||||
<TR>
|
<TR>
|
||||||
|
|
||||||
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
|
0.75
|
||||||
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
|
16.4
|
||||||
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
|
4.9
|
||||||
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
|
0.209
|
||||||
|
<TR>
|
||||||
|
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
1
|
1
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
1.65
|
12.4
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
0.36
|
2.3
|
||||||
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
|
0.33
|
||||||
<TR>
|
<TR>
|
||||||
|
|
||||||
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
|
1.5
|
||||||
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
|
8.2
|
||||||
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
|
1.4
|
||||||
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
|
0.455
|
||||||
|
<TR>
|
||||||
|
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
2
|
2
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
|
6.1
|
||||||
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
|
1.1
|
||||||
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
|
0.59
|
||||||
|
<TR>
|
||||||
|
|
||||||
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
|
3
|
||||||
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
|
4.0
|
||||||
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
0.8
|
0.8
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
0.76
|
0.87
|
||||||
<TR><TD ALIGN=LEFT NOWRAP COLSPAN=3><HR>
|
<TR>
|
||||||
|
|
||||||
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
|
5
|
||||||
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
|
2.3
|
||||||
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
|
0.7
|
||||||
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
|
1.50
|
||||||
|
<TR>
|
||||||
|
<TD ALIGN=CENTER NOWRAP COLSPAN=4><HR>
|
||||||
</TABLE>
|
</TABLE>
|
||||||
|
</CENTER>
|
||||||
|
|
||||||
|
\cgalFigureAnchor{Poisson_surface_reconstruction_3-fig-contouring_bench}
|
||||||
\cgalFigureBegin{Poisson_surface_reconstruction_3-fig-contouring_bench,contouring_bench.jpg}
|
<center>
|
||||||
|
<img src="contouring_bench.jpg" style="max-width:80%;"/>
|
||||||
|
</center>
|
||||||
|
\cgalFigureCaptionBegin{Poisson_surface_reconstruction_3-fig-contouring_bench}
|
||||||
Contouring duration (in s) and reconstruction error (mm)
|
Contouring duration (in s) and reconstruction error (mm)
|
||||||
against several approximation distance parameters
|
against several approximation distance parameters
|
||||||
for the Bimba con Nastrino point set simplified to 100k points.
|
for the Lucy point set simplified to 100k points.
|
||||||
\cgalFigureEnd
|
\cgalFigureCaptionEnd
|
||||||
|
|
||||||
\subsection SurfReconstPerfMem Memory
|
\subsection SurfReconstPerfMem Memory
|
||||||
|
|
||||||
We measure the memory occupancy for the reconstruction of the full Bimba con Nastrino point
|
We measure the memory occupancy for the reconstruction of the Lucy point
|
||||||
set (1.8 millions points) as well as for simplified versions.\n
|
set (2.9 millions points) as well as for further simplified versions.\n
|
||||||
The Poisson implicit function computation has a memory peak when solving the Poisson linear
|
The Poisson implicit function computation has a memory peak when solving the Poisson linear
|
||||||
system using the sparse linear solver.
|
system using the sparse linear solver.
|
||||||
|
|
||||||
|
<CENTER>
|
||||||
<TABLE CELLSPACING=5 >
|
<TABLE CELLSPACING=5 >
|
||||||
<TR><TD ALIGN=LEFT NOWRAP COLSPAN=2><HR>
|
<TR><TD ALIGN=LEFT NOWRAP COLSPAN=2><HR>
|
||||||
<TR>
|
<TR>
|
||||||
|
|
@ -479,47 +571,59 @@ Memory occupancy (MBytes)
|
||||||
<TR><TD ALIGN=LEFT NOWRAP COLSPAN=2><HR>
|
<TR><TD ALIGN=LEFT NOWRAP COLSPAN=2><HR>
|
||||||
<TR>
|
<TR>
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
|
30
|
||||||
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
|
128
|
||||||
|
<TR>
|
||||||
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
60
|
60
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
180
|
226
|
||||||
<TR>
|
<TR>
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
100
|
120
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
270
|
431
|
||||||
<TR>
|
<TR>
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
250
|
237.5
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
790
|
813
|
||||||
<TR>
|
<TR>
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
500
|
375
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
1300
|
1,232
|
||||||
<TR>
|
<TR>
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
1,000
|
750
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
2200
|
2,283
|
||||||
<TR>
|
<TR>
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
1,800
|
1,500
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
3800
|
4,042
|
||||||
|
<TR>
|
||||||
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
|
2,900
|
||||||
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
|
6,868
|
||||||
<TR><TD ALIGN=LEFT NOWRAP COLSPAN=2><HR>
|
<TR><TD ALIGN=LEFT NOWRAP COLSPAN=2><HR>
|
||||||
</TABLE>
|
</TABLE>
|
||||||
|
</CENTER>
|
||||||
|
|
||||||
|
|
||||||
\subsection SurfReconstPerfPSS Point Set Simplification
|
\subsection SurfReconstPerfPSS Point Set Simplification
|
||||||
|
|
||||||
Due to the memory limitations described above, we recommend to simplify the point sets captured by laser scanners.\n
|
Due to the memory limitations described above, we recommend to simplify the point sets captured by laser scanners.\n
|
||||||
We measure the reconstruction error for the Bimba con Nastrino point set (1.6M points) as well as for
|
We measure the reconstruction error for the Lucy point set (2.9M points) as well as for
|
||||||
simplified versions. All reconstructions use the recommended contouring parameter
|
simplified versions. All reconstructions use the recommended contouring parameter
|
||||||
`approximation distance = 0.25 * the input point` set's average spacing.
|
`approximation distance = 0.25 * the input point` set's average spacing.
|
||||||
The reconstruction error is expressed as the average distance from input points to the reconstructed surface in mm
|
The reconstruction error is expressed as the average distance from input points to the reconstructed surface in mm
|
||||||
(the Bimba con Nastrino statue is 324 mm tall).
|
(the Lucy statue is 1597 mm tall).
|
||||||
|
|
||||||
|
<CENTER>
|
||||||
<TABLE CELLSPACING=5 >
|
<TABLE CELLSPACING=5 >
|
||||||
<TR><TD ALIGN=LEFT NOWRAP COLSPAN=2><HR>
|
<TR><TD ALIGN=LEFT NOWRAP COLSPAN=2><HR>
|
||||||
<TR>
|
<TR>
|
||||||
|
|
@ -530,46 +634,67 @@ Reconstruction error (mm)
|
||||||
<TR><TD ALIGN=LEFT NOWRAP COLSPAN=2><HR>
|
<TR><TD ALIGN=LEFT NOWRAP COLSPAN=2><HR>
|
||||||
<TR>
|
<TR>
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
|
3.75
|
||||||
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
|
9.88395
|
||||||
|
<TR>
|
||||||
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
|
7.5
|
||||||
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
|
5.81843
|
||||||
|
<TR>
|
||||||
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
|
15
|
||||||
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
|
3.13479
|
||||||
|
<TR>
|
||||||
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
|
30
|
||||||
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
|
2.25391
|
||||||
|
<TR>
|
||||||
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
60
|
60
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
0.27
|
1.42965
|
||||||
<TR>
|
<TR>
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
120
|
120
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
0.15
|
1.17589
|
||||||
<TR>
|
<TR>
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
250
|
237.5
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
0.11
|
0.99509
|
||||||
<TR>
|
<TR>
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
500
|
375
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
0.079
|
0.75215
|
||||||
<TR>
|
<TR>
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
1,000
|
750
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
0.066
|
0.344654
|
||||||
<TR>
|
<TR>
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
1,500
|
1,500
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
0.061
|
0.225341
|
||||||
<TR>
|
<TR>
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
1,600
|
2,900
|
||||||
<TD class="math" ALIGN=CENTER NOWRAP>
|
<TD class="math" ALIGN=CENTER NOWRAP>
|
||||||
0.06
|
0.150947
|
||||||
<TR><TD ALIGN=LEFT NOWRAP COLSPAN=2><HR>
|
<TR><TD ALIGN=LEFT NOWRAP COLSPAN=2><HR>
|
||||||
</TABLE>
|
</TABLE>
|
||||||
|
</CENTER>
|
||||||
|
|
||||||
|
|
||||||
\cgalFigureBegin{Poisson_surface_reconstruction_3-fig-simplification_bench,simplification_bench.jpg}
|
\cgalFigureBegin{Poisson_surface_reconstruction_3-fig-simplification_bench,simplification_bench.jpg}
|
||||||
Reconstruction error (mm) against number of points
|
Reconstruction error (mm) against number of points
|
||||||
for the Bimba con Nastrino point set with 1.6M points
|
for the Lucy point set with 2.9M points
|
||||||
as well as for simplified versions.
|
as well as for simplified versions.
|
||||||
\cgalFigureEnd
|
\cgalFigureEnd
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,11 @@
|
||||||
Manual
|
Manual
|
||||||
Kernel_23
|
Kernel_23
|
||||||
|
BGL
|
||||||
STL_Extension
|
STL_Extension
|
||||||
|
Mesh_3
|
||||||
Algebraic_foundations
|
Algebraic_foundations
|
||||||
Circulator
|
Circulator
|
||||||
Stream_support
|
Stream_support
|
||||||
Point_set_processing_3
|
Point_set_processing_3
|
||||||
Solver_interface
|
Solver_interface
|
||||||
|
SMDS_3
|
||||||
|
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 133 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 53 KiB |
|
|
@ -7,7 +7,7 @@
|
||||||
#include <CGAL/Mesh_triangulation_3.h>
|
#include <CGAL/Mesh_triangulation_3.h>
|
||||||
#include <CGAL/Mesh_complex_3_in_triangulation_3.h>
|
#include <CGAL/Mesh_complex_3_in_triangulation_3.h>
|
||||||
#include <CGAL/Mesh_criteria_3.h>
|
#include <CGAL/Mesh_criteria_3.h>
|
||||||
#include <CGAL/Labeled_mesh_domain_3.h>
|
#include <CGAL/Poisson_mesh_domain_3.h>
|
||||||
#include <CGAL/make_mesh_3.h>
|
#include <CGAL/make_mesh_3.h>
|
||||||
#include <CGAL/facets_in_complex_3_to_triangle_mesh.h>
|
#include <CGAL/facets_in_complex_3_to_triangle_mesh.h>
|
||||||
|
|
||||||
|
|
@ -44,7 +44,7 @@ namespace params = CGAL::parameters;
|
||||||
template<typename Concurrency_tag, typename PointSet>
|
template<typename Concurrency_tag, typename PointSet>
|
||||||
void poisson_reconstruction(const PointSet& points, const char* output)
|
void poisson_reconstruction(const PointSet& points, const char* output)
|
||||||
{
|
{
|
||||||
typedef CGAL::Labeled_mesh_domain_3<Kernel> Mesh_domain;
|
typedef CGAL::Poisson_mesh_domain_3<Kernel> Mesh_domain;
|
||||||
typedef typename CGAL::Mesh_triangulation_3<Mesh_domain, CGAL::Default, Concurrency_tag>::type Tr;
|
typedef typename CGAL::Mesh_triangulation_3<Mesh_domain, CGAL::Default, Concurrency_tag>::type Tr;
|
||||||
typedef CGAL::Mesh_complex_3_in_triangulation_3<Tr> C3t3;
|
typedef CGAL::Mesh_complex_3_in_triangulation_3<Tr> C3t3;
|
||||||
typedef CGAL::Mesh_criteria_3<Tr> Mesh_criteria;
|
typedef CGAL::Mesh_criteria_3<Tr> Mesh_criteria;
|
||||||
|
|
@ -111,15 +111,14 @@ void poisson_reconstruction(const PointSet& points, const char* output)
|
||||||
params::facet_size = sm_radius * average_spacing,
|
params::facet_size = sm_radius * average_spacing,
|
||||||
params::facet_distance = sm_distance * average_spacing);
|
params::facet_distance = sm_distance * average_spacing);
|
||||||
|
|
||||||
Mesh_domain domain = Mesh_domain::create_implicit_mesh_domain(function, bsphere,
|
Mesh_domain domain = Mesh_domain::create_Poisson_mesh_domain(function, bsphere,
|
||||||
params::relative_error_bound(sm_dichotomy_error / sm_sphere_radius));
|
params::relative_error_bound(sm_dichotomy_error / sm_sphere_radius));
|
||||||
|
|
||||||
// Generates surface mesh with manifold option
|
// Generates surface mesh with manifold option
|
||||||
std::cout << "Start meshing...";
|
std::cout << "Start meshing...";
|
||||||
std::cout.flush();
|
std::cout.flush();
|
||||||
C3t3 c3t3 = CGAL::make_mesh_3<C3t3>(domain, criteria,
|
C3t3 c3t3 = CGAL::make_mesh_3<C3t3>(domain, criteria,
|
||||||
params::no_exude()
|
params::surface_only()
|
||||||
.no_perturb()
|
|
||||||
.manifold_with_boundary());
|
.manifold_with_boundary());
|
||||||
|
|
||||||
time.stop();
|
time.stop();
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
#include <CGAL/Mesh_triangulation_3.h>
|
#include <CGAL/Mesh_triangulation_3.h>
|
||||||
#include <CGAL/Mesh_complex_3_in_triangulation_3.h>
|
#include <CGAL/Mesh_complex_3_in_triangulation_3.h>
|
||||||
#include <CGAL/Mesh_criteria_3.h>
|
#include <CGAL/Mesh_criteria_3.h>
|
||||||
#include <CGAL/Labeled_mesh_domain_3.h>
|
#include <CGAL/Poisson_mesh_domain_3.h>
|
||||||
#include <CGAL/make_mesh_3.h>
|
#include <CGAL/make_mesh_3.h>
|
||||||
#include <CGAL/facets_in_complex_3_to_triangle_mesh.h>
|
#include <CGAL/facets_in_complex_3_to_triangle_mesh.h>
|
||||||
|
|
||||||
|
|
@ -56,7 +56,7 @@ typedef CGAL::Polyhedron_3<Kernel> Polyhedron;
|
||||||
typedef CGAL::Poisson_reconstruction_function<Kernel> Poisson_reconstruction_function;
|
typedef CGAL::Poisson_reconstruction_function<Kernel> Poisson_reconstruction_function;
|
||||||
|
|
||||||
// Mesh_3
|
// Mesh_3
|
||||||
typedef CGAL::Labeled_mesh_domain_3<Kernel> Mesh_domain;
|
typedef CGAL::Poisson_mesh_domain_3<Kernel> Mesh_domain;
|
||||||
typedef typename CGAL::Mesh_triangulation_3<Mesh_domain>::type Tr;
|
typedef typename CGAL::Mesh_triangulation_3<Mesh_domain>::type Tr;
|
||||||
typedef CGAL::Mesh_complex_3_in_triangulation_3<Tr> C3t3;
|
typedef CGAL::Mesh_complex_3_in_triangulation_3<Tr> C3t3;
|
||||||
typedef CGAL::Mesh_criteria_3<Tr> Mesh_criteria;
|
typedef CGAL::Mesh_criteria_3<Tr> Mesh_criteria;
|
||||||
|
|
@ -327,12 +327,12 @@ int main(int argc, char * argv[])
|
||||||
<< " manifold_with_boundary()\n";
|
<< " manifold_with_boundary()\n";
|
||||||
|
|
||||||
// Defines mesh domain
|
// Defines mesh domain
|
||||||
Mesh_domain domain = Mesh_domain::create_implicit_mesh_domain(function, bsphere,
|
Mesh_domain domain = Mesh_domain::create_Poisson_mesh_domain(function, bsphere,
|
||||||
CGAL::parameters::relative_error_bound(sm_dichotomy_error / sm_sphere_radius));
|
CGAL::parameters::relative_error_bound(sm_dichotomy_error / sm_sphere_radius));
|
||||||
|
|
||||||
// Generates mesh with manifold option
|
// Generates mesh with manifold option
|
||||||
C3t3 c3t3 = CGAL::make_mesh_3<C3t3>(domain, criteria,
|
C3t3 c3t3 = CGAL::make_mesh_3<C3t3>(domain, criteria,
|
||||||
CGAL::parameters::no_exude().no_perturb()
|
CGAL::parameters::surface_only()
|
||||||
.manifold_with_boundary());
|
.manifold_with_boundary());
|
||||||
|
|
||||||
// Prints status
|
// Prints status
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
#include <CGAL/Mesh_triangulation_3.h>
|
#include <CGAL/Mesh_triangulation_3.h>
|
||||||
#include <CGAL/Mesh_complex_3_in_triangulation_3.h>
|
#include <CGAL/Mesh_complex_3_in_triangulation_3.h>
|
||||||
#include <CGAL/Mesh_criteria_3.h>
|
#include <CGAL/Mesh_criteria_3.h>
|
||||||
#include <CGAL/Labeled_mesh_domain_3.h>
|
#include <CGAL/Poisson_mesh_domain_3.h>
|
||||||
#include <CGAL/make_mesh_3.h>
|
#include <CGAL/make_mesh_3.h>
|
||||||
#include <CGAL/facets_in_complex_3_to_triangle_mesh.h>
|
#include <CGAL/facets_in_complex_3_to_triangle_mesh.h>
|
||||||
|
|
||||||
|
|
@ -32,7 +32,7 @@ typedef Kernel::Sphere_3 Sphere;
|
||||||
typedef std::vector<Point_with_normal> PointList;
|
typedef std::vector<Point_with_normal> PointList;
|
||||||
typedef CGAL::Polyhedron_3<Kernel> Polyhedron;
|
typedef CGAL::Polyhedron_3<Kernel> Polyhedron;
|
||||||
typedef CGAL::Poisson_reconstruction_function<Kernel> Poisson_reconstruction_function;
|
typedef CGAL::Poisson_reconstruction_function<Kernel> Poisson_reconstruction_function;
|
||||||
typedef CGAL::Labeled_mesh_domain_3<Kernel> Mesh_domain;
|
typedef CGAL::Poisson_mesh_domain_3<Kernel> Mesh_domain;
|
||||||
typedef CGAL::Mesh_triangulation_3<Mesh_domain>::type Tr;
|
typedef CGAL::Mesh_triangulation_3<Mesh_domain>::type Tr;
|
||||||
typedef CGAL::Mesh_complex_3_in_triangulation_3<Tr> C3t3;
|
typedef CGAL::Mesh_complex_3_in_triangulation_3<Tr> C3t3;
|
||||||
typedef CGAL::Mesh_criteria_3<Tr> Mesh_criteria;
|
typedef CGAL::Mesh_criteria_3<Tr> Mesh_criteria;
|
||||||
|
|
@ -85,12 +85,12 @@ int main(void)
|
||||||
CGAL::parameters::facet_distance = sm_distance*average_spacing);
|
CGAL::parameters::facet_distance = sm_distance*average_spacing);
|
||||||
|
|
||||||
// Defines mesh domain
|
// Defines mesh domain
|
||||||
Mesh_domain domain = Mesh_domain::create_implicit_mesh_domain(function, bsphere,
|
Mesh_domain domain = Mesh_domain::create_Poisson_mesh_domain(function, bsphere,
|
||||||
CGAL::parameters::relative_error_bound(sm_dichotomy_error / sm_sphere_radius));
|
CGAL::parameters::relative_error_bound(sm_dichotomy_error / sm_sphere_radius));
|
||||||
|
|
||||||
// Generates mesh with manifold option
|
// Generates mesh with manifold option
|
||||||
C3t3 c3t3 = CGAL::make_mesh_3<C3t3>(domain, criteria,
|
C3t3 c3t3 = CGAL::make_mesh_3<C3t3>(domain, criteria,
|
||||||
CGAL::parameters::no_exude().no_perturb()
|
CGAL::parameters::surface_only()
|
||||||
.manifold_with_boundary());
|
.manifold_with_boundary());
|
||||||
|
|
||||||
const Tr& tr = c3t3.triangulation();
|
const Tr& tr = c3t3.triangulation();
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,409 @@
|
||||||
|
// Copyright (c) 2025 GeometryFactory (France).
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// This file is part of CGAL (www.cgal.org).
|
||||||
|
//
|
||||||
|
// $URL$
|
||||||
|
// $Id$
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||||||
|
//
|
||||||
|
// Author(s) : Sven Oesau
|
||||||
|
|
||||||
|
#ifndef CGAL_POISSON_MESH_DOMAIN_3_H
|
||||||
|
#define CGAL_POISSON_MESH_DOMAIN_3_H
|
||||||
|
|
||||||
|
#include <CGAL/license/Poisson_surface_reconstruction_3.h>
|
||||||
|
|
||||||
|
#include <CGAL/Labeled_mesh_domain_3.h>
|
||||||
|
#include <CGAL/Poisson_reconstruction_function.h>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\ingroup PkgPoissonSurfaceReconstruction3Ref
|
||||||
|
|
||||||
|
\brief The class `Poisson_mesh_domain_3` derives from `Labeled_mesh_domain_3` for the handling of `Poisson_reconstruction_function`.
|
||||||
|
|
||||||
|
This class has a constructor taking a labeling function. It has also a static template member
|
||||||
|
function that acts as named constructor:
|
||||||
|
<ul><li>`create_Poisson_mesh_domain()`</li>, to create a domain from a `Poisson_reconstruction_function`</ul>
|
||||||
|
|
||||||
|
\tparam BGT is a geometric traits class that provides
|
||||||
|
the basic operations to implement intersection tests and intersection computations through a bisection
|
||||||
|
method. This parameter must be instantiated with a model of the concept `BisectionGeometricTraits_3`.
|
||||||
|
|
||||||
|
\cgalModels{MeshDomain_3}
|
||||||
|
|
||||||
|
\sa `CGAL::Labeled_mesh_domain_3`
|
||||||
|
\sa `CGAL::make_mesh_3()`
|
||||||
|
*/
|
||||||
|
template<class BGT>
|
||||||
|
class Poisson_mesh_domain_3
|
||||||
|
#ifndef DOXYGEN_RUNNING
|
||||||
|
: public Labeled_mesh_domain_3<BGT>
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using Base = Labeled_mesh_domain_3<BGT>;
|
||||||
|
typedef typename Base::Subdomain Subdomain;
|
||||||
|
typedef typename Base::Subdomain_index Subdomain_index;
|
||||||
|
typedef typename Base::Surface_patch_index Surface_patch_index;
|
||||||
|
typedef typename Base::Intersection Intersection;
|
||||||
|
|
||||||
|
// Type of indexes for cells of the input complex
|
||||||
|
typedef std::optional<Surface_patch_index> Surface_patch;
|
||||||
|
|
||||||
|
// Type of indexes to characterize the lowest dimensional face of the input
|
||||||
|
// complex on which a vertex lie
|
||||||
|
typedef typename CGAL::Mesh_3::internal::Index_generator<Subdomain_index, Surface_patch_index>::Index Index;
|
||||||
|
|
||||||
|
// Geometric object types
|
||||||
|
#ifdef DOXYGEN_RUNNING
|
||||||
|
/// \name Types imported from the geometric traits class
|
||||||
|
///@{
|
||||||
|
/// The point type of the geometric traits class
|
||||||
|
typedef typename Geom_traits::Point_3 Point_3;
|
||||||
|
/// The sphere type of the geometric traits class
|
||||||
|
typedef typename Geom_traits::Sphere_3 Sphere_3;
|
||||||
|
/// The iso-cuboid type of the geometric traits class
|
||||||
|
typedef typename Geom_traits::Iso_cuboid_3 Iso_cuboid_3;
|
||||||
|
/// The bounding box type
|
||||||
|
typedef CGAL::Bbox_3 Bbox_3;
|
||||||
|
/// The number type (a field type) of the geometric traits class
|
||||||
|
typedef typename Geom_traits::FT FT;
|
||||||
|
/// The ray type of the geometric traits class
|
||||||
|
typedef typename Geom_traits::Ray_3 Ray_3;
|
||||||
|
/// The line type of the geometric traits class
|
||||||
|
typedef typename Geom_traits::Line_3 Line_3;
|
||||||
|
/// The segment type of the geometric traits class
|
||||||
|
typedef typename Geom_traits::Segment_3 Segment_3;
|
||||||
|
/// The Poisson function type
|
||||||
|
typedef CGAL::Poisson_reconstruction_function<Geom_traits> Function;
|
||||||
|
///@}
|
||||||
|
#else
|
||||||
|
/// The point type of the geometric traits class
|
||||||
|
typedef typename BGT::Point_3 Point_3;
|
||||||
|
/// The sphere type of the geometric traits class
|
||||||
|
typedef typename BGT::Sphere_3 Sphere_3;
|
||||||
|
/// The iso-cuboid type of the geometric traits class
|
||||||
|
typedef typename BGT::Iso_cuboid_3 Iso_cuboid_3;
|
||||||
|
/// The bounding box type
|
||||||
|
typedef CGAL::Bbox_3 Bbox_3;
|
||||||
|
/// The number type (a field type) of the geometric traits class
|
||||||
|
typedef typename BGT::FT FT;
|
||||||
|
/// The ray type of the geometric traits class
|
||||||
|
typedef typename BGT::Ray_3 Ray_3;
|
||||||
|
/// The line type of the geometric traits class
|
||||||
|
typedef typename BGT::Line_3 Line_3;
|
||||||
|
/// The segment type of the geometric traits class
|
||||||
|
typedef typename BGT::Segment_3 Segment_3;
|
||||||
|
/// The Poisson function type
|
||||||
|
typedef CGAL::Poisson_reconstruction_function<BGT> Function;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Function poisson_function;
|
||||||
|
|
||||||
|
/// \name Creation
|
||||||
|
/// @{
|
||||||
|
/*! \brief Construction from a function, a bounding object and a relative error bound.
|
||||||
|
*
|
||||||
|
* \tparam Bounding_object either a bounding sphere (of type `Sphere_3`), a bounding box (type `Bbox_3`),
|
||||||
|
* or a bounding `Iso_cuboid_3`
|
||||||
|
* \tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters"
|
||||||
|
*
|
||||||
|
* \param function the Poisson reconstruction function
|
||||||
|
* \param bounding_object the bounding object bounding the meshable space.
|
||||||
|
* \param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below:
|
||||||
|
*
|
||||||
|
* \cgalNamedParamsBegin
|
||||||
|
* \cgalParamNBegin{relative_error_bound}
|
||||||
|
* \cgalParamDescription{the relative error bound used to compute intersection points between the implicit surface and query segments.
|
||||||
|
* The bisection is stopped when the length of the intersected segment is less than the product
|
||||||
|
* of `relative_error_bound` by the diameter of the bounding object.}
|
||||||
|
* \cgalParamDefault{FT(1e-3)}
|
||||||
|
* \cgalParamNEnd
|
||||||
|
* \cgalNamedParamsEnd
|
||||||
|
*/
|
||||||
|
template<typename Bounding_object, typename CGAL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
Poisson_mesh_domain_3(const Function& function,
|
||||||
|
const Bounding_object& bounding_object,
|
||||||
|
const CGAL_NP_CLASS& np = parameters::default_values()
|
||||||
|
#ifndef DOXYGEN_RUNNING
|
||||||
|
, typename std::enable_if<!is_named_function_parameter<Function>>::type* = nullptr
|
||||||
|
#endif // DOXYGEN_RUNNING
|
||||||
|
)
|
||||||
|
: Base(make_implicit_to_labeling_function_wrapper<BGT>(function), bounding_object, np),
|
||||||
|
poisson_function(function)
|
||||||
|
{}
|
||||||
|
|
||||||
|
/*! \brief Construction from a function, a bounding object and a relative error bound.
|
||||||
|
*
|
||||||
|
* \tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters"
|
||||||
|
*
|
||||||
|
* \param function the Poisson reconstruction function
|
||||||
|
* \param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below:
|
||||||
|
*
|
||||||
|
* \cgalNamedParamsBegin
|
||||||
|
* \cgalParamNBegin{relative_error_bound}
|
||||||
|
* \cgalParamDescription{the relative error bound used to compute intersection points between the implicit surface and query segments.
|
||||||
|
* The bisection is stopped when the length of the intersected segment is less than the product
|
||||||
|
* of `relative_error_bound` by the diameter of the bounding object.}
|
||||||
|
* \cgalParamDefault{FT(1e-3)}
|
||||||
|
* \cgalParamNEnd
|
||||||
|
* \cgalNamedParamsEnd
|
||||||
|
*/
|
||||||
|
template<typename CGAL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
Poisson_mesh_domain_3(const Function & function,
|
||||||
|
const CGAL_NP_CLASS& np = parameters::default_values()
|
||||||
|
#ifndef DOXYGEN_RUNNING
|
||||||
|
, typename std::enable_if<!is_named_function_parameter<Function>>::type * = nullptr
|
||||||
|
#endif // DOXYGEN_RUNNING
|
||||||
|
)
|
||||||
|
: Base(make_implicit_to_labeling_function_wrapper<BGT>(function), function.bounding_sphere(), np),
|
||||||
|
poisson_function(function)
|
||||||
|
{}
|
||||||
|
///@}
|
||||||
|
|
||||||
|
#ifndef DOXYGEN_RUNNING
|
||||||
|
template<typename CGAL_NP_TEMPLATE_PARAMETERS_NO_DEFAULT>
|
||||||
|
Poisson_mesh_domain_3(const CGAL_NP_CLASS& np)
|
||||||
|
: Base(np)
|
||||||
|
{}
|
||||||
|
|
||||||
|
// Overload handling parameters passed with operator=
|
||||||
|
|
||||||
|
template<typename CGAL_NP_TEMPLATE_PARAMETERS_NO_DEFAULT_1,
|
||||||
|
typename CGAL_NP_TEMPLATE_PARAMETERS_NO_DEFAULT_2,
|
||||||
|
typename ... NP>
|
||||||
|
Poisson_mesh_domain_3(const Function& function,
|
||||||
|
const CGAL_NP_CLASS_1& np1,
|
||||||
|
const CGAL_NP_CLASS_2& np2,
|
||||||
|
const NP& ... nps)
|
||||||
|
: Base(internal_np::combine_named_parameters(
|
||||||
|
CGAL::parameters::function(make_implicit_to_labeling_function_wrapper<BGT>(function)), np1, np2, nps...)),
|
||||||
|
poisson_function(function)
|
||||||
|
{}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// \name Creation of domains from Poisson implicit functions
|
||||||
|
/// @{
|
||||||
|
/*! \brief Construction from a Poisson implicit function
|
||||||
|
*
|
||||||
|
* This static method is a <em>named constructor</em>. It constructs a domain
|
||||||
|
* whose bounding surface is described implicitly as the zero level set of a
|
||||||
|
* function. The domain to be discretized is assumed to be the domain where
|
||||||
|
* the function has negative values.
|
||||||
|
*
|
||||||
|
* \tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters"
|
||||||
|
* \tparam Bounding_object either a bounding sphere (of type `Sphere_3`), a bounding box (type `Bbox_3`),
|
||||||
|
* or a bounding `Iso_cuboid_3` which is required to circumscribe
|
||||||
|
* the surface and to have its center inside the domain.
|
||||||
|
*
|
||||||
|
* \param function the Poisson reconstruction function
|
||||||
|
* \param bounding_object object bounding the meshable domain and its center is inside the domain.
|
||||||
|
* \param np an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below:
|
||||||
|
*
|
||||||
|
* \cgalNamedParamsBegin
|
||||||
|
* \cgalParamNBegin{relative_error_bound}
|
||||||
|
* \cgalParamDescription{ is the relative error
|
||||||
|
* bound, relative to the diameter of the box of the image.}
|
||||||
|
* \cgalParamDefault{FT(1e-3)}
|
||||||
|
* \cgalParamNEnd
|
||||||
|
* \cgalNamedParamsEnd
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
template<typename Bounding_object, typename CGAL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
static Poisson_mesh_domain_3 create_Poisson_mesh_domain(const Function& function,
|
||||||
|
const Bounding_object& bounding_object,
|
||||||
|
const CGAL_NP_CLASS& np = parameters::default_values()
|
||||||
|
#ifndef DOXYGEN_RUNNING
|
||||||
|
,typename std::enable_if<!is_named_function_parameter<Function>>::type* = nullptr
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
{
|
||||||
|
using parameters::get_parameter;
|
||||||
|
using parameters::choose_parameter;
|
||||||
|
|
||||||
|
FT relative_error_bound_ = choose_parameter(get_parameter(np, internal_np::error_bound), FT(1e-3));
|
||||||
|
CGAL::Random* p_rng_ = choose_parameter(get_parameter(np, internal_np::rng), nullptr);
|
||||||
|
auto null_subdomain_index_ = choose_parameter(get_parameter(np, internal_np::null_subdomain_index_param), Null_functor());
|
||||||
|
auto construct_surface_patch_index_ = choose_parameter(get_parameter(np, internal_np::surface_patch_index), Null_functor());
|
||||||
|
|
||||||
|
return Poisson_mesh_domain_3(function,
|
||||||
|
bounding_object,
|
||||||
|
CGAL::parameters::relative_error_bound(relative_error_bound_)
|
||||||
|
.function(make_implicit_to_labeling_function_wrapper<BGT>(function))
|
||||||
|
.p_rng(p_rng_)
|
||||||
|
.null_subdomain_index(Base::create_null_subdomain_index(null_subdomain_index_))
|
||||||
|
.construct_surface_patch_index(Base::create_construct_surface_patch_index(construct_surface_patch_index_)));
|
||||||
|
}
|
||||||
|
/// @}
|
||||||
|
#ifndef DOXYGEN_RUNNING
|
||||||
|
template<typename CGAL_NP_TEMPLATE_PARAMETERS>
|
||||||
|
static Poisson_mesh_domain_3 create_Poisson_mesh_domain(const CGAL_NP_CLASS& np) {
|
||||||
|
using parameters::get_parameter;
|
||||||
|
|
||||||
|
static_assert(!parameters::is_default_parameter<CGAL_NP_CLASS, internal_np::function_param_t>::value, "Value for required parameter not found");
|
||||||
|
static_assert(!parameters::is_default_parameter<CGAL_NP_CLASS, internal_np::bounding_object_param_t>::value, "Value for required parameter not found");
|
||||||
|
|
||||||
|
return create_Poisson_mesh_domain(get_parameter(np, internal_np::function_param),
|
||||||
|
get_parameter(np, internal_np::bounding_object_param),
|
||||||
|
np);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Overload handling parameters passed with operator=
|
||||||
|
template<typename CGAL_NP_TEMPLATE_PARAMETERS_NO_DEFAULT_1,
|
||||||
|
typename CGAL_NP_TEMPLATE_PARAMETERS_NO_DEFAULT_2,
|
||||||
|
typename ... NP>
|
||||||
|
static Poisson_mesh_domain_3 create_Poisson_mesh_domain(const CGAL_NP_CLASS_1& np1,
|
||||||
|
const CGAL_NP_CLASS_2& np2,
|
||||||
|
const NP& ... nps)
|
||||||
|
{
|
||||||
|
return create_Poisson_mesh_domain(internal_np::combine_named_parameters(np1, np2, nps...));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns a point in the intersection of the primitive `type`
|
||||||
|
* with some boundary surface.
|
||||||
|
* `Type` is either `Segment_3`, `Ray_3` or `Line_3`.
|
||||||
|
*/
|
||||||
|
struct Construct_intersection
|
||||||
|
{
|
||||||
|
Construct_intersection(const Poisson_mesh_domain_3& domain) : domain_(domain) {}
|
||||||
|
|
||||||
|
Intersection operator()(const Segment_3& s) const
|
||||||
|
{
|
||||||
|
#ifndef CGAL_MESH_3_NO_LONGER_CALLS_DO_INTERSECT_3
|
||||||
|
CGAL_precondition(r_domain_.do_intersect_surface_object()(s) != std::nullopt);
|
||||||
|
#endif // NOT CGAL_MESH_3_NO_LONGER_CALLS_DO_INTERSECT_3
|
||||||
|
return this->operator()(s.source(), s.target());
|
||||||
|
}
|
||||||
|
|
||||||
|
Intersection operator()(const Ray_3& r) const
|
||||||
|
{
|
||||||
|
return clip_to_segment(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
Intersection operator()(const Line_3& l) const
|
||||||
|
{
|
||||||
|
return clip_to_segment(l);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
/*
|
||||||
|
* Returns a point in the intersection of `[a,b]` with the surface
|
||||||
|
* `a` must be the source point, and `b` the out point. It is important
|
||||||
|
* because it drives bisection cuts.
|
||||||
|
* Indeed, the returned point is the first intersection of `[a,b]`
|
||||||
|
* with a subdomain surface.
|
||||||
|
*
|
||||||
|
* The difference from the Labeled_mesh_domain_3::Construct_intersection is that
|
||||||
|
* the underlying Delaunay triangulation in the Poisson function is used for the bisection.
|
||||||
|
*/
|
||||||
|
Intersection operator()(const Point_3& a, const Point_3& b) const
|
||||||
|
{
|
||||||
|
// Functors
|
||||||
|
typename BGT::Compute_squared_distance_3 squared_distance =
|
||||||
|
BGT().compute_squared_distance_3_object();
|
||||||
|
typename BGT::Construct_midpoint_3 midpoint =
|
||||||
|
BGT().construct_midpoint_3_object();
|
||||||
|
|
||||||
|
// Non const points
|
||||||
|
Point_3 p1 = a;
|
||||||
|
Point_3 p2 = b;
|
||||||
|
Point_3 mid = midpoint(p1, p2);
|
||||||
|
|
||||||
|
FT value_at_p1, value_at_p2;
|
||||||
|
typename Function::Cell_handle c1, c2;
|
||||||
|
bool c1_is_inf, c2_is_inf;
|
||||||
|
|
||||||
|
std::tie(value_at_p1, c1, c1_is_inf) = domain_.poisson_function.special_func(p1);
|
||||||
|
std::tie(value_at_p2, c2, c2_is_inf) = domain_.poisson_function.special_func(p2);
|
||||||
|
|
||||||
|
Subdomain_index label_at_p1 = (value_at_p1 < 0) ? 1 : 0;
|
||||||
|
Subdomain_index label_at_p2 = (value_at_p2 < 0) ? 1 : 0;
|
||||||
|
|
||||||
|
// If both extremities are in the same subdomain,
|
||||||
|
// there is no intersection.
|
||||||
|
// Should only be able to happen during initial point generation.
|
||||||
|
if(label_at_p1 == label_at_p2)
|
||||||
|
return Intersection();
|
||||||
|
|
||||||
|
// Else lets find a point (by bisection)
|
||||||
|
// Bisection ends when the point is nearer from surface than the error bound
|
||||||
|
while(true) {
|
||||||
|
if(c1 == c2) {
|
||||||
|
if(c1_is_inf) {
|
||||||
|
std::cout << "Intersection(): c1 == c2 and inf!" << std::endl;
|
||||||
|
return Intersection();
|
||||||
|
} else {
|
||||||
|
const Surface_patch_index sp_index = domain_.make_surface_index(label_at_p1, label_at_p2);
|
||||||
|
const Index index = domain_.index_from_surface_patch_index(sp_index);
|
||||||
|
return Intersection(Point_3(ORIGIN + ((value_at_p2 * (p1 - ORIGIN)) - (value_at_p1 * (p2 - ORIGIN))) /
|
||||||
|
(value_at_p2 - value_at_p1)), index, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mid = midpoint(p1, p2);
|
||||||
|
// If the two points are enough close, then we return midpoint
|
||||||
|
if ( squared_distance(p1, p2) < domain_.squared_error_bound_ )
|
||||||
|
{
|
||||||
|
CGAL_assertion(value_at_p1 * value_at_p2 <= 0);
|
||||||
|
const Surface_patch_index sp_index = domain_.make_surface_index(label_at_p1, label_at_p2);
|
||||||
|
const Index index = domain_.index_from_surface_patch_index(sp_index);
|
||||||
|
return Intersection(mid, index, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cannot be const: those values are modified below.
|
||||||
|
FT value_at_mid;
|
||||||
|
typename Function::Cell_handle c_at_mid;
|
||||||
|
bool c_is_inf;
|
||||||
|
std::tie(value_at_mid, c_at_mid, c_is_inf) = domain_.poisson_function.special_func(mid);
|
||||||
|
Subdomain_index label_at_mid = (value_at_mid < 0) ? 1 : 0;
|
||||||
|
|
||||||
|
// Else we must go on
|
||||||
|
// Here we consider that p1(a) is the source point. Thus, we keep p1 and
|
||||||
|
// change p2 if f(p1)!=f(p2).
|
||||||
|
// That allows us to find the first intersection from a of [a,b] with
|
||||||
|
// a surface.
|
||||||
|
if(label_at_p1 != label_at_mid && !(domain_.null(label_at_p1) && domain_.null(label_at_mid)))
|
||||||
|
{
|
||||||
|
p2 = mid;
|
||||||
|
value_at_p2 = value_at_mid;
|
||||||
|
label_at_p2 = label_at_mid;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p1 = mid;
|
||||||
|
value_at_p1 = value_at_mid;
|
||||||
|
label_at_p1 = label_at_mid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clips `query` to a segment `s`, and call `operator()(s)`
|
||||||
|
template<typename Query>
|
||||||
|
Intersection clip_to_segment(const Query& query) const
|
||||||
|
{
|
||||||
|
const auto clipped = CGAL::intersection(query, domain_.bbox_);
|
||||||
|
if (clipped)
|
||||||
|
if (const Segment_3* s = std::get_if<Segment_3>(&*clipped))
|
||||||
|
return this->operator()(*s);
|
||||||
|
|
||||||
|
return Intersection();
|
||||||
|
}
|
||||||
|
|
||||||
|
const Poisson_mesh_domain_3& domain_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Returns Construct_intersection object
|
||||||
|
Construct_intersection construct_intersection_object() const
|
||||||
|
{
|
||||||
|
return Construct_intersection(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}; // end class Poisson_mesh_domain_3
|
||||||
|
|
||||||
|
} // end namespace CGAL
|
||||||
|
|
||||||
|
#endif // CGAL_LABELED_MESH_DOMAIN_3_H
|
||||||
|
|
@ -460,7 +460,7 @@ public:
|
||||||
// Add a pass of Delaunay refinement.
|
// Add a pass of Delaunay refinement.
|
||||||
//
|
//
|
||||||
// In that pass, the sizing field, of the refinement process of the
|
// In that pass, the sizing field, of the refinement process of the
|
||||||
// triangulation, is based on the result of a poisson function with a
|
// triangulation, is based on the result of a Poisson function with a
|
||||||
// sample of the input points. The ratio is 'approximation_ratio'.
|
// sample of the input points. The ratio is 'approximation_ratio'.
|
||||||
//
|
//
|
||||||
// For optimization reasons, the cell criteria of the refinement
|
// For optimization reasons, the cell criteria of the refinement
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
#include <CGAL/Mesh_triangulation_3.h>
|
#include <CGAL/Mesh_triangulation_3.h>
|
||||||
#include <CGAL/Mesh_complex_3_in_triangulation_3.h>
|
#include <CGAL/Mesh_complex_3_in_triangulation_3.h>
|
||||||
#include <CGAL/Mesh_criteria_3.h>
|
#include <CGAL/Mesh_criteria_3.h>
|
||||||
#include <CGAL/Labeled_mesh_domain_3.h>
|
#include <CGAL/Poisson_mesh_domain_3.h>
|
||||||
#include <CGAL/make_mesh_3.h>
|
#include <CGAL/make_mesh_3.h>
|
||||||
#include <CGAL/facets_in_complex_3_to_triangle_mesh.h>
|
#include <CGAL/facets_in_complex_3_to_triangle_mesh.h>
|
||||||
#include <CGAL/Poisson_reconstruction_function.h>
|
#include <CGAL/Poisson_reconstruction_function.h>
|
||||||
|
|
@ -99,7 +99,7 @@ namespace CGAL {
|
||||||
typedef typename Kernel::FT FT;
|
typedef typename Kernel::FT FT;
|
||||||
|
|
||||||
typedef CGAL::Poisson_reconstruction_function<Kernel> Poisson_reconstruction_function;
|
typedef CGAL::Poisson_reconstruction_function<Kernel> Poisson_reconstruction_function;
|
||||||
typedef CGAL::Labeled_mesh_domain_3<Kernel> Mesh_domain;
|
typedef CGAL::Poisson_mesh_domain_3<Kernel> Mesh_domain;
|
||||||
typedef typename CGAL::Mesh_triangulation_3<Mesh_domain, CGAL::Default, Sequential_tag>::type Tr;
|
typedef typename CGAL::Mesh_triangulation_3<Mesh_domain, CGAL::Default, Sequential_tag>::type Tr;
|
||||||
typedef CGAL::Mesh_complex_3_in_triangulation_3<Tr> C3t3;
|
typedef CGAL::Mesh_complex_3_in_triangulation_3<Tr> C3t3;
|
||||||
typedef CGAL::Mesh_criteria_3<Tr> Mesh_criteria;
|
typedef CGAL::Mesh_criteria_3<Tr> Mesh_criteria;
|
||||||
|
|
@ -115,7 +115,7 @@ namespace CGAL {
|
||||||
FT sm_sphere_radius = 5.0 * radius;
|
FT sm_sphere_radius = 5.0 * radius;
|
||||||
FT sm_dichotomy_error = sm_distance * spacing / 1000.0;
|
FT sm_dichotomy_error = sm_distance * spacing / 1000.0;
|
||||||
|
|
||||||
Mesh_domain domain = Mesh_domain::create_implicit_mesh_domain(function, Sphere(inner_point, sm_sphere_radius),
|
Mesh_domain domain = Mesh_domain::create_Poisson_mesh_domain(function, Sphere(inner_point, sm_sphere_radius),
|
||||||
CGAL::parameters::relative_error_bound(sm_dichotomy_error / sm_sphere_radius));
|
CGAL::parameters::relative_error_bound(sm_dichotomy_error / sm_sphere_radius));
|
||||||
|
|
||||||
Mesh_criteria criteria(CGAL::parameters::facet_angle = sm_angle,
|
Mesh_criteria criteria(CGAL::parameters::facet_angle = sm_angle,
|
||||||
|
|
@ -134,7 +134,7 @@ namespace CGAL {
|
||||||
|
|
||||||
C3t3 c3t3 = CGAL::make_mesh_3<C3t3>(domain, criteria,
|
C3t3 c3t3 = CGAL::make_mesh_3<C3t3>(domain, criteria,
|
||||||
turn_tag_into_mesh_3_manifold_option(tag)
|
turn_tag_into_mesh_3_manifold_option(tag)
|
||||||
.no_exude().no_perturb()
|
.surface_only()
|
||||||
.manifold_with_boundary());
|
.manifold_with_boundary());
|
||||||
|
|
||||||
const auto& tr = c3t3.triangulation();
|
const auto& tr = c3t3.triangulation();
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,8 @@ project(Poisson_surface_reconstruction_3_Tests)
|
||||||
|
|
||||||
# Find CGAL
|
# Find CGAL
|
||||||
find_package(CGAL REQUIRED)
|
find_package(CGAL REQUIRED)
|
||||||
|
find_package(TBB QUIET)
|
||||||
|
include(CGAL_TBB_support)
|
||||||
|
|
||||||
# VisualC++ optimization for applications dealing with large data
|
# VisualC++ optimization for applications dealing with large data
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
|
|
@ -22,15 +24,25 @@ find_package(Eigen3 3.1.0 QUIET) #(requires 3.1.0 or greater)
|
||||||
include(CGAL_Eigen3_support)
|
include(CGAL_Eigen3_support)
|
||||||
if(TARGET CGAL::Eigen3_support)
|
if(TARGET CGAL::Eigen3_support)
|
||||||
# Executables that require Eigen 3.1
|
# Executables that require Eigen 3.1
|
||||||
create_single_source_cgal_program("poisson_reconstruction_test_surface_mesher.cpp")
|
if(TARGET CGAL::TBB_support)
|
||||||
target_link_libraries(poisson_reconstruction_test_surface_mesher PRIVATE CGAL::Eigen3_support)
|
create_single_source_cgal_program("poisson_reconstruction_test_surface_mesher.cpp")
|
||||||
|
target_link_libraries(poisson_reconstruction_test_surface_mesher PRIVATE CGAL::Eigen3_support CGAL::TBB_support)
|
||||||
|
|
||||||
create_single_source_cgal_program("poisson_reconstruction_test_mesh_3.cpp")
|
create_single_source_cgal_program("poisson_reconstruction_test_mesh_3.cpp")
|
||||||
target_link_libraries(poisson_reconstruction_test_mesh_3 PRIVATE CGAL::Eigen3_support)
|
target_link_libraries(poisson_reconstruction_test_mesh_3 PRIVATE CGAL::Eigen3_support CGAL::TBB_support)
|
||||||
|
|
||||||
create_single_source_cgal_program("compare_mesh_3_vs_Poisson_implicit_surface_3.cpp")
|
create_single_source_cgal_program("compare_mesh_3_vs_Poisson_implicit_surface_3.cpp")
|
||||||
target_link_libraries(compare_mesh_3_vs_Poisson_implicit_surface_3 PRIVATE CGAL::Eigen3_support)
|
target_link_libraries(compare_mesh_3_vs_Poisson_implicit_surface_3 PRIVATE CGAL::Eigen3_support CGAL::TBB_support)
|
||||||
|
else()
|
||||||
|
create_single_source_cgal_program("poisson_reconstruction_test_surface_mesher.cpp")
|
||||||
|
target_link_libraries(poisson_reconstruction_test_surface_mesher PRIVATE CGAL::Eigen3_support)
|
||||||
|
|
||||||
|
create_single_source_cgal_program("poisson_reconstruction_test_mesh_3.cpp")
|
||||||
|
target_link_libraries(poisson_reconstruction_test_mesh_3 PRIVATE CGAL::Eigen3_support)
|
||||||
|
|
||||||
|
create_single_source_cgal_program("compare_mesh_3_vs_Poisson_implicit_surface_3.cpp")
|
||||||
|
target_link_libraries(compare_mesh_3_vs_Poisson_implicit_surface_3 PRIVATE CGAL::Eigen3_support)
|
||||||
|
endif()
|
||||||
else()
|
else()
|
||||||
message("NOTICE: Tests in this directory require Eigen 3.1 (or greater), and will not be compiled.")
|
message("NOTICE: Tests in this directory require Eigen 3.1 (or greater), and will not be compiled.")
|
||||||
endif()
|
endif()
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@
|
||||||
#include <CGAL/Mesh_complex_3_in_triangulation_3.h>
|
#include <CGAL/Mesh_complex_3_in_triangulation_3.h>
|
||||||
#include <CGAL/Mesh_criteria_3.h>
|
#include <CGAL/Mesh_criteria_3.h>
|
||||||
#include <CGAL/Labeled_mesh_domain_3.h>
|
#include <CGAL/Labeled_mesh_domain_3.h>
|
||||||
|
#include <CGAL/Poisson_mesh_domain_3.h>
|
||||||
#include <CGAL/make_mesh_3.h>
|
#include <CGAL/make_mesh_3.h>
|
||||||
#include <CGAL/facets_in_complex_3_to_triangle_mesh.h>
|
#include <CGAL/facets_in_complex_3_to_triangle_mesh.h>
|
||||||
|
|
||||||
|
|
@ -61,7 +62,12 @@ typedef CGAL::Surface_mesh_default_triangulation_3 STr;
|
||||||
typedef CGAL::Surface_mesh_complex_2_in_triangulation_3<STr> C2t3;
|
typedef CGAL::Surface_mesh_complex_2_in_triangulation_3<STr> C2t3;
|
||||||
|
|
||||||
// Mesh_3
|
// Mesh_3
|
||||||
typedef CGAL::Labeled_mesh_domain_3<Kernel> Mesh_domain;
|
typedef CGAL::Labeled_mesh_domain_3<Kernel> LMesh_domain;
|
||||||
|
typedef typename CGAL::Mesh_triangulation_3<LMesh_domain>::type LTr;
|
||||||
|
typedef CGAL::Mesh_complex_3_in_triangulation_3<LTr> LC3t3;
|
||||||
|
typedef CGAL::Mesh_criteria_3<LTr> LMesh_criteria;
|
||||||
|
|
||||||
|
typedef CGAL::Poisson_mesh_domain_3<Kernel> Mesh_domain;
|
||||||
typedef typename CGAL::Mesh_triangulation_3<Mesh_domain>::type Tr;
|
typedef typename CGAL::Mesh_triangulation_3<Mesh_domain>::type Tr;
|
||||||
typedef CGAL::Mesh_complex_3_in_triangulation_3<Tr> C3t3;
|
typedef CGAL::Mesh_complex_3_in_triangulation_3<Tr> C3t3;
|
||||||
typedef CGAL::Mesh_criteria_3<Tr> Mesh_criteria;
|
typedef CGAL::Mesh_criteria_3<Tr> Mesh_criteria;
|
||||||
|
|
@ -290,10 +296,10 @@ int main(int argc, char * argv[])
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
task_timer.stop();
|
||||||
|
|
||||||
// Prints status
|
// Prints status
|
||||||
std::cerr << "Total implicit function (triangulation+refinement+solver): " << task_timer.time() << " seconds\n";
|
std::cerr << "Total implicit function (triangulation+refinement+solver): " << task_timer.time() << " seconds\n";
|
||||||
task_timer.reset();
|
|
||||||
|
|
||||||
//***************************************
|
//***************************************
|
||||||
// Surface mesh generation
|
// Surface mesh generation
|
||||||
|
|
@ -331,47 +337,88 @@ int main(int argc, char * argv[])
|
||||||
const double implicit_function_time = reconstruction_timer.time();
|
const double implicit_function_time = reconstruction_timer.time();
|
||||||
reconstruction_timer.reset();
|
reconstruction_timer.reset();
|
||||||
|
|
||||||
// MESH_3
|
// MESH_3 labeled
|
||||||
{
|
{
|
||||||
|
// Defines generation criteria
|
||||||
|
LMesh_criteria criteria(CGAL::parameters::facet_angle = fangle, CGAL::parameters::facet_size = fsize,
|
||||||
|
CGAL::parameters::facet_distance = fdist);
|
||||||
|
|
||||||
|
std::cout << "* Use Mesh_3 implicit *" << std::endl;
|
||||||
|
|
||||||
CGAL::Real_timer meshing_timer;
|
CGAL::Real_timer meshing_timer;
|
||||||
meshing_timer.start();
|
meshing_timer.start();
|
||||||
|
|
||||||
std::cout << "* Use Mesh_3 *" << std::endl;
|
|
||||||
// Defines generation criteria
|
// Defines generation criteria
|
||||||
Mesh_criteria criteria(CGAL::parameters::facet_angle = fangle,
|
|
||||||
CGAL::parameters::facet_size = fsize,
|
|
||||||
CGAL::parameters::facet_distance = fdist);
|
|
||||||
|
|
||||||
// Defines mesh domain
|
// Defines mesh domain
|
||||||
Mesh_domain domain = Mesh_domain::create_implicit_mesh_domain(function, bsphere,
|
LMesh_domain domain = LMesh_domain::create_implicit_mesh_domain(
|
||||||
CGAL::parameters::relative_error_bound(sm_dichotomy_error / sm_sphere_radius));
|
function, bsphere, CGAL::parameters::relative_error_bound(sm_dichotomy_error / sm_sphere_radius));
|
||||||
|
|
||||||
// Generates mesh with manifold option
|
// Generates mesh with manifold option
|
||||||
C3t3 c3t3 = CGAL::make_mesh_3<C3t3>(domain, criteria,
|
LC3t3 c3t3 =
|
||||||
CGAL::parameters::no_exude().no_perturb()
|
CGAL::make_mesh_3<LC3t3>(domain, criteria, CGAL::parameters::surface_only().manifold_with_boundary());
|
||||||
.manifold_with_boundary());
|
|
||||||
meshing_timer.stop();
|
meshing_timer.stop();
|
||||||
|
|
||||||
const Tr& tr = c3t3.triangulation();
|
const LTr& tr = c3t3.triangulation();
|
||||||
// Prints status
|
// Prints status
|
||||||
std::cerr << "Mesh_3 meshing: " << meshing_timer.time() << " seconds, "
|
std::cerr << "Mesh_3 meshing: " << meshing_timer.time() << " seconds, " << tr.number_of_vertices()
|
||||||
<< tr.number_of_vertices() << " output vertices"
|
<< " output vertices" << std::endl;
|
||||||
<< std::endl;
|
|
||||||
|
|
||||||
if (tr.number_of_vertices() == 0)
|
if(tr.number_of_vertices() == 0)
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
// Prints total reconstruction duration
|
// Prints total reconstruction duration
|
||||||
reconstruction_timer.stop();
|
|
||||||
std::cerr << "Total reconstruction (implicit function + meshing): "
|
std::cerr << "Total reconstruction (implicit function + meshing): "
|
||||||
<< (implicit_function_time + reconstruction_timer.time()) << " seconds\n";
|
<< (implicit_function_time + meshing_timer.time()) << " seconds\n";
|
||||||
reconstruction_timer.reset();
|
|
||||||
|
|
||||||
// Converts to polyhedron
|
// Converts to polyhedron
|
||||||
Polyhedron output_mesh;
|
Polyhedron output_mesh;
|
||||||
CGAL::facets_in_complex_3_to_triangle_mesh(c3t3, output_mesh);
|
CGAL::facets_in_complex_3_to_triangle_mesh(c3t3, output_mesh);
|
||||||
|
|
||||||
std::ofstream out(output_basename + "_mesh_3.off");
|
std::ofstream out(output_basename + "_implicit_mesh_3.off");
|
||||||
|
out << output_mesh;
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
// MESH_3 poisson
|
||||||
|
{
|
||||||
|
// Defines generation criteria
|
||||||
|
Mesh_criteria criteria(CGAL::parameters::facet_angle = fangle, CGAL::parameters::facet_size = fsize,
|
||||||
|
CGAL::parameters::facet_distance = fdist);
|
||||||
|
std::cout << "* Use Mesh_3 poisson *" << std::endl;
|
||||||
|
|
||||||
|
CGAL::Real_timer meshing_timer;
|
||||||
|
meshing_timer.start();
|
||||||
|
|
||||||
|
// Defines generation criteria
|
||||||
|
|
||||||
|
// Defines mesh domain
|
||||||
|
Mesh_domain domain = Mesh_domain::create_Poisson_mesh_domain(
|
||||||
|
function, bsphere, CGAL::parameters::relative_error_bound(sm_dichotomy_error / sm_sphere_radius));
|
||||||
|
|
||||||
|
// Generates mesh with manifold option
|
||||||
|
C3t3 c3t3 =
|
||||||
|
CGAL::make_mesh_3<C3t3>(domain, criteria, CGAL::parameters::surface_only().manifold_with_boundary());
|
||||||
|
|
||||||
|
meshing_timer.stop();
|
||||||
|
|
||||||
|
const Tr& tr = c3t3.triangulation();
|
||||||
|
// Prints status
|
||||||
|
std::cerr << "Mesh_3 meshing: " << meshing_timer.time() << " seconds, " << tr.number_of_vertices()
|
||||||
|
<< " output vertices" << std::endl;
|
||||||
|
|
||||||
|
if(tr.number_of_vertices() == 0)
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
|
// Prints total reconstruction duration
|
||||||
|
std::cerr << "Total reconstruction (poisson function + meshing): "
|
||||||
|
<< (implicit_function_time + meshing_timer.time()) << " seconds\n";
|
||||||
|
|
||||||
|
// Converts to polyhedron
|
||||||
|
Polyhedron output_mesh;
|
||||||
|
CGAL::facets_in_complex_3_to_triangle_mesh(c3t3, output_mesh);
|
||||||
|
|
||||||
|
std::ofstream out(output_basename + "_poisson_mesh_3.off");
|
||||||
out << output_mesh;
|
out << output_mesh;
|
||||||
out.close();
|
out.close();
|
||||||
}
|
}
|
||||||
|
|
@ -380,7 +427,6 @@ int main(int argc, char * argv[])
|
||||||
{
|
{
|
||||||
CGAL::Real_timer meshing_timer;
|
CGAL::Real_timer meshing_timer;
|
||||||
meshing_timer.start();
|
meshing_timer.start();
|
||||||
reconstruction_timer.start();
|
|
||||||
|
|
||||||
std::cout << "\n\n* Use Surface_mesher with Poisson_implicit_surface_3 *" << std::endl;
|
std::cout << "\n\n* Use Surface_mesher with Poisson_implicit_surface_3 *" << std::endl;
|
||||||
Surface_3 surface(function,
|
Surface_3 surface(function,
|
||||||
|
|
@ -408,9 +454,8 @@ int main(int argc, char * argv[])
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
// Prints total reconstruction duration
|
// Prints total reconstruction duration
|
||||||
reconstruction_timer.stop();
|
|
||||||
std::cerr << "Total reconstruction (implicit function + meshing): "
|
std::cerr << "Total reconstruction (implicit function + meshing): "
|
||||||
<< (implicit_function_time + reconstruction_timer.time()) << " seconds\n";
|
<< (implicit_function_time + meshing_timer.time()) << " seconds\n";
|
||||||
|
|
||||||
Polyhedron output_mesh;
|
Polyhedron output_mesh;
|
||||||
CGAL::facets_in_complex_2_to_triangle_mesh(c2t3, output_mesh);
|
CGAL::facets_in_complex_2_to_triangle_mesh(c2t3, output_mesh);
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@
|
||||||
#include <CGAL/Mesh_complex_3_in_triangulation_3.h>
|
#include <CGAL/Mesh_complex_3_in_triangulation_3.h>
|
||||||
#include <CGAL/Mesh_criteria_3.h>
|
#include <CGAL/Mesh_criteria_3.h>
|
||||||
#include <CGAL/Labeled_mesh_domain_3.h>
|
#include <CGAL/Labeled_mesh_domain_3.h>
|
||||||
|
#include <CGAL/Poisson_mesh_domain_3.h>
|
||||||
#include <CGAL/make_mesh_3.h>
|
#include <CGAL/make_mesh_3.h>
|
||||||
#include <CGAL/facets_in_complex_3_to_triangle_mesh.h>
|
#include <CGAL/facets_in_complex_3_to_triangle_mesh.h>
|
||||||
|
|
||||||
|
|
@ -57,12 +58,18 @@ typedef CGAL::Polyhedron_3<Kernel> Polyhedron;
|
||||||
// Poisson implicit function
|
// Poisson implicit function
|
||||||
typedef CGAL::Poisson_reconstruction_function<Kernel> Poisson_reconstruction_function;
|
typedef CGAL::Poisson_reconstruction_function<Kernel> Poisson_reconstruction_function;
|
||||||
|
|
||||||
// Mesh_3
|
// Mesh_3 using Labeled_mesh_domain_3
|
||||||
typedef CGAL::Labeled_mesh_domain_3<Kernel> Mesh_domain;
|
typedef CGAL::Labeled_mesh_domain_3<Kernel> Mesh_domain;
|
||||||
typedef CGAL::Mesh_triangulation_3<Mesh_domain>::type Tr;
|
typedef CGAL::Mesh_triangulation_3<Mesh_domain>::type Tr;
|
||||||
typedef CGAL::Mesh_complex_3_in_triangulation_3<Tr> C3t3;
|
typedef CGAL::Mesh_complex_3_in_triangulation_3<Tr> C3t3;
|
||||||
typedef CGAL::Mesh_criteria_3<Tr> Mesh_criteria;
|
typedef CGAL::Mesh_criteria_3<Tr> Mesh_criteria;
|
||||||
|
|
||||||
|
// Mesh_3 using Poisson_mesh_domain_3
|
||||||
|
typedef CGAL::Poisson_mesh_domain_3<Kernel> Poisson_mesh_domain;
|
||||||
|
typedef CGAL::Mesh_triangulation_3<Poisson_mesh_domain>::type Poisson_Tr;
|
||||||
|
typedef CGAL::Mesh_complex_3_in_triangulation_3<Poisson_Tr> Poisson_C3t3;
|
||||||
|
typedef CGAL::Mesh_criteria_3<Poisson_Tr> Poisson_mesh_criteria;
|
||||||
|
|
||||||
namespace params = CGAL::parameters;
|
namespace params = CGAL::parameters;
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
@ -171,7 +178,6 @@ int main(int argc, char * argv[])
|
||||||
<< task_timer.time() << " seconds, "
|
<< task_timer.time() << " seconds, "
|
||||||
<< (memory>>20) << " Mb allocated"
|
<< (memory>>20) << " Mb allocated"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
task_timer.reset();
|
|
||||||
|
|
||||||
//***************************************
|
//***************************************
|
||||||
// Checks requirements
|
// Checks requirements
|
||||||
|
|
@ -192,14 +198,14 @@ int main(int argc, char * argv[])
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
CGAL::Timer reconstruction_timer; reconstruction_timer.start();
|
|
||||||
|
|
||||||
//***************************************
|
//***************************************
|
||||||
// Computes implicit function
|
// Computes implicit function
|
||||||
//***************************************
|
//***************************************
|
||||||
|
|
||||||
std::cerr << "Computes Poisson implicit function...\n";
|
std::cerr << "Computes Poisson implicit function...\n";
|
||||||
|
|
||||||
|
task_timer.reset();
|
||||||
|
|
||||||
// Creates implicit function from the read points.
|
// Creates implicit function from the read points.
|
||||||
// Note: this method requires an iterator over points
|
// Note: this method requires an iterator over points
|
||||||
// + property maps to access each point's position and normal.
|
// + property maps to access each point's position and normal.
|
||||||
|
|
@ -218,9 +224,9 @@ int main(int argc, char * argv[])
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double poisson_time = task_timer.time();
|
||||||
// Prints status
|
// Prints status
|
||||||
std::cerr << "Total implicit function (triangulation+refinement+solver): " << task_timer.time() << " seconds\n";
|
std::cerr << "Total implicit function (triangulation+refinement+solver): " << poisson_time << " seconds\n";
|
||||||
task_timer.reset();
|
|
||||||
|
|
||||||
//***************************************
|
//***************************************
|
||||||
// Surface mesh generation
|
// Surface mesh generation
|
||||||
|
|
@ -250,45 +256,92 @@ int main(int argc, char * argv[])
|
||||||
FT sm_sphere_radius = 5.0 * radius;
|
FT sm_sphere_radius = 5.0 * radius;
|
||||||
FT sm_dichotomy_error = sm_distance*average_spacing/1000.0; // Dichotomy error must be << sm_distance
|
FT sm_dichotomy_error = sm_distance*average_spacing/1000.0; // Dichotomy error must be << sm_distance
|
||||||
|
|
||||||
// Defines surface mesh generation criteria
|
{
|
||||||
Mesh_criteria criteria(params::facet_angle = sm_angle,
|
task_timer.reset();
|
||||||
params::facet_size = sm_radius*average_spacing,
|
// Defines surface mesh generation criteria
|
||||||
params::facet_distance = sm_distance*average_spacing);
|
Mesh_criteria criteria(params::facet_angle = sm_angle, params::facet_size = sm_radius * average_spacing,
|
||||||
|
params::facet_distance = sm_distance * average_spacing);
|
||||||
|
|
||||||
std::cerr << " make_mesh_3 with sphere center=("<<inner_point << "),\n"
|
std::cerr << " make_mesh_3 with sphere center=(" << inner_point << "),\n"
|
||||||
<< " sphere radius="<<sm_sphere_radius<<",\n"
|
<< " sphere radius=" << sm_sphere_radius << ",\n"
|
||||||
<< " angle="<<sm_angle << " degrees,\n"
|
<< " angle=" << sm_angle << " degrees,\n"
|
||||||
<< " triangle size="<<sm_radius<<" * average spacing="<<sm_radius*average_spacing<<",\n"
|
<< " triangle size=" << sm_radius
|
||||||
<< " distance="<<sm_distance<<" * average spacing="<<sm_distance*average_spacing<<",\n"
|
<< " * average spacing=" << sm_radius * average_spacing << ",\n"
|
||||||
<< " dichotomy = distance/"<<sm_distance*average_spacing/sm_dichotomy_error<<",\n"
|
<< " distance=" << sm_distance
|
||||||
<< " manifold_with_boundary()\n";
|
<< " * average spacing=" << sm_distance * average_spacing << ",\n"
|
||||||
|
<< " dichotomy = distance/" << sm_distance * average_spacing / sm_dichotomy_error
|
||||||
|
<< ",\n"
|
||||||
|
<< " manifold_with_boundary()\n";
|
||||||
|
|
||||||
// Generates surface mesh with manifold option
|
// Generates surface mesh with manifold option
|
||||||
Mesh_domain domain = Mesh_domain::create_implicit_mesh_domain(function, bsphere,
|
Mesh_domain domain = Mesh_domain::create_implicit_mesh_domain(
|
||||||
params::relative_error_bound(sm_dichotomy_error / sm_sphere_radius));
|
function, bsphere, params::relative_error_bound(sm_dichotomy_error / sm_sphere_radius));
|
||||||
C3t3 c3t3 = CGAL::make_mesh_3<C3t3>(domain, criteria,
|
C3t3 c3t3 = CGAL::make_mesh_3<C3t3>(domain, criteria, params::surface_only().manifold_with_boundary());
|
||||||
params::no_exude().no_perturb().manifold_with_boundary());
|
|
||||||
|
|
||||||
// Prints status
|
// Prints status
|
||||||
/*long*/ memory = CGAL::Memory_sizer().virtual_size();
|
/*long*/ memory = CGAL::Memory_sizer().virtual_size();
|
||||||
const Tr& tr = c3t3.triangulation();
|
const Tr& tr = c3t3.triangulation();
|
||||||
std::cerr << "Surface meshing: " << task_timer.time() << " seconds, "
|
std::cerr << "Surface meshing: " << task_timer.time() << " seconds, " << tr.number_of_vertices()
|
||||||
<< tr.number_of_vertices() << " output vertices, "
|
<< " output vertices, " << (memory >> 20) << " Mb allocated" << std::endl;
|
||||||
<< (memory>>20) << " Mb allocated"
|
task_timer.reset();
|
||||||
<< std::endl;
|
|
||||||
task_timer.reset();
|
|
||||||
|
|
||||||
if(tr.number_of_vertices() == 0) {
|
if(tr.number_of_vertices() == 0) {
|
||||||
accumulated_fatal_err = EXIT_FAILURE;
|
accumulated_fatal_err = EXIT_FAILURE;
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Converts to polyhedron
|
||||||
|
Polyhedron output_mesh;
|
||||||
|
CGAL::facets_in_complex_3_to_triangle_mesh(c3t3, output_mesh);
|
||||||
|
|
||||||
|
// Prints total reconstruction duration
|
||||||
|
std::cerr << "Total reconstruction using Labeled_mesh_domain_3 (implicit function + meshing): "
|
||||||
|
<< poisson_time + task_timer.time() << " seconds\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Converts to polyhedron
|
{
|
||||||
Polyhedron output_mesh;
|
task_timer.reset();
|
||||||
CGAL::facets_in_complex_3_to_triangle_mesh(c3t3, output_mesh);
|
// Defines surface mesh generation criteria
|
||||||
|
Poisson_mesh_criteria criteria(params::facet_angle = sm_angle, params::facet_size = sm_radius * average_spacing,
|
||||||
|
params::facet_distance = sm_distance * average_spacing);
|
||||||
|
|
||||||
// Prints total reconstruction duration
|
std::cerr << " make_mesh_3 with sphere center=(" << inner_point << "),\n"
|
||||||
std::cerr << "Total reconstruction (implicit function + meshing): " << reconstruction_timer.time() << " seconds\n";
|
<< " sphere radius=" << sm_sphere_radius << ",\n"
|
||||||
|
<< " angle=" << sm_angle << " degrees,\n"
|
||||||
|
<< " triangle size=" << sm_radius
|
||||||
|
<< " * average spacing=" << sm_radius * average_spacing << ",\n"
|
||||||
|
<< " distance=" << sm_distance
|
||||||
|
<< " * average spacing=" << sm_distance * average_spacing << ",\n"
|
||||||
|
<< " dichotomy = distance/" << sm_distance * average_spacing / sm_dichotomy_error
|
||||||
|
<< ",\n"
|
||||||
|
<< " manifold_with_boundary()\n";
|
||||||
|
|
||||||
|
// Generates surface mesh with manifold option
|
||||||
|
Poisson_mesh_domain domain = Poisson_mesh_domain::create_Poisson_mesh_domain(
|
||||||
|
function, bsphere, params::relative_error_bound(sm_dichotomy_error / sm_sphere_radius));
|
||||||
|
Poisson_C3t3 c3t3 =
|
||||||
|
CGAL::make_mesh_3<Poisson_C3t3>(domain, criteria, params::surface_only().manifold_with_boundary());
|
||||||
|
|
||||||
|
// Prints status
|
||||||
|
/* long */ memory = CGAL::Memory_sizer().virtual_size();
|
||||||
|
const Poisson_Tr& tr = c3t3.triangulation();
|
||||||
|
std::cerr << "Surface meshing: " << task_timer.time() << " seconds, " << tr.number_of_vertices()
|
||||||
|
<< " output vertices, " << (memory >> 20) << " Mb allocated" << std::endl;
|
||||||
|
task_timer.reset();
|
||||||
|
|
||||||
|
if(tr.number_of_vertices() == 0) {
|
||||||
|
accumulated_fatal_err = EXIT_FAILURE;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Converts to polyhedron
|
||||||
|
Polyhedron output_mesh;
|
||||||
|
CGAL::facets_in_complex_3_to_triangle_mesh(c3t3, output_mesh);
|
||||||
|
|
||||||
|
// Prints total reconstruction duration
|
||||||
|
std::cerr << "Total reconstruction using Poisson_mesh_domain_3 (implicit function + meshing): "
|
||||||
|
<< poisson_time + task_timer.time() << " seconds\n";
|
||||||
|
}
|
||||||
|
|
||||||
} // for each input file
|
} // for each input file
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -219,7 +219,7 @@ void refine_with_plane(PolygonMesh& pm,
|
||||||
/*
|
/*
|
||||||
* \cgalParamNBegin{visitor}
|
* \cgalParamNBegin{visitor}
|
||||||
* \cgalParamDescription{TODO add concept}
|
* \cgalParamDescription{TODO add concept}
|
||||||
* \cgalParamType{reference wrapper recommeded if it has state TODO}
|
* \cgalParamType{reference wrapper recommended if it has state TODO}
|
||||||
* \cgalParamDefault{None}
|
* \cgalParamDefault{None}
|
||||||
* \cgalParamNEnd
|
* \cgalParamNEnd
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@
|
||||||
\cgalPkgShortInfoBegin
|
\cgalPkgShortInfoBegin
|
||||||
\cgalPkgSince{6.1}
|
\cgalPkgSince{6.1}
|
||||||
\cgalPkgDependsOn{\ref PkgCombinatorialMaps}
|
\cgalPkgDependsOn{\ref PkgCombinatorialMaps}
|
||||||
\cgalPkgBib{cgal:y-t2}
|
\cgalPkgBib{cgal:ddpt-thss}
|
||||||
\cgalPkgLicense{\ref licensesGPL "GPL"}
|
\cgalPkgLicense{\ref licensesGPL "GPL"}
|
||||||
\cgalPkgDemo{2D Triangulations on Hyperbolic Surfaces,nofilefornow.zip}
|
\cgalPkgDemo{2D Triangulations on Hyperbolic Surfaces,nofilefornow.zip}
|
||||||
\cgalPkgShortInfoEnd
|
\cgalPkgShortInfoEnd
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue