mirror of https://github.com/CGAL/cgal
Merge branch 'master' into Periodic_3_mesh_3-Feature-MBogdanov
This commit is contained in:
commit
74e569db86
|
|
@ -114,6 +114,67 @@ as result of a partition algorithm; if it is not provided, this information is
|
|||
simply inaccessible.
|
||||
\cgalNPEnd
|
||||
|
||||
|
||||
\cgalNPBegin{vertex_to_vertex_output_iterator} \anchor BGL_vertex_to_vertex_output_iterator
|
||||
is a model of `OutputIterator` accepting `std::pair<vertex_descriptor, vertex_descriptor>`
|
||||
A typical use case is mapping the vertices from a source mesh to its copy's after a `copy_face_graph()`
|
||||
operation.\n
|
||||
<b>Type:</b>a class model of `OutputIterator` accepting
|
||||
`std::pair<`boost::graph_traits<PolygonMesh>::%vertex_descriptor, `boost::graph_traits<PolygonMesh>::%vertex_descriptor>`.\n
|
||||
<b>Default:</b> Emptyset_iterator
|
||||
\cgalNPEnd
|
||||
|
||||
\cgalNPBegin{halfedge_to_halfedge_output_iterator} \anchor BGL_halfedge_to_halfedge_output_iterator
|
||||
is a model of `OutputIterator` accepting `std::pair<halfedge_descriptor, halfedge_descriptor>`
|
||||
A typical use case is mapping the halfedges from a source mesh to its copy's after a `copy_face_graph()`
|
||||
operation.\n
|
||||
<b>Type:</b>a class model of `OutputIterator` accepting
|
||||
`std::pair<`boost::graph_traits<PolygonMesh>::%halfedge_descriptor, `boost::graph_traits<PolygonMesh>::%halfedge_descriptor>`.\n
|
||||
<b>Default:</b> Emptyset_iterator
|
||||
\cgalNPEnd
|
||||
|
||||
|
||||
\cgalNPBegin{face_to_face_output_iterator} \anchor BGL_face_to_face_output_iterator
|
||||
is a model of `OutputIterator` accepting `std::pair<face_descriptor, face_descriptor>`
|
||||
A typical use case is mapping the faces from a source mesh to its copy's after a `copy_face_graph()`
|
||||
operation.\n
|
||||
<b>Type:</b>a class model of `OutputIterator` accepting
|
||||
`std::pair<`boost::graph_traits<PolygonMesh>::%face_descriptor, `boost::graph_traits<PolygonMesh>::%face_descriptor>`.\n
|
||||
<b>Default:</b> Emptyset_iterator
|
||||
\cgalNPEnd
|
||||
|
||||
\cgalNPBegin{vertex_to_vertex_map} \anchor BGL_vertex_to_vertex_map
|
||||
is a property map storing for each vertex of a source mesh the corresponding vertex of another mesh.\n
|
||||
A typical use case is mapping the vertices from a source mesh to its copy's after a `copy_face_graph()`
|
||||
operation.\n
|
||||
<b>Type:</b>a class model of `ReadWritePropertyMap` with
|
||||
`boost::graph_traits<PolygonMesh1>::%vertex_descriptor` as key type and
|
||||
`boost::graph_traits<PolygonMesh2>::%vertex_descriptor` as value type.\n
|
||||
<b>Default:</b> None.
|
||||
\cgalNPEnd
|
||||
|
||||
\cgalNPBegin{halfedge_to_halfedge_map} \anchor BGL_halfedge_to_halfedge_map
|
||||
is a property map storing for each halfedge of a source mesh the corresponding halfedge of another mesh.\n
|
||||
A typical use case is mapping the vertices from a source mesh to its copy's after a `copy_face_graph()`
|
||||
operation.\n
|
||||
<b>Type:</b>a class model of `ReadWritePropertyMap` with
|
||||
`boost::graph_traits<PolygonMesh1>::%halfedge_descriptor` as key type and
|
||||
`boost::graph_traits<PolygonMesh2>::%halfedge_descriptor` as value type.\n
|
||||
<b>Default:</b> None.
|
||||
\cgalNPEnd
|
||||
|
||||
\cgalNPBegin{face_to_face_map} \anchor BGL_face_to_face_map
|
||||
is a property map storing for each face of a source mesh the corresponding face of another mesh.\n
|
||||
A typical use case is mapping the vertices from a source mesh to its copy's after a `copy_face_graph()`
|
||||
operation.\n
|
||||
<b>Type:</b>a class model of `ReadWritePropertyMap` with
|
||||
`boost::graph_traits<PolygonMesh1>::%face_descriptor` as key type and
|
||||
`boost::graph_traits<PolygonMesh2>::%face_descriptor` as value type.\n
|
||||
<b>Default:</b> None.
|
||||
\cgalNPEnd
|
||||
|
||||
|
||||
|
||||
\cgalNPTableEnd
|
||||
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -52,7 +52,8 @@ int main(int argc, char* argv[])
|
|||
boost::unordered_map<source_vertex_descriptor, tm_vertex_descriptor> v2v;
|
||||
boost::unordered_map<source_halfedge_descriptor, tm_halfedge_descriptor> h2h;
|
||||
|
||||
CGAL::copy_face_graph(T1, S, std::inserter(v2v, v2v.end()), std::inserter(h2h, h2h.end()));
|
||||
CGAL::copy_face_graph(T1, S, CGAL::parameters::vertex_to_vertex_output_iterator(std::inserter(v2v, v2v.end()))
|
||||
.halfedge_to_halfedge_output_iterator(std::inserter(h2h, h2h.end())));
|
||||
std::ofstream out("reverse.off");
|
||||
out << S;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
#include <iterator>
|
||||
#include <boost/unordered_map.hpp>
|
||||
|
||||
|
||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
|
||||
|
||||
typedef CGAL::Polyhedron_3<Kernel> Source;
|
||||
|
|
@ -57,9 +58,9 @@ int main(int argc, char* argv[])
|
|||
boost::unordered_map<sm_halfedge_descriptor, tm_halfedge_descriptor> h2h;
|
||||
boost::unordered_map<sm_face_descriptor, tm_face_descriptor> f2f;
|
||||
|
||||
CGAL::copy_face_graph(S, T2, std::inserter(v2v, v2v.end()),
|
||||
std::inserter(h2h, h2h.end()),
|
||||
std::inserter(f2f, f2f.end()));
|
||||
CGAL::copy_face_graph(S, T2, CGAL::parameters::vertex_to_vertex_output_iterator(std::inserter(v2v, v2v.end()))
|
||||
.halfedge_to_halfedge_output_iterator(std::inserter(h2h, h2h.end()))
|
||||
.face_to_face_output_iterator(std::inserter(f2f, f2f.end())));
|
||||
OpenMesh::IO::write_mesh(T2, "om.off");
|
||||
}
|
||||
#endif
|
||||
|
|
@ -67,16 +68,22 @@ int main(int argc, char* argv[])
|
|||
{
|
||||
typedef boost::graph_traits<Target1>::vertex_descriptor source_vertex_descriptor;
|
||||
typedef boost::graph_traits<Target1>::halfedge_descriptor source_halfedge_descriptor;
|
||||
typedef boost::graph_traits<Target1>::face_descriptor source_face_descriptor;
|
||||
|
||||
typedef boost::graph_traits<Source>::vertex_descriptor tm_vertex_descriptor;
|
||||
typedef boost::graph_traits<Source>::halfedge_descriptor tm_halfedge_descriptor;
|
||||
typedef boost::graph_traits<Source>::face_descriptor tm_face_descriptor;
|
||||
|
||||
|
||||
boost::unordered_map<source_vertex_descriptor, tm_vertex_descriptor> v2v;
|
||||
boost::unordered_map<source_halfedge_descriptor, tm_halfedge_descriptor> h2h;
|
||||
|
||||
boost::unordered_map<source_face_descriptor, tm_face_descriptor> f2f;
|
||||
CGAL::copy_face_graph(T1, S, std::inserter(v2v, v2v.end()), std::inserter(h2h, h2h.end()));
|
||||
std::ofstream out("reverse.off");
|
||||
out << S;
|
||||
CGAL::copy_face_graph(T1, S, CGAL::parameters::vertex_to_vertex_map(boost::make_assoc_property_map(v2v))
|
||||
.halfedge_to_halfedge_output_iterator(std::inserter(h2h, h2h.end()))
|
||||
.face_to_face_map(boost::make_assoc_property_map(f2f)));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,8 +29,12 @@
|
|||
#include <CGAL/boost/graph/Euler_operations.h>
|
||||
#include <CGAL/boost/graph/iterator.h>
|
||||
#include <CGAL/boost/graph/helpers.h>
|
||||
#include <CGAL/boost/graph/named_function_params.h>
|
||||
#include <CGAL/boost/graph/named_params_helper.h>
|
||||
#include <CGAL/property_map.h>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/function_output_iterator.hpp>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
|
|
@ -208,7 +212,39 @@ void copy_face_graph(const SourceMesh& sm, TargetMesh& tm,
|
|||
sm_vpm, tm_vpm);
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // end of namespace internal
|
||||
namespace impl
|
||||
{
|
||||
template<typename PMAP>
|
||||
struct Output_iterator_functor
|
||||
{
|
||||
typedef typename boost::property_traits<PMAP>::key_type input_t;
|
||||
typedef typename boost::property_traits<PMAP>::value_type output_t;
|
||||
PMAP map;
|
||||
Output_iterator_functor(PMAP map)
|
||||
:map(map)
|
||||
{
|
||||
}
|
||||
void operator()(const typename std::pair<input_t, output_t>& pair)
|
||||
{
|
||||
put(map, pair.first, pair.second);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<typename PMAP>
|
||||
boost::function_output_iterator<Output_iterator_functor<PMAP> > make_functor(PMAP map)
|
||||
{
|
||||
return boost::make_function_output_iterator(Output_iterator_functor<PMAP>(map));
|
||||
}
|
||||
|
||||
inline Emptyset_iterator make_functor(const boost::param_not_found&)
|
||||
{
|
||||
return Emptyset_iterator();
|
||||
}
|
||||
}//end of impl
|
||||
|
||||
/*!
|
||||
\ingroup PkgBGLHelperFct
|
||||
|
|
@ -223,50 +259,115 @@ void copy_face_graph(const SourceMesh& sm, TargetMesh& tm,
|
|||
and `boost::graph_traits<SourceMesh>::%face_descriptor` must be
|
||||
models of `Hashable`.
|
||||
\tparam TargetMesh a model of `FaceListGraph`
|
||||
\tparam V2V a model of `OutputIterator` accepting `std::pair<sm_vertex_descriptor, tm_vertex_descriptor>`
|
||||
\tparam H2H a model of `OutputIterator` accepting `std::pair<sm_halfedge_descriptor, tm_halfedge_descriptor>`
|
||||
\tparam F2F a model of `OutputIterator` accepting `std::pair<sm_face_descriptor, tm_face_descriptor>`
|
||||
\tparam Src_vpm a model of `ReadablePropertyMap` with `sm_vertex_descriptor` as key
|
||||
\tparam Tgt_vpm a model of `WritablePropertyMap` with `tm_vertex_descriptor` as key
|
||||
where the prefix `sm_` and `tm_` mean belonging to the source and
|
||||
target mesh respectively.
|
||||
\tparam NamedParameters1 a sequence of \ref pmp_namedparameters "Named Parameters"
|
||||
\tparam NamedParameters2 a sequence of \ref pmp_namedparameters "Named Parameters"
|
||||
|
||||
The types `sm_vertex_descriptor` and `sm_face_descriptor` must be models of the concept `Hashable`.
|
||||
|
||||
\param sm the source mesh
|
||||
\param tm the target mesh
|
||||
\param v2v pairs of `vertex_descriptors` from `sm` and corresponding `vertex_descriptors` in `tm` are added to `v2v`
|
||||
\param h2h pairs of `halfedge_descriptors` from `sm` and corresponding `halfedge_descriptors` in `tm` are added to `h2h`
|
||||
\param f2f pairs of `face_descriptors` from `sm` and corresponding `face_descriptors` in `tm` are added to `f2f`
|
||||
\param sm_vpm vertex point map for `sm`
|
||||
\param tm_vpm vertex point map for `tm`
|
||||
\param np1 optional sequence of \ref pmp_namedparameters "Named Parameters" among the ones listed below
|
||||
|
||||
\cgalNamedParamsBegin
|
||||
\cgalParamBegin{vertex_point_map}
|
||||
the property map with the points associated to the vertices of `sm` .
|
||||
If this parameter is omitted, an internal property map for
|
||||
`CGAL::vertex_point_t` should be available in `SourceMesh`
|
||||
\cgalParamEnd
|
||||
\cgalParamBegin{vertex_to_vertex_output_iterator} an `OutputIterator` containing the
|
||||
pairs source-vertex, target-vertex. If this parameter is given, then
|
||||
`vertex_to_vertex_map` cannot be used.
|
||||
\cgalParamEnd
|
||||
\cgalParamBegin{halfedge_to_halfedge_output_iterator} an `OutputIterator` containing the
|
||||
pairs source-halfedge, target-halfedge. If this parameter is given, then
|
||||
`halfedge_to_halfedge_map` cannot be used.
|
||||
\cgalParamEnd
|
||||
\cgalParamBegin{face_to_face_output_iterator} an `OutputIterator` containing the
|
||||
pairs source-face, target-face. If this parameter is given, then
|
||||
`face_to_face_map` cannot be used.
|
||||
\cgalParamEnd
|
||||
\cgalParamBegin{vertex_to_vertex_map} a `ReadWritePropertyMap` containing the
|
||||
pairs source-vertex, target-vertex.
|
||||
\cgalParamEnd
|
||||
\cgalParamBegin{halfedge_to_halfedge_map} a `ReadWritePropertyMap` containing the
|
||||
pairs source-halfedge, target-halfedge.
|
||||
\cgalParamEnd
|
||||
\cgalParamBegin{face_to_face_map} a `ReadWritePropertyMap` containing the
|
||||
pairs source-face, target-face.
|
||||
\cgalParamEnd
|
||||
\cgalNamedParamsEnd
|
||||
|
||||
\param np2 optional sequence of \ref pmp_namedparameters "Named Parameters" among the ones listed below
|
||||
|
||||
\cgalNamedParamsBegin
|
||||
\cgalParamBegin{vertex_point_map}
|
||||
the property map with the points associated to the vertices of `tm`.
|
||||
If this parameter is omitted, an internal property map for
|
||||
`CGAL::vertex_point_t` should be available in `TargetMesh`
|
||||
\cgalParamEnd
|
||||
\cgalNamedParamsEnd
|
||||
|
||||
The points from `sm` to `tm` are converted using
|
||||
`CGAL::Cartesian_converter<SourceKernel, TargetKernel>`.
|
||||
`SourceKernel` and `TargetKernel` are deduced using `CGAL::Kernel_traits`
|
||||
from the value types of `Src_vpm` and `Tgt_vpm`.
|
||||
from the value types of the vertex_point_maps.
|
||||
|
||||
Other properties are not copied.
|
||||
*/
|
||||
#if defined(DOXYGEN_RUNNING) // Use template default arguments
|
||||
template <typename SourceMesh, typename TargetMesh,
|
||||
typename V2V = Emptyset_iterator,
|
||||
typename H2H = Emptyset_iterator,
|
||||
typename F2F = Emptyset_iterator,
|
||||
typename Src_vpm = typename boost::property_map<SourceMesh, vertex_point_t>::const_type,
|
||||
typename Tgt_vpm = typename boost::property_map<TargetMesh, vertex_point_t>::type>
|
||||
#ifndef DOXYGEN_RUNNING
|
||||
typename T1, typename Tag1, typename Base1,
|
||||
typename T2, typename Tag2, typename Base2
|
||||
#else
|
||||
typename NamedParameters1, typename NamedParameters2
|
||||
#endif
|
||||
>
|
||||
void copy_face_graph(const SourceMesh& sm, TargetMesh& tm,
|
||||
V2V v2v = V2V(), H2H h2h = H2H(), F2F f2f = F2F(),
|
||||
Src_vpm sm_vpm = get(vertex_point, sm),
|
||||
Tgt_vpm tm_vpm = get(vertex_point, tm) )
|
||||
#else // use the overloads
|
||||
#ifndef DOXYGEN_RUNNING
|
||||
const CGAL::cgal_bgl_named_params<T1,Tag1,Base1>& np1,
|
||||
const CGAL::cgal_bgl_named_params<T2,Tag2,Base2>& np2
|
||||
#else
|
||||
const NamedParameters1& np1,
|
||||
const NamedParameters2& np2
|
||||
#endif
|
||||
)
|
||||
{
|
||||
using boost::choose_param;
|
||||
internal::copy_face_graph(sm, tm,
|
||||
CGAL::graph_has_property<SourceMesh,boost::halfedge_index_t>(),
|
||||
choose_param(get_param(np1, internal_np::vertex_to_vertex_output_iterator),
|
||||
impl::make_functor(get_param(np1, internal_np::vertex_to_vertex_map))),
|
||||
choose_param(get_param(np1, internal_np::halfedge_to_halfedge_output_iterator),
|
||||
impl::make_functor(get_param(np1, internal_np::halfedge_to_halfedge_map))),
|
||||
choose_param(get_param(np1, internal_np::face_to_face_output_iterator),
|
||||
impl::make_functor(get_param(np1, internal_np::face_to_face_map))),
|
||||
choose_param(get_param(np1, internal_np::vertex_point),
|
||||
get(vertex_point, sm)),
|
||||
choose_param(get_param(np2, internal_np::vertex_point),
|
||||
get(vertex_point, tm)));
|
||||
}
|
||||
|
||||
template <typename SourceMesh, typename TargetMesh>
|
||||
void copy_face_graph(const SourceMesh& sm, TargetMesh& tm)
|
||||
{
|
||||
copy_face_graph(sm, tm, parameters::all_default(), parameters::all_default());
|
||||
}
|
||||
|
||||
template <typename SourceMesh, typename TargetMesh,
|
||||
typename T, typename Tag, typename Base >
|
||||
void copy_face_graph(const SourceMesh& sm, TargetMesh& tm,
|
||||
const CGAL::cgal_bgl_named_params<T,Tag,Base>& np)
|
||||
{
|
||||
copy_face_graph(sm, tm, np, parameters::all_default());
|
||||
}
|
||||
|
||||
#if !defined(DOXYGEN_RUNNING)
|
||||
template <typename SourceMesh, typename TargetMesh,
|
||||
typename V2V, typename H2H, typename F2F,
|
||||
typename Src_vpm, typename Tgt_vpm>
|
||||
void copy_face_graph(const SourceMesh& sm, TargetMesh& tm,
|
||||
V2V v2v, H2H h2h, F2F f2f,
|
||||
Src_vpm sm_vpm, Tgt_vpm tm_vpm )
|
||||
#endif
|
||||
{
|
||||
internal::copy_face_graph(sm, tm,
|
||||
CGAL::graph_has_property<SourceMesh,boost::halfedge_index_t>(),
|
||||
|
|
@ -274,11 +375,6 @@ void copy_face_graph(const SourceMesh& sm, TargetMesh& tm,
|
|||
sm_vpm, tm_vpm);
|
||||
}
|
||||
|
||||
#if !defined(DOXYGEN_RUNNING)
|
||||
template <typename SourceMesh, typename TargetMesh>
|
||||
void copy_face_graph(const SourceMesh& sm, TargetMesh& tm)
|
||||
{ copy_face_graph(sm, tm, Emptyset_iterator(), Emptyset_iterator(), Emptyset_iterator(),
|
||||
get(vertex_point, sm), get(vertex_point, tm)); }
|
||||
|
||||
template <typename SourceMesh, typename TargetMesh, typename V2V>
|
||||
void copy_face_graph(const SourceMesh& sm, TargetMesh& tm, V2V v2v)
|
||||
|
|
|
|||
|
|
@ -33,6 +33,14 @@ CGAL_add_named_parameter(metis_options_t, METIS_options, METIS_options)
|
|||
CGAL_add_named_parameter(vertex_partition_id_t, vertex_partition_id, vertex_partition_id_map)
|
||||
CGAL_add_named_parameter(face_partition_id_t, face_partition_id, face_partition_id_map)
|
||||
|
||||
CGAL_add_named_parameter(vertex_to_vertex_output_iterator_t, vertex_to_vertex_output_iterator, vertex_to_vertex_output_iterator)
|
||||
CGAL_add_named_parameter(halfedge_to_halfedge_output_iterator_t, halfedge_to_halfedge_output_iterator, halfedge_to_halfedge_output_iterator)
|
||||
CGAL_add_named_parameter(face_to_face_output_iterator_t, face_to_face_output_iterator, face_to_face_output_iterator)
|
||||
|
||||
CGAL_add_named_parameter(vertex_to_vertex_map_t, vertex_to_vertex_map, vertex_to_vertex_map)
|
||||
CGAL_add_named_parameter(halfedge_to_halfedge_map_t, halfedge_to_halfedge_map, halfedge_to_halfedge_map)
|
||||
CGAL_add_named_parameter(face_to_face_map_t, face_to_face_map, face_to_face_map)
|
||||
|
||||
// List of named parameters that we use in the package 'Mesh_3'
|
||||
CGAL_add_named_parameter(vertex_feature_degree_t, vertex_feature_degree, vertex_feature_degree_map)
|
||||
|
||||
|
|
|
|||
|
|
@ -44,6 +44,15 @@ void test(const NamedParameters& np)
|
|||
assert(get_param(np, CGAL::internal_np::vertex_partition_id).v == 800000002);
|
||||
assert(get_param(np, CGAL::internal_np::face_partition_id).v == 800000003);
|
||||
|
||||
assert(get_param(np, CGAL::internal_np::vertex_to_vertex_output_iterator).v == 800000004);
|
||||
assert(get_param(np, CGAL::internal_np::halfedge_to_halfedge_output_iterator).v == 800000005);
|
||||
assert(get_param(np, CGAL::internal_np::face_to_face_output_iterator).v == 800000006);
|
||||
|
||||
assert(get_param(np, CGAL::internal_np::vertex_to_vertex_map).v == 800000007);
|
||||
assert(get_param(np, CGAL::internal_np::halfedge_to_halfedge_map).v == 800000008);
|
||||
assert(get_param(np, CGAL::internal_np::face_to_face_map).v == 800000009);
|
||||
|
||||
|
||||
// Named parameters that we use in the package 'Mesh_3'
|
||||
assert(get_param(np, CGAL::internal_np::vertex_feature_degree).v == 9);
|
||||
|
||||
|
|
@ -113,6 +122,12 @@ void test(const NamedParameters& np)
|
|||
check_same_type<800000001>(get_param(np, CGAL::internal_np::METIS_options));
|
||||
check_same_type<800000002>(get_param(np, CGAL::internal_np::vertex_partition_id));
|
||||
check_same_type<800000003>(get_param(np, CGAL::internal_np::face_partition_id));
|
||||
check_same_type<800000004>(get_param(np, CGAL::internal_np::vertex_to_vertex_output_iterator));
|
||||
check_same_type<800000005>(get_param(np, CGAL::internal_np::halfedge_to_halfedge_output_iterator));
|
||||
check_same_type<800000006>(get_param(np, CGAL::internal_np::face_to_face_output_iterator));
|
||||
check_same_type<800000007>(get_param(np, CGAL::internal_np::vertex_to_vertex_map));
|
||||
check_same_type<800000008>(get_param(np, CGAL::internal_np::halfedge_to_halfedge_map));
|
||||
check_same_type<800000009>(get_param(np, CGAL::internal_np::face_to_face_map));
|
||||
|
||||
// Named parameters that we use in the package 'Mesh_3'
|
||||
check_same_type<9>(get_param(np, CGAL::internal_np::vertex_feature_degree));
|
||||
|
|
@ -178,6 +193,12 @@ int main()
|
|||
.METIS_options(A<800000001>(800000001))
|
||||
.vertex_partition_id_map(A<800000002>(800000002))
|
||||
.face_partition_id_map(A<800000003>(800000003))
|
||||
.vertex_to_vertex_output_iterator(A<800000004>(800000004))
|
||||
.halfedge_to_halfedge_output_iterator(A<800000005>(800000005))
|
||||
.face_to_face_output_iterator(A<800000006>(800000006))
|
||||
.vertex_to_vertex_map(A<800000007>(800000007))
|
||||
.halfedge_to_halfedge_map(A<800000008>(800000008))
|
||||
.face_to_face_map(A<800000009>(800000009))
|
||||
.vertex_feature_degree_map(A<9>(9))
|
||||
.geom_traits(A<10>(10))
|
||||
.vertex_incident_patches_map(A<11>(11))
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ Release date: September 2018
|
|||
to reflect the real needs of the code (some types and operators were used
|
||||
in the code but did not appear in the concepts).
|
||||
|
||||
|
||||
### Point Set Processing
|
||||
|
||||
- Added a callback mechanism to the following functions:
|
||||
|
|
@ -77,7 +78,6 @@ Release date: September 2018
|
|||
`CGAL::pca_estimate_normals()`, `CGAL::remove_outliers()` and
|
||||
`CGAL::wlop_simplify_and_regularize_point_set()`.
|
||||
|
||||
|
||||
### Polygon Mesh Processing
|
||||
|
||||
- Added a named parameter in stitching functions that allows to choose whether the operation should
|
||||
|
|
@ -100,6 +100,8 @@ Release date: September 2018
|
|||
- Constrained vertices are now guaranteed to be kept in the mesh after calling `isotropic_remeshing()`
|
||||
(and not only the points associated to constrained vertices, as it was before).
|
||||
|
||||
- Added a function, `CGAL::Polygon_mesh_processing::extrude_mesh()`, to perform an extrusion of an open polygon mesh.
|
||||
|
||||
### 3D Mesh Generation
|
||||
|
||||
- **Breaking change:** The template parameters of the class template
|
||||
|
|
@ -143,6 +145,7 @@ Release date: September 2018
|
|||
- Added the function `Mesh_domain_with_polyline_features_3::add_corner()`, which allows users
|
||||
to add a single corner (that is not incident to any polyline) to the mesh complex.
|
||||
|
||||
|
||||
- **Breaking change**: `CGAL::lloyd_optimize_mesh_3` now depends on
|
||||
the _Eigen_ library.
|
||||
|
||||
|
|
@ -164,6 +167,17 @@ Release date: September 2018
|
|||
- Improved the function `CGAL::Euler::collapse_edge` such that the target
|
||||
vertex of the collapsed edge is now always kept after the collapse.
|
||||
|
||||
- The function `copy_face_graph()` now uses named parameters, some allowing it
|
||||
to use property maps instead of output iterators.
|
||||
|
||||
- Addition of the following named parameters :
|
||||
- vertex_to_vertex_output_iterator
|
||||
- halfedge_to_halfedge_output_iterator
|
||||
- face_to_face_output_iterator
|
||||
- vertex_to_vertex_map
|
||||
- halfedge_to_halfedge_map
|
||||
- face_to_face_map
|
||||
|
||||
### CGAL and Solvers
|
||||
|
||||
- **Breaking change**: `CGAL::Diagonalize_traits` is now deprecated
|
||||
|
|
|
|||
|
|
@ -86,8 +86,7 @@ function \ref PkgInterpolationNaturalNeighborCoordinates2.
|
|||
\tparam OutputFunctor must be a functor with argument type `std::pair<Dt::Vertex_handle, Traits::Vector_d>`.
|
||||
Note that the result type of the functor is not specified and is chosen by users to fit their needs.
|
||||
\tparam ValueFunctor must be a functor where:
|
||||
- `ValueFunctor::argument_type` must be either `std::pair<Dt::Vertex_handle, Dt::Geom_traits::FT>`
|
||||
or `std::pair<Dt::Point, Dt::Geom_traits::FT>`.
|
||||
- `ValueFunctor::argument_type` must be either `Dt::Vertex_handle` or `Dt::Point`.
|
||||
- `ValueFunctor::result_type` is a pair of the function value type and a Boolean.
|
||||
The function value type must provide a multiplication and addition operation with the type
|
||||
`Traits::FT` as well as a constructor with argument `0`.
|
||||
|
|
@ -124,8 +123,7 @@ functions \ref PkgInterpolationRegularNeighborCoordinates2.
|
|||
\tparam OutputFunctor must be a functor with argument type `std::pair<Rt::Vertex_handle, Traits::Vector_d>`.
|
||||
Note that the result type of the functor is not specified and is chosen by users to fit their needs.
|
||||
\tparam ValueFunctor must be a functor where:
|
||||
- `ValueFunctor::argument_type` must be either `std::pair<Rt::Vertex_handle, Rt::Geom_traits::FT>`
|
||||
or `std::pair<Rt::Weighted_point, Rt::Geom_traits::FT>`.
|
||||
- `ValueFunctor::argument_type` must be either `Rt::Vertex_handle` or `Rt::Weighted_point`.
|
||||
- `ValueFunctor::result_type` is a pair of the function value type and a Boolean.
|
||||
The function value type must provide a multiplication and addition operation with the type
|
||||
`Traits::FT` as well as a constructor with argument `0`.
|
||||
|
|
|
|||
|
|
@ -94,6 +94,7 @@ int main()
|
|||
|
||||
Delaunay_triangulation T;
|
||||
|
||||
// Note that a supported alternative to creating the functors below is to use lambdas
|
||||
Value_function<Vertex_handle, Coord_type> value_function;
|
||||
Gradient_function<Vertex_handle, Vector> gradient_function;
|
||||
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ int main()
|
|||
{
|
||||
Regular_triangulation rt;
|
||||
|
||||
// Note that a supported alternative to creating the functors below is to use lambdas
|
||||
Value_function<Vertex_handle, Coord_type> value_function;
|
||||
Gradient_function<Vertex_handle, Vector> gradient_function;
|
||||
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@ int main()
|
|||
{
|
||||
Delaunay_triangulation dt;
|
||||
|
||||
// Note that a supported alternative to creating the functors below is to use lambdas
|
||||
Value_function<Vertex_handle, Coord_type> value_function;
|
||||
Gradient_function<Vertex_handle, Vector> gradient_function;
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@
|
|||
#include <CGAL/double.h>
|
||||
#include <CGAL/use.h>
|
||||
|
||||
#include <boost/utility/result_of.hpp>
|
||||
|
||||
#include <iterator>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
|
@ -58,17 +60,21 @@ struct Data_access
|
|||
|
||||
//the interpolation functions:
|
||||
template < class ForwardIterator, class ValueFunctor >
|
||||
typename ValueFunctor::result_type::first_type
|
||||
typename boost::result_of<
|
||||
ValueFunctor(typename std::iterator_traits<ForwardIterator>::value_type::first_type)>
|
||||
::type::first_type
|
||||
linear_interpolation(ForwardIterator first, ForwardIterator beyond,
|
||||
const typename std::iterator_traits<ForwardIterator>::value_type::second_type& norm,
|
||||
ValueFunctor value_function)
|
||||
{
|
||||
CGAL_precondition(norm > 0);
|
||||
|
||||
typedef typename ValueFunctor::result_type::first_type Value_type;
|
||||
typedef typename std::iterator_traits<ForwardIterator>::value_type::first_type arg_type;
|
||||
typedef typename boost::result_of<ValueFunctor(arg_type)>::type result_type;
|
||||
typedef typename result_type::first_type Value_type;
|
||||
|
||||
Value_type result(0);
|
||||
typename ValueFunctor::result_type val;
|
||||
result_type val;
|
||||
for(; first!=beyond; ++first)
|
||||
{
|
||||
val = value_function(first->first);
|
||||
|
|
@ -78,9 +84,12 @@ linear_interpolation(ForwardIterator first, ForwardIterator beyond,
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
template < class ForwardIterator, class ValueFunctor, class GradFunctor, class Traits, class Point >
|
||||
std::pair< typename ValueFunctor::result_type::first_type, bool>
|
||||
std::pair<
|
||||
typename boost::result_of<
|
||||
ValueFunctor(typename std::iterator_traits<ForwardIterator>::value_type::first_type)>
|
||||
::type::first_type,
|
||||
bool>
|
||||
quadratic_interpolation(ForwardIterator first, ForwardIterator beyond,
|
||||
const typename std::iterator_traits<ForwardIterator>::value_type::second_type& norm,
|
||||
const Point& p,
|
||||
|
|
@ -89,15 +98,20 @@ quadratic_interpolation(ForwardIterator first, ForwardIterator beyond,
|
|||
const Traits& traits)
|
||||
{
|
||||
CGAL_precondition(norm > 0);
|
||||
typedef typename ValueFunctor::result_type::first_type Value_type;
|
||||
|
||||
typedef typename std::iterator_traits<ForwardIterator>::value_type::first_type arg_type;
|
||||
typedef typename boost::result_of<ValueFunctor(arg_type)>::type value_functor_result_type;
|
||||
typedef typename boost::result_of<GradFunctor(arg_type)>::type gradient_functor_result_type;
|
||||
typedef typename value_functor_result_type::first_type Value_type;
|
||||
|
||||
typedef typename Traits::Point_d Bare_point;
|
||||
|
||||
Interpolation::internal::Extract_bare_point<Traits> cp(traits);
|
||||
const Bare_point& bp = cp(p);
|
||||
|
||||
Value_type result(0);
|
||||
typename ValueFunctor::result_type f;
|
||||
typename GradFunctor::result_type grad;
|
||||
value_functor_result_type f;
|
||||
gradient_functor_result_type grad;
|
||||
|
||||
for(; first!=beyond; ++first)
|
||||
{
|
||||
|
|
@ -119,7 +133,11 @@ quadratic_interpolation(ForwardIterator first, ForwardIterator beyond,
|
|||
|
||||
|
||||
template < class ForwardIterator, class ValueFunctor, class GradFunctor, class Traits, class Point >
|
||||
std::pair< typename ValueFunctor::result_type::first_type, bool >
|
||||
std::pair<
|
||||
typename boost::result_of<
|
||||
ValueFunctor(typename std::iterator_traits<ForwardIterator>::value_type::first_type)>
|
||||
::type::first_type,
|
||||
bool>
|
||||
sibson_c1_interpolation(ForwardIterator first, ForwardIterator beyond,
|
||||
const typename std::iterator_traits<ForwardIterator>::value_type::second_type& norm,
|
||||
const Point& p,
|
||||
|
|
@ -129,7 +147,11 @@ sibson_c1_interpolation(ForwardIterator first, ForwardIterator beyond,
|
|||
{
|
||||
CGAL_precondition(norm >0);
|
||||
|
||||
typedef typename ValueFunctor::result_type::first_type Value_type;
|
||||
typedef typename std::iterator_traits<ForwardIterator>::value_type::first_type arg_type;
|
||||
typedef typename boost::result_of<ValueFunctor(arg_type)>::type value_functor_result_type;
|
||||
typedef typename boost::result_of<GradFunctor(arg_type)>::type gradient_functor_result_type;
|
||||
typedef typename value_functor_result_type::first_type Value_type;
|
||||
|
||||
typedef typename Traits::FT Coord_type;
|
||||
typedef typename Traits::Point_d Bare_point;
|
||||
|
||||
|
|
@ -138,8 +160,8 @@ sibson_c1_interpolation(ForwardIterator first, ForwardIterator beyond,
|
|||
|
||||
Coord_type term1(0), term2(term1), term3(term1), term4(term1);
|
||||
Value_type linear_int(0), gradient_int(0);
|
||||
typename ValueFunctor::result_type f;
|
||||
typename GradFunctor::result_type grad;
|
||||
value_functor_result_type f;
|
||||
gradient_functor_result_type grad;
|
||||
|
||||
for(; first!=beyond; ++first)
|
||||
{
|
||||
|
|
@ -193,7 +215,11 @@ sibson_c1_interpolation(ForwardIterator first, ForwardIterator beyond,
|
|||
// gradient_int += (coeff/inv_weight) * (vh->get_value()+ vh->get_gradient() * (p - vh->point()));
|
||||
|
||||
template < class ForwardIterator, class ValueFunctor, class GradFunctor, class Traits, class Point >
|
||||
std::pair< typename ValueFunctor::result_type::first_type, bool >
|
||||
std::pair<
|
||||
typename boost::result_of<
|
||||
ValueFunctor(typename std::iterator_traits<ForwardIterator>::value_type::first_type)>
|
||||
::type::first_type,
|
||||
bool>
|
||||
sibson_c1_interpolation_square(ForwardIterator first, ForwardIterator beyond,
|
||||
const typename std::iterator_traits<ForwardIterator>::value_type::second_type& norm,
|
||||
const Point& p,
|
||||
|
|
@ -203,7 +229,11 @@ sibson_c1_interpolation_square(ForwardIterator first, ForwardIterator beyond,
|
|||
{
|
||||
CGAL_precondition(norm > 0);
|
||||
|
||||
typedef typename ValueFunctor::result_type::first_type Value_type;
|
||||
typedef typename std::iterator_traits<ForwardIterator>::value_type::first_type arg_type;
|
||||
typedef typename boost::result_of<ValueFunctor(arg_type)>::type value_functor_result_type;
|
||||
typedef typename boost::result_of<GradFunctor(arg_type)>::type gradient_functor_result_type;
|
||||
typedef typename value_functor_result_type::first_type Value_type;
|
||||
|
||||
typedef typename Traits::FT Coord_type;
|
||||
typedef typename Traits::Point_d Bare_point;
|
||||
|
||||
|
|
@ -212,8 +242,8 @@ sibson_c1_interpolation_square(ForwardIterator first, ForwardIterator beyond,
|
|||
|
||||
Coord_type term1(0), term2(term1), term3(term1), term4(term1);
|
||||
Value_type linear_int(0), gradient_int(0);
|
||||
typename ValueFunctor::result_type f;
|
||||
typename GradFunctor::result_type grad;
|
||||
value_functor_result_type f;
|
||||
gradient_functor_result_type grad;
|
||||
|
||||
for(; first!=beyond; ++first)
|
||||
{
|
||||
|
|
@ -257,7 +287,11 @@ sibson_c1_interpolation_square(ForwardIterator first, ForwardIterator beyond,
|
|||
|
||||
template < class RandomAccessIterator, class ValueFunctor, class GradFunctor,
|
||||
class Traits, class Point_>
|
||||
std::pair< typename ValueFunctor::result_type::first_type, bool>
|
||||
std::pair<
|
||||
typename boost::result_of<
|
||||
ValueFunctor(typename std::iterator_traits<RandomAccessIterator>::value_type::first_type)>
|
||||
::type::first_type,
|
||||
bool>
|
||||
farin_c1_interpolation(RandomAccessIterator first,
|
||||
RandomAccessIterator beyond,
|
||||
const typename std::iterator_traits<RandomAccessIterator>::value_type::second_type& norm,
|
||||
|
|
@ -268,14 +302,16 @@ farin_c1_interpolation(RandomAccessIterator first,
|
|||
{
|
||||
CGAL_precondition(norm >0);
|
||||
|
||||
// the function value is available for all points
|
||||
// if a gradient value is not availble: function returns false
|
||||
typedef typename ValueFunctor::result_type::first_type Value_type;
|
||||
typedef typename std::iterator_traits<RandomAccessIterator>::value_type::first_type arg_type;
|
||||
typedef typename boost::result_of<ValueFunctor(arg_type)>::type value_functor_result_type;
|
||||
typedef typename boost::result_of<GradFunctor(arg_type)>::type gradient_functor_result_type;
|
||||
typedef typename value_functor_result_type::first_type Value_type;
|
||||
|
||||
typedef typename Traits::FT Coord_type;
|
||||
|
||||
Interpolation::internal::Extract_bare_point<Traits> cp(traits);
|
||||
typename ValueFunctor::result_type f;
|
||||
typename GradFunctor::result_type grad;
|
||||
value_functor_result_type f;
|
||||
gradient_functor_result_type grad;
|
||||
|
||||
int n = static_cast<int>(beyond - first);
|
||||
if(n == 1)
|
||||
|
|
|
|||
|
|
@ -29,14 +29,22 @@
|
|||
#include <CGAL/regular_neighbor_coordinates_2.h>
|
||||
|
||||
#include <CGAL/Origin.h>
|
||||
#include <CGAL/function.h>
|
||||
|
||||
#include <boost/any.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/utility/result_of.hpp>
|
||||
|
||||
#include <iterator>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#ifdef CGAL_CXX11
|
||||
#include <type_traits>
|
||||
#include <functional>
|
||||
#endif
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
template < class ForwardIterator, class ValueFunctor, class Traits, class Point >
|
||||
|
|
@ -45,12 +53,17 @@ sibson_gradient_fitting(ForwardIterator first,
|
|||
ForwardIterator beyond,
|
||||
const typename std::iterator_traits<ForwardIterator>::value_type::second_type& norm,
|
||||
const Point& p,
|
||||
const typename ValueFunctor::result_type::first_type fn,
|
||||
const typename boost::result_of<
|
||||
ValueFunctor(typename std::iterator_traits<ForwardIterator>::value_type::first_type)>
|
||||
::type::first_type fn,
|
||||
ValueFunctor value_function,
|
||||
const Traits& traits)
|
||||
{
|
||||
CGAL_precondition( first != beyond && norm != 0);
|
||||
|
||||
typedef typename std::iterator_traits<ForwardIterator>::value_type::first_type arg_type;
|
||||
typedef typename boost::result_of<ValueFunctor(arg_type)>::type value_functor_result_type;
|
||||
|
||||
typedef typename Traits::Aff_transformation_d Aff_transformation;
|
||||
typedef typename Traits::FT Coord_type;
|
||||
typedef typename Traits::Point_d Bare_point;
|
||||
|
|
@ -69,7 +82,7 @@ sibson_gradient_fitting(ForwardIterator first,
|
|||
typename Traits::Vector_d d = traits.construct_vector_d_object()(bp, bare_f);
|
||||
|
||||
// compute the vector pn:
|
||||
typename ValueFunctor::result_type f = value_function(first->first);
|
||||
value_functor_result_type f = value_function(first->first);
|
||||
CGAL_assertion(f.second); // function value of first->first is valid
|
||||
pn = pn + traits.construct_scaled_vector_d_object()(d, scale * (f.first - fn));
|
||||
|
||||
|
|
@ -91,7 +104,10 @@ sibson_gradient_fitting(ForwardIterator first,
|
|||
ValueFunctor value_function,
|
||||
const Traits& traits)
|
||||
{
|
||||
typename ValueFunctor::result_type fn = value_function(p);
|
||||
typedef typename std::iterator_traits<ForwardIterator>::value_type::first_type arg_type;
|
||||
typedef typename boost::result_of<ValueFunctor(arg_type)>::type value_functor_result_type;
|
||||
|
||||
value_functor_result_type fn = value_function(p);
|
||||
CGAL_assertion(fn.second);
|
||||
|
||||
return sibson_gradient_fitting(first, beyond, norm, p, fn.first, value_function, traits);
|
||||
|
|
@ -101,7 +117,7 @@ sibson_gradient_fitting(ForwardIterator first,
|
|||
// types of arguments and pass a final (bare) point + value to the function above.
|
||||
template < class ForwardIterator, class ValueFunctor, class Traits, class VH >
|
||||
typename Traits::Vector_d
|
||||
sibson_gradient_fitting_internal(ForwardIterator first,
|
||||
sibson_gradient_fitting_internal_with_dummy(ForwardIterator first,
|
||||
ForwardIterator beyond,
|
||||
const typename std::iterator_traits<
|
||||
ForwardIterator>::value_type::second_type& norm,
|
||||
|
|
@ -110,8 +126,11 @@ sibson_gradient_fitting_internal(ForwardIterator first,
|
|||
const Traits& traits,
|
||||
const typename Traits::Point_d& /*dummy*/)
|
||||
{
|
||||
typedef typename std::iterator_traits<ForwardIterator>::value_type::first_type arg_type;
|
||||
typedef typename boost::result_of<ValueFunctor(arg_type)>::type value_functor_result_type;
|
||||
|
||||
const typename Traits::Point_d& bare_p = traits.construct_point_d_object()(vh->point());
|
||||
typename ValueFunctor::result_type fn = value_function(bare_p);
|
||||
value_functor_result_type fn = value_function(bare_p);
|
||||
CGAL_assertion(fn.second);
|
||||
|
||||
return sibson_gradient_fitting(first, beyond, norm, bare_p, fn.first, value_function, traits);
|
||||
|
|
@ -120,7 +139,7 @@ sibson_gradient_fitting_internal(ForwardIterator first,
|
|||
|
||||
template < class ForwardIterator, class ValueFunctor, class Traits, class VH >
|
||||
typename Traits::Vector_d
|
||||
sibson_gradient_fitting_internal(ForwardIterator first,
|
||||
sibson_gradient_fitting_internal_with_dummy(ForwardIterator first,
|
||||
ForwardIterator beyond,
|
||||
const typename std::iterator_traits<
|
||||
ForwardIterator>::value_type::second_type& norm,
|
||||
|
|
@ -129,7 +148,10 @@ sibson_gradient_fitting_internal(ForwardIterator first,
|
|||
const Traits& traits,
|
||||
const typename Traits::Weighted_point_d& /*dummy*/)
|
||||
{
|
||||
typename ValueFunctor::result_type fn = value_function(vh->point());
|
||||
typedef typename std::iterator_traits<ForwardIterator>::value_type::first_type arg_type;
|
||||
typedef typename boost::result_of<ValueFunctor(arg_type)>::type value_functor_result_type;
|
||||
|
||||
value_functor_result_type fn = value_function(vh->point());
|
||||
CGAL_assertion(fn.second);
|
||||
|
||||
return sibson_gradient_fitting(first, beyond, norm, vh->point(), fn.first, value_function, traits);
|
||||
|
|
@ -138,7 +160,7 @@ sibson_gradient_fitting_internal(ForwardIterator first,
|
|||
|
||||
template < class ForwardIterator, class ValueFunctor, class Traits, class VH >
|
||||
typename Traits::Vector_d
|
||||
sibson_gradient_fitting_internal(ForwardIterator first,
|
||||
sibson_gradient_fitting_internal_with_dummy(ForwardIterator first,
|
||||
ForwardIterator beyond,
|
||||
const typename std::iterator_traits<
|
||||
ForwardIterator>::value_type::second_type& norm,
|
||||
|
|
@ -147,15 +169,19 @@ sibson_gradient_fitting_internal(ForwardIterator first,
|
|||
const Traits& traits,
|
||||
VH /*dummy*/)
|
||||
{
|
||||
typedef typename std::iterator_traits<ForwardIterator>::value_type::first_type arg_type;
|
||||
typedef typename boost::result_of<ValueFunctor(arg_type)>::type value_functor_result_type;
|
||||
|
||||
const typename Traits::Point_d& bare_p = traits.construct_point_d_object()(vh->point());
|
||||
typename ValueFunctor::result_type fn = value_function(vh);
|
||||
value_functor_result_type fn = value_function(vh);
|
||||
CGAL_assertion(fn.second);
|
||||
|
||||
return sibson_gradient_fitting(first, beyond, norm, bare_p, fn.first, value_function, traits);
|
||||
}
|
||||
|
||||
|
||||
template < class Tr, class OutputIterator, class OutputFunctor,
|
||||
template < class ValueFunctorArgType,
|
||||
class Tr, class OutputIterator, class OutputFunctor,
|
||||
class ValueFunctor, class CoordFunctor, class Traits >
|
||||
OutputIterator
|
||||
sibson_gradient_fitting_internal(const Tr& tr,
|
||||
|
|
@ -170,7 +196,7 @@ sibson_gradient_fitting_internal(const Tr& tr,
|
|||
typedef typename Tr::Vertex_handle Vertex_handle;
|
||||
|
||||
Coord_type norm;
|
||||
std::vector<std::pair<typename ValueFunctor::argument_type, Coord_type> > coords;
|
||||
std::vector<std::pair<ValueFunctorArgType, Coord_type> > coords;
|
||||
|
||||
typename Tr::Finite_vertices_iterator vit = tr.finite_vertices_begin();
|
||||
for(; vit != tr.finite_vertices_end(); ++vit)
|
||||
|
|
@ -181,13 +207,13 @@ sibson_gradient_fitting_internal(const Tr& tr,
|
|||
norm = compute_coordinates(tr, vit, std::back_inserter(coords), Coord_OutputFunctor()).second;
|
||||
|
||||
*out++ = fct(std::make_pair(vit,
|
||||
sibson_gradient_fitting_internal(coords.begin(),
|
||||
sibson_gradient_fitting_internal_with_dummy(coords.begin(),
|
||||
coords.end(),
|
||||
norm,
|
||||
Vertex_handle(vit),
|
||||
value_function,
|
||||
traits,
|
||||
typename ValueFunctor::argument_type())));
|
||||
ValueFunctorArgType())));
|
||||
|
||||
coords.clear();
|
||||
}
|
||||
|
|
@ -196,12 +222,73 @@ sibson_gradient_fitting_internal(const Tr& tr,
|
|||
return out;
|
||||
}
|
||||
|
||||
|
||||
// The following functions allow to fit the gradients for all points in
|
||||
// a triangulation except the convex hull points.
|
||||
// -> _nn2: natural_neighbor_coordinates_2
|
||||
// -> _rn2: regular_neighbor_coordinates_2
|
||||
// -> _sn2_3: surface_neighbor_coordinates_2_3
|
||||
|
||||
// The ugly distinction below is needed to make it work with lambdas for C++11 because std::is_constructible
|
||||
// is used, which is C++11 (there is a boost equivalent, but it is said (by boost) to be relying on C++11 features
|
||||
// to properly work...)
|
||||
#ifdef CGAL_CXX11
|
||||
|
||||
template < class Dt, class OutputIterator, class OutputFunctor, class ValueFunctor, class Traits >
|
||||
OutputIterator
|
||||
sibson_gradient_fitting_nn_2(const Dt& dt,
|
||||
OutputIterator out,
|
||||
OutputFunctor fct,
|
||||
ValueFunctor value_function,
|
||||
const Traits& traits,
|
||||
// Some SFINAE to distinguish whether the argument type
|
||||
// of the value functor is 'DT::Point' or 'DT::Vertex_handle'
|
||||
typename boost::enable_if_c<
|
||||
std::is_constructible<
|
||||
std::function<boost::any(typename Dt::Point)>,
|
||||
ValueFunctor
|
||||
>::value>::type* = NULL)
|
||||
{
|
||||
typedef typename Traits::FT FT;
|
||||
typedef typename Dt::Point VF_arg_type;
|
||||
typedef typename std::back_insert_iterator<std::vector<
|
||||
std::pair<VF_arg_type, FT> > > CoordInserter;
|
||||
typedef Interpolation::internal::Extract_point_in_pair<Dt, FT> Coord_OutputFunctor;
|
||||
|
||||
return sibson_gradient_fitting_internal<VF_arg_type>(dt, out, fct, value_function,
|
||||
natural_neighbor_coordinates_2_object<Dt,
|
||||
CoordInserter,
|
||||
Coord_OutputFunctor>(),
|
||||
traits);
|
||||
}
|
||||
|
||||
template < class Dt, class OutputIterator, class OutputFunctor, class ValueFunctor, class Traits >
|
||||
OutputIterator
|
||||
sibson_gradient_fitting_nn_2(const Dt& dt,
|
||||
OutputIterator out,
|
||||
OutputFunctor fct,
|
||||
ValueFunctor value_function,
|
||||
const Traits& traits,
|
||||
typename boost::enable_if_c<
|
||||
std::is_constructible<
|
||||
std::function<boost::any(typename Dt::Vertex_handle)>,
|
||||
ValueFunctor
|
||||
>::value>::type* = NULL)
|
||||
{
|
||||
typedef typename Traits::FT FT;
|
||||
typedef typename Dt::Vertex_handle VF_arg_type;
|
||||
typedef typename std::back_insert_iterator<std::vector<
|
||||
std::pair<VF_arg_type, FT> > > CoordInserter;
|
||||
typedef CGAL::Identity<std::pair<VF_arg_type, FT> > Coord_OutputFunctor;
|
||||
|
||||
return sibson_gradient_fitting_internal<VF_arg_type>(dt, out, fct, value_function,
|
||||
natural_neighbor_coordinates_2_object<Dt,
|
||||
CoordInserter,
|
||||
Coord_OutputFunctor>(),
|
||||
traits);
|
||||
}
|
||||
|
||||
#else // not CGAL_CXX11
|
||||
|
||||
template < class Dt, class OutputIterator, class OutputFunctor, class ValueFunctor, class Traits >
|
||||
OutputIterator
|
||||
sibson_gradient_fitting_nn_2(const Dt& dt,
|
||||
|
|
@ -224,15 +311,16 @@ sibson_gradient_fitting_nn_2(const Dt& dt,
|
|||
CGAL::Identity<std::pair<VF_arg_type, FT> >
|
||||
>::type Coord_OutputFunctor;
|
||||
|
||||
return sibson_gradient_fitting_internal(dt, out, fct, value_function,
|
||||
return sibson_gradient_fitting_internal<VF_arg_type>(dt, out, fct, value_function,
|
||||
natural_neighbor_coordinates_2_object<Dt,
|
||||
CoordInserter,
|
||||
Coord_OutputFunctor>(),
|
||||
traits);
|
||||
}
|
||||
#endif // CGAL_CXX11
|
||||
|
||||
|
||||
// Same as above but without OutputFunctor. Default to extracting the point, for backward compatibility.
|
||||
// Same as above but without OutputFunctor.
|
||||
// Defaults to extracting the point, for backward compatibility.
|
||||
template < class Dt, class OutputIterator, class ValueFunctor, class Traits >
|
||||
OutputIterator
|
||||
sibson_gradient_fitting_nn_2(const Dt& dt,
|
||||
|
|
@ -246,6 +334,64 @@ sibson_gradient_fitting_nn_2(const Dt& dt,
|
|||
return sibson_gradient_fitting_nn_2(dt, out, OutputFunctor(), value_function, traits);
|
||||
}
|
||||
|
||||
// See above for the explanation.
|
||||
#ifdef CGAL_CXX11
|
||||
|
||||
template < class Rt, class OutputIterator, class OutputFunctor, class ValueFunctor, class Traits >
|
||||
OutputIterator
|
||||
sibson_gradient_fitting_rn_2(const Rt& rt,
|
||||
OutputIterator out,
|
||||
OutputFunctor fct,
|
||||
ValueFunctor value_function,
|
||||
const Traits& traits,
|
||||
// Some SFINAE to distinguish whether the argument type
|
||||
// of the value functor is 'Rt::Point' (weighted point) or 'Rt::Vertex_handle'
|
||||
typename boost::enable_if_c<
|
||||
std::is_constructible<
|
||||
std::function<boost::any(typename Rt::Point)>,
|
||||
ValueFunctor
|
||||
>::value>::type* = NULL)
|
||||
{
|
||||
typedef typename Traits::FT FT;
|
||||
typedef typename Rt::Point VF_arg_type;
|
||||
typedef typename std::back_insert_iterator<std::vector<
|
||||
std::pair<VF_arg_type, FT> > > CoordInserter;
|
||||
typedef Interpolation::internal::Extract_point_in_pair<Rt, FT> Coord_OutputFunctor;
|
||||
|
||||
return sibson_gradient_fitting_internal<VF_arg_type>(rt, out, fct, value_function,
|
||||
regular_neighbor_coordinates_2_object<Rt,
|
||||
CoordInserter,
|
||||
Coord_OutputFunctor>(),
|
||||
traits);
|
||||
}
|
||||
|
||||
template < class Rt, class OutputIterator, class OutputFunctor, class ValueFunctor, class Traits >
|
||||
OutputIterator
|
||||
sibson_gradient_fitting_rn_2(const Rt& rt,
|
||||
OutputIterator out,
|
||||
OutputFunctor fct,
|
||||
ValueFunctor value_function,
|
||||
const Traits& traits,
|
||||
typename boost::enable_if_c<
|
||||
std::is_constructible<
|
||||
std::function<boost::any(typename Rt::Vertex_handle)>,
|
||||
ValueFunctor
|
||||
>::value>::type* = NULL)
|
||||
{
|
||||
typedef typename Traits::FT FT;
|
||||
typedef typename Rt::Vertex_handle VF_arg_type;
|
||||
typedef typename std::back_insert_iterator<std::vector<
|
||||
std::pair<VF_arg_type, FT> > > CoordInserter;
|
||||
typedef CGAL::Identity<std::pair<VF_arg_type, FT> > Coord_OutputFunctor;
|
||||
|
||||
return sibson_gradient_fitting_internal<VF_arg_type>(rt, out, fct, value_function,
|
||||
regular_neighbor_coordinates_2_object<Rt,
|
||||
CoordInserter,
|
||||
Coord_OutputFunctor>(),
|
||||
traits);
|
||||
}
|
||||
|
||||
#else // CGAL_CXX11
|
||||
|
||||
template < class Rt, class OutputIterator, class OutputFunctor, class ValueFunctor, class Traits >
|
||||
OutputIterator
|
||||
|
|
@ -269,13 +415,14 @@ sibson_gradient_fitting_rn_2(const Rt& rt,
|
|||
CGAL::Identity<std::pair<VF_arg_type, FT> >
|
||||
>::type Coord_OutputFunctor;
|
||||
|
||||
return sibson_gradient_fitting_internal(rt, out, fct, value_function,
|
||||
return sibson_gradient_fitting_internal<VF_arg_type>(rt, out, fct, value_function,
|
||||
regular_neighbor_coordinates_2_object<Rt,
|
||||
CoordInserter,
|
||||
Coord_OutputFunctor>(),
|
||||
traits);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// Same as above but without OutputFunctor. Default to extracting the point, for backward compatibility.
|
||||
template < class Rt, class OutputIterator, class ValueFunctor, class Traits >
|
||||
|
|
|
|||
|
|
@ -31,11 +31,14 @@
|
|||
#include <CGAL/algorithm.h>
|
||||
#include <CGAL/double.h>
|
||||
#include <CGAL/function_objects.h>
|
||||
#include <CGAL/function.h>
|
||||
#include <CGAL/Origin.h>
|
||||
#include <CGAL/point_generators_2.h>
|
||||
#include <CGAL/Random.h>
|
||||
#include <CGAL/squared_distance_2.h>
|
||||
|
||||
#include <boost/utility/result_of.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
#include <utility>
|
||||
|
|
@ -47,6 +50,8 @@ struct Extract_point
|
|||
typedef typename Traits::Point_2 Point_2;
|
||||
typedef typename Traits::Weighted_point_2 Weighted_point_2;
|
||||
|
||||
typedef typename Traits::Construct_point_2 Construct_point_2;
|
||||
|
||||
Extract_point(const Traits& traits = Traits()) : traits(traits) {}
|
||||
|
||||
const Point_2& operator()(const Point_2& p) const { return p; }
|
||||
|
|
@ -56,7 +61,8 @@ struct Extract_point
|
|||
}
|
||||
|
||||
template <typename VH>
|
||||
const Point_2& operator()(const VH& vh) const {
|
||||
typename boost::result_of<const Construct_point_2(const Point_2&)>::type
|
||||
operator()(const VH& vh) const {
|
||||
return traits.construct_point_2_object()(vh->point());
|
||||
}
|
||||
|
||||
|
|
@ -64,6 +70,42 @@ private:
|
|||
Traits traits;
|
||||
};
|
||||
|
||||
template <typename V, typename T>
|
||||
struct Value_function
|
||||
{
|
||||
typedef V argument_type;
|
||||
typedef std::pair<T, bool> result_type;
|
||||
|
||||
Value_function(std::size_t i) : index(i) { }
|
||||
|
||||
result_type operator()(const argument_type& a) const {
|
||||
return result_type(a->info()[index].value, true);
|
||||
}
|
||||
|
||||
private:
|
||||
std::size_t index;
|
||||
};
|
||||
|
||||
template <typename V, typename G>
|
||||
struct Gradient_function
|
||||
: public CGAL::cpp98::iterator<std::output_iterator_tag, void, void, void, void>
|
||||
{
|
||||
|
||||
typedef V argument_type;
|
||||
typedef std::pair<G, bool> result_type;
|
||||
|
||||
Gradient_function(std::size_t i) : index(i) { }
|
||||
|
||||
result_type operator()(const argument_type& a) const {
|
||||
return std::make_pair(a->info()[index].gradient,
|
||||
a->info()[index].gradient != CGAL::NULL_VECTOR);
|
||||
}
|
||||
|
||||
private:
|
||||
std::size_t index;
|
||||
};
|
||||
|
||||
|
||||
template < class ForwardIterator >
|
||||
bool test_norm(ForwardIterator first, ForwardIterator beyond,
|
||||
typename std::iterator_traits<ForwardIterator>::value_type::second_type norm)
|
||||
|
|
@ -83,10 +125,10 @@ bool test_norm(ForwardIterator first, ForwardIterator beyond,
|
|||
}
|
||||
}
|
||||
|
||||
template < class Tr, class ForwardIterator >
|
||||
template < class Tr, class ForwardIterator, class Point >
|
||||
bool test_barycenter(ForwardIterator first, ForwardIterator beyond,
|
||||
typename std::iterator_traits<ForwardIterator>::value_type::second_type norm,
|
||||
const typename std::iterator_traits<ForwardIterator>::value_type::first_type& p,
|
||||
const Point& p,
|
||||
const typename std::iterator_traits<ForwardIterator>::value_type::second_type& tolerance)
|
||||
{
|
||||
typedef typename Tr::Geom_traits Gt;
|
||||
|
|
@ -133,9 +175,13 @@ bool _test_sibson_c1_interpolation_sqrt(ForwardIterator first, ForwardIterator b
|
|||
const typename std::iterator_traits<ForwardIterator>::value_type::second_type& exact_value,
|
||||
CGAL::Field_with_sqrt_tag)
|
||||
{
|
||||
typename ValueFunctor::result_type res = CGAL::sibson_c1_interpolation(first, beyond,
|
||||
typedef typename std::iterator_traits<ForwardIterator>::value_type::first_type arg_type;
|
||||
typedef typename boost::result_of<ValueFunctor(arg_type)>::type value_functor_result_type;
|
||||
|
||||
value_functor_result_type res = CGAL::sibson_c1_interpolation(first, beyond,
|
||||
norm, p, f,
|
||||
grad_f, geom_traits);
|
||||
|
||||
return res.second && (CGAL_NTS abs(res.first-exact_value) <= tolerance);
|
||||
}
|
||||
|
||||
|
|
@ -143,14 +189,18 @@ template < class ForwardIterator, class ValueFunctor, class GradFunctor, class G
|
|||
bool test_interpolation_with_value(ForwardIterator first, ForwardIterator beyond,
|
||||
const typename std::iterator_traits<ForwardIterator>::value_type::second_type& norm,
|
||||
const Point& p,
|
||||
const typename ValueFunctor::result_type::first_type exact_value,
|
||||
const typename boost::result_of<
|
||||
ValueFunctor(typename std::iterator_traits<ForwardIterator>::value_type::first_type)>
|
||||
::type::first_type exact_value,
|
||||
ValueFunctor f,
|
||||
GradFunctor grad_f,
|
||||
const Gt& geom_traits,
|
||||
const int& i,
|
||||
const typename std::iterator_traits<ForwardIterator>::value_type::second_type& tolerance)
|
||||
{
|
||||
typedef typename ValueFunctor::result_type::first_type Value_type;
|
||||
typedef typename std::iterator_traits<ForwardIterator>::value_type::first_type arg_type;
|
||||
typedef typename boost::result_of<ValueFunctor(arg_type)>::type value_functor_result_type;
|
||||
typedef typename value_functor_result_type::first_type Value_type;
|
||||
|
||||
if(i == 0)
|
||||
{
|
||||
|
|
@ -158,7 +208,7 @@ bool test_interpolation_with_value(ForwardIterator first, ForwardIterator beyond
|
|||
assert(CGAL_NTS abs(val - exact_value) <= tolerance);
|
||||
}
|
||||
|
||||
typename ValueFunctor::result_type res = CGAL::quadratic_interpolation(first, beyond, norm, p, f,
|
||||
value_functor_result_type res = CGAL::quadratic_interpolation(first, beyond, norm, p, f,
|
||||
grad_f, geom_traits);
|
||||
assert(res.second && (CGAL_NTS abs(res.first - exact_value) <= tolerance));
|
||||
|
||||
|
|
@ -185,20 +235,17 @@ bool test_interpolation_with_value(ForwardIterator first, ForwardIterator beyond
|
|||
return true;
|
||||
}
|
||||
|
||||
template < class ForwardIterator, class ValueFunctor, class GradFunctor, class Gt, class Point>
|
||||
template < class ForwardIterator, class ValueFunctor, class GradFunctor, class Gt, class Point, class Value_type>
|
||||
bool test_interpolation(ForwardIterator first, ForwardIterator beyond,
|
||||
const typename std::iterator_traits<ForwardIterator>::value_type::second_type& norm,
|
||||
const Point& p,
|
||||
const Value_type exact_value,
|
||||
ValueFunctor f,
|
||||
GradFunctor grad_f,
|
||||
const Gt& geom_traits,
|
||||
const int& i,
|
||||
const typename std::iterator_traits<ForwardIterator>::value_type::second_type& tolerance)
|
||||
{
|
||||
typedef typename ValueFunctor::result_type::first_type Value_type;
|
||||
assert(f(p).second);
|
||||
Value_type exact_value = f(p).first;
|
||||
|
||||
return test_interpolation_with_value(first, beyond, norm, p, exact_value, f, grad_f, geom_traits, i, tolerance);
|
||||
}
|
||||
|
||||
|
|
@ -308,7 +355,8 @@ void _test_interpolation_functions_2_Delaunay_without_OutputFunctor(const Dt&, c
|
|||
|
||||
for(int i=0; i<3; ++i)
|
||||
{
|
||||
assert(test_interpolation(coords.begin(), coords.end(), norm, points[j],
|
||||
assert(test_interpolation(coords.begin(), coords.end(), norm,
|
||||
points[j], values[i][points[j]],
|
||||
CGAL::Data_access< Point_value_map >(values[i]),
|
||||
CGAL::Data_access< Point_vector_map >(gradients[i]),
|
||||
Traits(), i, tolerance));
|
||||
|
|
@ -368,7 +416,8 @@ void _test_interpolation_functions_2_Delaunay_without_OutputFunctor(const Dt&, c
|
|||
|
||||
for(int j=0; j<3; ++j)
|
||||
{
|
||||
assert(test_interpolation(coords.begin(), coords.end(), norm, points[n/2],
|
||||
assert(test_interpolation(coords.begin(), coords.end(), norm,
|
||||
points[n/2], values[j][points[n/2]],
|
||||
CGAL::Data_access<Point_value_map>(values[j]),
|
||||
CGAL::Data_access<Point_vector_map>(gradients[j]),
|
||||
Traits(), j, tolerance));
|
||||
|
|
@ -391,16 +440,18 @@ void _test_interpolation_functions_2_Delaunay_with_OutputFunctor(const Dt&, cons
|
|||
typedef typename Dt::Geom_traits Gt;
|
||||
typedef CGAL::Interpolation_traits_2<Gt> Traits;
|
||||
|
||||
typedef typename Dt::Vertex_handle Vertex_handle;
|
||||
|
||||
typedef typename Gt::FT Coord_type;
|
||||
typedef typename Dt::Point Point;
|
||||
typedef typename Gt::Vector_2 Vector;
|
||||
|
||||
typedef std::map<Point, Coord_type, typename Gt::Less_xy_2> Point_value_map ;
|
||||
typedef std::map<Point, Vector, typename Gt::Less_xy_2> Point_vector_map;
|
||||
typedef std::vector<std::pair<Vertex_handle, Coord_type> > Coordinate_vector;
|
||||
typedef typename Coordinate_vector::const_iterator CV_cit;
|
||||
typedef CGAL::Identity<std::pair<Vertex_handle, Coord_type> > Output_functor;
|
||||
|
||||
typedef std::vector<std::pair<Point, Coord_type> > Point_coordinate_vector;
|
||||
typedef typename Point_coordinate_vector::const_iterator PCV_cit;
|
||||
typedef CGAL::Interpolation::internal::Extract_point_in_pair<Dt, Coord_type> Point_output_functor;
|
||||
typedef std::map<Point, Coord_type> Point_value_map;
|
||||
typedef std::map<Point, Vector> Point_vector_map;
|
||||
|
||||
std::cout << "NN2: Testing random points." << std::endl;
|
||||
|
||||
|
|
@ -420,9 +471,6 @@ void _test_interpolation_functions_2_Delaunay_with_OutputFunctor(const Dt&, cons
|
|||
|
||||
CGAL::Random random;
|
||||
|
||||
Point_value_map values[3];
|
||||
Point_vector_map gradients[3];
|
||||
|
||||
Coord_type alpha = Coord_type(random.get_double(-max_value, max_value)),
|
||||
beta1 = Coord_type(random.get_double(-max_value, max_value)),
|
||||
beta2 = Coord_type(random.get_double(-max_value, max_value)),
|
||||
|
|
@ -431,67 +479,110 @@ void _test_interpolation_functions_2_Delaunay_with_OutputFunctor(const Dt&, cons
|
|||
gamma3 = Coord_type(random.get_double(-max_value, max_value));
|
||||
|
||||
//INSERTION + DET. of GRADIENT for n DATA POINTS :
|
||||
for(int j=0; j<n; ++j)
|
||||
{
|
||||
T.insert(points[j]);
|
||||
|
||||
gradients[0].insert(std::make_pair(points[j], Vector(beta1, beta2)));
|
||||
|
||||
gradients[1].insert(std::make_pair(points[j],
|
||||
Vector(beta1 + Coord_type(2)*gamma1*points[j].x(),
|
||||
beta2 + Coord_type(2)*gamma1*points[j].y())));
|
||||
gradients[2].insert(std::make_pair(points[j],
|
||||
Vector(beta1 + Coord_type(2)*gamma1*points[j].x() + gamma3*points[j].y(),
|
||||
beta2 + Coord_type(2)*gamma2*points[j].y() + gamma3*points[j].x())));
|
||||
}
|
||||
|
||||
//DETERMINE VALUES FOR n DATA POINTS AND m RANDOM TEST POINTS:
|
||||
for(int j=0; j<n+m; j++)
|
||||
Point_value_map exact_values[3];
|
||||
|
||||
std::map<Point, Vertex_handle> p_to_vh;
|
||||
|
||||
for(int j=0; j<n+m; ++j)
|
||||
{
|
||||
// linear function
|
||||
values[0].insert(std::make_pair(points[j], alpha + beta1*points[j].x() + beta2*points[j].y()));
|
||||
Vector gradient0(beta1, beta2);
|
||||
Vector gradient1(beta1 + Coord_type(2)*gamma1*points[j].x(),
|
||||
beta2 + Coord_type(2)*gamma1*points[j].y());
|
||||
Vector gradient2(beta1 + Coord_type(2)*gamma1*points[j].x() + gamma3*points[j].y(),
|
||||
beta2 + Coord_type(2)*gamma2*points[j].y() + gamma3*points[j].x());
|
||||
|
||||
// spherical function:
|
||||
values[1].insert(std::make_pair(points[j], alpha + beta1*points[j].x() +
|
||||
beta2*points[j].y() +
|
||||
gamma1*points[j].x()*points[j].x()+
|
||||
gamma1*points[j].y()*points[j].y()));
|
||||
Coord_type value0 = alpha + beta1*points[j].x() + beta2*points[j].y();
|
||||
Coord_type value1 = alpha + beta1*points[j].x()
|
||||
+ beta2*points[j].y()
|
||||
+ gamma1*points[j].x()*points[j].x()
|
||||
+ gamma1*points[j].y()*points[j].y();
|
||||
Coord_type value2 = alpha + beta1*points[j].x()
|
||||
+ beta2*points[j].y()
|
||||
+ gamma1*points[j].x()*points[j].x()
|
||||
+ gamma2*points[j].y()*points[j].y()
|
||||
+ gamma3*points[j].x()*points[j].y();
|
||||
|
||||
// quadratic function
|
||||
values[2].insert(std::make_pair(points[j], alpha + beta1*points[j].x() +
|
||||
beta2*points[j].y() +
|
||||
gamma1*points[j].x()*points[j].x() +
|
||||
gamma2*points[j].y()*points[j].y() +
|
||||
gamma3*points[j].x()*points[j].y()));
|
||||
if(j<n) // only insert n points
|
||||
{
|
||||
Vertex_handle vh = T.insert(points[j]);
|
||||
p_to_vh[points[j]] = vh;
|
||||
|
||||
vh->info()[0].gradient = gradient0;
|
||||
vh->info()[1].gradient = gradient1;
|
||||
vh->info()[2].gradient = gradient2;
|
||||
|
||||
|
||||
vh->info()[0].value = value0;
|
||||
vh->info()[1].value = value1;
|
||||
vh->info()[2].value = value2;
|
||||
}
|
||||
else
|
||||
{
|
||||
exact_values[0][points[j]] = value0;
|
||||
exact_values[1][points[j]] = value1;
|
||||
exact_values[2][points[j]] = value2;
|
||||
}
|
||||
}
|
||||
|
||||
//INTERPOLATION OF RANDOM POINTS:
|
||||
Coord_type norm;
|
||||
|
||||
Point_coordinate_vector pt_coords;
|
||||
Point_output_functor pt_fct;
|
||||
Coordinate_vector coords;
|
||||
Output_functor out_fct;
|
||||
|
||||
for(int j=n; j<n+m; ++j)
|
||||
{
|
||||
CGAL::Triple<std::back_insert_iterator<Point_coordinate_vector>, Coord_type, bool> coordinate_result =
|
||||
CGAL::natural_neighbor_coordinates_2(T, points[j], std::back_inserter(pt_coords), pt_fct);
|
||||
CGAL::Triple<std::back_insert_iterator<Coordinate_vector>, Coord_type, bool> coordinate_result =
|
||||
CGAL::natural_neighbor_coordinates_2(T, points[j], std::back_inserter(coords), out_fct);
|
||||
assert(coordinate_result.third);
|
||||
norm = coordinate_result.second;
|
||||
|
||||
bool is_equal = test_norm(pt_coords.begin(), pt_coords.end(), norm);
|
||||
bool is_equal = test_norm(coords.begin(), coords.end(), norm);
|
||||
assert(norm > 0);
|
||||
assert(is_equal);
|
||||
is_equal = test_barycenter<Dt>(pt_coords.begin(), pt_coords.end(), norm, points[j], tolerance);
|
||||
is_equal = test_barycenter<Dt>(coords.begin(), coords.end(), norm, points[j], tolerance);
|
||||
assert(is_equal);
|
||||
|
||||
#ifdef CGAL_CXX11
|
||||
assert(test_interpolation(coords.begin(), coords.end(), norm,
|
||||
points[j], exact_values[0][points[j]],
|
||||
[](const Vertex_handle vh) -> std::pair<Coord_type, bool> { return std::make_pair(vh->info()[0].value, true); },
|
||||
[](const Vertex_handle vh) -> std::pair<Vector, bool> { return std::make_pair(vh->info()[0].gradient, true); },
|
||||
Traits(), 0, tolerance));
|
||||
|
||||
|
||||
// wrapping the lambda in a std function
|
||||
CGAL::cpp11::function<std::pair<Coord_type, bool>(const Vertex_handle)> value_function_1 =
|
||||
[](const Vertex_handle vh) -> std::pair<Coord_type, bool> { return std::make_pair(vh->info()[1].value, true); };
|
||||
|
||||
std::function<std::pair<Vector, bool>(const Vertex_handle)> gradient_function_1 =
|
||||
[](const Vertex_handle vh) -> std::pair<Vector, bool> { return std::make_pair(vh->info()[1].gradient, true); };
|
||||
|
||||
assert(test_interpolation(coords.begin(), coords.end(), norm,
|
||||
points[j], exact_values[1][points[j]],
|
||||
value_function_1, gradient_function_1,
|
||||
Traits(), 1, tolerance));
|
||||
|
||||
assert(test_interpolation(coords.begin(), coords.end(), norm,
|
||||
points[j], exact_values[2][points[j]],
|
||||
[](const Vertex_handle vh) -> std::pair<Coord_type, bool> { return std::make_pair(vh->info()[2].value, true); },
|
||||
[](const Vertex_handle vh) -> std::pair<Vector, bool> { return std::make_pair(vh->info()[2].gradient, true); },
|
||||
Traits(), 2, tolerance));
|
||||
#else
|
||||
for(int i=0; i<3; ++i)
|
||||
{
|
||||
assert(test_interpolation(pt_coords.begin(), pt_coords.end(), norm, points[j],
|
||||
CGAL::Data_access< Point_value_map >(values[i]),
|
||||
CGAL::Data_access< Point_vector_map >(gradients[i]),
|
||||
Value_function<Vertex_handle, Coord_type> value_function(i);
|
||||
Gradient_function<Vertex_handle, Vector> gradient_function(i);
|
||||
|
||||
assert(test_interpolation(coords.begin(), coords.end(), norm,
|
||||
points[j], exact_values[i][points[j]],
|
||||
value_function, gradient_function,
|
||||
Traits(), i, tolerance));
|
||||
}
|
||||
pt_coords.clear();
|
||||
#endif
|
||||
|
||||
coords.clear();
|
||||
}
|
||||
|
||||
//TESTING THE GRADIENT APPRXIMATION METHOD:
|
||||
|
|
@ -499,18 +590,44 @@ void _test_interpolation_functions_2_Delaunay_with_OutputFunctor(const Dt&, cons
|
|||
std::cout << "Testing gradient estimation method on random points." << std::endl;
|
||||
|
||||
typedef CGAL::Interpolation_gradient_fitting_traits_2<Gt> GradTraits;
|
||||
|
||||
Point_vector_map approx_gradients[2];
|
||||
|
||||
#ifdef CGAL_CXX11
|
||||
{
|
||||
CGAL::sibson_gradient_fitting_nn_2(T,
|
||||
std::inserter(approx_gradients[0], approx_gradients[0].begin()), // OutputIterator
|
||||
CGAL::Interpolation::internal::Extract_point_in_pair<Dt, Vector>(), // OutputFunctor
|
||||
CGAL::Data_access<Point_value_map>(values[0]), // ValueFunctor
|
||||
[](const Vertex_handle vh)
|
||||
-> std::pair<Coord_type, bool>
|
||||
{ return std::make_pair(vh->info()[0].value, true); },
|
||||
GradTraits());
|
||||
|
||||
std::function<std::pair<Coord_type, bool>(const Vertex_handle)> value_function_1 =
|
||||
[](const Vertex_handle vh) -> std::pair<Coord_type, bool> { return std::make_pair(vh->info()[1].value, true); };
|
||||
|
||||
CGAL::sibson_gradient_fitting_nn_2(T,
|
||||
std::inserter(approx_gradients[1], approx_gradients[1].begin()),
|
||||
CGAL::Interpolation::internal::Extract_point_in_pair<Dt, Vector>(),
|
||||
value_function_1,
|
||||
GradTraits());
|
||||
}
|
||||
#else
|
||||
Value_function<Vertex_handle, Coord_type> value_function_0(0);
|
||||
Value_function<Vertex_handle, Coord_type> value_function_1(1);
|
||||
|
||||
CGAL::sibson_gradient_fitting_nn_2(T,
|
||||
std::inserter(approx_gradients[0], approx_gradients[0].begin()), // OutputIterator
|
||||
CGAL::Interpolation::internal::Extract_point_in_pair<Dt, Vector>(), // OutputFunctor
|
||||
value_function_0,
|
||||
GradTraits());
|
||||
|
||||
CGAL::sibson_gradient_fitting_nn_2(T,
|
||||
std::inserter(approx_gradients[1], approx_gradients[1].begin()),
|
||||
CGAL::Interpolation::internal::Extract_point_in_pair<Dt, Vector>(),
|
||||
CGAL::Data_access<Point_value_map>(values[1]),
|
||||
value_function_1,
|
||||
GradTraits());
|
||||
#endif
|
||||
|
||||
for(int j=0; j<n; ++j)
|
||||
{
|
||||
|
|
@ -518,16 +635,19 @@ void _test_interpolation_functions_2_Delaunay_with_OutputFunctor(const Dt&, cons
|
|||
|
||||
if(res.second)
|
||||
{
|
||||
Gradient_function<Vertex_handle, Vector> gradient_function_0(0);
|
||||
Gradient_function<Vertex_handle, Vector> gradient_function_1(1);
|
||||
|
||||
// if it is the exact computation kernel: test the equality:
|
||||
assert(tolerance > Coord_type(0) ||
|
||||
res.first == CGAL::Data_access<Point_vector_map>(gradients[0])(points[j]).first);
|
||||
res.first == (gradient_function_0(p_to_vh[points[j]])).first);
|
||||
res = CGAL::Data_access<Point_vector_map>(approx_gradients[1])(points[j]);
|
||||
|
||||
// if one exists->the other must also exist
|
||||
assert(res.second);
|
||||
|
||||
assert(tolerance > Coord_type(0) ||
|
||||
res.first == CGAL::Data_access<Point_vector_map>(gradients[1])(points[j]).first);
|
||||
res.first == gradient_function_1(p_to_vh[points[j]]).first);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -536,31 +656,66 @@ void _test_interpolation_functions_2_Delaunay_with_OutputFunctor(const Dt&, cons
|
|||
}
|
||||
|
||||
//TESTING A POINT == A DATA POINT:
|
||||
CGAL::Triple<std::back_insert_iterator<Point_coordinate_vector>, Coord_type, bool> coordinate_result =
|
||||
CGAL::natural_neighbor_coordinates_2(T, points[n/2], std::back_inserter(pt_coords), pt_fct);
|
||||
CGAL::Triple<std::back_insert_iterator<Coordinate_vector>, Coord_type, bool> coordinate_result =
|
||||
CGAL::natural_neighbor_coordinates_2(T, points[n/2], std::back_inserter(coords), out_fct);
|
||||
assert(coordinate_result.third);
|
||||
norm = coordinate_result.second;
|
||||
assert(norm == Coord_type(1));
|
||||
|
||||
PCV_cit ci = pt_coords.begin();
|
||||
assert(ci->first == points[n/2]);
|
||||
CV_cit ci = coords.begin();
|
||||
assert(ci->first == p_to_vh[points[n/2]]);
|
||||
assert(ci->second == Coord_type(1));
|
||||
ci++;
|
||||
assert(ci == pt_coords.end());
|
||||
assert(ci == coords.end());
|
||||
|
||||
#ifdef CGAL_CXX11
|
||||
Value_function<Vertex_handle, Coord_type> value_function_0(0);
|
||||
Value_function<Vertex_handle, Coord_type> value_function_2(2);
|
||||
|
||||
assert(test_interpolation(coords.begin(), coords.end(), norm,
|
||||
points[n/2], value_function_0(p_to_vh[points[n/2]]).first,
|
||||
[](const Vertex_handle vh) -> std::pair<Coord_type, bool> { return std::make_pair(vh->info()[0].value, true); },
|
||||
[](const Vertex_handle vh) -> std::pair<Vector, bool> { return std::make_pair(vh->info()[0].gradient, true); },
|
||||
Traits(), 0, tolerance));
|
||||
|
||||
// wrapping the lambda in a std function
|
||||
CGAL::cpp11::function<std::pair<Coord_type, bool>(const Vertex_handle)> value_function_1 =
|
||||
[](const Vertex_handle vh) -> std::pair<Coord_type, bool> { return std::make_pair(vh->info()[1].value, true); };
|
||||
|
||||
std::function<std::pair<Vector, bool>(const Vertex_handle)> gradient_function_1 =
|
||||
[](const Vertex_handle vh) -> std::pair<Vector, bool> { return std::make_pair(vh->info()[1].gradient, true); };
|
||||
|
||||
assert(test_interpolation(coords.begin(), coords.end(), norm,
|
||||
points[n/2], value_function_1(p_to_vh[points[n/2]]).first,
|
||||
value_function_1, gradient_function_1,
|
||||
Traits(), 1, tolerance));
|
||||
|
||||
assert(test_interpolation(coords.begin(), coords.end(), norm,
|
||||
points[n/2], value_function_2(p_to_vh[points[n/2]]).first,
|
||||
[](const Vertex_handle vh) -> std::pair<Coord_type, bool> { return std::make_pair(vh->info()[2].value, true); },
|
||||
[](const Vertex_handle vh) -> std::pair<Vector, bool> { return std::make_pair(vh->info()[2].gradient, true); },
|
||||
Traits(), 2, tolerance));
|
||||
#else
|
||||
for(int j=0; j<3; ++j)
|
||||
{
|
||||
assert(test_interpolation(pt_coords.begin(), pt_coords.end(), norm, points[n/2],
|
||||
CGAL::Data_access<Point_value_map>(values[j]),
|
||||
CGAL::Data_access<Point_vector_map>(gradients[j]),
|
||||
Value_function<Vertex_handle, Coord_type> value_function(j);
|
||||
Gradient_function<Vertex_handle, Vector> gradient_function(j);
|
||||
|
||||
assert(test_interpolation(coords.begin(), coords.end(), norm,
|
||||
points[n/2], value_function(p_to_vh[points[n/2]]).first,
|
||||
value_function, gradient_function,
|
||||
Traits(), j, tolerance));
|
||||
}
|
||||
pt_coords.clear();
|
||||
#endif
|
||||
|
||||
coords.clear();
|
||||
}
|
||||
|
||||
template <class Rt>
|
||||
void _test_interpolation_functions_2_regular_without_OutputFunctor(const Rt&, const typename Rt::Geom_traits::FT& tolerance)
|
||||
{
|
||||
std::cout << "Testing backward compatibility..." << std::endl;
|
||||
|
||||
CGAL::Set_ieee_double_precision pfr;
|
||||
Rt T;
|
||||
|
||||
|
|
@ -582,7 +737,7 @@ void _test_interpolation_functions_2_regular_without_OutputFunctor(const Rt&, co
|
|||
|
||||
typedef std::vector<std::pair<Weighted_point, Coord_type> > Point_coordinate_vector;
|
||||
|
||||
std::cout << "NN2: Testing random points." << std::endl;
|
||||
std::cout << "RN2: Testing random points." << std::endl;
|
||||
|
||||
// test random points in a square of length r:
|
||||
std::vector<Weighted_point> points;
|
||||
|
|
@ -674,7 +829,8 @@ void _test_interpolation_functions_2_regular_without_OutputFunctor(const Rt&, co
|
|||
|
||||
for(int i=0; i<3; ++i)
|
||||
{
|
||||
assert(test_interpolation(coords.begin(), coords.end(), norm, points[j],
|
||||
assert(test_interpolation(coords.begin(), coords.end(), norm,
|
||||
points[j], values[i][points[j]],
|
||||
CGAL::Data_access< Point_value_map >(values[i]),
|
||||
CGAL::Data_access< Point_vector_map >(gradients[i]),
|
||||
Traits(), i, tolerance));
|
||||
|
|
@ -735,7 +891,8 @@ void _test_interpolation_functions_2_regular_without_OutputFunctor(const Rt&, co
|
|||
|
||||
for(int j=0; j<3; ++j)
|
||||
{
|
||||
assert(test_interpolation(coords.begin(), coords.end(), norm, points[n/2],
|
||||
assert(test_interpolation(coords.begin(), coords.end(), norm,
|
||||
points[n/2], values[j][points[n/2]],
|
||||
CGAL::Data_access<Point_value_map>(values[j]),
|
||||
CGAL::Data_access<Point_vector_map>(gradients[j]),
|
||||
Traits(), j, tolerance));
|
||||
|
|
@ -782,7 +939,7 @@ void _test_interpolation_functions_2_regular_with_OutputFunctor(const Rt&, const
|
|||
|
||||
Identity_output_functor vh_fct;
|
||||
|
||||
std::cout << "NN2: Testing random points." << std::endl;
|
||||
std::cout << "RN2: Testing random points." << std::endl;
|
||||
|
||||
// test random points in a square of length r:
|
||||
std::vector<Weighted_point> points;
|
||||
|
|
@ -979,8 +1136,8 @@ void _test_interpolation_functions_2_regular_with_OutputFunctor(const Rt&, const
|
|||
std::pair<FT, bool> ev = CGAL::Data_access<Vertex_value_map>(values[j])(vh);
|
||||
assert(ev.second);
|
||||
|
||||
assert(test_interpolation_with_value(vh_coords.begin(), vh_coords.end(), norm, vh->point(),
|
||||
ev.first /*exact value*/,
|
||||
assert(test_interpolation_with_value(vh_coords.begin(), vh_coords.end(), norm,
|
||||
vh->point(), ev.first /*exact value*/,
|
||||
CGAL::Data_access<Vertex_value_map>(values[j]),
|
||||
CGAL::Data_access<Vertex_vector_map>(gradients[j]),
|
||||
Traits(), j, tolerance));
|
||||
|
|
|
|||
|
|
@ -21,44 +21,59 @@
|
|||
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
|
||||
#include <CGAL/array.h>
|
||||
#include <CGAL/Triangulation_vertex_base_with_info_2.h>
|
||||
#include <CGAL/Delaunay_triangulation_2.h>
|
||||
#include <CGAL/Regular_triangulation_2.h>
|
||||
#include <CGAL/Origin.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
typedef CGAL::Exact_predicates_exact_constructions_kernel K;
|
||||
typedef CGAL::Delaunay_triangulation_2<K> Dt;
|
||||
typedef CGAL::Regular_triangulation_2<K> Rt;
|
||||
typedef CGAL::Exact_predicates_exact_constructions_kernel EPECK;
|
||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel EPICK;
|
||||
|
||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel K2;
|
||||
typedef CGAL::Delaunay_triangulation_2<K2> Dt2;
|
||||
typedef CGAL::Regular_triangulation_2<K2> Rt2;
|
||||
template <typename V, typename G>
|
||||
struct Value_and_gradient
|
||||
{
|
||||
Value_and_gradient() : value(), gradient(CGAL::NULL_VECTOR) {}
|
||||
|
||||
V value;
|
||||
G gradient;
|
||||
};
|
||||
|
||||
template<typename Kernel>
|
||||
void test_interpolation_functions()
|
||||
{
|
||||
// For the Delaunay triangulation, values and gradients (three different data sets)
|
||||
// are stored directly in the vertices
|
||||
typedef typename Kernel::FT Coord_type;
|
||||
typedef typename Kernel::Vector_2 Vector;
|
||||
|
||||
typedef CGAL::Triangulation_vertex_base_with_info_2<
|
||||
CGAL::cpp11::array<
|
||||
Value_and_gradient<Coord_type, Vector>, 3>,
|
||||
Kernel> Vb;
|
||||
typedef CGAL::Triangulation_data_structure_2<Vb> Tds;
|
||||
typedef CGAL::Delaunay_triangulation_2<Kernel, Tds> Delaunay_triangulation;
|
||||
|
||||
typedef CGAL::Regular_triangulation_2<Kernel> Regular_triangulation;
|
||||
|
||||
std::cout << "Testing interpolation functions with 2D NN neighbors " << std::endl;
|
||||
_test_interpolation_functions_2_Delaunay(Delaunay_triangulation(), Coord_type(1e-10));
|
||||
|
||||
std::cout << "Testing interpolation functions with 2D RN neighbors " << std::endl;
|
||||
_test_interpolation_functions_2_regular(Regular_triangulation(), Coord_type(1e-10));
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
std::cout << "Testing interpolation functions with 2D NN neighbors "
|
||||
<< std::endl;
|
||||
std::cout << " using Exact_predicates_exact_constructions_kernel: "
|
||||
<< std::endl ;
|
||||
_test_interpolation_functions_2_Delaunay(Dt(), K::FT(1e-10));
|
||||
std::cout << "--------------------------------------------" << std::endl;
|
||||
std::cout << "Testing with EPECK" << std::endl;
|
||||
test_interpolation_functions<EPECK>();
|
||||
|
||||
std::cout << "Testing interpolation functions with 2D NN neighbors "
|
||||
<< std::endl;
|
||||
std::cout << " using Exact_predicates_inexact_constructions_kernel: "
|
||||
<< std::endl ;
|
||||
_test_interpolation_functions_2_Delaunay(Dt2(), K2::FT(1e-10));
|
||||
|
||||
std::cout << "Testing interpolation functions with 2D RN neighbors "
|
||||
<< std::endl;
|
||||
std::cout << " using Exact_predicates_exact_constructions_kernel: "
|
||||
<< std::endl ;
|
||||
_test_interpolation_functions_2_regular(Rt(), K::FT(1e-10));
|
||||
|
||||
std::cout << "Testing interpolation functions with 2D RN neighbors "
|
||||
<< std::endl;
|
||||
std::cout << " using Exact_predicates_inexact_constructions_kernel: "
|
||||
<< std::endl ;
|
||||
_test_interpolation_functions_2_regular(Rt2(), K2::FT(1e-10));
|
||||
std::cout << "--------------------------------------------" << std::endl;
|
||||
std::cout << "Testing with EPICK" << std::endl;
|
||||
test_interpolation_functions<EPICK>();
|
||||
|
||||
std::cout << "test_interpolation_functions_2 is finished" << std::endl;
|
||||
|
||||
|
|
|
|||
|
|
@ -100,6 +100,7 @@ and provides a list of the parameters that are used in this package.
|
|||
- \link PMP_meshing_grp `CGAL::Polygon_mesh_processing::isotropic_remeshing()` \endlink
|
||||
- \link PMP_meshing_grp `CGAL::Polygon_mesh_processing::split_long_edges()` \endlink
|
||||
- `CGAL::Polygon_mesh_processing::random_perturbation()`
|
||||
- `CGAL::Polygon_mesh_processing::extrude_mesh()`
|
||||
|
||||
## Hole Filling Functions ##
|
||||
- `CGAL::Polygon_mesh_processing::triangulate_hole()`
|
||||
|
|
|
|||
|
|
@ -420,21 +420,15 @@ corefine_and_compute_boolean_operations(
|
|||
if (&tm1 != *output[Corefinement::UNION])
|
||||
copy_face_graph(tm1,
|
||||
*(*output[Corefinement::UNION]),
|
||||
Emptyset_iterator(),
|
||||
Emptyset_iterator(),
|
||||
Emptyset_iterator(),
|
||||
vpm1,
|
||||
*cpp11::get<Corefinement::UNION>(vpm_out_tuple));
|
||||
|
||||
parameters::vertex_point_map(vpm1),
|
||||
parameters::vertex_point_map(*cpp11::get<Corefinement::UNION>(vpm_out_tuple)));
|
||||
if (output[Corefinement::INTERSECTION] != boost::none)
|
||||
if (&tm1 != *output[Corefinement::INTERSECTION])
|
||||
copy_face_graph(tm1,
|
||||
*(*output[Corefinement::INTERSECTION]),
|
||||
Emptyset_iterator(),
|
||||
Emptyset_iterator(),
|
||||
Emptyset_iterator(),
|
||||
vpm1,
|
||||
*cpp11::get<Corefinement::INTERSECTION>(vpm_out_tuple));
|
||||
parameters::vertex_point_map(vpm1),
|
||||
parameters::vertex_point_map(*cpp11::get<Corefinement::INTERSECTION>(vpm_out_tuple)));
|
||||
|
||||
|
||||
if (output[Corefinement::TM1_MINUS_TM2] != boost::none)
|
||||
if (&tm1 == *output[Corefinement::TM1_MINUS_TM2])
|
||||
|
|
|
|||
|
|
@ -0,0 +1,323 @@
|
|||
// Copyright (c) 2018 GeometryFactory (France).
|
||||
// All rights reserved.
|
||||
//
|
||||
// This file is part of CGAL (www.cgal.org).
|
||||
// You can redistribute it and/or modify it under the terms of the GNU
|
||||
// General Public License as published by the Free Software Foundation,
|
||||
// either version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// Licensees holding a valid commercial license may use this file in
|
||||
// accordance with the commercial license agreement provided with the software.
|
||||
//
|
||||
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// $URL$
|
||||
// $Id$
|
||||
// SPDX-License-Identifier: GPL-3.0+
|
||||
//
|
||||
//
|
||||
// Author(s) : Sebastien Loriot, Maxime Gimeno
|
||||
|
||||
|
||||
#ifndef CGAL_POLYGON_MESH_PROCESSING_EXTRUDE_H
|
||||
#define CGAL_POLYGON_MESH_PROCESSING_EXTRUDE_H
|
||||
|
||||
#include <CGAL/license/Polygon_mesh_processing/meshing_hole_filling.h>
|
||||
|
||||
|
||||
#include <CGAL/Polygon_mesh_processing/orientation.h>
|
||||
#include <CGAL/boost/graph/named_params_helper.h>
|
||||
#include <CGAL/boost/graph/named_function_params.h>
|
||||
#include <CGAL/boost/graph/copy_face_graph.h>
|
||||
#include <CGAL/Kernel_traits.h>
|
||||
#include <CGAL/boost/graph/Euler_operations.h>
|
||||
#include <vector>
|
||||
|
||||
namespace CGAL {
|
||||
namespace Polygon_mesh_processing {
|
||||
namespace extrude_impl{
|
||||
|
||||
template<typename BorderHalfedgesRange, class PolygonMesh>
|
||||
void create_strip(const BorderHalfedgesRange& input_halfedges,
|
||||
const BorderHalfedgesRange& output_halfedges,
|
||||
PolygonMesh& mesh)
|
||||
{
|
||||
CGAL_assertion(input_halfedges.size() == output_halfedges.size());
|
||||
typedef typename boost::graph_traits<PolygonMesh>::halfedge_descriptor halfedge_descriptor;
|
||||
typedef typename boost::graph_traits<PolygonMesh>::face_descriptor face_descriptor;
|
||||
for(std::size_t i = 0; i < input_halfedges.size(); ++i)
|
||||
{
|
||||
halfedge_descriptor h1 = input_halfedges[i], h2=output_halfedges[i],
|
||||
nh1 = next(h1, mesh), ph2 = prev(h2, mesh);
|
||||
halfedge_descriptor newh = halfedge(add_edge(mesh), mesh),
|
||||
newh_opp = opposite(newh, mesh);
|
||||
// set target vertices of the new halfedges
|
||||
set_target(newh, target(h1, mesh), mesh);
|
||||
set_target(newh_opp, target(ph2, mesh), mesh);
|
||||
// update next/prev pointers
|
||||
set_next(h1, newh_opp, mesh);
|
||||
set_next(newh_opp, h2, mesh);
|
||||
set_next(ph2, newh, mesh);
|
||||
set_next(newh, nh1, mesh);
|
||||
}
|
||||
for(std::size_t i = 0; i < input_halfedges.size(); ++i)
|
||||
{
|
||||
halfedge_descriptor h = input_halfedges[i];
|
||||
face_descriptor nf = add_face(mesh);
|
||||
|
||||
CGAL::cpp11::array<halfedge_descriptor, 4> hedges;
|
||||
for (int k=0; k<4; ++k)
|
||||
{
|
||||
hedges[k]=h;
|
||||
h = next(h, mesh);
|
||||
}
|
||||
|
||||
set_face(hedges[0], nf, mesh);
|
||||
set_face(hedges[1], nf, mesh);
|
||||
set_face(hedges[2], nf, mesh);
|
||||
set_face(hedges[3], nf, mesh);
|
||||
set_halfedge(nf, hedges[0], mesh);
|
||||
Euler::split_face(hedges[0], hedges[2], mesh);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename PMAP, typename Vector>
|
||||
struct Const_dist_translation{
|
||||
Const_dist_translation(PMAP map, const Vector& dir)
|
||||
:map(map), dir(dir){}
|
||||
|
||||
template<typename VertexDescriptor, typename U>
|
||||
void operator()(const VertexDescriptor vd, const U&) const
|
||||
{
|
||||
typename boost::property_traits<PMAP>::value_type p = get(map, vd) + dir;
|
||||
put(map, vd, p);
|
||||
}
|
||||
|
||||
PMAP map;
|
||||
Vector dir;
|
||||
};
|
||||
|
||||
struct Identity_functor
|
||||
{
|
||||
template<typename T, typename U>
|
||||
void operator()(const T&, const U&) const {}
|
||||
};
|
||||
}//end extrude_impl
|
||||
|
||||
/**
|
||||
* \ingroup PMP_meshing_grp
|
||||
* \brief performs a generalized extrusion of `input` and puts it in `output`.
|
||||
*
|
||||
* This function extrudes the open surface mesh `input` and puts the result in `output`. The mesh generated is a closed
|
||||
* surface mesh with a bottom and top part, both having the same graph combinatorics as `input` (except
|
||||
* that the orientation of the faces of the bottom part is reversed). The bottom and the top parts are
|
||||
* connected by a triangle strip between boundary cycles. The coordinates of the points associated to the
|
||||
* vertices of the bottom and top part are first initialized to the same value as the corresponding
|
||||
* vertices of `input`. Then for each vertex, a call to `bot` and `top` is done for the vertices of the
|
||||
* bottom part and the top part, respectively.
|
||||
* \attention `output` may be self intersecting.
|
||||
* @tparam InputMesh a model of `FaceListGraph`
|
||||
* @tparam OutputMesh a model of `FaceListGraph` and `MutableFaceGraph`
|
||||
* @tparam NamedParameters1 a sequence of \ref pmp_namedparameters "Named Parameters" for `InputMesh`
|
||||
* @tparam NamedParameters2 a sequence of \ref pmp_namedparameters "Named Parameters" for `OutputMesh`
|
||||
* @tparam BottomFunctor a functor providing
|
||||
* \code {.cpp}
|
||||
* void operator()`(boost::graph_traits<InputMesh>::vertex_descriptor input_v,boost::graph_traits<OutputMesh>::vertex_descriptor output_v)
|
||||
* \endcode
|
||||
* where `output_v` is the copy of `input_v` from `input` into the bottom part of `output`.
|
||||
*
|
||||
* @tparam TopFunctor a functor providing a similar `operator()` as `BottomFunctor`.
|
||||
* @param input an open surface mesh to extrude.
|
||||
* @param output a surface mesh that will contain the result of the extrusion.
|
||||
* @param bot functor that will transform all points copied from
|
||||
* `input` in order to shape the bottom part of the extrusion.
|
||||
* @param top functor that will transform all points copied from
|
||||
* `input` in order to shape the top part of the extrusion.
|
||||
* @param np_in an optional sequence of \ref pmp_namedparameters "Named Parameters" among the ones listed below
|
||||
*
|
||||
* \cgalNamedParamsBegin
|
||||
* \cgalParamBegin{vertex_point_map}
|
||||
* the property map that contains the points associated to the vertices of `input`.
|
||||
* If this parameter is omitted, an internal property map for `CGAL::vertex_point_t`
|
||||
* should be available for the vertices of `input` \cgalParamEnd
|
||||
* \cgalNamedParamsEnd
|
||||
*
|
||||
* * @param np_out an optional sequence of \ref pmp_namedparameters "Named Parameters" among the ones listed below
|
||||
*
|
||||
* \cgalNamedParamsBegin
|
||||
* \cgalParamBegin{vertex_point_map}
|
||||
* the property map that will contain the points associated to the vertices of `output`.
|
||||
* If this parameter is omitted, an internal property map for `CGAL::vertex_point_t`
|
||||
* should be available for the vertices of `output` \cgalParamEnd
|
||||
* \cgalNamedParamsEnd
|
||||
*/
|
||||
template <class InputMesh,
|
||||
class OutputMesh,
|
||||
class BottomFunctor,
|
||||
class TopFunctor,
|
||||
class NamedParameters1,
|
||||
class NamedParameters2
|
||||
>
|
||||
void extrude_mesh(const InputMesh& input,
|
||||
OutputMesh& output,
|
||||
const BottomFunctor& bot,
|
||||
const TopFunctor& top,
|
||||
const NamedParameters1& np_in,
|
||||
const NamedParameters2& np_out)
|
||||
{
|
||||
typedef typename boost::graph_traits<InputMesh>::vertex_descriptor input_vertex_descriptor;
|
||||
typedef typename boost::graph_traits<InputMesh>::halfedge_descriptor input_halfedge_descriptor;
|
||||
|
||||
typedef typename boost::graph_traits<OutputMesh>::vertex_descriptor output_vertex_descriptor;
|
||||
typedef typename boost::graph_traits<OutputMesh>::halfedge_descriptor output_halfedge_descriptor;
|
||||
|
||||
CGAL_assertion(!CGAL::is_closed(input));
|
||||
typedef typename GetVertexPointMap < OutputMesh, NamedParameters2>::type VPMap;
|
||||
typedef typename GetVertexPointMap < InputMesh, NamedParameters1>::const_type IVPMap;
|
||||
|
||||
VPMap output_vpm = choose_param(get_param(np_out, internal_np::vertex_point),
|
||||
get_property_map(vertex_point, output));
|
||||
IVPMap input_vpm = choose_param(get_param(np_in, internal_np::vertex_point),
|
||||
get_const_property_map(vertex_point, input));
|
||||
|
||||
std::vector<std::pair<input_vertex_descriptor, output_vertex_descriptor> > bottom_v2v;
|
||||
std::vector<std::pair<input_halfedge_descriptor, output_halfedge_descriptor> > bottom_h2h;
|
||||
copy_face_graph(input, output, std::back_inserter(bottom_v2v),
|
||||
std::back_inserter(bottom_h2h), Emptyset_iterator(),
|
||||
input_vpm, output_vpm);
|
||||
|
||||
// create the offset for the other side
|
||||
for(std::size_t i = 0; i< bottom_v2v.size(); ++i)
|
||||
{
|
||||
bot(bottom_v2v[i].first, bottom_v2v[i].second);
|
||||
}
|
||||
CGAL::Polygon_mesh_processing::reverse_face_orientations(output);
|
||||
|
||||
// collect border halfedges for the creation of the triangle strip
|
||||
std::vector<std::pair<input_vertex_descriptor, output_vertex_descriptor> > top_v2v;
|
||||
std::vector<std::pair<input_halfedge_descriptor, output_halfedge_descriptor> > top_h2h;
|
||||
copy_face_graph(input, output, std::inserter(top_v2v, top_v2v.end()),
|
||||
std::inserter(top_h2h, top_h2h.end()), Emptyset_iterator(),
|
||||
input_vpm, output_vpm);
|
||||
for(std::size_t i = 0; i< top_v2v.size(); ++i)
|
||||
{
|
||||
top(top_v2v[i].first, top_v2v[i].second);
|
||||
}
|
||||
std::vector<output_halfedge_descriptor> border_hedges;
|
||||
std::vector<output_halfedge_descriptor> offset_border_hedges;
|
||||
for(std::size_t i = 0; i< top_h2h.size(); ++i)
|
||||
{
|
||||
input_halfedge_descriptor h = top_h2h[i].first;
|
||||
if( CGAL::is_border(h, input) )
|
||||
{
|
||||
border_hedges.push_back(top_h2h[i].second);
|
||||
offset_border_hedges.push_back(bottom_h2h[i].second);
|
||||
CGAL_assertion(is_border(border_hedges.back(), output));
|
||||
CGAL_assertion(is_border(offset_border_hedges.back(), output));
|
||||
}
|
||||
}
|
||||
// now create a triangle strip
|
||||
extrude_impl::create_strip(border_hedges, offset_border_hedges, output);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \ingroup PMP_meshing_grp
|
||||
* fills `output` with a closed mesh bounding the volume swept by `input` when translating its
|
||||
* vertices by `v`. The mesh is oriented so that the faces corresponding to `input`
|
||||
* in `output` have the same orientation.
|
||||
* \attention `output` may be self intersecting.
|
||||
* @tparam InputMesh a model of the concept `FaceListGraph`
|
||||
* @tparam OutputMesh a model of the concept `FaceListGraph` and `MutableFaceGraph`
|
||||
* @tparam Vector_3 vector type from the same CGAL kernel as the point of the vertex point map used for `OutputMesh`.
|
||||
* @tparam NamedParameters1 a sequence of \ref pmp_namedparameters "Named Parameters" for `InputMesh`
|
||||
* @tparam NamedParameters2 a sequence of \ref pmp_namedparameters "Named Parameters" for `OutputMesh`
|
||||
* @param input an open surface mesh to extrude.
|
||||
* @param output a surface mesh that will contain the result of the extrusion.
|
||||
* @param v the vector defining the direction of the extrusion
|
||||
* @param np_in an optional sequence of \ref pmp_namedparameters "Named Parameters" among the ones listed below
|
||||
*
|
||||
* \cgalNamedParamsBegin
|
||||
* \cgalParamBegin{vertex_point_map}
|
||||
* the property map that contains the points associated to the vertices of `input`.
|
||||
* If this parameter is omitted, an internal property map for `CGAL::vertex_point_t`
|
||||
* should be available for the vertices of `input` \cgalParamEnd
|
||||
* \cgalNamedParamsEnd
|
||||
*
|
||||
* * @param np_out an optional sequence of \ref pmp_namedparameters "Named Parameters" among the ones listed below
|
||||
*
|
||||
* \cgalNamedParamsBegin
|
||||
* \cgalParamBegin{vertex_point_map}
|
||||
* the property map that will contain the points associated to the vertices of `output`.
|
||||
* If this parameter is omitted, an internal property map for `CGAL::vertex_point_t`
|
||||
* should be available for the vertices of `output` \cgalParamEnd
|
||||
* \cgalNamedParamsEnd
|
||||
*/
|
||||
template <class InputMesh,
|
||||
class OutputMesh,
|
||||
class NamedParameters1,
|
||||
class NamedParameters2>
|
||||
void extrude_mesh(const InputMesh& input,
|
||||
OutputMesh& output,
|
||||
#ifdef DOXYGEN_RUNNING
|
||||
Vector_3 v,
|
||||
#else
|
||||
typename GetGeomTraits<OutputMesh, NamedParameters2>::type::Vector_3 v,
|
||||
#endif
|
||||
const NamedParameters1& np_in,
|
||||
const NamedParameters2& np_out)
|
||||
{
|
||||
typedef typename GetVertexPointMap < OutputMesh, NamedParameters2>::type VPMap;
|
||||
VPMap output_vpm = choose_param(get_param(np_out, internal_np::vertex_point),
|
||||
get_property_map(vertex_point, output));
|
||||
|
||||
extrude_impl::Const_dist_translation<
|
||||
typename GetVertexPointMap<OutputMesh, NamedParameters2>::type,
|
||||
typename GetGeomTraits<OutputMesh, NamedParameters2>::type::Vector_3> bot(output_vpm,
|
||||
v);
|
||||
extrude_impl::Identity_functor top;
|
||||
extrude_mesh(input, output, bot,top, np_in, np_out);
|
||||
}
|
||||
//convenience overload
|
||||
template <class InputMesh,
|
||||
class OutputMesh,
|
||||
typename Vector>
|
||||
void extrude_mesh(const InputMesh& input,
|
||||
OutputMesh& output,
|
||||
Vector dir)
|
||||
{
|
||||
extrude_mesh(input, output, dir,
|
||||
parameters::all_default(),
|
||||
parameters::all_default());
|
||||
}
|
||||
|
||||
template <class InputMesh,
|
||||
class OutputMesh,
|
||||
typename Vector,
|
||||
typename CGAL_PMP_NP_TEMPLATE_PARAMETERS>
|
||||
void extrude_mesh(const InputMesh& input,
|
||||
OutputMesh& output,
|
||||
Vector dir,
|
||||
const CGAL_PMP_NP_CLASS& np)
|
||||
{
|
||||
extrude_mesh(input, output, dir,
|
||||
np,
|
||||
parameters::all_default());
|
||||
}
|
||||
|
||||
template <class InputMesh,
|
||||
class OutputMesh,
|
||||
class BottomFunctor,
|
||||
class TopFunctor>
|
||||
void extrude_mesh(const InputMesh& input,
|
||||
OutputMesh& output,
|
||||
const BottomFunctor& bot,
|
||||
const TopFunctor& top)
|
||||
{
|
||||
extrude_mesh(input, output, bot, top,
|
||||
parameters::all_default(), parameters::all_default());
|
||||
}
|
||||
|
||||
}} //end CGAL::PMP
|
||||
#endif //CGAL_POLYGON_MESH_PROCESSING_EXTRUDE_H
|
||||
|
|
@ -44,6 +44,11 @@
|
|||
#include <CGAL/Polygon_mesh_processing/remesh.h>
|
||||
#include <CGAL/Polygon_mesh_processing/corefinement.h>
|
||||
#include <CGAL/Polygon_mesh_processing/detect_features.h>
|
||||
#include <CGAL/Polygon_mesh_processing/extrude.h>
|
||||
#include <CGAL/Polygon_mesh_processing/random_perturbation.h>
|
||||
#include <CGAL/Polygon_mesh_processing/distance.h>
|
||||
#include <CGAL/Polygon_mesh_processing/intersection.h>
|
||||
#include <CGAL/Polygon_mesh_processing/transform.h>
|
||||
|
||||
// the named parameter header being not documented the doc is put here for now
|
||||
#ifdef DOXYGEN_RUNNING
|
||||
|
|
|
|||
|
|
@ -100,6 +100,7 @@ endif()
|
|||
create_single_source_cgal_program("surface_intersection_sm_poly.cpp" )
|
||||
create_single_source_cgal_program("test_orient_cc.cpp")
|
||||
create_single_source_cgal_program("test_pmp_transform.cpp")
|
||||
create_single_source_cgal_program("extrude_test.cpp")
|
||||
|
||||
if( TBB_FOUND )
|
||||
CGAL_target_use_TBB(test_pmp_distance)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
OFF
|
||||
4 2 0
|
||||
-0.5 -0.5 0
|
||||
0.5 -0.5 0
|
||||
0.5 0.5 0
|
||||
-0.5 0.5 0
|
||||
|
||||
3 0 1 2
|
||||
3 0 2 3
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
#include <CGAL/Surface_mesh.h>
|
||||
#include <CGAL/Polyhedron_3.h>
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/Polygon_mesh_processing/extrude.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
|
||||
typedef CGAL::Surface_mesh<Kernel::Point_3> SMesh;
|
||||
typedef CGAL::Polyhedron_3<Kernel> Polyhedron;
|
||||
|
||||
template<typename MAP>
|
||||
struct Bot
|
||||
{
|
||||
Bot(MAP map):map(map){}
|
||||
template<typename VD, typename T>
|
||||
void operator()(const T&,VD vd) const
|
||||
{
|
||||
put(map, vd, get(map, vd)+Kernel::Vector_3(-2.0,0.0,1.0));
|
||||
}
|
||||
MAP map;
|
||||
|
||||
};
|
||||
|
||||
template<typename MAP>
|
||||
struct Top
|
||||
{
|
||||
Top(MAP map):map(map){}
|
||||
|
||||
template<typename VD, typename T>
|
||||
void operator()(const T&, VD vd) const
|
||||
{
|
||||
put(map, vd, get(map, vd)+Kernel::Vector_3(0.0,2.0,-1.0));
|
||||
}
|
||||
|
||||
MAP map;
|
||||
};
|
||||
|
||||
template <class Mesh>
|
||||
void test_mesh(const char* filename)
|
||||
{
|
||||
Mesh in, out;
|
||||
std::ifstream input(filename);
|
||||
|
||||
if (!input || !(input >> in))
|
||||
{
|
||||
std::cerr << "Error: cannot read Surface Mesh : " << filename << "\n";
|
||||
assert(!CGAL::is_empty(in));
|
||||
assert(false);
|
||||
return ;
|
||||
}
|
||||
CGAL::Polygon_mesh_processing::extrude_mesh(in, out, Kernel::Vector_3(0.0, 0.0, -1.0));
|
||||
std::ofstream extruded_off("extruded.off");
|
||||
extruded_off << out;
|
||||
extruded_off.close();
|
||||
out.clear();
|
||||
|
||||
typedef typename boost::property_map<Mesh, CGAL::vertex_point_t>::type VPMap;
|
||||
Bot<VPMap> bot(get(CGAL::vertex_point, out));
|
||||
Top<VPMap> top(get(CGAL::vertex_point, out));
|
||||
CGAL::Polygon_mesh_processing::extrude_mesh(in, out, bot, top);
|
||||
std::ofstream gen_extruded_off("gen_extruded.off");
|
||||
gen_extruded_off << out;
|
||||
gen_extruded_off.close();
|
||||
std::cerr << "All done." << std::endl;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
const char* filename = (argc > 1) ? argv[1] : "data/quad.off";
|
||||
test_mesh<SMesh>(filename);
|
||||
test_mesh<Polyhedron>(filename);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -181,10 +181,8 @@ void Polyhedron_demo_kernel_plugin::on_actionKernel_triggered()
|
|||
vpm[fd] = CGAL::ORIGIN + normal / distance_to_origin + translate;
|
||||
}
|
||||
CGAL::copy_face_graph(dual, *pKernel,
|
||||
CGAL::Emptyset_iterator(),
|
||||
CGAL::Emptyset_iterator(),
|
||||
CGAL::Emptyset_iterator(),
|
||||
boost::make_assoc_property_map(vpm));
|
||||
CGAL::parameters::vertex_point_map(
|
||||
boost::make_assoc_property_map(vpm)));
|
||||
|
||||
|
||||
// pKernel->inside_out();
|
||||
|
|
|
|||
|
|
@ -163,3 +163,10 @@ polyhedron_demo_plugin(degenerated_faces_sm_plugin Degenerated_faces_plugin)
|
|||
target_link_libraries(degenerated_faces_sm_plugin PUBLIC scene_surface_mesh_item scene_surface_mesh_selection_item)
|
||||
target_compile_definitions(degenerated_faces_sm_plugin PUBLIC "-DUSE_SURFACE_MESH" )
|
||||
|
||||
|
||||
polyhedron_demo_plugin(extrude_poly_plugin Extrude_plugin)
|
||||
target_link_libraries(extrude_poly_plugin PUBLIC scene_polyhedron_item scene_polyhedron_selection_item)
|
||||
|
||||
polyhedron_demo_plugin(extrude_sm_plugin Extrude_plugin)
|
||||
target_link_libraries(extrude_sm_plugin PUBLIC scene_surface_mesh_item scene_surface_mesh_selection_item)
|
||||
target_compile_definitions(extrude_sm_plugin PUBLIC "-DUSE_SURFACE_MESH" )
|
||||
|
|
|
|||
|
|
@ -0,0 +1,478 @@
|
|||
#include <CGAL/Three/Polyhedron_demo_plugin_interface.h>
|
||||
#include <QApplication>
|
||||
#include <QObject>
|
||||
#include <QAction>
|
||||
#include <QMainWindow>
|
||||
#include <QInputDialog>
|
||||
#include <QMessageBox>
|
||||
|
||||
#include <CGAL/Three/Scene_item.h>
|
||||
#include <CGAL/Three/Viewer_interface.h>
|
||||
|
||||
#include <CGAL/linear_least_squares_fitting_3.h>
|
||||
#include <CGAL/Polygon_mesh_processing/extrude.h>
|
||||
#include <CGAL/Polygon_mesh_processing/compute_normal.h>
|
||||
|
||||
#include <CGAL/Qt/manipulatedFrame.h>
|
||||
#include <CGAL/Qt/constraint.h>
|
||||
|
||||
#include <CGAL/number_type_config.h>
|
||||
|
||||
#include "Messages_interface.h"
|
||||
#ifdef USE_SURFACE_MESH
|
||||
#include "Kernel_type.h"
|
||||
#include "Scene_surface_mesh_item.h"
|
||||
#else
|
||||
#include "Scene_polyhedron_item.h"
|
||||
#include "Polyhedron_type.h"
|
||||
#endif
|
||||
#include "Scene_polyhedron_selection_item.h"
|
||||
#include "Scene.h"
|
||||
#ifdef USE_SURFACE_MESH
|
||||
typedef Scene_surface_mesh_item Scene_face_graph_item;
|
||||
#else
|
||||
typedef Scene_polyhedron_item Scene_face_graph_item;
|
||||
#endif
|
||||
|
||||
typedef Scene_face_graph_item::Face_graph Face_graph;
|
||||
typedef CGAL::qglviewer::Vec Vec;
|
||||
using namespace CGAL::Three;
|
||||
//use frame to get dist and dir.
|
||||
//fix frame in translation and use mousewheel to choose dist
|
||||
//finding frame's position : first try at the center of the item's bbox
|
||||
//maybe find intersection between surface and diag bbox.
|
||||
//orientation : PCA : normal.
|
||||
typedef Kernel::Plane_3 Plane;
|
||||
typedef Kernel::Triangle_3 Triangle;
|
||||
typedef Kernel::Point_3 Point;
|
||||
typedef Kernel::Vector_3 Vector;
|
||||
class Scene_arrow_item : public Scene_item
|
||||
{
|
||||
Q_OBJECT
|
||||
public :
|
||||
Scene_arrow_item(Vec center_, double r, double length_)
|
||||
:Scene_item(2, 1), center_(center_), length_(length_), R(r),
|
||||
frame(new Scene_item::ManipulatedFrame())
|
||||
{
|
||||
const CGAL::qglviewer::Vec offset = static_cast<Viewer_interface*>(CGAL::QGLViewer::QGLViewerPool().first())->offset();
|
||||
frame->setPosition( center_+offset);
|
||||
nb_pos = 0;
|
||||
tick = length_/10.0f;
|
||||
ctrl_pressing = false;
|
||||
}
|
||||
// Indicates if rendering mode is supported
|
||||
bool supportsRenderingMode(RenderingMode m) const Q_DECL_OVERRIDE {
|
||||
return (m == Gouraud);
|
||||
}
|
||||
//Displays the item
|
||||
void draw(Viewer_interface* viewer) const Q_DECL_OVERRIDE
|
||||
{
|
||||
if(!are_buffers_filled)
|
||||
{
|
||||
initializeBuffers(viewer);
|
||||
}
|
||||
vaos[0]->bind();
|
||||
program = getShaderProgram(PROGRAM_WITH_LIGHT);
|
||||
GLdouble d_mat[16];
|
||||
QMatrix4x4 mvp_mat;
|
||||
GLdouble matrix[16];
|
||||
QMatrix4x4 f_matrix;
|
||||
frame->getMatrix(matrix);
|
||||
for (int i=0; i<16; ++i)
|
||||
f_matrix.data()[i] = (float)matrix[i];
|
||||
viewer->camera()->getModelViewProjectionMatrix(d_mat);
|
||||
for (int i=0; i<16; ++i)
|
||||
mvp_mat.data()[i] = GLfloat(d_mat[i]);
|
||||
mvp_mat = mvp_mat*f_matrix;
|
||||
QMatrix4x4 mv_mat;
|
||||
viewer->camera()->getModelViewMatrix(d_mat);
|
||||
for (int i=0; i<16; ++i)
|
||||
mv_mat.data()[i] = GLfloat(d_mat[i]);
|
||||
mv_mat = mv_mat*f_matrix;
|
||||
attribBuffers(viewer, PROGRAM_WITH_LIGHT);
|
||||
program->bind();
|
||||
program->setUniformValue("mvp_matrix", mvp_mat);
|
||||
program->setUniformValue("mv_matrix", mv_mat);
|
||||
program->setUniformValue("is_clipbox_on", false);
|
||||
program->setAttributeValue("radius",0.01*diagonalBbox());
|
||||
program->setAttributeValue("colors", QColor(Qt::red));
|
||||
program->setAttributeValue("colors", this->color());
|
||||
viewer->glDrawArrays(GL_TRIANGLES, 0, static_cast<GLsizei>(nb_pos/3));
|
||||
vaos[0]->release();
|
||||
program->release();
|
||||
}
|
||||
void invalidateOpenGLBuffers() Q_DECL_OVERRIDE
|
||||
{
|
||||
are_buffers_filled = false;
|
||||
}
|
||||
Scene_item* clone() const Q_DECL_OVERRIDE {return 0;}
|
||||
QString toolTip() const Q_DECL_OVERRIDE {return QString();}
|
||||
Vec center()const { return center_; }
|
||||
Scene_item::ManipulatedFrame* manipulatedFrame() Q_DECL_OVERRIDE { return frame; }
|
||||
bool manipulatable() const Q_DECL_OVERRIDE { return true; }
|
||||
bool eventFilter(QObject *, QEvent *event) Q_DECL_OVERRIDE
|
||||
{
|
||||
if(event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease)
|
||||
{
|
||||
ctrl_pressing = static_cast<QKeyEvent*>(event)->modifiers().testFlag(Qt::ControlModifier);
|
||||
}
|
||||
if(event->type() == QEvent::Wheel && ctrl_pressing)
|
||||
{
|
||||
QWheelEvent *mouseEvent = static_cast<QWheelEvent*>(event);
|
||||
int steps = mouseEvent->delta() / 120;
|
||||
if (steps > 0)
|
||||
length_+=tick;
|
||||
else
|
||||
length_-=tick;
|
||||
invalidateOpenGLBuffers();
|
||||
redraw();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
double length()const { return length_; }
|
||||
private:
|
||||
//make an arrow showing the length and direction of the transformation for the extrusion.
|
||||
void initializeBuffers(Viewer_interface *viewer)const
|
||||
{
|
||||
std::vector<float> vertices;
|
||||
std::vector<float> normals;
|
||||
int prec = 60;
|
||||
//Head
|
||||
const float Rf = static_cast<float>(R);
|
||||
for(int d = 0; d<360; d+= 360/prec)
|
||||
{
|
||||
float D = (float) (d * CGAL_PI / 180.);
|
||||
float a = (float) std::atan(Rf / 0.33);
|
||||
QVector4D pR(0., 1.*length_, 0, 1.);
|
||||
QVector4D nR(Rf*2.*sin(D), sin(a), Rf*2.*cos(D), 1.);
|
||||
|
||||
//point A1
|
||||
vertices.push_back(pR.x());
|
||||
vertices.push_back(pR.y());
|
||||
vertices.push_back(pR.z());
|
||||
normals.push_back(nR.x());
|
||||
normals.push_back(nR.y());
|
||||
normals.push_back(nR.z());
|
||||
|
||||
//point B1
|
||||
pR = QVector4D(Rf*2.*sin(D), 0.66f*length_, Rf*2.* cos(D), 1.f);
|
||||
nR = QVector4D(sin(D), sin(a), cos(D), 1.);
|
||||
vertices.push_back(pR.x());
|
||||
vertices.push_back(pR.y());
|
||||
vertices.push_back(pR.z());
|
||||
normals.push_back(nR.x());
|
||||
normals.push_back(nR.y());
|
||||
normals.push_back(nR.z());
|
||||
//point C1
|
||||
D = (d+360/prec)*CGAL_PI/180.0;
|
||||
pR = QVector4D(Rf*2.* sin(D), 0.66f*length_, Rf *2.* cos(D), 1.f);
|
||||
nR = QVector4D(sin(D), sin(a), cos(D), 1.0);
|
||||
|
||||
vertices.push_back(pR.x());
|
||||
vertices.push_back(pR.y());
|
||||
vertices.push_back(pR.z());
|
||||
normals.push_back(nR.x());
|
||||
normals.push_back(nR.y());
|
||||
normals.push_back(nR.z());
|
||||
}
|
||||
|
||||
//cylinder
|
||||
//body of the cylinder
|
||||
for(int d = 0; d<360; d+= 360/prec)
|
||||
{
|
||||
//point A1
|
||||
double D = d*CGAL_PI/180.0;
|
||||
QVector4D pR(Rf*sin(D), 0.66f*length_, Rf*cos(D), 1.f);
|
||||
QVector4D nR(sin(D), 0.f, cos(D), 1.f);
|
||||
|
||||
vertices.push_back(pR.x());
|
||||
vertices.push_back(pR.y());
|
||||
vertices.push_back(pR.z());
|
||||
normals.push_back(nR.x());
|
||||
normals.push_back(nR.y());
|
||||
normals.push_back(nR.z());
|
||||
//point B1
|
||||
pR = QVector4D(Rf * sin(D),0,Rf*cos(D), 1.0);
|
||||
nR = QVector4D(sin(D), 0, cos(D), 1.0);
|
||||
|
||||
vertices.push_back(pR.x());
|
||||
vertices.push_back(pR.y());
|
||||
vertices.push_back(pR.z());
|
||||
normals.push_back(nR.x());
|
||||
normals.push_back(nR.y());
|
||||
normals.push_back(nR.z());
|
||||
//point C1
|
||||
D = (d+360/prec)*CGAL_PI/180.0;
|
||||
pR = QVector4D(Rf * sin(D),0,Rf*cos(D), 1.0);
|
||||
nR = QVector4D(sin(D), 0, cos(D), 1.0);
|
||||
vertices.push_back(pR.x());
|
||||
vertices.push_back(pR.y());
|
||||
vertices.push_back(pR.z());
|
||||
normals.push_back(nR.x());
|
||||
normals.push_back(nR.y());
|
||||
normals.push_back(nR.z());
|
||||
//point A2
|
||||
D = (d+360/prec)*CGAL_PI/180.0;
|
||||
|
||||
pR = QVector4D(Rf * sin(D),0,Rf*cos(D), 1.0);
|
||||
nR = QVector4D(sin(D), 0, cos(D), 1.0);
|
||||
|
||||
vertices.push_back(pR.x());
|
||||
vertices.push_back(pR.y());
|
||||
vertices.push_back(pR.z());
|
||||
normals.push_back(nR.x());
|
||||
normals.push_back(nR.y());
|
||||
normals.push_back(nR.z());
|
||||
//point B2
|
||||
pR = QVector4D(Rf * sin(D), 0.66f*length_, Rf*cos(D), 1.f);
|
||||
nR = QVector4D(sin(D), 0, cos(D), 1.0);
|
||||
|
||||
vertices.push_back(pR.x());
|
||||
vertices.push_back(pR.y());
|
||||
vertices.push_back(pR.z());
|
||||
normals.push_back(nR.x());
|
||||
normals.push_back(nR.y());
|
||||
normals.push_back(nR.z());
|
||||
//point C2
|
||||
D = d*CGAL_PI/180.0;
|
||||
pR = QVector4D(Rf * sin(D), 0.66f*length_, Rf*cos(D), 1.f);
|
||||
nR = QVector4D(sin(D), 0.f, cos(D), 1.f);
|
||||
|
||||
vertices.push_back(pR.x());
|
||||
vertices.push_back(pR.y());
|
||||
vertices.push_back(pR.z());
|
||||
normals.push_back(nR.x());
|
||||
normals.push_back(nR.y());
|
||||
normals.push_back(nR.z());
|
||||
}
|
||||
|
||||
//fill buffers
|
||||
//vao containing the data for the facets
|
||||
program = getShaderProgram(PROGRAM_WITH_LIGHT, viewer);
|
||||
program->bind();
|
||||
vaos[0]->bind();
|
||||
buffers[0].bind();
|
||||
buffers[0].allocate(vertices.data(),
|
||||
static_cast<GLsizei>(vertices.size()*sizeof(float)));
|
||||
program->enableAttributeArray("vertex");
|
||||
program->setAttributeBuffer("vertex",GL_FLOAT,0,3);
|
||||
buffers[0].release();
|
||||
buffers[1].bind();
|
||||
buffers[1].allocate(normals.data(),
|
||||
static_cast<GLsizei>(normals.size()*sizeof(float)));
|
||||
program->enableAttributeArray("normals");
|
||||
program->setAttributeBuffer("normals",GL_FLOAT,0,3);
|
||||
buffers[1].release();
|
||||
vaos[0]->release();
|
||||
program->release();
|
||||
//once the buffers are filled, we can empty the vectors to optimize memory consumption
|
||||
nb_pos = vertices.size();
|
||||
_bbox = Bbox(0,0,0,0,0,0);
|
||||
for(std::size_t i = 0; i< vertices.size(); i+=3)
|
||||
{
|
||||
_bbox += Point(vertices[i],
|
||||
vertices[i+1],
|
||||
vertices[i+2]).bbox();
|
||||
}
|
||||
|
||||
are_buffers_filled = true;
|
||||
}
|
||||
|
||||
mutable std::size_t nb_pos;
|
||||
Vec center_;
|
||||
double length_;
|
||||
double tick;
|
||||
double R;
|
||||
bool ctrl_pressing;
|
||||
mutable QOpenGLShaderProgram *program;
|
||||
Scene_item::ManipulatedFrame* frame;
|
||||
}; //end of class Scene_arrow_item
|
||||
|
||||
|
||||
template <typename TriangleMesh, typename OutputIterator>
|
||||
CGAL::Bbox_3 triangles(const TriangleMesh& mesh,
|
||||
OutputIterator out)
|
||||
{
|
||||
CGAL::Bbox_3 bb;
|
||||
typename boost::property_map<TriangleMesh,CGAL::vertex_point_t>::const_type vpm =
|
||||
get(CGAL::vertex_point, mesh);
|
||||
BOOST_FOREACH(typename boost::graph_traits<TriangleMesh>::face_descriptor fd, faces(mesh)){
|
||||
typename boost::graph_traits<TriangleMesh>::halfedge_descriptor hd = halfedge(fd,mesh);
|
||||
Triangle t(get(vpm,source(hd,mesh)),
|
||||
get(vpm,target(hd,mesh)),
|
||||
get(vpm,target(next(hd,mesh),mesh)));
|
||||
*out++ = t;
|
||||
bb = bb + t.bbox();
|
||||
}
|
||||
return bb;
|
||||
}
|
||||
|
||||
Vector estimate_normals(const std::vector<Triangle>& tris)
|
||||
{
|
||||
Vector moy(0,0,0);
|
||||
|
||||
BOOST_FOREACH(const Triangle& tri, tris)
|
||||
{
|
||||
Vector norm = CGAL::Polygon_mesh_processing::internal::triangle_normal(
|
||||
tri[0], tri[1], tri[2], Kernel());
|
||||
norm /= CGAL::sqrt(norm.squared_length());
|
||||
moy += norm;
|
||||
}
|
||||
return moy;
|
||||
}
|
||||
|
||||
|
||||
class ExtrudePlugin :
|
||||
public QObject,
|
||||
public Polyhedron_demo_plugin_interface
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface)
|
||||
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0")
|
||||
public:
|
||||
|
||||
bool applicable(QAction* action) const Q_DECL_OVERRIDE
|
||||
{
|
||||
if(action == actionCreateItem)
|
||||
{
|
||||
return !oliver_queen &&
|
||||
(qobject_cast<Scene_face_graph_item*>(scene->item(scene->mainSelectionIndex()))
|
||||
|| qobject_cast<Scene_polyhedron_selection_item*>(scene->item(scene->mainSelectionIndex())));
|
||||
}
|
||||
else if(oliver_queen)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
QList<QAction*> actions() const Q_DECL_OVERRIDE
|
||||
{
|
||||
return _actions;
|
||||
}
|
||||
|
||||
void init(QMainWindow* mainWindow, Scene_interface* sc, Messages_interface* mi) Q_DECL_OVERRIDE
|
||||
{
|
||||
this->messageInterface = mi;
|
||||
this->scene = sc;
|
||||
this->mw = mainWindow;
|
||||
oliver_queen = NULL;
|
||||
target = NULL;
|
||||
actionCreateItem = new QAction(QString("Extrude Item"), mw);
|
||||
actionCreateItem->setProperty("submenuName", "Polygon Mesh Processing");
|
||||
connect(actionCreateItem, SIGNAL(triggered()),
|
||||
this, SLOT(createItem()));
|
||||
_actions << actionCreateItem;
|
||||
actionExtrude = new QAction(QString("Perform Extrusion"), mw);
|
||||
actionExtrude->setProperty("submenuName", "Polygon Mesh Processing");
|
||||
connect(actionExtrude, SIGNAL(triggered()),
|
||||
this, SLOT(do_extrude()));
|
||||
_actions << actionExtrude;
|
||||
}
|
||||
private Q_SLOTS:
|
||||
void createItem()
|
||||
{
|
||||
Scene_item * item = scene->item(scene->mainSelectionIndex());
|
||||
Scene_polyhedron_selection_item* sel_item = qobject_cast<Scene_polyhedron_selection_item*>(scene->item(scene->mainSelectionIndex()));
|
||||
Scene_face_graph_item* fg_item = qobject_cast<Scene_face_graph_item*>(item);
|
||||
Face_graph* pMesh = NULL;
|
||||
if(sel_item)
|
||||
{
|
||||
pMesh = new Face_graph();
|
||||
if(!sel_item->export_selected_facets_as_polyhedron(pMesh))
|
||||
{
|
||||
messageInterface->error("Face selection is not valid. Aborting.");
|
||||
|
||||
return;
|
||||
}
|
||||
fg_item = new Scene_facegraph_item(pMesh);
|
||||
fg_item->setName(QString("%1 selection").arg(sel_item->polyhedron_item()->name()));
|
||||
scene->addItem(fg_item);
|
||||
sel_item->polyhedron_item()->setWireframeMode();
|
||||
sel_item->polyhedron_item()->redraw();
|
||||
}
|
||||
if(fg_item)
|
||||
pMesh = fg_item->face_graph();
|
||||
else
|
||||
return;
|
||||
if(CGAL::is_closed(*pMesh))
|
||||
{
|
||||
messageInterface->error("The face graph must be open. Aborting.");
|
||||
return;
|
||||
}
|
||||
std::vector<Triangle> triangles;
|
||||
::triangles(*pMesh,std::back_inserter(triangles));
|
||||
Plane plane;
|
||||
CGAL::linear_least_squares_fitting_3(triangles.begin(),triangles.end(),plane,CGAL::Dimension_tag<2>());
|
||||
|
||||
// compute centroid
|
||||
Point c = CGAL::centroid(triangles.begin(),triangles.end());
|
||||
|
||||
oliver_queen = new Scene_arrow_item(Vec(c.x(),c.y(),c.z()), fg_item->diagonalBbox() / 50.0f,
|
||||
fg_item->diagonalBbox()/3.0f);
|
||||
Vec dir(plane.orthogonal_vector().x(),
|
||||
plane.orthogonal_vector().y(),
|
||||
plane.orthogonal_vector().z());
|
||||
if(CGAL::scalar_product(Vector(dir.x, dir.y, dir.z), estimate_normals(triangles)) > 0)
|
||||
dir = -dir;
|
||||
|
||||
CGAL::qglviewer::Quaternion orientation(CGAL::qglviewer::Vec(0,1,0), dir);
|
||||
oliver_queen->manipulatedFrame()->setOrientation(orientation);
|
||||
constraint.setRotationConstraintType(CGAL::qglviewer::AxisPlaneConstraint::FREE);
|
||||
constraint.setTranslationConstraintType(CGAL::qglviewer::AxisPlaneConstraint::FORBIDDEN);
|
||||
oliver_queen->manipulatedFrame()->setConstraint(&constraint);
|
||||
oliver_queen->setColor(QColor(Qt::green));
|
||||
oliver_queen->setName("Extrude item");
|
||||
CGAL::QGLViewer* viewer = *CGAL::QGLViewer::QGLViewerPool().begin();
|
||||
viewer->installEventFilter(oliver_queen);
|
||||
mw->installEventFilter(oliver_queen);
|
||||
scene->addItem(oliver_queen);
|
||||
target = fg_item;
|
||||
|
||||
connect(oliver_queen, &Scene_arrow_item::aboutToBeDestroyed,
|
||||
[this](){
|
||||
oliver_queen = NULL;
|
||||
});
|
||||
|
||||
//!@todo : add a way to track scene's bbox recomputation and reset frame's position when triggered.
|
||||
}
|
||||
void do_extrude()
|
||||
{
|
||||
if(!target)
|
||||
return;
|
||||
Face_graph pMesh = *target->face_graph();
|
||||
target->face_graph()->clear();
|
||||
double length = oliver_queen->length();
|
||||
double matrix[16];
|
||||
oliver_queen->manipulatedFrame()->getMatrix(matrix);
|
||||
QMatrix4x4 rotate_matrix;
|
||||
QMatrix4x4 transform_matrix;
|
||||
for(int i=0; i<16; ++i)
|
||||
transform_matrix.data()[i] = (float)matrix[i];
|
||||
rotate_matrix = transform_matrix;
|
||||
rotate_matrix.setColumn(3, QVector4D(0,0,0,1));
|
||||
QVector3D dir = rotate_matrix * QVector3D(0,1,0);
|
||||
dir.normalize();
|
||||
dir = length * dir;
|
||||
|
||||
CGAL::Polygon_mesh_processing::extrude_mesh(pMesh, *target->face_graph(),
|
||||
Kernel::Vector_3(dir.x(), dir.y(), dir.z()));
|
||||
scene->erase(scene->item_id(oliver_queen));
|
||||
oliver_queen = NULL;
|
||||
target->invalidateOpenGLBuffers();
|
||||
target->itemChanged();
|
||||
target = NULL;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
QList<QAction*> _actions;
|
||||
Messages_interface* messageInterface;
|
||||
Scene_interface* scene;
|
||||
QMainWindow* mw;
|
||||
QAction *actionCreateItem;
|
||||
QAction *actionExtrude;
|
||||
Scene_arrow_item* oliver_queen;
|
||||
Scene_face_graph_item* target;
|
||||
CGAL::qglviewer::LocalConstraint constraint;
|
||||
};
|
||||
#include "Extrude_plugin.moc"
|
||||
|
|
@ -638,6 +638,10 @@ void Viewer::attribBuffers(int program_name) const {
|
|||
program->setUniformValue("clipbox1", clipbox1);
|
||||
program->setUniformValue("clipbox2", clipbox2);
|
||||
}
|
||||
if(program_name == PROGRAM_WITH_LIGHT)
|
||||
{
|
||||
program->setUniformValue("alpha", 1.0f); //overriden in item draw() if necessary
|
||||
}
|
||||
switch(program_name)
|
||||
{
|
||||
case PROGRAM_WITH_LIGHT:
|
||||
|
|
|
|||
|
|
@ -140,6 +140,8 @@ distance_plugin \
|
|||
distance_sm_plugin \
|
||||
edit_polyhedron_plugin \
|
||||
edit_sm_plugin \
|
||||
extrude_poly_plugin \
|
||||
extrude_sm_plugin \
|
||||
fairing_plugin \
|
||||
features_detection_plugin \
|
||||
gocad_plugin \
|
||||
|
|
|
|||
|
|
@ -2,6 +2,18 @@ from sys import argv
|
|||
from sys import exit
|
||||
import codecs
|
||||
import re
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("filename",
|
||||
help="the Mardown file to process")
|
||||
parser.add_argument("--codebase",
|
||||
help="for a Markdown file of Codebase instead of Github",
|
||||
action="store_true")
|
||||
parser.add_argument("--h1",
|
||||
help="support level one sections (h1)",
|
||||
action="store_true")
|
||||
args = parser.parse_args()
|
||||
|
||||
# a probably incomplete version to generate an anchor from a section name
|
||||
def get_anchor(s):
|
||||
|
|
@ -13,6 +25,9 @@ def get_anchor(s):
|
|||
s = s.replace(":","")
|
||||
s = s.replace(",","")
|
||||
s = s.replace(";","")
|
||||
if args.codebase:
|
||||
s = s.replace("/","-")
|
||||
else:
|
||||
s = s.replace("/","")
|
||||
s = s.replace("<","")
|
||||
s = s.replace(">","")
|
||||
|
|
@ -23,8 +38,11 @@ def get_anchor(s):
|
|||
s = s.lstrip(" ")
|
||||
s = s.rstrip("\n")
|
||||
s = s.rstrip(" ")
|
||||
s = s.replace(" ","-")
|
||||
s = re.sub(r'\s+','-',s)
|
||||
if not args.codebase:
|
||||
s = s.lower()
|
||||
if args.codebase:
|
||||
s = s.replace("'","-and-39-")
|
||||
return "#"+s
|
||||
|
||||
# indices the nesting level (first level allowed is ##)
|
||||
|
|
@ -45,11 +63,14 @@ def get_name(s):
|
|||
#generate the entry for one section
|
||||
def get_toc_entry(s):
|
||||
name = get_name(s)
|
||||
if args.h1:
|
||||
level = get_level(s)-1
|
||||
else:
|
||||
level = get_level(s)-2
|
||||
anchor = get_anchor(s)
|
||||
|
||||
if level<0:
|
||||
return "ERROR: h1 section are not allowed"
|
||||
return "ERROR: h1 sections are not allowed"
|
||||
|
||||
res="* ["+name+"]("+anchor+")"
|
||||
for i in range(0,level):
|
||||
|
|
@ -57,11 +78,7 @@ def get_toc_entry(s):
|
|||
return res
|
||||
|
||||
#now the main
|
||||
if len(argv) < 2:
|
||||
print("Nothing done, no input file provided")
|
||||
exit()
|
||||
|
||||
input = argv[1]
|
||||
input = args.filename
|
||||
|
||||
f = codecs.open(input, 'r', encoding='utf-8')
|
||||
|
||||
|
|
|
|||
|
|
@ -27,12 +27,12 @@ typedef boost::graph_traits<SurfaceMesh>::face_descriptor face_descriptor;
|
|||
|
||||
namespace SMP = CGAL::Surface_mesh_parameterization;
|
||||
|
||||
int main(int argc, char * argv[])
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
std::ifstream in((argc>1) ? argv[1] : "data/three_peaks.off");
|
||||
if(!in) {
|
||||
std::cerr << "Problem loading the input data" << std::endl;
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
SurfaceMesh sm;
|
||||
|
|
@ -52,11 +52,11 @@ int main(int argc, char * argv[])
|
|||
|
||||
if(err != SMP::OK) {
|
||||
std::cerr << "Error: " << SMP::get_error_message(err) << std::endl;
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
std::ofstream out("result.off");
|
||||
SMP::IO::output_uvmap_to_off(sm, bhd, uv_map, out);
|
||||
|
||||
return 0;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,12 +37,12 @@ typedef boost::graph_traits<Mesh>::face_descriptor face_descriptor;
|
|||
|
||||
namespace SMP = CGAL::Surface_mesh_parameterization;
|
||||
|
||||
int main(int argc, char * argv[])
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
std::ifstream in_mesh((argc>1) ? argv[1] : "data/lion.off");
|
||||
if(!in_mesh){
|
||||
std::cerr << "Error: problem loading the input data" << std::endl;
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
SurfaceMesh sm;
|
||||
|
|
@ -97,6 +97,6 @@ int main(int argc, char * argv[])
|
|||
std::ofstream out("result.off");
|
||||
SMP::IO::output_uvmap_to_off(mesh, bhd, uv_pm, out);
|
||||
|
||||
return 0;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ typedef SurfaceMesh::Property_map<SM_halfedge_descriptor, Point_2> UV_pmap;
|
|||
|
||||
namespace SMP = CGAL::Surface_mesh_parameterization;
|
||||
|
||||
int main(int argc, char * argv[])
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
CGAL::Timer task_timer;
|
||||
task_timer.start();
|
||||
|
|
@ -50,7 +50,7 @@ int main(int argc, char * argv[])
|
|||
std::ifstream in_mesh(mesh_filename);
|
||||
if(!in_mesh) {
|
||||
std::cerr << "Error: problem loading the input data" << std::endl;
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
SurfaceMesh sm; // underlying mesh of the seam mesh
|
||||
|
|
@ -120,4 +120,5 @@ int main(int argc, char * argv[])
|
|||
parameterizer.parameterize(mesh, bhd, cmap, uvmap, vimap);
|
||||
|
||||
std::cout << "Finished in " << task_timer.time() << " seconds" << std::endl;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,12 +37,12 @@ typedef boost::graph_traits<Mesh>::face_descriptor face_descriptor;
|
|||
|
||||
namespace SMP = CGAL::Surface_mesh_parameterization;
|
||||
|
||||
int main(int argc, char * argv[])
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
std::ifstream in_mesh((argc>1)?argv[1]:"data/lion.off");
|
||||
if(!in_mesh) {
|
||||
std::cerr << "Error: problem loading the input data" << std::endl;
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
PolyMesh sm;
|
||||
|
|
@ -77,6 +77,6 @@ int main(int argc, char * argv[])
|
|||
std::ofstream out("result.off");
|
||||
SMP::IO::output_uvmap_to_off(mesh, bhd, uv_pm, out);
|
||||
|
||||
return 0;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,12 +21,12 @@ typedef boost::graph_traits<SurfaceMesh>::face_descriptor face_descriptor;
|
|||
|
||||
namespace SMP = CGAL::Surface_mesh_parameterization;
|
||||
|
||||
int main(int argc, char * argv[])
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
std::ifstream in((argc>1) ? argv[1] : "data/nefertiti.off");
|
||||
if(!in) {
|
||||
std::cerr << "Problem loading the input data" << std::endl;
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
SurfaceMesh sm;
|
||||
|
|
@ -44,5 +44,5 @@ int main(int argc, char * argv[])
|
|||
std::ofstream out("result.off");
|
||||
SMP::IO::output_uvmap_to_off(sm, bhd, uv_map, out);
|
||||
|
||||
return 0;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ bool read_vertices(const PolyMesh& mesh,
|
|||
return true;
|
||||
}
|
||||
|
||||
int main(int argc, char * argv[])
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
std::ifstream in((argc>1) ? argv[1] : "data/nefertiti.off");
|
||||
if(!in){
|
||||
|
|
@ -118,7 +118,7 @@ int main(int argc, char * argv[])
|
|||
Vd_array vda;
|
||||
if(!read_vertices(sm, filename, vda)) {
|
||||
std::cerr << "Error: problem loading the square corners" << std::endl;
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
typedef SMP::Square_border_uniform_parameterizer_3<PolyMesh> Border_parameterizer;
|
||||
|
|
@ -138,5 +138,5 @@ int main(int argc, char * argv[])
|
|||
std::ofstream out("result.off");
|
||||
SMP::IO::output_uvmap_to_off(sm, bhd, uv_map, out);
|
||||
|
||||
return 0;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1327,8 +1327,11 @@ public:
|
|||
NT energy_this = compute_current_energy(mesh, faces, ctmap, lp, lpmap,
|
||||
ltmap, uvmap);
|
||||
NT energy_last;
|
||||
|
||||
#ifdef CGAL_PARAMETERIZATION_ARAP_VERBOSE
|
||||
std::cout << "Initial energy: " << energy_this << std::endl;
|
||||
std::cout << m_iterations << " max iterations" << std::endl;
|
||||
#endif
|
||||
|
||||
// main loop
|
||||
for(unsigned int ite=1; ite<=m_iterations; ++ite)
|
||||
|
|
@ -1342,7 +1345,9 @@ public:
|
|||
energy_last = energy_this;
|
||||
energy_this = compute_current_energy(mesh, faces, ctmap, lp, lpmap,
|
||||
ltmap, uvmap);
|
||||
#ifdef CGAL_PARAMETERIZATION_ARAP_VERBOSE
|
||||
std::cout << "Energy at iteration " << ite << " : " << energy_this << std::endl;
|
||||
#endif
|
||||
CGAL_warning(energy_this >= 0);
|
||||
|
||||
if(status != OK)
|
||||
|
|
@ -1353,9 +1358,11 @@ public:
|
|||
{ // also no need compute energy if this iteration is the last iteration
|
||||
double energy_diff = std::abs((energy_last - energy_this) / energy_this);
|
||||
if(energy_diff < m_tolerance) {
|
||||
#ifdef CGAL_PARAMETERIZATION_ARAP_VERBOSE
|
||||
std::cout << "Minimization process ended after: "
|
||||
<< ite + 1 << " iterations. "
|
||||
<< "Energy diff: " << energy_diff << std::endl;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -744,7 +744,6 @@ public:
|
|||
// Run the MVC
|
||||
parameterize_convex_hull_with_MVC(mesh, vertices, faces, ct, uvmap, vimap, vpmap);
|
||||
|
||||
std::cout << "End of post processing" << std::endl;
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -110,10 +110,12 @@ Error_code read_cones(const TriangleMesh& tm, std::ifstream& in, VertexIndexMap
|
|||
while(in >> cone_index)
|
||||
cones.push_back(cone_index);
|
||||
|
||||
#ifdef CGAL_PARAMETERIZATION_ORBIFOLD_CONE_VERBOSE
|
||||
std::cout << "Input cones: ";
|
||||
for(std::size_t i=0; i<cones.size(); ++i)
|
||||
std::cout << cones[i] << " ";
|
||||
std::cout << std::endl;
|
||||
#endif
|
||||
|
||||
if(cones.size() < 3 || cones.size() > 4) {
|
||||
std::cerr << "Error: Not enough or too many input cones" << std::endl;
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ namespace Surface_mesh_parameterization {
|
|||
namespace internal {
|
||||
|
||||
// -> ->
|
||||
// Return cotangent of (P,Q,R) corner (i.e. cotan of QP, QR angle).
|
||||
// Returns the cotangent of the corner (P,Q,R) (i.e. the cotan of the angle (QP, QR) ).
|
||||
template<typename K>
|
||||
typename K::FT cotangent(const typename K::Point_3& P,
|
||||
const typename K::Point_3& Q,
|
||||
|
|
@ -46,18 +46,17 @@ typename K::FT cotangent(const typename K::Point_3& P,
|
|||
|
||||
Vector_3 u = P - Q;
|
||||
Vector_3 v = R - Q;
|
||||
// (u . v) / ((u x v).len)
|
||||
NT dot = (u * v);
|
||||
Vector_3 cross_vector = CGAL::cross_product(u, v);
|
||||
NT cross_norm = CGAL::sqrt(cross_vector * cross_vector);
|
||||
if(cross_norm != 0.0)
|
||||
if(cross_norm != NT(0))
|
||||
return (dot / cross_norm);
|
||||
else
|
||||
return 0.0; // undefined
|
||||
return 0; // undefined
|
||||
}
|
||||
|
||||
// -> ->
|
||||
// Return tangent of (P,Q,R) corner (i.e. tangent of QP, QR angle).
|
||||
// Returns the tangent of the corner (P,Q,R) (i.e. the tangent of angle (QP, QR) ).
|
||||
template<typename K>
|
||||
typename K::FT tangent(const typename K::Point_3& P,
|
||||
const typename K::Point_3& Q,
|
||||
|
|
@ -68,17 +67,16 @@ typename K::FT tangent(const typename K::Point_3& P,
|
|||
|
||||
Vector_3 u = P - Q;
|
||||
Vector_3 v = R - Q;
|
||||
// (u . v) / ((u x v).len)
|
||||
NT dot = (u * v);
|
||||
Vector_3 cross_vector = CGAL::cross_product(u, v);
|
||||
NT cross_norm = CGAL::sqrt(cross_vector * cross_vector);
|
||||
if(dot != 0.0)
|
||||
if(dot != NT(0))
|
||||
return (cross_norm / dot);
|
||||
else
|
||||
return 0.0; // undefined
|
||||
return 0; // undefined
|
||||
}
|
||||
|
||||
// Fix sine to be within [-1;1].
|
||||
// Fixes the sine to be within [-1;1].
|
||||
template<typename K>
|
||||
typename K::FT fix_sine(typename K::FT sine)
|
||||
{
|
||||
|
|
@ -91,7 +89,7 @@ typename K::FT fix_sine(typename K::FT sine)
|
|||
}
|
||||
|
||||
// -> ->
|
||||
// Return angle (in radians) of of (P,Q,R) corner (i.e. QP, QR angle).
|
||||
// Returns the angle (in radians) of the corner (P,Q,R) (i.e. the angle (QP, QR) ).
|
||||
template<typename K>
|
||||
typename K::FT compute_angle_rad(const typename K::Point_3& P,
|
||||
const typename K::Point_3& Q,
|
||||
|
|
@ -103,10 +101,9 @@ typename K::FT compute_angle_rad(const typename K::Point_3& P,
|
|||
Vector_3 u = P - Q;
|
||||
Vector_3 v = R - Q;
|
||||
|
||||
// check
|
||||
NT product = CGAL::sqrt(u * u) * CGAL::sqrt(v * v);
|
||||
if(product == 0)
|
||||
return 0.0;
|
||||
if(product == NT(0))
|
||||
return 0;
|
||||
|
||||
// cosine
|
||||
NT dot = (u * v);
|
||||
|
|
@ -116,7 +113,7 @@ typename K::FT compute_angle_rad(const typename K::Point_3& P,
|
|||
Vector_3 w = CGAL::cross_product(u, v);
|
||||
NT abs_sine = CGAL::sqrt(w * w) / product;
|
||||
|
||||
if(cosine >= 0)
|
||||
if(cosine >= NT(0))
|
||||
return std::asin(fix_sine<K>(abs_sine));
|
||||
else
|
||||
return CGAL_PI - std::asin(fix_sine<K>(abs_sine));
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ void compute_shortest_paths_between_two_cones(const TriangleMesh& mesh,
|
|||
EdgeOutputIterator oi)
|
||||
{
|
||||
if(source == target) {
|
||||
std::cout << "Warning: the source and target are identical in 'shortest_path' " << std::endl;
|
||||
std::cerr << "Warning: the source and target are identical in 'shortest_path' " << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -150,7 +150,7 @@ void compute_shortest_paths_between_two_cones(const TriangleMesh& mesh,
|
|||
try {
|
||||
boost::dijkstra_shortest_paths(mesh, source, boost::predecessor_map(pred_pmap).visitor(vis));
|
||||
} catch (const std::exception& e) {
|
||||
std::cout << e.what() << std::endl;
|
||||
std::cerr << e.what() << std::endl;
|
||||
}
|
||||
|
||||
// Draw the path from target to source and collect the edges along the way
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ int main(int, char**)
|
|||
in >> pm;
|
||||
if(!in || num_vertices(pm) == 0) {
|
||||
std::cerr << "Problem loading the input data" << std::endl;
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
PM_halfedge_descriptor hd = CGAL::Polygon_mesh_processing::longest_border(pm).first;
|
||||
|
|
@ -108,7 +108,7 @@ int main(int, char**)
|
|||
|
||||
if(status != SMP::OK) {
|
||||
std::cout << "Encountered a problem: " << status << std::endl;
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
else {
|
||||
std::cout << "Parameterized with MVC (POLY)!" << std::endl;
|
||||
|
|
@ -129,7 +129,7 @@ int main(int, char**)
|
|||
in >> pm;
|
||||
if(!in || num_vertices(pm) == 0) {
|
||||
std::cerr << "Problem loading the input data" << std::endl;
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
PM_halfedge_descriptor hd = CGAL::Polygon_mesh_processing::longest_border(pm).first;
|
||||
|
|
@ -162,7 +162,7 @@ int main(int, char**)
|
|||
|
||||
if(status != SMP::OK) {
|
||||
std::cout << "Encountered a problem: " << status << std::endl;
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
else {
|
||||
std::cout << "Parameterized with ARAP (POLY)!" << std::endl;
|
||||
|
|
@ -183,7 +183,7 @@ int main(int, char**)
|
|||
in >> sm;
|
||||
if(!in || num_vertices(sm) == 0) {
|
||||
std::cerr << "Problem loading the input data" << std::endl;
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
SM_halfedge_descriptor hd = CGAL::Polygon_mesh_processing::longest_border(sm).first;
|
||||
|
|
@ -214,7 +214,7 @@ int main(int, char**)
|
|||
|
||||
if(status != SMP::OK) {
|
||||
std::cout << "Encountered a problem: " << status << std::endl;
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
else {
|
||||
std::cout << "Parameterized with Barycentric (SM)!" << std::endl;
|
||||
|
|
@ -235,7 +235,7 @@ int main(int, char**)
|
|||
in >> sm;
|
||||
if(!in || num_vertices(sm) == 0) {
|
||||
std::cerr << "Problem loading the input data" << std::endl;
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// halfedge on the longest border
|
||||
|
|
@ -269,7 +269,7 @@ int main(int, char**)
|
|||
SMP::Error_code status = parameterizer.parameterize(sm, hd, uv_pm, vipm, vpm);
|
||||
if(status != SMP::OK) {
|
||||
std::cout << "Encountered a problem: " << status << std::endl;
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
else {
|
||||
std::cout << "Parameterized with ARAP (SM)!" << std::endl;
|
||||
|
|
@ -286,7 +286,7 @@ int main(int, char**)
|
|||
in >> pm;
|
||||
if(!in || num_vertices(pm) == 0) {
|
||||
std::cerr << "Problem loading the input data" << std::endl;
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
const char* selection = "data/fandisk.dcm.selection.txt";
|
||||
|
||||
|
|
@ -330,7 +330,7 @@ int main(int, char**)
|
|||
|
||||
if(status != SMP::OK) {
|
||||
std::cout << "Encountered a problem: " << status << std::endl;
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
else {
|
||||
std::cout << "Parameterized with DCM (SEAM POLY)!" << std::endl;
|
||||
|
|
@ -351,7 +351,7 @@ int main(int, char**)
|
|||
in >> sm;
|
||||
if(!in || num_vertices(sm) == 0) {
|
||||
std::cerr << "Problem loading the input data" << std::endl;
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
const char* selection = "data/bear.dac.selection.txt";
|
||||
|
|
@ -395,7 +395,7 @@ int main(int, char**)
|
|||
SMP::Error_code status = parameterizer.parameterize(mesh, hd, uv_pm, vipm, vpm);
|
||||
if(status != SMP::OK) {
|
||||
std::cout << "Encountered a problem: " << status << std::endl;
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
else {
|
||||
std::cout << "Parameterized with DAC (SEAM SM)!" << std::endl;
|
||||
|
|
@ -413,7 +413,7 @@ int main(int, char**)
|
|||
in >> sm;
|
||||
if(!in || num_vertices(sm) == 0) {
|
||||
std::cerr << "Problem loading the input data" << std::endl;
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
const char* cone_filename = "data/fandisk.orbifold.selection.txt";
|
||||
|
|
@ -471,7 +471,7 @@ int main(int, char**)
|
|||
SMP::Error_code status = parameterizer.parameterize(mesh, hd, cmap, uvmap, vimap);
|
||||
if(status != SMP::OK) {
|
||||
std::cout << "Encountered a problem: " << status << std::endl;
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
else {
|
||||
std::cout << "Parameterized with Orbifold (SEAM SM)!" << std::endl;
|
||||
|
|
@ -481,5 +481,5 @@ int main(int, char**)
|
|||
|
||||
std::cout << "Done!" << std::endl;
|
||||
|
||||
return 0;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -847,7 +847,8 @@ private:
|
|||
{
|
||||
typedef std::pair<Input_vertex_descriptor, vertex_descriptor> Vertex_pair;
|
||||
std::vector<Vertex_pair> v2v;
|
||||
copy_face_graph(tmesh, m_tmesh, std::back_inserter(v2v));
|
||||
copy_face_graph(tmesh, m_tmesh,
|
||||
CGAL::parameters::vertex_to_vertex_output_iterator(std::back_inserter(v2v)));
|
||||
|
||||
// copy input vertices to keep correspondence
|
||||
BOOST_FOREACH(const Vertex_pair& vp, v2v)
|
||||
|
|
|
|||
Loading…
Reference in New Issue