mirror of https://github.com/CGAL/cgal
Add alpha TC + point set protection + another test to solve inconsistencies
Test: see check_and_solve_inconsistencies_by_filtering_simplices_out()
This commit is contained in:
parent
4016d0d247
commit
018ee66557
|
|
@ -6,6 +6,9 @@
|
|||
# define TBB_USE_THREADING_TOOL
|
||||
#endif
|
||||
|
||||
|
||||
#include <CGAL/Tangential_complex/protected_sets.h> // CJTODO TEST
|
||||
|
||||
#include <CGAL/assertions_behaviour.h>
|
||||
#include <CGAL/Epick_d.h>
|
||||
#include <CGAL/Tangential_complex.h>
|
||||
|
|
@ -36,14 +39,17 @@ const char * const BENCHMARK_SCRIPT_FILENAME = "benchmark_script.txt";
|
|||
typedef CGAL::Epick_d<CGAL::Dynamic_dimension_tag> Kernel;
|
||||
typedef Kernel::FT FT;
|
||||
typedef Kernel::Point_d Point;
|
||||
typedef Kernel::Vector_d Vector;
|
||||
typedef CGAL::Tangential_complex<
|
||||
Kernel, CGAL::Dynamic_dimension_tag,
|
||||
CGAL::Parallel_tag> TC;
|
||||
|
||||
//#define CGAL_TC_USE_ANOTHER_POINT_SET_FOR_TANGENT_SPACE_ESTIM
|
||||
//#define TC_PROTECT_POINT_SET_DELTA 0.003
|
||||
//#define JUST_BENCHMARK_SPATIAL_SEARCH // CJTODO: test
|
||||
//#define CHECK_IF_ALL_SIMPLICES_ARE_IN_THE_AMBIENT_DELAUNAY
|
||||
#define TC_INPUT_STRIDES 3 // only take one point every TC_INPUT_STRIDES points
|
||||
#define TC_NO_EXPORT
|
||||
//#define TC_INPUT_STRIDES 10 // only take one point every TC_INPUT_STRIDES points
|
||||
//#define TC_NO_EXPORT
|
||||
|
||||
#ifdef JUST_BENCHMARK_SPATIAL_SEARCH
|
||||
std::ofstream spatial_search_csv_file("benchmark_spatial_search.csv");
|
||||
|
|
@ -217,8 +223,10 @@ bool export_to_off(
|
|||
}
|
||||
|
||||
void make_tc(std::vector<Point> &points,
|
||||
TC::TS_container const& tangent_spaces, // can be empty
|
||||
int intrinsic_dim,
|
||||
double sparsity = 0.,
|
||||
bool sparsify = true,
|
||||
double sparsity = 0.01,
|
||||
bool perturb = true,
|
||||
bool add_high_dim_simpl = false,
|
||||
bool collapse = false,
|
||||
|
|
@ -226,6 +234,12 @@ void make_tc(std::vector<Point> &points,
|
|||
const char *input_name = "tc")
|
||||
{
|
||||
Kernel k;
|
||||
|
||||
if (sparsify && !tangent_spaces.empty())
|
||||
{
|
||||
std::cerr << "Error: cannot sparsify point set with pre-computed normals.\n";
|
||||
return;
|
||||
}
|
||||
|
||||
// CJTODO TEMP TEST
|
||||
//TC::Simplicial_complex compl;
|
||||
|
|
@ -275,14 +289,14 @@ void make_tc(std::vector<Point> &points,
|
|||
|
||||
CGAL_TC_SET_PERFORMANCE_DATA("Num_points_in_input", points.size());
|
||||
|
||||
#ifdef USE_ANOTHER_POINT_SET_FOR_TANGENT_SPACE_ESTIM
|
||||
#ifdef CGAL_TC_USE_ANOTHER_POINT_SET_FOR_TANGENT_SPACE_ESTIM
|
||||
std::vector<Point> points_not_sparse = points;
|
||||
#endif
|
||||
|
||||
//===========================================================================
|
||||
// Sparsify point set if requested
|
||||
//===========================================================================
|
||||
if (sparsity != 0.)
|
||||
if (sparsify)
|
||||
{
|
||||
std::size_t num_points_before = points.size();
|
||||
points = sparsify_point_set(k, points, sparsity*sparsity);
|
||||
|
|
@ -290,6 +304,27 @@ void make_tc(std::vector<Point> &points,
|
|||
<< num_points_before << " / " << points.size() << std::endl;
|
||||
}
|
||||
|
||||
#ifdef TC_PROTECT_POINT_SET_DELTA
|
||||
// CJTODO TEST
|
||||
# ifdef CGAL_TC_PROFILING
|
||||
Wall_clock_timer t_protection;
|
||||
# endif
|
||||
|
||||
std::vector<Point> points2;
|
||||
std::vector<int> dummy;
|
||||
std::vector<std::vector<int> > dummy2;
|
||||
landmark_choice_protected_delaunay(
|
||||
points, points.size(), points2, dummy, TC_PROTECT_POINT_SET_DELTA, dummy2, false, true);
|
||||
points = points2;
|
||||
|
||||
# ifdef CGAL_TC_PROFILING
|
||||
std::cerr << "Point set protected in " << t_protection.elapsed()
|
||||
<< " seconds." << std::endl;
|
||||
# endif
|
||||
|
||||
std::cerr << "Number of points after PROTECTION: " << points.size() << "\n";
|
||||
#endif
|
||||
|
||||
CGAL_TC_SET_PERFORMANCE_DATA("Sparsity", sparsity);
|
||||
CGAL_TC_SET_PERFORMANCE_DATA("Num_points", points.size());
|
||||
|
||||
|
|
@ -297,13 +332,18 @@ void make_tc(std::vector<Point> &points,
|
|||
// Compute Tangential Complex
|
||||
//===========================================================================
|
||||
|
||||
#ifdef USE_ANOTHER_POINT_SET_FOR_TANGENT_SPACE_ESTIM
|
||||
#ifdef CGAL_TC_USE_ANOTHER_POINT_SET_FOR_TANGENT_SPACE_ESTIM
|
||||
TC tc(points.begin(), points.end(), sparsity, intrinsic_dim,
|
||||
points_not_sparse.begin(), points_not_sparse.end(), k);
|
||||
#else
|
||||
TC tc(points.begin(), points.end(), sparsity, intrinsic_dim, k);
|
||||
#endif
|
||||
|
||||
if (!tangent_spaces.empty())
|
||||
{
|
||||
tc.set_tangent_planes(tangent_spaces);
|
||||
}
|
||||
|
||||
double init_time = t.elapsed(); t.reset();
|
||||
|
||||
tc.compute_tangential_complex();
|
||||
|
|
@ -356,7 +396,7 @@ void make_tc(std::vector<Point> &points,
|
|||
//===========================================================================
|
||||
t.reset();
|
||||
double export_before_time =
|
||||
(export_to_off(tc, input_name_stripped, "_BEFORE_FIX") ? t.elapsed() : -1);
|
||||
(export_to_off(tc, input_name_stripped, "_INITIAL_TC") ? t.elapsed() : -1);
|
||||
t.reset();
|
||||
|
||||
unsigned int num_perturb_steps = 0;
|
||||
|
|
@ -406,6 +446,9 @@ void make_tc(std::vector<Point> &points,
|
|||
CGAL_TC_SET_PERFORMANCE_DATA("Final_num_inconsistent_local_tr", "N/A");
|
||||
}
|
||||
|
||||
// CJTODO TEST
|
||||
//tc.check_and_solve_inconsistencies_by_filtering_simplices_out();
|
||||
|
||||
int max_dim = -1;
|
||||
double fix2_time = -1;
|
||||
double export_after_fix2_time = -1.;
|
||||
|
|
@ -447,14 +490,14 @@ void make_tc(std::vector<Point> &points,
|
|||
|
||||
complex.display_stats();
|
||||
|
||||
// Export to OFF with higher-dim simplices colored
|
||||
std::set<std::set<std::size_t> > higher_dim_simplices;
|
||||
// CJTODO TEMP: Export to OFF with higher-dim simplices colored
|
||||
/*std::set<std::set<std::size_t> > higher_dim_simplices;
|
||||
complex.get_simplices_matching_test(
|
||||
Test_dim(intrinsic_dim + 1),
|
||||
std::inserter(higher_dim_simplices, higher_dim_simplices.begin()));
|
||||
export_to_off(
|
||||
tc, input_name_stripped, "_BEFORE_COLLAPSE", false, &complex,
|
||||
&higher_dim_simplices);
|
||||
&higher_dim_simplices);*/
|
||||
|
||||
//===========================================================================
|
||||
// Collapse
|
||||
|
|
@ -484,18 +527,23 @@ void make_tc(std::vector<Point> &points,
|
|||
//===========================================================================
|
||||
// Export to OFF
|
||||
//===========================================================================
|
||||
t.reset();
|
||||
bool exported = export_to_off(
|
||||
tc, input_name_stripped, "_AFTER_COLLAPSE", false, &complex,
|
||||
&wrong_dim_simplices, &wrong_number_of_cofaces_simplices,
|
||||
&unconnected_stars_simplices);
|
||||
std::cerr
|
||||
<< " OFF colors:" << std::endl
|
||||
<< " * Red: wrong dim simplices" << std::endl
|
||||
<< " * Green: wrong number of cofaces simplices" << std::endl
|
||||
<< " * Blue: not-connected stars" << std::endl;
|
||||
double export_after_collapse_time = (exported ? t.elapsed() : -1);
|
||||
t.reset();
|
||||
|
||||
double export_after_collapse_time = -1.;
|
||||
if (collapse)
|
||||
{
|
||||
t.reset();
|
||||
bool exported = export_to_off(
|
||||
tc, input_name_stripped, "_AFTER_COLLAPSE", false, &complex,
|
||||
&wrong_dim_simplices, &wrong_number_of_cofaces_simplices,
|
||||
&unconnected_stars_simplices);
|
||||
std::cerr
|
||||
<< " OFF colors:" << std::endl
|
||||
<< " * Red: wrong dim simplices" << std::endl
|
||||
<< " * Green: wrong number of cofaces simplices" << std::endl
|
||||
<< " * Blue: not-connected stars" << std::endl;
|
||||
double export_after_collapse_time = (exported ? t.elapsed() : -1.);
|
||||
t.reset();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
// Display info
|
||||
|
|
@ -550,7 +598,7 @@ int main()
|
|||
# ifdef _DEBUG
|
||||
int num_threads = 1;
|
||||
# else
|
||||
int num_threads = 10;
|
||||
int num_threads = 8;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
|
@ -608,6 +656,7 @@ int main()
|
|||
std::size_t num_points;
|
||||
int ambient_dim;
|
||||
int intrinsic_dim;
|
||||
char sparsify;
|
||||
double sparsity;
|
||||
char perturb, add_high_dim_simpl, collapse;
|
||||
double time_limit_for_perturb;
|
||||
|
|
@ -619,6 +668,7 @@ int main()
|
|||
sstr >> num_points;
|
||||
sstr >> ambient_dim;
|
||||
sstr >> intrinsic_dim;
|
||||
sstr >> sparsify;
|
||||
sstr >> sparsity;
|
||||
sstr >> perturb;
|
||||
sstr >> add_high_dim_simpl;
|
||||
|
|
@ -657,6 +707,7 @@ int main()
|
|||
#endif
|
||||
|
||||
std::vector<Point> points;
|
||||
TC::TS_container tangent_spaces;
|
||||
|
||||
if (input == "generate_moment_curve")
|
||||
{
|
||||
|
|
@ -728,8 +779,9 @@ int main()
|
|||
}
|
||||
else
|
||||
{
|
||||
load_points_from_file<Point>(
|
||||
input, std::back_inserter(points)/*, 600*/);
|
||||
load_points_from_file<Kernel, typename TC::Tangent_space_basis>(
|
||||
input, std::back_inserter(points),
|
||||
std::back_inserter(tangent_spaces)/*, 600*/);
|
||||
}
|
||||
|
||||
#ifdef CGAL_TC_PROFILING
|
||||
|
|
@ -747,9 +799,9 @@ int main()
|
|||
<< " points.\n"
|
||||
<< "****************************************\n";
|
||||
#endif
|
||||
make_tc(points, intrinsic_dim, sparsity, // strided: CJTODO TEMP
|
||||
perturb=='Y', add_high_dim_simpl=='Y', collapse=='Y',
|
||||
time_limit_for_perturb, input.c_str());
|
||||
make_tc(points, tangent_spaces, intrinsic_dim, sparsify=='Y',
|
||||
sparsity, perturb=='Y', add_high_dim_simpl=='Y',
|
||||
collapse=='Y', time_limit_for_perturb, input.c_str());
|
||||
|
||||
std::cerr << "TC #" << i++ << " done." << std::endl;
|
||||
std::cerr << std::endl << "---------------------------------"
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@
|
|||
#include <CGAL/Delaunay_triangulation.h>
|
||||
#include <CGAL/Combination_enumerator.h>
|
||||
#include <CGAL/point_generators_d.h>
|
||||
#include <CGAL/QP_models.h>
|
||||
#include <CGAL/QP_functions.h>
|
||||
|
||||
# include <CGAL/Mesh_3/Profiling_tools.h>
|
||||
|
||||
|
|
@ -47,6 +49,8 @@
|
|||
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/iterator/transform_iterator.hpp>
|
||||
#include <boost/range/adaptor/transformed.hpp>
|
||||
#include <boost/range/counting_range.hpp>
|
||||
#include <boost/math/special_functions/factorials.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
|
@ -65,6 +69,12 @@
|
|||
# include <tbb/mutex.h>
|
||||
#endif
|
||||
|
||||
// choose exact integral type for QP solver
|
||||
// (Gmpzf is not thread-safe)
|
||||
#include <CGAL/MP_Float.h>
|
||||
typedef CGAL::MP_Float ET;
|
||||
//#define CGAL_QP_NO_ASSERTIONS // CJTODO: NECESSARY? http://doc.cgal.org/latest/QP_solver/group__PkgQPSolverFunctions.html#ga1fefbd0436aca0e281f88e8e6cd8eb74
|
||||
|
||||
//#define CGAL_TC_EXPORT_NORMALS // Only for 3D surfaces (k=2, d=3)
|
||||
|
||||
//static std::ofstream csv_stream("output/stats.csv"); // CJTODO TEMP
|
||||
|
|
@ -98,7 +108,7 @@ private:
|
|||
|
||||
/// The class Tangential_complex represents a tangential complex
|
||||
template <
|
||||
typename Kernel_, // ambiant dimension
|
||||
typename Kernel_, // ambiant kernel
|
||||
typename DimensionTag, // intrinsic dimension
|
||||
typename Concurrency_tag = CGAL::Parallel_tag,
|
||||
#ifdef CGAL_ALPHA_TC
|
||||
|
|
@ -149,9 +159,6 @@ class Tangential_complex
|
|||
typedef typename Triangulation::Full_cell_handle Tr_full_cell_handle;
|
||||
typedef typename Tr_traits::Vector_d Tr_vector;
|
||||
|
||||
typedef Basis<K> Tangent_space_basis;
|
||||
typedef Basis<K> Orthogonal_space_basis;
|
||||
|
||||
typedef std::vector<Point> Points;
|
||||
#if defined(CGAL_LINKED_WITH_TBB) && defined(CGAL_TC_GLOBAL_REFRESH)
|
||||
typedef tbb::mutex Mutex_for_perturb;
|
||||
|
|
@ -212,11 +219,14 @@ class Tangential_complex
|
|||
};
|
||||
|
||||
public:
|
||||
typedef typename std::vector<Tangent_space_basis> TS_container;
|
||||
typedef typename std::vector<Orthogonal_space_basis> OS_container;
|
||||
typedef Basis<K> Tangent_space_basis;
|
||||
typedef Basis<K> Orthogonal_space_basis;
|
||||
typedef std::vector<Tangent_space_basis> TS_container;
|
||||
typedef std::vector<Orthogonal_space_basis> OS_container;
|
||||
|
||||
private:
|
||||
typedef typename std::vector<Tr_and_VH> Tr_container;
|
||||
typedef typename std::vector<Vector> Vectors;
|
||||
typedef std::vector<Tr_and_VH> Tr_container;
|
||||
typedef std::vector<Vector> Vectors;
|
||||
|
||||
// An Incident_simplex is the list of the vertex indices
|
||||
// except the center vertex
|
||||
|
|
@ -262,6 +272,22 @@ private:
|
|||
{
|
||||
return vh->point();
|
||||
}
|
||||
struct First_of_pair
|
||||
{
|
||||
template<typename> struct result;
|
||||
|
||||
template <typename F, typename Pair>
|
||||
struct result<F(Pair)>
|
||||
{
|
||||
typedef typename boost::remove_reference<Pair>::type::first_type const& type;
|
||||
};
|
||||
|
||||
template <typename Pair>
|
||||
typename Pair::first_type const& operator()(Pair const& pair) const
|
||||
{
|
||||
return pair.first;
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
typedef Tangential_complex_::Simplicial_complex Simplicial_complex;
|
||||
|
|
@ -270,7 +296,7 @@ public:
|
|||
template <typename InputIterator>
|
||||
Tangential_complex(InputIterator first, InputIterator last,
|
||||
double sparsity, int intrinsic_dimension,
|
||||
#ifdef USE_ANOTHER_POINT_SET_FOR_TANGENT_SPACE_ESTIM
|
||||
#ifdef CGAL_TC_USE_ANOTHER_POINT_SET_FOR_TANGENT_SPACE_ESTIM
|
||||
InputIterator first_for_tse, InputIterator last_for_tse,
|
||||
#endif
|
||||
const K &k = K()
|
||||
|
|
@ -295,7 +321,7 @@ public:
|
|||
#ifdef CGAL_TC_EXPORT_NORMALS
|
||||
, m_orth_spaces(m_points.size(), Orthogonal_space_basis())
|
||||
#endif
|
||||
#ifdef USE_ANOTHER_POINT_SET_FOR_TANGENT_SPACE_ESTIM
|
||||
#ifdef CGAL_TC_USE_ANOTHER_POINT_SET_FOR_TANGENT_SPACE_ESTIM
|
||||
, m_points_for_tse(first_for_tse, last_for_tse)
|
||||
, m_points_ds_for_tse(m_points_for_tse)
|
||||
#endif
|
||||
|
|
@ -581,9 +607,10 @@ public:
|
|||
<< stats_before.second
|
||||
<< " (" << 100. * stats_before.second / stats_before.first << "%)"
|
||||
<< std::endl
|
||||
<< " * Num inconsistent stars: "
|
||||
/*<< " * Num inconsistent stars: "
|
||||
<< num_inconsistent_local_tr
|
||||
<< " (" << 100. * num_inconsistent_local_tr / m_points.size() << "%)"
|
||||
<< std::endl*/
|
||||
<< std::endl
|
||||
<< " * AFTER fix_inconsistencies_using_perturbation:" << std::endl
|
||||
<< " - Total number of simplices in stars (incl. duplicates): "
|
||||
|
|
@ -752,7 +779,46 @@ public:
|
|||
<< 100. * stats_after.second / stats_after.first << "%"
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
|
||||
// Returns true if some inconsistencies were found
|
||||
bool check_and_solve_inconsistencies_by_filtering_simplices_out()
|
||||
{
|
||||
// CJTODO TEMP
|
||||
std::pair<std::size_t, std::size_t> stats_before =
|
||||
number_of_inconsistent_simplices(false);
|
||||
std::cerr << "BEFORE check_and_solve_inconsistencies_by_filtering_simplices_out():\n"
|
||||
<< " - Total number of simplices in stars (incl. duplicates): "
|
||||
<< stats_before.first << std::endl
|
||||
<< " - Num inconsistent simplices in stars (incl. duplicates): "
|
||||
<< stats_before.second << std::endl
|
||||
<< " - Percentage of inconsistencies: "
|
||||
<< 100. * stats_before.second / stats_before.first << "%"
|
||||
<< std::endl;
|
||||
|
||||
bool inconsistencies_found = false;
|
||||
|
||||
// CJTODO: parallel_for???
|
||||
for (std::size_t idx = 0 ; idx < m_triangulations.size() ; ++idx)
|
||||
{
|
||||
if (filter_inconsistent_simplices_in_a_local_triangulation(idx))
|
||||
inconsistencies_found = true;
|
||||
}
|
||||
|
||||
// CJTODO TEMP
|
||||
std::pair<std::size_t, std::size_t> stats_after =
|
||||
number_of_inconsistent_simplices(false);
|
||||
std::cerr << "AFTER check_and_solve_inconsistencies_by_filtering_simplices_out():\n"
|
||||
<< " - Total number of simplices in stars (incl. duplicates): "
|
||||
<< stats_after.first << std::endl
|
||||
<< " - Num inconsistent simplices in stars (incl. duplicates): "
|
||||
<< stats_after.second << std::endl
|
||||
<< " - Percentage of inconsistencies: "
|
||||
<< 100. * stats_after.second / stats_after.first << "%"
|
||||
<< std::endl;
|
||||
|
||||
return inconsistencies_found;
|
||||
}
|
||||
|
||||
|
||||
#ifdef CGAL_ALPHA_TC
|
||||
private:
|
||||
|
|
@ -804,21 +870,71 @@ private:
|
|||
// star(p) does not contain "s"
|
||||
std::size_t p = *it_p;
|
||||
|
||||
// Compute the intersection between aff(Voronoi_cell(s)) and Tq
|
||||
boost::optional<Tr_bare_point> intersection =
|
||||
compute_aff_of_voronoi_face_and_tangent_subspace_intersection(
|
||||
boost::optional<Tr_bare_point> intersection;
|
||||
|
||||
// If we know the intersection between Tq and voronoi(s) is a point
|
||||
// I.e. dim(Tq) + dim(V(full_simplex)) = D
|
||||
// <=> dim(Tq) = dim(full_simplex)
|
||||
if (q_tr.current_dimension() == s.size())
|
||||
{
|
||||
// Compute the intersection between aff(Voronoi_cell(s)) and Tq
|
||||
// Note that the computation in done in the sub-space defined by Tq
|
||||
intersection =
|
||||
compute_aff_of_voronoi_face_and_tangent_subspace_intersection(
|
||||
q_tr.current_dimension(),
|
||||
project_points_and_compute_weights(
|
||||
full_simplex, m_tangent_spaces[i], q_tr.geom_traits()),
|
||||
m_tangent_spaces[i],
|
||||
q_tr.geom_traits());
|
||||
|
||||
// CJTODO: replace with an assertion?
|
||||
if (!intersection)
|
||||
{
|
||||
std::cerr << "ERROR fill_pqueues_for_alpha_tc: "
|
||||
"aff(Voronoi_cell(s)) and Tq do not intersect.\n";
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "***************** Intersection is not a point ********************\n"; // CJTODO TEMP
|
||||
// Compute the intersection between Voronoi_cell(s) and Tq
|
||||
// We need Q, i.e. the vertices which are common neighbors of all
|
||||
// vertices of full_simplex in the Delaunay triangulation, but we
|
||||
// don't have, so we use the 5^d nearest neighbors instead
|
||||
int num_neighbors_for_Q_approx = std::pow(
|
||||
BASE_VALUE_FOR_ALPHA_TC_NEIGHBORHOOD, m_intrinsic_dim);
|
||||
const Point center_pt = compute_perturbed_point(p);
|
||||
KNS_range ins_range = m_points_ds.query_ANN(
|
||||
center_pt, num_neighbors_for_Q_approx);
|
||||
|
||||
// CJTODO: optimize that, use a vector!
|
||||
std::set<std::size_t> Q(
|
||||
boost::make_counting_iterator(std::size_t(0)),
|
||||
boost::make_counting_iterator(m_points.size()));
|
||||
for (auto i : full_simplex)
|
||||
Q.erase(i);
|
||||
|
||||
intersection =
|
||||
compute_voronoi_face_and_tangent_subspace_intersection(
|
||||
q_tr.current_dimension(),
|
||||
project_points_and_compute_weights(
|
||||
full_simplex, m_tangent_spaces[i], q_tr.geom_traits()),
|
||||
full_simplex, m_tangent_spaces[i], q_tr.geom_traits()),
|
||||
project_points_and_compute_weights(
|
||||
Q,
|
||||
//boost::counting_range(std::size_t(0), m_points.size() - 1),
|
||||
//boost::adaptors::transform(ins_range, First_of_pair()),
|
||||
m_tangent_spaces[i], q_tr.geom_traits()),
|
||||
m_tangent_spaces[i],
|
||||
q_tr.geom_traits());
|
||||
|
||||
// CJTODO: replace with an assertion?
|
||||
if (!intersection)
|
||||
{
|
||||
std::cerr << "ERROR fill_pqueues_for_alpha_tc: "
|
||||
"aff(Voronoi_cell(s)) and Tq do not intersect.\n";
|
||||
continue;
|
||||
// CJTODO: replace with an assertion?
|
||||
if (!intersection)
|
||||
{
|
||||
std::cerr << "ERROR fill_pqueues_for_alpha_tc: "
|
||||
"Voronoi_cell(s) and Tq do not intersect.\n";
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// The following computations are done in the Euclidian space
|
||||
|
|
@ -1436,6 +1552,205 @@ private:
|
|||
return *s.rbegin() == std::numeric_limits<std::size_t>::max();
|
||||
}
|
||||
|
||||
// Output: "triangulation" is a Regular Triangulation containing at least the
|
||||
// star of "center_pt"
|
||||
// Returns the handle of the center vertex
|
||||
Tr_vertex_handle compute_star(
|
||||
std::size_t i, const Point ¢er_pt, const Tangent_space_basis &tsb,
|
||||
Triangulation &triangulation, bool verbose = false)
|
||||
{
|
||||
int tangent_space_dim = tsb.dimension();
|
||||
const Tr_traits &local_tr_traits = triangulation.geom_traits();
|
||||
Tr_vertex_handle center_vertex;
|
||||
|
||||
// Kernel functor & objects
|
||||
typename K::Squared_distance_d k_sqdist = m_k.squared_distance_d_object();
|
||||
|
||||
// Triangulation's traits functor & objects
|
||||
typename Tr_traits::Point_weight_d point_weight =
|
||||
local_tr_traits.point_weight_d_object();
|
||||
typename Tr_traits::Power_center_d power_center =
|
||||
local_tr_traits.power_center_d_object();
|
||||
|
||||
//***************************************************
|
||||
// Build a minimal triangulation in the tangent space
|
||||
// (we only need the star of p)
|
||||
//***************************************************
|
||||
|
||||
// Insert p
|
||||
Tr_point proj_wp;
|
||||
if (i == tsb.origin())
|
||||
{
|
||||
// Insert {(0, 0, 0...), m_weights[i]}
|
||||
proj_wp = local_tr_traits.construct_weighted_point_d_object()(
|
||||
local_tr_traits.construct_point_d_object()(tangent_space_dim, ORIGIN),
|
||||
m_weights[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
const Weighted_point& wp = compute_perturbed_weighted_point(i);
|
||||
proj_wp = project_point_and_compute_weight(wp, tsb, local_tr_traits);
|
||||
}
|
||||
|
||||
center_vertex = triangulation.insert(proj_wp);
|
||||
center_vertex->data() = i;
|
||||
if (verbose)
|
||||
std::cerr << "* Inserted point #" << i << std::endl;
|
||||
|
||||
#ifdef CGAL_TC_VERY_VERBOSE
|
||||
std::size_t num_attempts_to_insert_points = 1;
|
||||
std::size_t num_inserted_points = 1;
|
||||
#endif
|
||||
//const int NUM_NEIGHBORS = 150;
|
||||
//KNS_range ins_range = m_points_ds.query_ANN(center_pt, NUM_NEIGHBORS);
|
||||
INS_range ins_range = m_points_ds.query_incremental_ANN(center_pt);
|
||||
|
||||
// While building the local triangulation, we keep the radius
|
||||
// of the sphere "star sphere" centered at "center_vertex"
|
||||
// and which contains all the
|
||||
// circumspheres of the star of "center_vertex"
|
||||
boost::optional<FT> squared_star_sphere_radius_plus_margin;
|
||||
|
||||
#ifdef CGAL_ALPHA_TC
|
||||
/*FT max_absolute_alpha = tsb.max_absolute_alpha();
|
||||
// "2*m_half_sparsity" because both points can be perturbed
|
||||
FT max_sqdist_to_tangent_space = (max_absolute_alpha == FT(0) ?
|
||||
FT(0) : CGAL::square(2*max_absolute_alpha + 2*m_half_sparsity));*/
|
||||
std::size_t number_of_attempts_to_insert_points = 0;
|
||||
const std::size_t MAX_NUM_INSERTED_POINTS =
|
||||
tsb.num_thickening_vectors() > 0 ?
|
||||
static_cast<std::size_t>(std::pow(BASE_VALUE_FOR_ALPHA_TC_NEIGHBORHOOD, /*tsb.dimension()*/m_intrinsic_dim))
|
||||
: std::numeric_limits<std::size_t>::max();
|
||||
#endif
|
||||
|
||||
// Insert points until we find a point which is outside "star shere"
|
||||
for (INS_iterator nn_it = ins_range.begin() ;
|
||||
nn_it != ins_range.end() ;
|
||||
++nn_it)
|
||||
{
|
||||
#ifdef CGAL_ALPHA_TC
|
||||
++number_of_attempts_to_insert_points;
|
||||
/*if (number_of_attempts_to_insert_points > MAX_NUM_INSERTED_POINTS)
|
||||
break;*/
|
||||
#endif
|
||||
|
||||
std::size_t neighbor_point_idx = nn_it->first;
|
||||
|
||||
// ith point = p, which is already inserted
|
||||
if (neighbor_point_idx != i)
|
||||
{
|
||||
// No need to lock the Mutex_for_perturb here since this will not be
|
||||
// called while other threads are perturbing the positions
|
||||
Point neighbor_pt;
|
||||
FT neighbor_weight;
|
||||
compute_perturbed_weighted_point(
|
||||
neighbor_point_idx, neighbor_pt, neighbor_weight);
|
||||
|
||||
if (squared_star_sphere_radius_plus_margin
|
||||
&& k_sqdist(center_pt, neighbor_pt)
|
||||
> *squared_star_sphere_radius_plus_margin)
|
||||
break;
|
||||
|
||||
Tr_point proj_pt = project_point_and_compute_weight(
|
||||
neighbor_pt, neighbor_weight, tsb,
|
||||
local_tr_traits);
|
||||
|
||||
#ifdef CGAL_ALPHA_TC
|
||||
/*for (int i = 0 ; i < tsb.num_thickening_vectors() ; ++i)
|
||||
{
|
||||
FT c = coord(proj_pt, m_intrinsic_dim + i);
|
||||
if (c > 2.5*tsb.alpha_plus(i) + 2*m_half_sparsity //CJTODO: il faut 2*tsb.alpha_plus(i)
|
||||
|| c < 2.5*tsb.alpha_minus(i) - 2*m_half_sparsity) //CJTODO: il faut 2*tsb.alpha_minus(i)
|
||||
{
|
||||
goto end_of_insert_loop; // "continue" in n-2 for-loop
|
||||
}
|
||||
|
||||
}*/
|
||||
/*if (max_sqdist_to_tangent_space != FT(0)
|
||||
&& center_to_nbor_sqdist > max_sqdist_to_tangent_space)
|
||||
break;*/
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef CGAL_TC_VERY_VERBOSE
|
||||
++num_attempts_to_insert_points;
|
||||
#endif
|
||||
|
||||
|
||||
Tr_vertex_handle vh = triangulation.insert_if_in_star(proj_pt, center_vertex);
|
||||
//Tr_vertex_handle vh = triangulation.insert(proj_pt);
|
||||
if (vh != Tr_vertex_handle())
|
||||
{
|
||||
#ifdef CGAL_TC_VERY_VERBOSE
|
||||
++num_inserted_points;
|
||||
#endif
|
||||
if (verbose)
|
||||
std::cerr << "* Inserted point #" << neighbor_point_idx << std::endl;
|
||||
|
||||
vh->data() = neighbor_point_idx;
|
||||
|
||||
// Let's recompute squared_star_sphere_radius_plus_margin
|
||||
if (triangulation.current_dimension() >= tangent_space_dim)
|
||||
{
|
||||
squared_star_sphere_radius_plus_margin = boost::none;
|
||||
// Get the incident cells and look for the biggest circumsphere
|
||||
std::vector<Tr_full_cell_handle> incident_cells;
|
||||
triangulation.incident_full_cells(
|
||||
center_vertex,
|
||||
std::back_inserter(incident_cells));
|
||||
for (typename std::vector<Tr_full_cell_handle>::iterator cit =
|
||||
incident_cells.begin(); cit != incident_cells.end(); ++cit)
|
||||
{
|
||||
Tr_full_cell_handle cell = *cit;
|
||||
if (triangulation.is_infinite(cell))
|
||||
{
|
||||
squared_star_sphere_radius_plus_margin = boost::none;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
Tr_point c = power_center(
|
||||
boost::make_transform_iterator(
|
||||
cell->vertices_begin(),
|
||||
vertex_handle_to_point<Tr_point, Tr_vertex_handle>),
|
||||
boost::make_transform_iterator(
|
||||
cell->vertices_end(),
|
||||
vertex_handle_to_point<Tr_point, Tr_vertex_handle>));
|
||||
|
||||
FT sq_power_sphere_diam = 4 * point_weight(c);
|
||||
|
||||
if (!squared_star_sphere_radius_plus_margin
|
||||
|| sq_power_sphere_diam >
|
||||
*squared_star_sphere_radius_plus_margin)
|
||||
{
|
||||
squared_star_sphere_radius_plus_margin = sq_power_sphere_diam;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Let's add the margin, now
|
||||
// The value depends on whether we perturb weight or position
|
||||
if (squared_star_sphere_radius_plus_margin)
|
||||
{
|
||||
#ifdef CGAL_TC_PERTURB_WEIGHT
|
||||
// "4*m_sq_half_sparsity" because both points can be perturbed
|
||||
squared_star_sphere_radius_plus_margin =
|
||||
*squared_star_sphere_radius_plus_margin + 4 * m_sq_half_sparsity;
|
||||
#else
|
||||
// "2*m_half_sparsity" because both points can be perturbed
|
||||
squared_star_sphere_radius_plus_margin = CGAL::square(
|
||||
CGAL::sqrt(*squared_star_sphere_radius_plus_margin)
|
||||
+ 2 * m_half_sparsity);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return center_vertex;
|
||||
}
|
||||
|
||||
void compute_tangent_triangulation(std::size_t i, bool verbose = false)
|
||||
{
|
||||
if (verbose)
|
||||
|
|
@ -1484,176 +1799,9 @@ private:
|
|||
int tangent_space_dim = tangent_basis_dim(i);
|
||||
Triangulation &local_tr =
|
||||
m_triangulations[i].construct_triangulation(tangent_space_dim);
|
||||
const Tr_traits &local_tr_traits = local_tr.geom_traits();
|
||||
Tr_vertex_handle ¢er_vertex = m_triangulations[i].center_vertex();
|
||||
|
||||
// Kernel functor & objects
|
||||
typename K::Squared_distance_d k_sqdist = m_k.squared_distance_d_object();
|
||||
|
||||
// Triangulation's traits functor & objects
|
||||
typename Tr_traits::Point_weight_d point_weight =
|
||||
local_tr_traits.point_weight_d_object();
|
||||
typename Tr_traits::Power_center_d power_center =
|
||||
local_tr_traits.power_center_d_object();
|
||||
|
||||
|
||||
//***************************************************
|
||||
// Build a minimal triangulation in the tangent space
|
||||
// (we only need the star of p)
|
||||
//***************************************************
|
||||
|
||||
// Insert p
|
||||
Tr_point proj_wp;
|
||||
if(i == tsb.origin())
|
||||
{
|
||||
proj_wp = local_tr_traits.construct_weighted_point_d_object()(
|
||||
local_tr_traits.construct_point_d_object()(tangent_space_dim, ORIGIN),
|
||||
m_weights[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
const Weighted_point& wp = compute_perturbed_weighted_point(i);
|
||||
proj_wp = project_point_and_compute_weight(wp, tsb, local_tr_traits);
|
||||
}
|
||||
|
||||
center_vertex = local_tr.insert(proj_wp);
|
||||
center_vertex->data() = i;
|
||||
if (verbose)
|
||||
std::cerr << "* Inserted point #" << i << std::endl;
|
||||
|
||||
#ifdef CGAL_TC_VERY_VERBOSE
|
||||
std::size_t num_attempts_to_insert_points = 1;
|
||||
std::size_t num_inserted_points = 1;
|
||||
#endif
|
||||
//const int NUM_NEIGHBORS = 150;
|
||||
//KNS_range ins_range = m_points_ds.query_ANN(center_pt, NUM_NEIGHBORS);
|
||||
INS_range ins_range = m_points_ds.query_incremental_ANN(center_pt);
|
||||
|
||||
// While building the local triangulation, we keep the radius
|
||||
// of the sphere "star sphere" centered at "center_vertex"
|
||||
// and which contains all the
|
||||
// circumspheres of the star of "center_vertex"
|
||||
boost::optional<FT> squared_star_sphere_radius_plus_margin;
|
||||
|
||||
#ifdef CGAL_ALPHA_TC
|
||||
/*FT max_absolute_alpha = tsb.max_absolute_alpha();
|
||||
// "2*m_half_sparsity" because both points can be perturbed
|
||||
FT max_sqdist_to_tangent_space = (max_absolute_alpha == FT(0) ?
|
||||
FT(0) : CGAL::square(2*max_absolute_alpha + 2*m_half_sparsity));*/
|
||||
std::size_t number_of_attempts_to_insert_points = 0;
|
||||
const std::size_t MAX_NUM_INSERTED_POINTS =
|
||||
tsb.num_thickening_vectors() > 0 ?
|
||||
static_cast<std::size_t>(std::pow(4, /*tsb.dimension()*/m_intrinsic_dim))
|
||||
: std::numeric_limits<std::size_t>::max();
|
||||
#endif
|
||||
|
||||
// Insert points until we find a point which is outside "star shere"
|
||||
for (INS_iterator nn_it = ins_range.begin() ;
|
||||
nn_it != ins_range.end() ;
|
||||
++nn_it)
|
||||
{
|
||||
#ifdef CGAL_ALPHA_TC
|
||||
++number_of_attempts_to_insert_points;
|
||||
if (number_of_attempts_to_insert_points > MAX_NUM_INSERTED_POINTS)
|
||||
break;
|
||||
#endif
|
||||
|
||||
std::size_t neighbor_point_idx = nn_it->first;
|
||||
|
||||
// ith point = p, which is already inserted
|
||||
if (neighbor_point_idx != i)
|
||||
{
|
||||
// No need to lock the Mutex_for_perturb here since this will not be
|
||||
// called while other threads are perturbing the positions
|
||||
Point neighbor_pt;
|
||||
FT neighbor_weight;
|
||||
compute_perturbed_weighted_point(
|
||||
neighbor_point_idx, neighbor_pt, neighbor_weight);
|
||||
|
||||
if (squared_star_sphere_radius_plus_margin
|
||||
&& k_sqdist(center_pt, neighbor_pt)
|
||||
> *squared_star_sphere_radius_plus_margin)
|
||||
break;
|
||||
|
||||
Tr_point proj_pt = project_point_and_compute_weight(
|
||||
neighbor_pt, neighbor_weight, tsb,
|
||||
local_tr_traits);
|
||||
|
||||
#ifdef CGAL_TC_VERY_VERBOSE
|
||||
++num_attempts_to_insert_points;
|
||||
#endif
|
||||
|
||||
|
||||
Tr_vertex_handle vh = local_tr.insert_if_in_star(proj_pt, center_vertex);
|
||||
//Tr_vertex_handle vh = local_tr.insert(proj_pt);
|
||||
if (vh != Tr_vertex_handle())
|
||||
{
|
||||
#ifdef CGAL_TC_VERY_VERBOSE
|
||||
++num_inserted_points;
|
||||
#endif
|
||||
if (verbose)
|
||||
std::cerr << "* Inserted point #" << neighbor_point_idx << std::endl;
|
||||
|
||||
vh->data() = neighbor_point_idx;
|
||||
|
||||
// Let's recompute squared_star_sphere_radius_plus_margin
|
||||
if (local_tr.current_dimension() >= tangent_space_dim)
|
||||
{
|
||||
squared_star_sphere_radius_plus_margin = boost::none;
|
||||
// Get the incident cells and look for the biggest circumsphere
|
||||
std::vector<Tr_full_cell_handle> incident_cells;
|
||||
local_tr.incident_full_cells(
|
||||
center_vertex,
|
||||
std::back_inserter(incident_cells));
|
||||
for (typename std::vector<Tr_full_cell_handle>::iterator cit =
|
||||
incident_cells.begin(); cit != incident_cells.end(); ++cit)
|
||||
{
|
||||
Tr_full_cell_handle cell = *cit;
|
||||
if (local_tr.is_infinite(cell))
|
||||
{
|
||||
squared_star_sphere_radius_plus_margin = boost::none;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
Tr_point c = power_center(
|
||||
boost::make_transform_iterator(
|
||||
cell->vertices_begin(),
|
||||
vertex_handle_to_point<Tr_point, Tr_vertex_handle>),
|
||||
boost::make_transform_iterator(
|
||||
cell->vertices_end(),
|
||||
vertex_handle_to_point<Tr_point, Tr_vertex_handle>));
|
||||
|
||||
FT sq_power_sphere_diam = 4*point_weight(c);
|
||||
|
||||
if (!squared_star_sphere_radius_plus_margin
|
||||
|| sq_power_sphere_diam >
|
||||
*squared_star_sphere_radius_plus_margin)
|
||||
{
|
||||
squared_star_sphere_radius_plus_margin = sq_power_sphere_diam;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Let's add the margin, now
|
||||
// The value depends on whether we perturb weight or position
|
||||
if (squared_star_sphere_radius_plus_margin)
|
||||
{
|
||||
#ifdef CGAL_TC_PERTURB_WEIGHT
|
||||
// "4*m_sq_half_sparsity" because both points can be perturbed
|
||||
squared_star_sphere_radius_plus_margin =
|
||||
*squared_star_sphere_radius_plus_margin + 4*m_sq_half_sparsity;
|
||||
#else
|
||||
// "2*m_half_sparsity" because both points can be perturbed
|
||||
squared_star_sphere_radius_plus_margin = CGAL::square(
|
||||
CGAL::sqrt(*squared_star_sphere_radius_plus_margin)
|
||||
+ 2*m_half_sparsity);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
m_triangulations[i].center_vertex() =
|
||||
compute_star(i, center_pt, tsb, local_tr, verbose);
|
||||
|
||||
#if defined(CGAL_TC_PROFILING) && defined(CGAL_TC_VERY_VERBOSE)
|
||||
std::cerr << " - triangulation construction: " << t.elapsed() << " s.\n";
|
||||
|
|
@ -2003,7 +2151,7 @@ next_face:
|
|||
//typename K::Translated_point_d transl =
|
||||
// m_k.translated_point_d_object();
|
||||
|
||||
#ifdef USE_ANOTHER_POINT_SET_FOR_TANGENT_SPACE_ESTIM
|
||||
#ifdef CGAL_TC_USE_ANOTHER_POINT_SET_FOR_TANGENT_SPACE_ESTIM
|
||||
KNS_range kns_range = m_points_ds_for_tse.query_ANN(
|
||||
p, num_points_for_pca, false);
|
||||
const Points &points_for_pca = m_points_for_tse;
|
||||
|
|
@ -2127,6 +2275,95 @@ next_face:
|
|||
*/
|
||||
}
|
||||
|
||||
// Compute the space tangent to a simplex (p1, p2, ... pn)
|
||||
// CJTODO: Improve this?
|
||||
// Basically, it takes all the neighbor points to p1, p2... pn and runs PCA
|
||||
// on it. Note that most points are duplicated.
|
||||
Tangent_space_basis compute_tangent_space(
|
||||
const Indexed_simplex &s, bool normalize_basis = true)
|
||||
{
|
||||
unsigned int num_points_for_pca = static_cast<unsigned int>(
|
||||
std::pow(BASE_VALUE_FOR_PCA, m_intrinsic_dim));
|
||||
|
||||
// Kernel functors
|
||||
typename K::Construct_vector_d constr_vec =
|
||||
m_k.construct_vector_d_object();
|
||||
typename K::Compute_coordinate_d coord =
|
||||
m_k.compute_coordinate_d_object();
|
||||
typename K::Squared_length_d sqlen =
|
||||
m_k.squared_length_d_object();
|
||||
typename K::Scaled_vector_d scaled_vec =
|
||||
m_k.scaled_vector_d_object();
|
||||
typename K::Scalar_product_d scalar_pdct =
|
||||
m_k.scalar_product_d_object();
|
||||
typename K::Difference_of_vectors_d diff_vec =
|
||||
m_k.difference_of_vectors_d_object();
|
||||
//typename K::Translated_point_d transl =
|
||||
// m_k.translated_point_d_object();
|
||||
|
||||
// One row = one point
|
||||
Eigen::MatrixXd mat_points(s.size()*num_points_for_pca, m_ambient_dim);
|
||||
unsigned int current_row = 0;
|
||||
|
||||
for (Indexed_simplex::const_iterator it_index = s.begin();
|
||||
it_index != s.end() ; ++it_index)
|
||||
{
|
||||
const Point &p = m_points[*it_index];
|
||||
|
||||
#ifdef CGAL_TC_USE_ANOTHER_POINT_SET_FOR_TANGENT_SPACE_ESTIM
|
||||
KNS_range kns_range = m_points_ds_for_tse.query_ANN(
|
||||
p, num_points_for_pca, false);
|
||||
const Points &points_for_pca = m_points_for_tse;
|
||||
#else
|
||||
KNS_range kns_range = m_points_ds.query_ANN(p, num_points_for_pca, false);
|
||||
const Points &points_for_pca = m_points;
|
||||
#endif
|
||||
|
||||
KNS_iterator nn_it = kns_range.begin();
|
||||
for ( ;
|
||||
current_row < num_points_for_pca && nn_it != kns_range.end() ;
|
||||
++current_row, ++nn_it)
|
||||
{
|
||||
for (int i = 0 ; i < m_ambient_dim ; ++i)
|
||||
{
|
||||
//const Point p = transl(
|
||||
// points_for_pca[nn_it->first], m_translations[nn_it->first]);
|
||||
mat_points(current_row, i) =
|
||||
CGAL::to_double(coord(points_for_pca[nn_it->first], i));
|
||||
}
|
||||
}
|
||||
}
|
||||
Eigen::MatrixXd centered = mat_points.rowwise() - mat_points.colwise().mean();
|
||||
Eigen::MatrixXd cov = centered.adjoint() * centered;
|
||||
Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> eig(cov);
|
||||
|
||||
Tangent_space_basis tsb;
|
||||
|
||||
// The eigenvectors are sorted in increasing order of their corresponding
|
||||
// eigenvalues
|
||||
for (int j = m_ambient_dim - 1 ;
|
||||
j >= m_ambient_dim - m_intrinsic_dim ;
|
||||
--j)
|
||||
{
|
||||
if (normalize_basis)
|
||||
{
|
||||
Vector v = constr_vec(m_ambient_dim,
|
||||
eig.eigenvectors().col(j).data(),
|
||||
eig.eigenvectors().col(j).data() + m_ambient_dim);
|
||||
tsb.push_back(normalize_vector(v, m_k));
|
||||
}
|
||||
else
|
||||
{
|
||||
tsb.push_back(constr_vec(
|
||||
m_ambient_dim,
|
||||
eig.eigenvectors().col(j).data(),
|
||||
eig.eigenvectors().col(j).data() + m_ambient_dim));
|
||||
}
|
||||
}
|
||||
|
||||
return tsb;
|
||||
}
|
||||
|
||||
// Returns the dimension of the ith local triangulation
|
||||
// This is particularly useful for the alpha-TC
|
||||
int tangent_basis_dim(std::size_t i) const
|
||||
|
|
@ -2830,6 +3067,95 @@ next_face:
|
|||
return is_inconsistent;
|
||||
}
|
||||
|
||||
|
||||
bool filter_inconsistent_simplices_in_a_local_triangulation(
|
||||
std::size_t tr_index)
|
||||
{
|
||||
bool is_inconsistent = false;
|
||||
|
||||
Star &star = m_stars[tr_index];
|
||||
Triangulation const& tr = m_triangulations[tr_index].tr();
|
||||
Tr_vertex_handle center_vh = m_triangulations[tr_index].center_vertex();
|
||||
const Tr_traits &local_tr_traits = tr.geom_traits();
|
||||
int cur_dim = tr.current_dimension();
|
||||
|
||||
// For each incident simplex
|
||||
Star::iterator it_inc_simplex = star.begin();
|
||||
while (it_inc_simplex != star.end())
|
||||
{
|
||||
const Incident_simplex &incident_simplex = *it_inc_simplex;
|
||||
|
||||
// Don't check infinite cells
|
||||
if (is_infinite(incident_simplex))
|
||||
{
|
||||
++it_inc_simplex;
|
||||
continue;
|
||||
}
|
||||
|
||||
Indexed_simplex c = incident_simplex;
|
||||
c.insert(tr_index); // Add the missing index
|
||||
|
||||
// Inconsistent?
|
||||
if (!is_simplex_consistent(c))
|
||||
{
|
||||
is_inconsistent = true;
|
||||
|
||||
// Compute T, the space tangent to "c"
|
||||
Tangent_space_basis tsb = compute_tangent_space(c);
|
||||
|
||||
std::size_t center_index = *(c.begin());
|
||||
// Compute the star of "center_index" in the RT restricted to T
|
||||
tsb.set_origin(center_index);
|
||||
Triangulation tr(m_intrinsic_dim);
|
||||
Tr_vertex_handle center_vh = compute_star(
|
||||
center_index, compute_perturbed_point(center_index), tsb, tr);
|
||||
|
||||
// Get incident cells
|
||||
std::vector<Tr_full_cell_handle> incident_cells;
|
||||
tr.incident_full_cells(
|
||||
center_vh, std::back_inserter(incident_cells));
|
||||
|
||||
// Check if "c" is among them
|
||||
typename std::vector<Tr_full_cell_handle>::const_iterator it_c = incident_cells.begin();
|
||||
typename std::vector<Tr_full_cell_handle>::const_iterator it_c_end = incident_cells.end();
|
||||
bool found = false;
|
||||
// For each cell
|
||||
for (; !found && it_c != it_c_end ; ++it_c)
|
||||
{
|
||||
Incident_simplex incident_simplex;
|
||||
for (int j = 0 ; j < tr.current_dimension() + 1 ; ++j)
|
||||
{
|
||||
std::size_t index = (*it_c)->vertex(j)->data();
|
||||
incident_simplex.insert(index);
|
||||
}
|
||||
if (incident_simplex == c)
|
||||
found = true;
|
||||
}
|
||||
// If the simplex is not in the new star, we remove it
|
||||
if (!found)
|
||||
{
|
||||
if (it_inc_simplex != star.end() - 1)
|
||||
{
|
||||
*it_inc_simplex = star.back();
|
||||
star.pop_back();
|
||||
}
|
||||
else
|
||||
{
|
||||
star.pop_back();
|
||||
it_inc_simplex = star.end(); // end the loop
|
||||
}
|
||||
}
|
||||
else
|
||||
++it_inc_simplex;
|
||||
}
|
||||
// Consistent
|
||||
else
|
||||
++it_inc_simplex;
|
||||
}
|
||||
|
||||
return is_inconsistent;
|
||||
}
|
||||
|
||||
std::ostream &export_vertices_to_off(
|
||||
std::ostream & os, std::size_t &num_vertices,
|
||||
bool use_perturbed_points = false) const
|
||||
|
|
@ -4105,7 +4431,7 @@ private:
|
|||
//std::vector<Tr_mutex> m_tr_mutexes;
|
||||
#endif
|
||||
|
||||
#ifdef USE_ANOTHER_POINT_SET_FOR_TANGENT_SPACE_ESTIM
|
||||
#ifdef CGAL_TC_USE_ANOTHER_POINT_SET_FOR_TANGENT_SPACE_ESTIM
|
||||
Points m_points_for_tse;
|
||||
Points_ds m_points_ds_for_tse;
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in New Issue