Skip to content

Commit

Permalink
add default L21 metric API
Browse files Browse the repository at this point in the history
  • Loading branch information
aboudev committed Jul 24, 2017
1 parent 241309a commit f82a6e9
Showing 1 changed file with 229 additions and 0 deletions.
229 changes: 229 additions & 0 deletions Surface_mesh_approximation/include/CGAL/vsa_mesh_approximation.h
Expand Up @@ -2,7 +2,9 @@
#define CGAL_SURFACE_MESH_APPROXIMATION_VSA_MESH_APPROXIMATION_H

#include <CGAL/internal/Surface_mesh_approximation/VSA.h>
#include <CGAL/vsa_mesh_approximation_traits.h>
#include <CGAL/property_map.h>
#include <boost/graph/graph_traits.hpp>

namespace CGAL
{
Expand Down Expand Up @@ -262,6 +264,233 @@ void vsa_approximate_and_extract(
BOOST_FOREACH(const typename VSA_mesh_extraction::Anchor &a, extractor.collect_anchors())
pos.push_back(a.pos);
}

/*!
* \ingroup PkgTSMA
* @brief Using the VSA algorithm to approximate a triangle mesh.
* This function approximate the input mesh by fitting it with proxies.
* Facet proxy index output only.
* Use default L21 metric.
*
* @tparam TriangleMesh model of `FaceGraph`.
* @tparam FacetProxyMap a property map containing the approximated facet patch id,
and `boost::graph_traits<TriangleMesh>::%face_descriptor` as key type,
std::size_t as value type
* @param tm a triangle mesh
* @param[out] f_proxy_pmap facet proxy patch id property map
* @param init select seed initialization
* @param number_of_segments target number of approximation patches
* @param number_of_iterations number of fitting iterations
*/
template<typename TriangleMesh,
typename FacetProxyMap>
void vsa_approximate(
const TriangleMesh &tm,
FacetProxyMap f_proxy_pmap,
const int init,
const std::size_t number_of_segments,
const std::size_t number_of_iterations) {
// CGAL_precondition(is_pure_triangle(tm));

typedef typename TriangleMesh::Traits GeomTraits;
typedef typename GeomTraits::FT FT;
typedef typename GeomTraits::Vector_3 Vector_3;
typedef typename GeomTraits::Point_3 Point_3;
typedef typename boost::graph_traits<TriangleMesh>::face_descriptor face_descriptor;
typedef typename boost::graph_traits<TriangleMesh>::halfedge_descriptor halfedge_descriptor;
typedef boost::associative_property_map<std::map<face_descriptor, Vector_3> > FacetNormalMap;
typedef boost::associative_property_map<std::map<face_descriptor, FT> > FacetAreaMap;
typedef boost::property_map<TriangleMesh, boost::vertex_point_t>::type VertexPointMap;

typedef CGAL::PlaneProxy<TriangleMesh> PlaneProxy;
typedef CGAL::L21Metric<PlaneProxy, FacetNormalMap, FacetAreaMap> L21Metric;
typedef CGAL::L21ProxyFitting<PlaneProxy, L21Metric, FacetNormalMap, FacetAreaMap> L21ProxyFitting;
typedef CGAL::PlaneFitting<TriangleMesh, FacetAreaMap, FacetNormalMap, VertexPointMap> PlaneFitting;
typedef CGAL::L21ApproximationTrait<PlaneProxy, TriangleMesh, L21Metric, L21ProxyFitting, PlaneFitting, VertexPointMap, FacetNormalMap, FacetAreaMap> L21ApproximationTrait;

VertexPointMap point_pmap = get(boost::vertex_point, const_cast<TriangleMesh &>(tm));
// construct facet normal & area map
std::map<face_descriptor, Vector_3> facet_normals;
std::map<face_descriptor, FT> facet_areas;
BOOST_FOREACH(face_descriptor f, faces(tm)) {
const halfedge_descriptor he = halfedge(f, tm);
const Point_3 p0 = point_pmap[source(he, tm)];
const Point_3 p1 = point_pmap[target(he, tm)];
const Point_3 p2 = point_pmap[target(next(he, tm), tm)];
Vector_3 normal = CGAL::unit_normal(p0, p1, p2);
facet_normals.insert(std::pair<face_descriptor, Vector_3>(f, normal));
FT area(std::sqrt(CGAL::to_double(CGAL::squared_area(p0, p1, p2))));
facet_areas.insert(std::pair<face_descriptor, FT>(f, area));
}
FacetNormalMap normal_pmap(facet_normals);
FacetAreaMap area_pmap(facet_areas);

vsa_approximate(tm,
f_proxy_pmap,
L21ApproximationTrait(tm, point_pmap, normal_pmap, area_pmap),
init,
number_of_segments,
number_of_iterations);
}

/*!
* \ingroup PkgTSMA
* @brief Using the VSA algorithm to extract the approximated surface mesh.
* This function approximate the input triangulated mesh by fitting it with proxies.
* Approximated triangle mesh output only.
* Use default L21 metric.
*
* @tparam TriangleMesh model of `FaceGraph`.
* @tparam AnchorIndexContainer a container of approximated indexed triangle soup
* @tparam AnchorPositionContainer a container of extracted anchor position
* @param tm a triangle mesh
* @param[out] tris approximation indexed triangle soup
* @param[out] pos anchor position container
* @param init select seed initialization
* @param number_of_segments target number of approximation patches
* @param number_of_iterations number of fitting iterations
*/
template<typename TriangleMesh,
typename AnchorIndexContainer,
typename AnchorPositionContainer>
void vsa_extract(
const TriangleMesh &tm,
AnchorIndexContainer &tris,
AnchorPositionContainer &pos,
const int init,
const std::size_t number_of_segments,
const std::size_t number_of_iterations) {
// CGAL_precondition(is_pure_triangle(tm));

typedef typename TriangleMesh::Traits GeomTraits;
typedef typename GeomTraits::FT FT;
typedef typename GeomTraits::Vector_3 Vector_3;
typedef typename GeomTraits::Point_3 Point_3;
typedef typename boost::graph_traits<TriangleMesh>::face_descriptor face_descriptor;
typedef typename boost::graph_traits<TriangleMesh>::halfedge_descriptor halfedge_descriptor;
typedef boost::associative_property_map<std::map<face_descriptor, Vector_3> > FacetNormalMap;
typedef boost::associative_property_map<std::map<face_descriptor, FT> > FacetAreaMap;
typedef boost::property_map<TriangleMesh, boost::vertex_point_t>::type VertexPointMap;

typedef CGAL::PlaneProxy<TriangleMesh> PlaneProxy;
typedef CGAL::L21Metric<PlaneProxy, FacetNormalMap, FacetAreaMap> L21Metric;
typedef CGAL::L21ProxyFitting<PlaneProxy, L21Metric, FacetNormalMap, FacetAreaMap> L21ProxyFitting;
typedef CGAL::PlaneFitting<TriangleMesh, FacetAreaMap, FacetNormalMap, VertexPointMap> PlaneFitting;
typedef CGAL::L21ApproximationTrait<PlaneProxy, TriangleMesh, L21Metric, L21ProxyFitting, PlaneFitting, VertexPointMap, FacetNormalMap, FacetAreaMap> L21ApproximationTrait;

VertexPointMap point_pmap = get(boost::vertex_point, const_cast<TriangleMesh &>(tm));
// construct facet normal & area map
std::map<face_descriptor, Vector_3> facet_normals;
std::map<face_descriptor, FT> facet_areas;
BOOST_FOREACH(face_descriptor f, faces(tm)) {
const halfedge_descriptor he = halfedge(f, tm);
const Point_3 p0 = point_pmap[source(he, tm)];
const Point_3 p1 = point_pmap[target(he, tm)];
const Point_3 p2 = point_pmap[target(next(he, tm), tm)];
Vector_3 normal = CGAL::unit_normal(p0, p1, p2);
facet_normals.insert(std::pair<face_descriptor, Vector_3>(f, normal));
FT area(std::sqrt(CGAL::to_double(CGAL::squared_area(p0, p1, p2))));
facet_areas.insert(std::pair<face_descriptor, FT>(f, area));
}
FacetNormalMap normal_pmap(facet_normals);
FacetAreaMap area_pmap(facet_areas);

typedef typename boost::associative_property_map<std::map<face_descriptor, std::size_t> > FacetProxyMap;
std::map<face_descriptor, std::size_t> facet_proxy_map;
BOOST_FOREACH(face_descriptor f, faces(tm))
facet_proxy_map.insert(std::pair<face_descriptor, std::size_t>(f, 0));
FacetProxyMap f_proxy_pmap(facet_proxy_map);

vsa_extract(tm,
tris,
pos,
L21ApproximationTrait(tm, point_pmap, normal_pmap, area_pmap),
init,
number_of_segments,
number_of_iterations);
}

/*!
* \ingroup PkgTSMA
* @brief Triangle mesh variational shape approximation.
* This function approximate the input triangulated mesh by fitting it with proxies.
* Facet proxy index and approximated triangle mesh output.
* Use default L21 metric.
*
* @tparam TriangleMesh model of `FaceGraph`.
* @tparam FacetProxyMap a property map containing the approximated facet patch id,
and `boost::graph_traits<TriangleMesh>::%face_descriptor` as key type,
std::size_t as value type
* @tparam AnchorIndexContainer a container of approximated indexed triangle soup
* @tparam AnchorPositionContainer a container of extracted anchor position
* @param tm a triangle mesh
* @param[out] f_proxy_pmap facet proxy patch id property map
* @param[out] tris approximation indexed triangle soup
* @param[out] pos anchor position container
* @param init select seed initialization
* @param number_of_segments target number of approximation patches
* @param number_of_iterations number of fitting iterations
*/
template<typename TriangleMesh,
typename FacetProxyMap,
typename AnchorIndexContainer,
typename AnchorPositionContainer>
void vsa_approximate_and_extract(
const TriangleMesh &tm,
FacetProxyMap f_proxy_pmap,
AnchorIndexContainer &tris,
AnchorPositionContainer &pos,
const int init,
const std::size_t number_of_segments,
const std::size_t number_of_iterations) {
// CGAL_precondition(is_pure_triangle(tm));

typedef typename TriangleMesh::Traits GeomTraits;
typedef typename GeomTraits::FT FT;
typedef typename GeomTraits::Vector_3 Vector_3;
typedef typename GeomTraits::Point_3 Point_3;
typedef typename boost::graph_traits<TriangleMesh>::face_descriptor face_descriptor;
typedef typename boost::graph_traits<TriangleMesh>::halfedge_descriptor halfedge_descriptor;
typedef boost::associative_property_map<std::map<face_descriptor, Vector_3> > FacetNormalMap;
typedef boost::associative_property_map<std::map<face_descriptor, FT> > FacetAreaMap;
typedef boost::property_map<TriangleMesh, boost::vertex_point_t>::type VertexPointMap;

typedef CGAL::PlaneProxy<TriangleMesh> PlaneProxy;
typedef CGAL::L21Metric<PlaneProxy, FacetNormalMap, FacetAreaMap> L21Metric;
typedef CGAL::L21ProxyFitting<PlaneProxy, L21Metric, FacetNormalMap, FacetAreaMap> L21ProxyFitting;
typedef CGAL::PlaneFitting<TriangleMesh, FacetAreaMap, FacetNormalMap, VertexPointMap> PlaneFitting;
typedef CGAL::L21ApproximationTrait<PlaneProxy, TriangleMesh, L21Metric, L21ProxyFitting, PlaneFitting, VertexPointMap, FacetNormalMap, FacetAreaMap> L21ApproximationTrait;

VertexPointMap point_pmap = get(boost::vertex_point, const_cast<TriangleMesh &>(tm));
// construct facet normal & area map
std::map<face_descriptor, Vector_3> facet_normals;
std::map<face_descriptor, FT> facet_areas;
BOOST_FOREACH(face_descriptor f, faces(tm)) {
const halfedge_descriptor he = halfedge(f, tm);
const Point_3 p0 = point_pmap[source(he, tm)];
const Point_3 p1 = point_pmap[target(he, tm)];
const Point_3 p2 = point_pmap[target(next(he, tm), tm)];
Vector_3 normal = CGAL::unit_normal(p0, p1, p2);
facet_normals.insert(std::pair<face_descriptor, Vector_3>(f, normal));
FT area(std::sqrt(CGAL::to_double(CGAL::squared_area(p0, p1, p2))));
facet_areas.insert(std::pair<face_descriptor, FT>(f, area));
}
FacetNormalMap normal_pmap(facet_normals);
FacetAreaMap area_pmap(facet_areas);

L21ApproximationTrait app_trait(tm, point_pmap, normal_pmap, area_pmap);
vsa_approximate_and_extract(tm,
f_proxy_pmap,
tris,
pos,
app_trait,
init,
number_of_segments,
number_of_iterations);
}
} // end namespace CGAL

#endif // CGAL_SURFACE_MESH_APPROXIMATION_VSA_MESH_APPROXIMATION_H

0 comments on commit f82a6e9

Please sign in to comment.