add comment

This commit is contained in:
Lingjie Zhu
2018-11-30 15:24:16 +08:00
parent fb7fd3eb9d
commit cb3393ccaa
@@ -26,19 +26,17 @@ namespace CGAL
namespace internal
{
/**
* @brief Main entry point for VSA mesh approximation algorithm.
*
* blah blah...
* @brief Main class for Variational Shape Approximation algorithm.
*
* @tparam Polyhedron a CGAL polyhedron
* @tparam GeomTraits a model of ApproximationGeomTraits
*/
template <typename Polyhedron,
typename GeomTraits,
//typename FacetSegmentMap,
typename VertexPointPmap>
class VSA
{
// type definitions
private:
typedef typename GeomTraits::FT FT;
typedef typename GeomTraits::Point_3 Point;
@@ -60,7 +58,6 @@ private:
typedef typename boost::graph_traits<Polyhedron>::edge_descriptor edge_descriptor;
typedef typename boost::graph_traits<Polyhedron>::edge_iterator edge_iterator;
//typedef boost::associative_property_map<std::map<face_descriptor, std::size_t> > FacetSegmentMap;
typedef boost::associative_property_map<std::map<face_descriptor, Vector> > FacetNormalMap;
typedef boost::associative_property_map<std::map<face_descriptor, FT> > FacetAreaMap;
typedef boost::associative_property_map<std::map<vertex_descriptor, int> > VertexStatusPMap;
@@ -69,22 +66,26 @@ private:
typedef std::vector<halfedge_descriptor> ChordVector;
typedef typename ChordVector::iterator ChordVectorIterator;
// The attached anchor index of a vertex.
enum Vertex_status {
NO_ANCHOR = -1 // vertex v has no anchor attached
NO_ANCHOR = -1 // No anchor attached
};
// Halfedge status.
enum Halfedge_status {
OFF_BORDER, // halfedge h is off proxy border
CANDIDATE, // halfedge h is on proxy border, waiting to be visited
ON_BORDER // halfedge h is on proxy border
OFF_BORDER, // In the inside of a region.
CANDIDATE, // On the region border, waiting to be visited.
ON_BORDER // On proxy border, already visited.
};
public:
// The approximated plane proxy.
struct PlaneProxy {
Vector normal;
face_descriptor seed;
};
// The facet candidate to be queued.
struct FacetToIntegrate {
face_descriptor f;
std::size_t i;
@@ -95,14 +96,8 @@ public:
}
};
/*template <typename ShapeProxy,
typename FacetNormalMap = boost::associative_property_map<std::map<face_descriptor, Vector> >,
typename FacetAreaMap = boost::associative_property_map<std::map<face_descriptor, FT> >>*/
/*template <typename FacetNormalMap,
typename FacetAreaMap>*/
// The l21 metric, compute the fitting error from a facet to a plane proxy.
struct L21Metric {
//L21Metric() {}
L21Metric(GeomTraits traits,
const FacetNormalMap &normal_pmap,
const FacetAreaMap &area_pmap)
@@ -125,25 +120,26 @@ public:
Construct_sum_of_vectors_3 sum_functor;
};
// Anchor
// The average positioned anchor attached to a vertex.
struct Anchor {
Anchor(const vertex_descriptor &vtx_, const Point &pos_)
: vtx(vtx_), pos(pos_) {}
vertex_descriptor vtx; // The associated vertex
Point pos; // The position of the anchor
vertex_descriptor vtx; // The associated vertex.
Point pos; // The position of the anchor.
};
// Border
// The border cycle of a region.
// One region may have multiple border cycles.
struct Border {
Border(const halfedge_descriptor &h)
: he_head(h), num_anchors(0) {}
halfedge_descriptor he_head; // The heading halfedge of the border
std::size_t num_anchors; // The number of anchors of the border
halfedge_descriptor he_head; // The heading halfedge of the border cylce.
std::size_t num_anchors; // The number of anchors on the border.
};
// member variables
// member variables
private:
const Polyhedron &mesh;
const VertexPointPmap &vertex_point_pmap;
@@ -155,40 +151,40 @@ private:
Compute_scalar_product_3 scalar_product_functor;
Compute_squared_area_3 area_functor;
// Proxy and its auxiliary information.
std::vector<PlaneProxy> proxies;
// proxy auxiliary information
std::vector<Point> proxies_center; // proxy center
std::vector<FT> proxies_area; // proxy area
std::vector<Point> proxies_center; // The proxy center.
std::vector<FT> proxies_area; // The proxy area.
// the lifetime of the container must encompass the use of the adaptor
// Mesh facet normal and area map.
std::map<face_descriptor, Vector> facet_normals;
FacetNormalMap normal_pmap;
std::map<face_descriptor, FT> facet_areas;
FacetAreaMap area_pmap;
// Mesh vertex anchor map and halfedge status map.
std::map<vertex_descriptor, int> vertex_status_map;
VertexStatusPMap vertex_status_pmap;
std::map<halfedge_descriptor, int> halfedge_status_map;
HalfedgeStatusPMap halfedge_status_pmap;
// All anchors
// All anchors.
std::vector<Anchor> anchors;
// All borders, some regions may have multiple borders
// All borders cycles.
std::vector<Border> borders;
// The error metric.
L21Metric fit_error;
//L21Metric<FacetNormalMap, FacetAreaMap> fit_error;
//L21Metric<PlaneProxy> fit_error;
//boost::associative_property_map<std::map<face_descriptor, std::size_t> > seg_pmap;
//boost::property_map<face_descriptor, std::size_t> &seg_pmap;
//member functions
//member functions
public:
/**
* Initialize and prepare for the approximation.
* @pre @a polyhedron.is_pure_triangle()
* @param mesh `CGAL Polyhedron` on which other functions operate.
* @param _mesh `CGAL Polyhedron` on which approximation operate.
* @param _vertex_point_map vertex point map of the input mesh.
* @param _traits geometric trait object.
*/
VSA(const Polyhedron &_mesh,
VertexPointPmap _vertex_point_map,
@@ -235,6 +231,13 @@ public:
}
}
/**
* Partitions the mesh into the designated number of regions, and stores them in @a seg_map.
* @tparam FacetSegmentMap `WritablePropertyMap` with `boost::graph_traits<Polyhedron>::face_handle` as key and `std::size_t` as value type
* @param number_of_segments number of designated proxies
* @param number_of_iterations number of iterations when fitting the proxy
* @param[out] seg_map facet partition index
*/
template<typename FacetSegmentMap>
void partition(const std::size_t number_of_segments, const std::size_t number_of_iterations, FacetSegmentMap &seg_pmap) {
random_seed(number_of_segments);
@@ -245,6 +248,13 @@ public:
}
}
/**
* Partitions the mesh incrementally into the designated number of regions, and stores them in @a seg_map.
* @tparam FacetSegmentMap `WritablePropertyMap` with `boost::graph_traits<Polyhedron>::face_handle` as key and `std::size_t` as value type
* @param number_of_segments number of designated proxies
* @param number_of_iterations number of iterations when fitting the proxy
* @param[out] seg_map facet partition index
*/
template<typename FacetSegmentMap>
void partition_incre(const std::size_t number_of_segments, const std::size_t number_of_iterations, FacetSegmentMap &seg_pmap) {
// random_seed(number_of_segments);
@@ -264,7 +274,12 @@ public:
}
}
// extract the approximated mesh from a partition
/**
* Extracts the approximated triangle mesh from a partition @a seg_pmap, and stores the triangles in @a tris.
* @tparam FacetSegmentMap `WritablePropertyMap` with `boost::graph_traits<Polyhedron>::face_handle` as key and `std::size_t` as value type
* @param seg_map facet partition index
* @tris[out] indexed triangles
*/
template<typename FacetSegmentMap>
void extract_mesh(FacetSegmentMap &seg_pmap, std::vector<int> &tris) {
compute_proxy_area(seg_pmap);
@@ -277,10 +292,20 @@ public:
pseudo_CDT(seg_pmap, tris);
}
/**
* Collect the anchors.
* @return vector of anchors
*/
std::vector<Anchor> collect_anchors() {
return anchors;
}
/**
* Collect the partition @a seg_pmap approximated borders.
* @tparam FacetSegmentMap `WritablePropertyMap` with `boost::graph_traits<Polyhedron>::face_handle` as key and `std::size_t` as value type
* @param seg_map facet partition index
* @return anchor indexes of each border
*/
template<typename FacetSegmentMap>
std::vector<std::vector<std::size_t> >
collect_borders(const FacetSegmentMap &seg_pmap) {
@@ -301,6 +326,10 @@ public:
}
private:
/**
* Random initialize proxies.
* @param initial_px number of proxies
*/
void random_seed(const std::size_t initial_px) {
proxies.clear();
std::size_t number_of_faces = num_faces(mesh);
@@ -322,6 +351,11 @@ private:
std::cerr << initial_px << ' ' << proxies.size() << std::endl;
}
/**
* Propagates the proxy seed facets and floods the whole mesh to minimize the fitting error.
* @tparam FacetSegmentMap `WritablePropertyMap` with `boost::graph_traits<Polyhedron>::face_handle` as key and `std::size_t` as value type
* @param[out] seg_map facet partition index
*/
template<typename FacetSegmentMap>
void flooding(FacetSegmentMap &seg_pmap) {
typedef std::multiset<FacetToIntegrate> CandidateSet;
@@ -365,6 +399,11 @@ private:
}
}
/**
* Calculates and updates the best fitting proxies of a given partition @a seg_pmap.
* @tparam FacetSegmentMap `WritablePropertyMap` with `boost::graph_traits<Polyhedron>::face_handle` as key and `std::size_t` as value type
* @param seg_map facet partition index
*/
template <typename FacetSegmentMap>
void fitting(FacetSegmentMap &seg_pmap) {
// update normal
@@ -411,7 +450,11 @@ private:
}
}
// insert proxy at the facet with the maximum fitting error in the proxy with maximum error
/**
* Inserts a proxy of a given partition @a seg_pmap at the furthest facet of the region with the maximum fitting error.
* @tparam FacetSegmentMap `WritablePropertyMap` with `boost::graph_traits<Polyhedron>::face_handle` as key and `std::size_t` as value type
* @param seg_map facet partition index
*/
template <typename FacetSegmentMap>
void insert_proxy(FacetSegmentMap &seg_pmap) {
std::vector<FT> px_error(proxies.size(), FT(0.0));
@@ -445,6 +488,11 @@ private:
proxies.push_back(new_px);
}
/**
* Finds the anchors of a given partition @a seg_pmap.
* @tparam FacetSegmentMap `WritablePropertyMap` with `boost::graph_traits<Polyhedron>::face_handle` as key and `std::size_t` as value type
* @param seg_map facet partition index
*/
template<typename FacetSegmentMap>
void find_anchors(FacetSegmentMap &seg_pmap) {
anchors.clear();
@@ -469,6 +517,11 @@ private:
}
}
/**
* Finds and approximates the edges connecting the anchors of a given partition @a seg_pmap.
* @tparam FacetSegmentMap `WritablePropertyMap` with `boost::graph_traits<Polyhedron>::face_handle` as key and `std::size_t` as value type
* @param seg_map facet partition index
*/
template<typename FacetSegmentMap>
void find_edges(FacetSegmentMap &seg_pmap) {
// tag all proxy border halfedges as candidate
@@ -512,7 +565,11 @@ private:
}
}
// add anchors to the borders with only 2 anchors
/**
* Adds anchors to the border cycles with only 2 anchors of a given partition @a seg_pmap.
* @tparam FacetSegmentMap `WritablePropertyMap` with `boost::graph_traits<Polyhedron>::face_handle` as key and `std::size_t` as value type
* @param seg_map facet partition index
*/
template<typename FacetSegmentMap>
void add_anchors(const FacetSegmentMap &seg_pmap) {
typedef typename std::vector<Border>::iterator BorderIterator;
@@ -575,6 +632,12 @@ private:
}
}
/**
* Runs the pseudo Constrained Delaunay Triangulation at each region of a given partition @a seg_pmap, and stores the extracted indexed triangles in @a tris.
* @tparam FacetSegmentMap `WritablePropertyMap` with `boost::graph_traits<Polyhedron>::face_handle` as key and `std::size_t` as value type
* @param seg_map facet partition index
* @param tris extracted tirangles, index of anchors
*/
template<typename FacetSegmentMap>
void pseudo_CDT(const FacetSegmentMap &seg_pmap,
std::vector<int> &tris) {
@@ -712,6 +775,11 @@ private:
}
}
/**
* Computes and updates the proxy centers of a given partition @a seg_pmap.
* @tparam FacetSegmentMap `WritablePropertyMap` with `boost::graph_traits<Polyhedron>::face_handle` as key and `std::size_t` as value type
* @param seg_map facet partition index
*/
template<typename FacetSegmentMap>
void compute_proxy_center(const FacetSegmentMap &seg_pmap) {
proxies_center = std::vector<Point>(proxies.size());
@@ -737,6 +805,11 @@ private:
}
}
/**
* Computes and updates the proxy areas of a given partition @a seg_pmap.
* @tparam FacetSegmentMap `WritablePropertyMap` with `boost::graph_traits<Polyhedron>::face_handle` as key and `std::size_t` as value type
* @param seg_map facet partition index
*/
template<typename FacetSegmentMap>
void compute_proxy_area(const FacetSegmentMap &seg_pmap) {
std::vector<FT> areas(proxies.size(), FT(0));
@@ -746,6 +819,11 @@ private:
proxies_area.swap(areas);
}
/**
* Tags all the region border halfedges of a given partition @a seg_pmap to CANDIDATE states.
* @tparam FacetSegmentMap `WritablePropertyMap` with `boost::graph_traits<Polyhedron>::face_handle` as key and `std::size_t` as value type
* @param seg_map facet partition index
*/
template<typename FacetSegmentMap>
void tag_halfedges_status(FacetSegmentMap &seg_pmap) {
BOOST_FOREACH(halfedge_descriptor h, halfedges(mesh)) {
@@ -758,7 +836,12 @@ private:
}
}
// walk along the proxy border to the first halfedge pointing to a vertex associated with an anchor
/**
* Walks along the region border to the first halfedge pointing to a vertex associated with an anchor of a given partition @a seg_pmap.
* @tparam FacetSegmentMap `WritablePropertyMap` with `boost::graph_traits<Polyhedron>::face_handle` as key and `std::size_t` as value type
* @param[in/out] he_start region border halfedge
* @param seg_map facet partition index
*/
template<typename FacetSegmentMap>
void walk_to_first_anchor(halfedge_descriptor &he_start, const FacetSegmentMap &seg_pmap) {
const halfedge_descriptor start_mark = he_start;
@@ -770,8 +853,13 @@ private:
}
}
// starting at a border halfedge pointing to a vertex associated with an anchor
// walk along the proxy border to the next anchor, which may be itself
/**
* Walks along the region border to the next anchor and records the path as @a chord of a given partition @a seg_pmap.
* @tparam FacetSegmentMap `WritablePropertyMap` with `boost::graph_traits<Polyhedron>::face_handle` as key and `std::size_t` as value type
* @param[in/out] he_start starting region border halfedge pointing to a vertex associated with an anchor
* @param[out] chord recorded path chord
* @param seg_map facet partition index
*/
template<typename FacetSegmentMap>
void walk_to_next_anchor(
halfedge_descriptor &he_start,
@@ -783,7 +871,12 @@ private:
} while (!is_anchor_attached(he_start));
}
// walk to next border halfedge, the input halfedge must be a border halfedge
/**
* Walks to next border halfedge of a given partition @a seg_pmap.
* @tparam FacetSegmentMap `WritablePropertyMap` with `boost::graph_traits<Polyhedron>::face_handle` as key and `std::size_t` as value type
* @param[in/out] he_start region border halfedge
* @param seg_map facet partition index
*/
template<typename FacetSegmentMap>
void walk_to_next_border_halfedge(halfedge_descriptor &he_start, const FacetSegmentMap &seg_pmap) {
const std::size_t px_idx = seg_pmap[face(he_start, mesh)];
@@ -795,8 +888,14 @@ private:
}
}
// subdivide a chord in range [chord_begin, chord_end)
// returns the number of anchors of the chord apart from the first one
/**
* Subdivides a chord recursively in range [@a chord_begin, @a chord_end) of a given partition @a seg_pmap.
* @tparam FacetSegmentMap `WritablePropertyMap` with `boost::graph_traits<Polyhedron>::face_handle` as key and `std::size_t` as value type
* @param chord_begin begin iterator of the chord
* @param chord_end end iterator of the chord
* @param seg_map facet partition index
* @return the number of anchors of the chord apart from the first one
*/
template<typename FacetSegmentMap>
std::size_t subdivide_chord(
const ChordVectorIterator &chord_begin,
@@ -878,13 +977,20 @@ private:
return 1;
}
// check if halfedge target vertex is attached with an anchor
/**
* Check if the target vertex of a halfedge is attached with an anchor.
* @param he halfedge
*/
bool is_anchor_attached(const halfedge_descriptor &he) {
return is_anchor_attached(target(he, mesh), vertex_status_pmap);
}
// check if a vertex is attached with an anchor
// suppose anchor index starts with 0
/**
* Check if a vertex is attached with an anchor.
* @tparam VertexAnchorIndexMap `WritablePropertyMap` with `boost::graph_traights<Polyhedron>::vertex_descriptor` as key and `std::size_t` as value type
* @param v vertex
* @param vertex_anchor_map vertex anchor index map
*/
template<typename VertexAnchorIndexMap>
bool is_anchor_attached(
const typename boost::property_traits<VertexAnchorIndexMap>::key_type &v,
@@ -892,7 +998,11 @@ private:
return vertex_anchor_map[v] >= 0;
}
// attach anchor to vertex
/**
* Attachs an anchor to the vertex, the position is area weighted average.
* @param vtx vertex
* @param px_set proxies around the vertex
*/
void attach_anchor(const vertex_descriptor &vtx, const std::set<std::size_t> &px_set) {
// construct an anchor from vertex and the incident proxies
FT avgx(0), avgy(0), avgz(0), sum_area(0);
@@ -913,7 +1023,11 @@ private:
anchors.push_back(Anchor(vtx, pos));
}
// attach anchor to the target vertex of the halfedge
/**
* Attachs an anchor to the target vertex of the halfedge.
* @param he halfedge
* @param px_set proxies around the target vertex
*/
void attach_anchor(const halfedge_descriptor &he, const std::set<std::size_t> &px_set) {
vertex_descriptor vtx = target(he, mesh);
attach_anchor(vtx, px_set);