facet -> face

This commit is contained in:
Lingjie Zhu 2018-07-14 22:37:09 +08:00
parent 4b03e9de89
commit 878e0f3ad0
1 changed files with 94 additions and 94 deletions

View File

@ -158,16 +158,16 @@ private:
FT area; FT area;
}; };
// The facet candidate to be queued. // The face candidate to be queued.
struct Facet_to_integrate { struct Face_to_integrate {
Facet_to_integrate(const face_descriptor f_, const std::size_t &px_, const FT &err_) Face_to_integrate(const face_descriptor f_, const std::size_t &px_, const FT &err_)
: f(f_), px(px_), err(err_) {} : f(f_), px(px_), err(err_) {}
bool operator<(const Facet_to_integrate &rhs) const { bool operator<(const Face_to_integrate &rhs) const {
return err > rhs.err; return err > rhs.err;
} }
face_descriptor f; // facet face_descriptor f; // face
std::size_t px; // proxy index std::size_t px; // proxy index
FT err; // fitting error FT err; // fitting error
}; };
@ -253,7 +253,7 @@ private:
Compute_scalar_product_3 scalar_product_functor; Compute_scalar_product_3 scalar_product_functor;
Construct_translated_point_3 translate_point_functor; Construct_translated_point_3 translate_point_functor;
// The facet proxy index map. // The face proxy index map.
Face_proxy_map m_fproxy_map; Face_proxy_map m_fproxy_map;
// The attached anchor index of a vertex. // The attached anchor index of a vertex.
Vertex_anchor_map m_vanchor_map; Vertex_anchor_map m_vanchor_map;
@ -563,18 +563,18 @@ public:
if (avg_error <= 0.0) { if (avg_error <= 0.0) {
// rare case on extremely regular geometry like a cube // rare case on extremely regular geometry like a cube
#ifdef CGAL_SURFACE_MESH_APPROXIMATION_DEBUG #ifdef CGAL_SURFACE_MESH_APPROXIMATION_DEBUG
std::cerr << "zero error, diffuse w.r.t. number of facets" << std::endl; std::cerr << "zero error, diffuse w.r.t. number of faces" << std::endl;
#endif #endif
const double avg_facet = const double avg_face =
static_cast<double>(num_faces(*m_ptm)) / static_cast<double>(num_proxies); static_cast<double>(num_faces(*m_ptm)) / static_cast<double>(num_proxies);
std::vector<double> px_size(m_proxies.size(), 0.0); std::vector<double> px_size(m_proxies.size(), 0.0);
BOOST_FOREACH(face_descriptor f, faces(*m_ptm)) BOOST_FOREACH(face_descriptor f, faces(*m_ptm))
px_size[get(m_fproxy_map, f)] += 1.0; px_size[get(m_fproxy_map, f)] += 1.0;
double residual = 0.0; double residual = 0.0;
for (std::size_t i = 0; i < m_proxies.size(); ++i) { for (std::size_t i = 0; i < m_proxies.size(); ++i) {
const double to_add = (residual + px_size[i]) / avg_facet; const double to_add = (residual + px_size[i]) / avg_face;
const double to_add_round_up = std::floor(to_add + 0.5); const double to_add_round_up = std::floor(to_add + 0.5);
residual = (to_add - to_add_round_up) * avg_facet; residual = (to_add - to_add_round_up) * avg_face;
num_to_add[i] = static_cast<std::size_t>(to_add_round_up); num_to_add[i] = static_cast<std::size_t>(to_add_round_up);
} }
} }
@ -671,7 +671,7 @@ public:
if (px_worst == px_enlarged || px_worst == px_merged) if (px_worst == px_enlarged || px_worst == px_merged)
return num_teleported; return num_teleported;
// teleport to a facet of the worst region // teleport to a face of the worst region
// update merged proxies // update merged proxies
std::list<face_descriptor> merged_patch; std::list<face_descriptor> merged_patch;
BOOST_FOREACH(face_descriptor f, faces(*m_ptm)) { BOOST_FOREACH(face_descriptor f, faces(*m_ptm)) {
@ -683,7 +683,7 @@ public:
} }
m_proxies[px_enlarged] = fit_proxy_from_patch(merged_patch, px_enlarged); m_proxies[px_enlarged] = fit_proxy_from_patch(merged_patch, px_enlarged);
// replace the merged proxy position to the newly teleported proxy // replace the merged proxy position to the newly teleported proxy
m_proxies[px_merged] = fit_proxy_from_facet(tele_to, px_merged); m_proxies[px_merged] = fit_proxy_from_face(tele_to, px_merged);
num_teleported++; num_teleported++;
// coarse re-fitting // coarse re-fitting
@ -726,7 +726,7 @@ public:
m_proxies.erase(m_proxies.begin() + px1); m_proxies.erase(m_proxies.begin() + px1);
for (std::size_t i = 0; i < m_proxies.size(); ++i) for (std::size_t i = 0; i < m_proxies.size(); ++i)
m_proxies[i].idx = i; m_proxies[i].idx = i;
// keep facet proxy map valid // keep face proxy map valid
BOOST_FOREACH(face_descriptor f, faces(*m_ptm)) { BOOST_FOREACH(face_descriptor f, faces(*m_ptm)) {
if (get(m_fproxy_map, f) > px1) if (get(m_fproxy_map, f) > px1)
put(m_fproxy_map, f, get(m_fproxy_map, f) - 1); put(m_fproxy_map, f, get(m_fproxy_map, f) - 1);
@ -755,9 +755,9 @@ public:
typedef std::pair<std::size_t, std::size_t> ProxyPair; typedef std::pair<std::size_t, std::size_t> ProxyPair;
typedef std::set<ProxyPair> MergedPair; typedef std::set<ProxyPair> MergedPair;
std::vector<std::list<face_descriptor> > px_facets(m_proxies.size()); std::vector<std::list<face_descriptor> > px_faces(m_proxies.size());
BOOST_FOREACH(face_descriptor f, faces(*m_ptm)) BOOST_FOREACH(face_descriptor f, faces(*m_ptm))
px_facets[get(m_fproxy_map, f)].push_back(f); px_faces[get(m_fproxy_map, f)].push_back(f);
// find best merge // find best merge
MergedPair merged_set; MergedPair merged_set;
@ -777,8 +777,8 @@ public:
merged_set.insert(ProxyPair(pxi, pxj)); merged_set.insert(ProxyPair(pxi, pxj));
// simulated merge // simulated merge
std::list<face_descriptor> merged_patch(px_facets[pxi]); std::list<face_descriptor> merged_patch(px_faces[pxi]);
BOOST_FOREACH(face_descriptor f, px_facets[pxj]) BOOST_FOREACH(face_descriptor f, px_faces[pxj])
merged_patch.push_back(f); merged_patch.push_back(f);
Proxy_wrapper pxw_tmp = fit_proxy_from_patch(merged_patch, CGAL_VSA_INVALID_TAG); Proxy_wrapper pxw_tmp = fit_proxy_from_patch(merged_patch, CGAL_VSA_INVALID_TAG);
@ -826,7 +826,7 @@ public:
BOOST_FOREACH(face_descriptor f, faces(*m_ptm)) BOOST_FOREACH(face_descriptor f, faces(*m_ptm))
if (get(m_fproxy_map, f) == px_idx) if (get(m_fproxy_map, f) == px_idx)
confined_area.push_back(f); confined_area.push_back(f);
// not enough facets to split // not enough faces to split
if (n > confined_area.size()) if (n > confined_area.size())
return false; return false;
@ -834,7 +834,7 @@ public:
std::vector<Proxy_wrapper> confined_proxies; std::vector<Proxy_wrapper> confined_proxies;
confined_proxies.push_back(m_proxies[px_idx]); confined_proxies.push_back(m_proxies[px_idx]);
// select seed facets in the confined area // select seed faces in the confined area
std::size_t count = 1; std::size_t count = 1;
BOOST_FOREACH(face_descriptor f, confined_area) { BOOST_FOREACH(face_descriptor f, confined_area) {
if (count >= n) if (count >= n)
@ -935,19 +935,19 @@ public:
/// \name Output /// \name Output
/// @{ /// @{
/*! /*!
* @brief Gets the facet-proxy index map. * @brief Gets the face-proxy index map.
* @tparam FacetProxyMap `WritablePropertyMap` with * @tparam FaceProxyMap `WritablePropertyMap` with
* `boost::graph_traits<TriangleMesh>::%face_descriptor` as key and `std::size_t` as value type * `boost::graph_traits<TriangleMesh>::%face_descriptor` as key and `std::size_t` as value type
* @param[out] face_proxy_map facet proxy index map * @param[out] face_proxy_map face proxy index map
*/ */
template <typename FacetProxyMap> template <typename FaceProxyMap>
void proxy_map(FacetProxyMap &face_proxy_map) const { void proxy_map(FaceProxyMap &face_proxy_map) const {
BOOST_FOREACH(face_descriptor f, faces(*m_ptm)) BOOST_FOREACH(face_descriptor f, faces(*m_ptm))
face_proxy_map[f] = get(m_fproxy_map, f); face_proxy_map[f] = get(m_fproxy_map, f);
} }
/*! /*!
* @brief Gets the facet region of the specified proxy. * @brief Gets the face region of the specified proxy.
* @tparam OutputIterator output iterator with `boost::graph_traits<TriangleMesh>::%face_descriptor` as value type * @tparam OutputIterator output iterator with `boost::graph_traits<TriangleMesh>::%face_descriptor` as value type
* @param px_idx proxy index * @param px_idx proxy index
* @param out output iterator * @param out output iterator
@ -1057,9 +1057,9 @@ private:
*/ */
std::size_t init_random(const std::size_t max_nb_of_proxies, std::size_t init_random(const std::size_t max_nb_of_proxies,
const std::size_t num_iterations) { const std::size_t num_iterations) {
// pick from current non seed facets randomly // pick from current non seed faces randomly
std::vector<face_descriptor> picked_seeds; std::vector<face_descriptor> picked_seeds;
if (random_pick_non_seed_facets(max_nb_of_proxies - m_proxies.size(), picked_seeds)) { if (random_pick_non_seed_faces(max_nb_of_proxies - m_proxies.size(), picked_seeds)) {
BOOST_FOREACH(face_descriptor f, picked_seeds) BOOST_FOREACH(face_descriptor f, picked_seeds)
add_one_proxy_at(f); add_one_proxy_at(f);
run(num_iterations); run(num_iterations);
@ -1131,9 +1131,9 @@ private:
const std::size_t nb_to_add = const std::size_t nb_to_add =
(nb_px * 2 > max_nb_of_proxies) ? max_nb_of_proxies - nb_px : nb_px; (nb_px * 2 > max_nb_of_proxies) ? max_nb_of_proxies - nb_px : nb_px;
// pick from current non seed facets randomly // pick from current non seed faces randomly
std::vector<face_descriptor> picked_seeds; std::vector<face_descriptor> picked_seeds;
if (!random_pick_non_seed_facets(nb_to_add, picked_seeds)) if (!random_pick_non_seed_faces(nb_to_add, picked_seeds))
return m_proxies.size(); return m_proxies.size();
BOOST_FOREACH(face_descriptor f, picked_seeds) BOOST_FOREACH(face_descriptor f, picked_seeds)
@ -1198,15 +1198,15 @@ private:
} }
/*! /*!
* @brief Partitions the area tagged with CGAL_VSA_INVALID_TAG with proxies, global facet proxy map is updated. * @brief Partitions the area tagged with CGAL_VSA_INVALID_TAG with proxies, global face proxy map is updated.
* Propagates the proxy seed facets and floods the tagged area to minimize the fitting error. * Propagates the proxy seed faces and floods the tagged area to minimize the fitting error.
* @tparam ProxyWrapperIterator forward iterator with Proxy_wrapper as value type * @tparam ProxyWrapperIterator forward iterator with Proxy_wrapper as value type
* @param beg iterator point to the first element * @param beg iterator point to the first element
* @param end iterator point to the one past the last element * @param end iterator point to the one past the last element
*/ */
template<typename ProxyWrapperIterator> template<typename ProxyWrapperIterator>
void partition(const ProxyWrapperIterator beg, const ProxyWrapperIterator end) { void partition(const ProxyWrapperIterator beg, const ProxyWrapperIterator end) {
std::priority_queue<Facet_to_integrate> facet_pqueue; std::priority_queue<Face_to_integrate> face_pqueue;
for (ProxyWrapperIterator pxw_itr = beg; pxw_itr != end; ++pxw_itr) { for (ProxyWrapperIterator pxw_itr = beg; pxw_itr != end; ++pxw_itr) {
face_descriptor f = pxw_itr->seed; face_descriptor f = pxw_itr->seed;
put(m_fproxy_map, f, pxw_itr->idx); put(m_fproxy_map, f, pxw_itr->idx);
@ -1214,21 +1214,21 @@ private:
BOOST_FOREACH(face_descriptor fadj, faces_around_face(halfedge(f, *m_ptm), *m_ptm)) { BOOST_FOREACH(face_descriptor fadj, faces_around_face(halfedge(f, *m_ptm), *m_ptm)) {
if (fadj != boost::graph_traits<TriangleMesh>::null_face() if (fadj != boost::graph_traits<TriangleMesh>::null_face()
&& get(m_fproxy_map, fadj) == CGAL_VSA_INVALID_TAG) { && get(m_fproxy_map, fadj) == CGAL_VSA_INVALID_TAG) {
facet_pqueue.push(Facet_to_integrate( face_pqueue.push(Face_to_integrate(
fadj, pxw_itr->idx, m_metric->compute_error(*m_ptm, fadj, pxw_itr->px))); fadj, pxw_itr->idx, m_metric->compute_error(*m_ptm, fadj, pxw_itr->px)));
} }
} }
} }
while (!facet_pqueue.empty()) { while (!face_pqueue.empty()) {
const Facet_to_integrate c = facet_pqueue.top(); const Face_to_integrate c = face_pqueue.top();
facet_pqueue.pop(); face_pqueue.pop();
if (get(m_fproxy_map, c.f) == CGAL_VSA_INVALID_TAG) { if (get(m_fproxy_map, c.f) == CGAL_VSA_INVALID_TAG) {
put(m_fproxy_map, c.f, c.px); put(m_fproxy_map, c.f, c.px);
BOOST_FOREACH(face_descriptor fadj, faces_around_face(halfedge(c.f, *m_ptm), *m_ptm)) { BOOST_FOREACH(face_descriptor fadj, faces_around_face(halfedge(c.f, *m_ptm), *m_ptm)) {
if (fadj != boost::graph_traits<TriangleMesh>::null_face() if (fadj != boost::graph_traits<TriangleMesh>::null_face()
&& get(m_fproxy_map, fadj) == CGAL_VSA_INVALID_TAG) { && get(m_fproxy_map, fadj) == CGAL_VSA_INVALID_TAG) {
facet_pqueue.push(Facet_to_integrate( face_pqueue.push(Face_to_integrate(
fadj, c.px, m_metric->compute_error(*m_ptm, fadj, m_proxies[c.px].px))); fadj, c.px, m_metric->compute_error(*m_ptm, fadj, m_proxies[c.px].px)));
} }
} }
@ -1245,14 +1245,14 @@ private:
*/ */
template<typename ProxyWrapperIterator> template<typename ProxyWrapperIterator>
void fit(const ProxyWrapperIterator beg, const ProxyWrapperIterator end, const CGAL::Sequential_tag &) { void fit(const ProxyWrapperIterator beg, const ProxyWrapperIterator end, const CGAL::Sequential_tag &) {
std::vector<std::list<face_descriptor> > px_facets(m_proxies.size()); std::vector<std::list<face_descriptor> > px_faces(m_proxies.size());
BOOST_FOREACH(face_descriptor f, faces(*m_ptm)) BOOST_FOREACH(face_descriptor f, faces(*m_ptm))
px_facets[get(m_fproxy_map, f)].push_back(f); px_faces[get(m_fproxy_map, f)].push_back(f);
// update proxy parameters and seed // update proxy parameters and seed
for (ProxyWrapperIterator pxw_itr = beg; pxw_itr != end; ++pxw_itr) { for (ProxyWrapperIterator pxw_itr = beg; pxw_itr != end; ++pxw_itr) {
const std::size_t px_idx = pxw_itr->idx; const std::size_t px_idx = pxw_itr->idx;
*pxw_itr = fit_proxy_from_patch(px_facets[px_idx], px_idx); *pxw_itr = fit_proxy_from_patch(px_faces[px_idx], px_idx);
} }
} }
@ -1266,23 +1266,23 @@ private:
*/ */
template<typename ProxyWrapperIterator> template<typename ProxyWrapperIterator>
void fit(const ProxyWrapperIterator beg, const ProxyWrapperIterator end, const CGAL::Parallel_tag &) { void fit(const ProxyWrapperIterator beg, const ProxyWrapperIterator end, const CGAL::Parallel_tag &) {
std::vector<std::list<face_descriptor> > px_facets(m_proxies.size()); std::vector<std::list<face_descriptor> > px_faces(m_proxies.size());
BOOST_FOREACH(face_descriptor f, faces(*m_ptm)) BOOST_FOREACH(face_descriptor f, faces(*m_ptm))
px_facets[get(m_fproxy_map, f)].push_back(f); px_faces[get(m_fproxy_map, f)].push_back(f);
// update proxy parameters and seed // update proxy parameters and seed
tbb::parallel_for(tbb::blocked_range<ProxyWrapperIterator>(beg, end), tbb::parallel_for(tbb::blocked_range<ProxyWrapperIterator>(beg, end),
[&](tbb::blocked_range<ProxyWrapperIterator> &r) { [&](tbb::blocked_range<ProxyWrapperIterator> &r) {
for (ProxyWrapperIterator pxw_itr = r.begin(); pxw_itr != r.end(); ++pxw_itr) { for (ProxyWrapperIterator pxw_itr = r.begin(); pxw_itr != r.end(); ++pxw_itr) {
const std::size_t px_idx = pxw_itr->idx; const std::size_t px_idx = pxw_itr->idx;
*pxw_itr = fit_proxy_from_patch(px_facets[px_idx], px_idx); *pxw_itr = fit_proxy_from_patch(px_faces[px_idx], px_idx);
} }
}); });
} }
#endif // CGAL_LINKED_WITH_TBB #endif // CGAL_LINKED_WITH_TBB
/*! /*!
* @brief Adds a proxy seed at the facet with the maximum fitting error. * @brief Adds a proxy seed at the face with the maximum fitting error.
* @return `true` add successfully, `false` otherwise * @return `true` add successfully, `false` otherwise
*/ */
bool add_to_furthest_proxy() { bool add_to_furthest_proxy() {
@ -1323,16 +1323,16 @@ private:
/*! /*!
* @brief Fits a new (wrapped) proxy from a region patch. * @brief Fits a new (wrapped) proxy from a region patch.
* 1. Compute proxy parameters from a list of facets. * 1. Compute proxy parameters from a list of faces.
* 2. Find proxy seed facet. * 2. Find proxy seed face.
* 3. Sum the proxy error. * 3. Sum the proxy error.
* @tparam FacetPatch container with `face_descriptor` as data type * @tparam FacePatch container with `face_descriptor` as data type
* @param px_patch proxy patch container * @param px_patch proxy patch container
* @param px_idx proxy index * @param px_idx proxy index
* @return fitted wrapped proxy * @return fitted wrapped proxy
*/ */
template<typename FacetPatch> template<typename FacePatch>
Proxy_wrapper fit_proxy_from_patch(const FacetPatch &px_patch, const std::size_t px_idx) { Proxy_wrapper fit_proxy_from_patch(const FacePatch &px_patch, const std::size_t px_idx) {
CGAL_assertion(!px_patch.empty()); CGAL_assertion(!px_patch.empty());
// use Proxy_fitting functor to fit proxy parameters // use Proxy_fitting functor to fit proxy parameters
@ -1355,25 +1355,25 @@ private:
} }
/*! /*!
* @brief Adds a proxy at facet f. * @brief Adds a proxy at face f.
* @param f where to the proxy is initialized from * @param f where to the proxy is initialized from
*/ */
void add_one_proxy_at(const face_descriptor f) { void add_one_proxy_at(const face_descriptor f) {
m_proxies.push_back(fit_proxy_from_facet(f, m_proxies.size())); m_proxies.push_back(fit_proxy_from_face(f, m_proxies.size()));
} }
/*! /*!
* @brief Fits a new (wrapped) proxy from a facet. * @brief Fits a new (wrapped) proxy from a face.
* 1. Compute proxy parameters from the facet. * 1. Compute proxy parameters from the face.
* 2. Set seed to this facet. * 2. Set seed to this face.
* 3. Update the proxy error. * 3. Update the proxy error.
* 4. Update proxy map. * 4. Update proxy map.
* @pre current facet proxy map is valid * @pre current face proxy map is valid
* @param face_descriptor facet * @param face_descriptor face
* @param px_idx proxy index * @param px_idx proxy index
* @return fitted wrapped proxy * @return fitted wrapped proxy
*/ */
Proxy_wrapper fit_proxy_from_facet(const face_descriptor f, const std::size_t px_idx) { Proxy_wrapper fit_proxy_from_face(const face_descriptor f, const std::size_t px_idx) {
// fit proxy parameters // fit proxy parameters
std::vector<face_descriptor> fvec(1, f); std::vector<face_descriptor> fvec(1, f);
const Proxy px = m_metric->fit_proxy(fvec, *m_ptm); const Proxy px = m_metric->fit_proxy(fvec, *m_ptm);
@ -1390,47 +1390,47 @@ private:
} }
/*! /*!
* @brief Picks a number of non-seed facets into an empty vector randomly. * @brief Picks a number of non-seed faces into an empty vector randomly.
* @param nb_requested requested number of facets * @param nb_requested requested number of faces
* @param[out] facets shuffled facets vector * @param[out] picked_faces shuffled faces vector
* @return `true` if requested number of facets are selected, `false` otherwise * @return `true` if requested number of faces are selected, `false` otherwise
*/ */
bool random_pick_non_seed_facets(const std::size_t nb_requested, bool random_pick_non_seed_faces(const std::size_t nb_requested,
std::vector<face_descriptor> &facets) { std::vector<face_descriptor> &picked_faces) {
if (nb_requested + m_proxies.size() >= num_faces(*m_ptm)) if (nb_requested + m_proxies.size() >= num_faces(*m_ptm))
return false; return false;
std::set<face_descriptor> seed_facets_set; std::set<face_descriptor> seed_faces_set;
BOOST_FOREACH(const Proxy_wrapper &pxw, m_proxies) BOOST_FOREACH(const Proxy_wrapper &pxw, m_proxies)
seed_facets_set.insert(pxw.seed); seed_faces_set.insert(pxw.seed);
const std::size_t nb_nsf = num_faces(*m_ptm) - m_proxies.size(); const std::size_t nb_nsf = num_faces(*m_ptm) - m_proxies.size();
std::vector<face_descriptor> non_seed_facets; std::vector<face_descriptor> non_seed_faces;
non_seed_facets.reserve(nb_nsf); non_seed_faces.reserve(nb_nsf);
BOOST_FOREACH(face_descriptor f, faces(*m_ptm)) { BOOST_FOREACH(face_descriptor f, faces(*m_ptm)) {
if (seed_facets_set.find(f) != seed_facets_set.end()) if (seed_faces_set.find(f) != seed_faces_set.end())
continue; continue;
non_seed_facets.push_back(f); non_seed_faces.push_back(f);
} }
// random shuffle first few facets // random shuffle first few faces
for (std::size_t i = 0; i < nb_requested; ++i) { for (std::size_t i = 0; i < nb_requested; ++i) {
// swap ith element with a random one // swap ith element with a random one
std::size_t r = static_cast<std::size_t>( std::size_t r = static_cast<std::size_t>(
static_cast<double>(std::rand()) / static_cast<double>(RAND_MAX) * static_cast<double>(std::rand()) / static_cast<double>(RAND_MAX) *
static_cast<double>(nb_nsf - 1)); static_cast<double>(nb_nsf - 1));
std::swap(non_seed_facets[i], non_seed_facets[r]); std::swap(non_seed_faces[i], non_seed_faces[r]);
} }
for (std::size_t i = 0; i < nb_requested; ++i) for (std::size_t i = 0; i < nb_requested; ++i)
facets.push_back(non_seed_facets[i]); picked_faces.push_back(non_seed_faces[i]);
return true; return true;
} }
/*! /*!
* @brief Initializes proxies from each connected component of the input mesh. * @brief Initializes proxies from each connected component of the input mesh.
* @note This function clears proxy vector and sets facet proxy map to initial state, * @note This function clears proxy vector and sets face proxy map to initial state,
* intended only for bootstrapping initialization. * intended only for bootstrapping initialization.
* Coarse approximation iteration is not performed, because it is inaccurate anyway * Coarse approximation iteration is not performed, because it is inaccurate anyway
* and may yield degenerate cases (e.g. a standard cube model). * and may yield degenerate cases (e.g. a standard cube model).
@ -1444,19 +1444,19 @@ private:
std::vector<std::list<face_descriptor> > cc_patches; std::vector<std::list<face_descriptor> > cc_patches;
bool if_all_visited = false; bool if_all_visited = false;
std::size_t cc_idx = 0; std::size_t cc_idx = 0;
face_descriptor seed_facet = *(faces(*m_ptm).first); face_descriptor seed_face = *(faces(*m_ptm).first);
while (!if_all_visited) { while (!if_all_visited) {
// use current seed facet to traverse the conneceted componnets // use current seed face to traverse the conneceted componnets
std::list<face_descriptor> cc_patch; std::list<face_descriptor> cc_patch;
cc_patch.push_back(seed_facet); cc_patch.push_back(seed_face);
std::stack<face_descriptor> fstack; std::stack<face_descriptor> fstack;
fstack.push(seed_facet); fstack.push(seed_face);
put(m_fproxy_map, seed_facet, cc_idx); put(m_fproxy_map, seed_face, cc_idx);
while (!fstack.empty()) { while (!fstack.empty()) {
face_descriptor active_facet = fstack.top(); face_descriptor active_face = fstack.top();
fstack.pop(); fstack.pop();
BOOST_FOREACH(face_descriptor fadj, BOOST_FOREACH(face_descriptor fadj,
faces_around_face(halfedge(active_facet, *m_ptm), *m_ptm)) { faces_around_face(halfedge(active_face, *m_ptm), *m_ptm)) {
if (fadj != boost::graph_traits<TriangleMesh>::null_face() if (fadj != boost::graph_traits<TriangleMesh>::null_face()
&& get(m_fproxy_map, fadj) == CGAL_VSA_INVALID_TAG) { && get(m_fproxy_map, fadj) == CGAL_VSA_INVALID_TAG) {
cc_patch.push_back(fadj); cc_patch.push_back(fadj);
@ -1472,7 +1472,7 @@ private:
if (get(m_fproxy_map, f) == CGAL_VSA_INVALID_TAG) { if (get(m_fproxy_map, f) == CGAL_VSA_INVALID_TAG) {
if_all_visited = false; if_all_visited = false;
++cc_idx; ++cc_idx;
seed_facet = f; seed_face = f;
break; break;
} }
} }
@ -1494,11 +1494,11 @@ private:
*/ */
void compute_proxy_planes(const bool if_pca_plane) { void compute_proxy_planes(const bool if_pca_plane) {
// fit proxy planes, areas, normals // fit proxy planes, areas, normals
std::vector<std::list<face_descriptor> > px_facets(m_proxies.size()); std::vector<std::list<face_descriptor> > px_faces(m_proxies.size());
BOOST_FOREACH(face_descriptor f, faces(*m_ptm)) BOOST_FOREACH(face_descriptor f, faces(*m_ptm))
px_facets[get(m_fproxy_map, f)].push_back(f); px_faces[get(m_fproxy_map, f)].push_back(f);
BOOST_FOREACH(const std::list<face_descriptor> &px_patch, px_facets) { BOOST_FOREACH(const std::list<face_descriptor> &px_patch, px_faces) {
Plane_3 fit_plane = if_pca_plane ? Plane_3 fit_plane = if_pca_plane ?
fit_plane_pca(px_patch.begin(), px_patch.end()) : fit_plane_pca(px_patch.begin(), px_patch.end()) :
fit_plane_area_averaged(px_patch.begin(), px_patch.end()); fit_plane_area_averaged(px_patch.begin(), px_patch.end());
@ -2045,20 +2045,20 @@ private:
} }
/*! /*!
* @brief Fits an area averaged plane from a range of facets. * @brief Fits an area averaged plane from a range of faces.
* @tparam FacetIterator face_descriptor container iterator * @tparam FaceIterator face_descriptor container iterator
* @param beg container begin * @param beg container begin
* @param end container end * @param end container end
* @return fitted plane * @return fitted plane
*/ */
template <typename FacetIterator> template <typename FaceIterator>
Plane_3 fit_plane_area_averaged(const FacetIterator &beg, const FacetIterator &end) { Plane_3 fit_plane_area_averaged(const FaceIterator &beg, const FaceIterator &end) {
CGAL_assertion(beg != end); CGAL_assertion(beg != end);
// area average normal and centroid // area average normal and centroid
Vector_3 norm = CGAL::NULL_VECTOR; Vector_3 norm = CGAL::NULL_VECTOR;
Vector_3 cent = CGAL::NULL_VECTOR; Vector_3 cent = CGAL::NULL_VECTOR;
FT sum_area(0.0); FT sum_area(0.0);
for (FacetIterator fitr = beg; fitr != end; ++fitr) { for (FaceIterator fitr = beg; fitr != end; ++fitr) {
const halfedge_descriptor he = halfedge(*fitr, *m_ptm); const halfedge_descriptor he = halfedge(*fitr, *m_ptm);
const Point_3 &p0 = m_vpoint_map[source(he, *m_ptm)]; const Point_3 &p0 = m_vpoint_map[source(he, *m_ptm)];
const Point_3 &p1 = m_vpoint_map[target(he, *m_ptm)]; const Point_3 &p1 = m_vpoint_map[target(he, *m_ptm)];
@ -2080,19 +2080,19 @@ private:
} }
/*! /*!
* @brief Fits a plane from a range of facets with PCA algorithm. * @brief Fits a plane from a range of faces with PCA algorithm.
* @tparam FacetIterator face_descriptor container iterator * @tparam FaceIterator face_descriptor container iterator
* @param beg container begin * @param beg container begin
* @param end container end * @param end container end
* @return fitted plane * @return fitted plane
*/ */
template <typename FacetIterator> template <typename FaceIterator>
Plane_3 fit_plane_pca(const FacetIterator &beg, const FacetIterator &end) { Plane_3 fit_plane_pca(const FaceIterator &beg, const FaceIterator &end) {
CGAL_assertion(beg != end); CGAL_assertion(beg != end);
typedef typename Geom_traits::Triangle_3 Triangle_3; typedef typename Geom_traits::Triangle_3 Triangle_3;
std::list<Triangle_3> tri_list; std::list<Triangle_3> tri_list;
for (FacetIterator fitr = beg; fitr != end; ++fitr) { for (FaceIterator fitr = beg; fitr != end; ++fitr) {
halfedge_descriptor he = halfedge(*fitr, *m_ptm); halfedge_descriptor he = halfedge(*fitr, *m_ptm);
const Point_3 &p0 = m_vpoint_map[source(he, *m_ptm)]; const Point_3 &p0 = m_vpoint_map[source(he, *m_ptm)];
const Point_3 &p1 = m_vpoint_map[target(he, *m_ptm)]; const Point_3 &p1 = m_vpoint_map[target(he, *m_ptm)];