Prusa Slicer 2.6.0
Loading...
Searching...
No Matches
igl::geodesic::GeodesicAlgorithmExact Class Reference
+ Inheritance diagram for igl::geodesic::GeodesicAlgorithmExact:
+ Collaboration diagram for igl::geodesic::GeodesicAlgorithmExact:

Public Types

enum  AlgorithmType { EXACT , DIJKSTRA , SUBDIVISION , UNDEFINED_ALGORITHM }
 

Public Member Functions

 GeodesicAlgorithmExact (geodesic::Mesh *mesh)
 
 ~GeodesicAlgorithmExact ()
 
void propagate (std::vector< SurfacePoint > &sources, double max_propagation_distance=GEODESIC_INF, std::vector< SurfacePoint > *stop_points=NULL)
 
void trace_back (SurfacePoint &destination, std::vector< SurfacePoint > &path)
 
unsigned best_source (SurfacePoint &point, double &best_source_distance)
 
void print_statistics ()
 
void geodesic (SurfacePoint &source, SurfacePoint &destination, std::vector< SurfacePoint > &path)
 
void geodesic (std::vector< SurfacePoint > &sources, std::vector< SurfacePoint > &destinations, std::vector< std::vector< SurfacePoint > > &paths)
 
AlgorithmType type ()
 
virtual std::string name ()
 
geodesic::Meshmesh ()
 

Protected Types

typedef std::pair< vertex_pointer, double > stop_vertex_with_distace_type
 

Protected Member Functions

void set_stop_conditions (std::vector< SurfacePoint > *stop_points, double stop_distance)
 
double stop_distance ()
 

Protected Attributes

AlgorithmType m_type
 
std::vector< stop_vertex_with_distace_typem_stop_vertices
 
double m_max_propagation_distance
 
geodesic::Meshm_mesh
 
double m_time_consumed
 
double m_propagation_distance_stopped
 

Private Types

enum  MapType { OLD , NEW }
 
typedef std::set< interval_pointer, IntervalIntervalQueue
 

Private Member Functions

void update_list_and_queue (list_pointer list, IntervalWithStop *candidates, unsigned num_candidates)
 
unsigned compute_propagated_parameters (double pseudo_x, double pseudo_y, double d, double start, double end, double alpha, double L, bool first_interval, bool last_interval, bool turn_left, bool turn_right, IntervalWithStop *candidates)
 
void construct_propagated_intervals (bool invert, edge_pointer edge, face_pointer face, IntervalWithStop *candidates, unsigned &num_candidates, interval_pointer source_interval)
 
double compute_positive_intersection (double start, double pseudo_x, double pseudo_y, double sin_alpha, double cos_alpha)
 
unsigned intersect_intervals (interval_pointer zero, IntervalWithStop *one)
 
interval_pointer best_first_interval (SurfacePoint &point, double &best_total_distance, double &best_interval_position, unsigned &best_source_index)
 
bool check_stop_conditions (unsigned &index)
 
void clear ()
 
list_pointer interval_list (edge_pointer e)
 
void set_sources (std::vector< SurfacePoint > &sources)
 
void initialize_propagation_data ()
 
void list_edges_visible_from_source (MeshElementBase *p, std::vector< edge_pointer > &storage)
 
long visible_from_source (SurfacePoint &point)
 
void best_point_on_the_edge_set (SurfacePoint &point, std::vector< edge_pointer > const &storage, interval_pointer &best_interval, double &best_total_distance, double &best_interval_position)
 
void possible_traceback_edges (SurfacePoint &point, std::vector< edge_pointer > &storage)
 
bool erase_from_queue (interval_pointer p)
 

Private Attributes

IntervalQueue m_queue
 
MemoryAllocator< Intervalm_memory_allocator
 
std::vector< IntervalListm_edge_interval_lists
 
MapType map [5]
 
double start [6]
 
interval_pointer i_new [5]
 
unsigned m_queue_max_size
 
unsigned m_iterations
 
SortedSources m_sources
 

Detailed Description

Member Typedef Documentation

◆ IntervalQueue

◆ stop_vertex_with_distace_type

Member Enumeration Documentation

◆ AlgorithmType

Enumerator
EXACT 
DIJKSTRA 
SUBDIVISION 
UNDEFINED_ALGORITHM 
1618 {
1619 EXACT,
1620 DIJKSTRA,
1623 };
@ EXACT
Definition exact_geodesic.cpp:1619
@ SUBDIVISION
Definition exact_geodesic.cpp:1621
@ UNDEFINED_ALGORITHM
Definition exact_geodesic.cpp:1622
@ DIJKSTRA
Definition exact_geodesic.cpp:1620

◆ MapType

Enumerator
OLD 
NEW 
1909{OLD, NEW}; //used for interval intersection
@ OLD
Definition exact_geodesic.cpp:1909
@ NEW
Definition exact_geodesic.cpp:1909

Constructor & Destructor Documentation

◆ GeodesicAlgorithmExact()

igl::geodesic::GeodesicAlgorithmExact::GeodesicAlgorithmExact ( geodesic::Mesh mesh)
inline
1795 :
1797 m_memory_allocator(mesh->edges().size(), mesh->edges().size()),
1799 {
1800 m_type = EXACT;
1801
1802 for(unsigned i=0; i<m_edge_interval_lists.size(); ++i)
1803 {
1804 m_edge_interval_lists[i].initialize(&mesh->edges()[i]);
1805 }
1806 };
AlgorithmType m_type
Definition exact_geodesic.cpp:1670
GeodesicAlgorithmBase(geodesic::Mesh *mesh)
Definition exact_geodesic.cpp:1625
geodesic::Mesh * mesh()
Definition exact_geodesic.cpp:1660
MemoryAllocator< Interval > m_memory_allocator
Definition exact_geodesic.cpp:1906
std::vector< IntervalList > m_edge_interval_lists
Definition exact_geodesic.cpp:1907
std::vector< Edge > & edges()
Definition exact_geodesic.cpp:705

References igl::geodesic::Mesh::edges(), igl::geodesic::GeodesicAlgorithmBase::EXACT, m_edge_interval_lists, igl::geodesic::GeodesicAlgorithmBase::m_type, and igl::geodesic::GeodesicAlgorithmBase::mesh().

+ Here is the call graph for this function:

◆ ~GeodesicAlgorithmExact()

igl::geodesic::GeodesicAlgorithmExact::~GeodesicAlgorithmExact ( )
inline
1808{};

Member Function Documentation

◆ best_first_interval()

interval_pointer igl::geodesic::GeodesicAlgorithmExact::best_first_interval ( SurfacePoint point,
double &  best_total_distance,
double &  best_interval_position,
unsigned &  best_source_index 
)
inlineprivate
2967{
2968 assert(point.type() != UNDEFINED_POINT);
2969
2970 interval_pointer best_interval = NULL;
2971 best_total_distance = GEODESIC_INF;
2972
2973 if(point.type() == EDGE)
2974 {
2975 edge_pointer e = static_cast<edge_pointer>(point.base_element());
2976 list_pointer list = interval_list(e);
2977
2978 best_interval_position = point.distance(e->v0());
2979 best_interval = list->covering_interval(best_interval_position);
2980 if(best_interval)
2981 {
2982 //assert(best_interval && best_interval->d() < GEODESIC_INF);
2983 best_total_distance = best_interval->signal(best_interval_position);
2984 best_source_index = best_interval->source_index();
2985 }
2986 }
2987 else if(point.type() == FACE)
2988 {
2989 face_pointer f = static_cast<face_pointer>(point.base_element());
2990 for(unsigned i=0; i<3; ++i)
2991 {
2992 edge_pointer e = f->adjacent_edges()[i];
2993 list_pointer list = interval_list(e);
2994
2995 double offset;
2996 double distance;
2997 interval_pointer interval;
2998
2999 list->find_closest_point(&point,
3000 offset,
3001 distance,
3002 interval);
3003
3004 if(interval && distance < best_total_distance)
3005 {
3006 best_interval = interval;
3007 best_total_distance = distance;
3008 best_interval_position = offset;
3009 best_source_index = interval->source_index();
3010 }
3011 }
3012
3013 //check for all sources that might be located inside this face
3015 for(SortedSources::sorted_iterator it=local_sources.first; it != local_sources.second; ++it)
3016 {
3017 SurfacePointWithIndex* source = *it;
3018 double distance = point.distance(source);
3019 if(distance < best_total_distance)
3020 {
3021 best_interval = NULL;
3022 best_total_distance = distance;
3023 best_interval_position = 0.0;
3024 best_source_index = source->index();
3025 }
3026 }
3027 }
3028 else if(point.type() == VERTEX)
3029 {
3030 vertex_pointer v = static_cast<vertex_pointer>(point.base_element());
3031 for(unsigned i=0; i<v->adjacent_edges().size(); ++i)
3032 {
3033 edge_pointer e = v->adjacent_edges()[i];
3034 list_pointer list = interval_list(e);
3035
3036 double position = e->v0()->id() == v->id() ? 0.0 : e->length();
3037 interval_pointer interval = list->covering_interval(position);
3038 if(interval)
3039 {
3040 double distance = interval->signal(position);
3041
3042 if(distance < best_total_distance)
3043 {
3044 best_interval = interval;
3045 best_total_distance = distance;
3046 best_interval_position = position;
3047 best_source_index = interval->source_index();
3048 }
3049 }
3050 }
3051 }
3052
3053 if(best_total_distance > m_propagation_distance_stopped) //result is unreliable
3054 {
3055 best_total_distance = GEODESIC_INF;
3056 return NULL;
3057 }
3058 else
3059 {
3060 return best_interval;
3061 }
3062}
double m_propagation_distance_stopped
Definition exact_geodesic.cpp:1679
SortedSources m_sources
Definition exact_geodesic.cpp:1917
list_pointer interval_list(edge_pointer e)
Definition exact_geodesic.cpp:1876
void find_closest_point(double const x, double const y, double &offset, double &distance)
Definition exact_geodesic.cpp:1509
edge_pointer_vector & adjacent_edges()
Definition exact_geodesic.cpp:347
sorted_iterator_pair sources(base_pointer mesh_element)
Definition exact_geodesic.cpp:1471
std::pair< sorted_iterator, sorted_iterator > sorted_iterator_pair
Definition exact_geodesic.cpp:1469
sorted_vector_type::iterator sorted_iterator
Definition exact_geodesic.cpp:1468
Edge * edge_pointer
Definition exact_geodesic.cpp:281
Face * face_pointer
Definition exact_geodesic.cpp:282
Interval * interval_pointer
Definition exact_geodesic.cpp:1190
IntervalList * list_pointer
Definition exact_geodesic.cpp:1191
double const GEODESIC_INF
Definition exact_geodesic.cpp:32
@ UNDEFINED_POINT
Definition exact_geodesic.cpp:331
@ VERTEX
Definition exact_geodesic.cpp:328
@ FACE
Definition exact_geodesic.cpp:330
@ EDGE
Definition exact_geodesic.cpp:329
Vertex * vertex_pointer
Definition exact_geodesic.cpp:280
double distance(const P &p1, const P &p2)
Definition geometry_traits.hpp:329
void offset(Slic3r::ExPolygon &sh, coord_t distance, const PolygonTag &)
Definition geometries.hpp:132

References igl::geodesic::MeshElementBase::adjacent_edges(), igl::geodesic::SurfacePoint::base_element(), igl::geodesic::IntervalList::covering_interval(), igl::geodesic::Point3D::distance(), igl::geodesic::EDGE, igl::geodesic::FACE, igl::geodesic::IntervalList::find_closest_point(), igl::geodesic::GEODESIC_INF, igl::geodesic::MeshElementBase::id(), igl::geodesic::SurfacePointWithIndex::index(), interval_list(), igl::geodesic::Edge::length(), igl::geodesic::GeodesicAlgorithmBase::m_propagation_distance_stopped, m_sources, igl::geodesic::Interval::signal(), igl::geodesic::SimpleVector< Data >::size(), igl::geodesic::Interval::source_index(), igl::geodesic::SortedSources::sources(), igl::geodesic::SurfacePoint::type(), igl::geodesic::UNDEFINED_POINT, igl::geodesic::Edge::v0(), and igl::geodesic::VERTEX.

Referenced by best_source(), and trace_back().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ best_point_on_the_edge_set()

void igl::geodesic::GeodesicAlgorithmExact::best_point_on_the_edge_set ( SurfacePoint point,
std::vector< edge_pointer > const storage,
interval_pointer best_interval,
double &  best_total_distance,
double &  best_interval_position 
)
inlineprivate
1925{
1926 best_total_distance = 1e100;
1927 for(unsigned i=0; i<storage.size(); ++i)
1928 {
1929 edge_pointer e = storage[i];
1930 list_pointer list = interval_list(e);
1931
1932 double offset;
1933 double distance;
1934 interval_pointer interval;
1935
1936 list->find_closest_point(&point,
1937 offset,
1938 distance,
1939 interval);
1940
1941 if(distance < best_total_distance)
1942 {
1943 best_interval = interval;
1944 best_total_distance = distance;
1945 best_interval_position = offset;
1946 }
1947 }
1948}

References igl::geodesic::IntervalList::find_closest_point(), and interval_list().

Referenced by trace_back().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ best_source()

unsigned igl::geodesic::GeodesicAlgorithmExact::best_source ( SurfacePoint point,
double &  best_source_distance 
)
inlinevirtual

Implements igl::geodesic::GeodesicAlgorithmBase.

2951{
2952 double best_interval_position;
2953 unsigned best_source_index;
2954
2955 best_first_interval(point,
2956 best_source_distance,
2957 best_interval_position,
2958 best_source_index);
2959
2960 return best_source_index;
2961}
interval_pointer best_first_interval(SurfacePoint &point, double &best_total_distance, double &best_interval_position, unsigned &best_source_index)
Definition exact_geodesic.cpp:2963

References best_first_interval().

+ Here is the call graph for this function:

◆ check_stop_conditions()

bool igl::geodesic::GeodesicAlgorithmExact::check_stop_conditions ( unsigned &  index)
inlineprivate
2458{
2459 double queue_distance = (*m_queue.begin())->min();
2460 if(queue_distance < stop_distance())
2461 {
2462 return false;
2463 }
2464
2465 while(index < m_stop_vertices.size())
2466 {
2467 vertex_pointer v = m_stop_vertices[index].first;
2468 edge_pointer edge = v->adjacent_edges()[0]; //take any edge
2469
2470 double distance = edge->v0()->id() == v->id() ?
2471 interval_list(edge)->signal(0.0) :
2472 interval_list(edge)->signal(edge->length());
2473
2474 if(queue_distance < distance + m_stop_vertices[index].second)
2475 {
2476 return false;
2477 }
2478
2479 ++index;
2480 }
2481 return true;
2482}
std::vector< stop_vertex_with_distace_type > m_stop_vertices
Definition exact_geodesic.cpp:1673
double stop_distance()
Definition exact_geodesic.cpp:1665
IntervalQueue m_queue
Definition exact_geodesic.cpp:1904
double signal(double x)
Definition exact_geodesic.cpp:1420
IGL_INLINE void min(const Eigen::SparseMatrix< AType > &A, const int dim, Eigen::PlainObjectBase< DerivedB > &B, Eigen::PlainObjectBase< DerivedI > &I)
Definition min.cpp:6

References igl::geodesic::MeshElementBase::adjacent_edges(), igl::geodesic::MeshElementBase::id(), interval_list(), igl::geodesic::Edge::length(), m_queue, igl::geodesic::GeodesicAlgorithmBase::m_stop_vertices, igl::min(), igl::geodesic::IntervalList::signal(), igl::geodesic::GeodesicAlgorithmBase::stop_distance(), and igl::geodesic::Edge::v0().

Referenced by propagate().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ clear()

void igl::geodesic::GeodesicAlgorithmExact::clear ( )
inlineprivate
1866 {
1867 m_memory_allocator.clear();
1868 m_queue.clear();
1869 for(unsigned i=0; i<m_edge_interval_lists.size(); ++i)
1870 {
1871 m_edge_interval_lists[i].clear();
1872 }
1874 };

References igl::geodesic::GEODESIC_INF, m_edge_interval_lists, m_memory_allocator, igl::geodesic::GeodesicAlgorithmBase::m_propagation_distance_stopped, and m_queue.

Referenced by initialize_propagation_data().

+ Here is the caller graph for this function:

◆ compute_positive_intersection()

double igl::geodesic::GeodesicAlgorithmExact::compute_positive_intersection ( double  start,
double  pseudo_x,
double  pseudo_y,
double  sin_alpha,
double  cos_alpha 
)
inlineprivate
2037{
2038 assert(pseudo_y < 0);
2039
2040 double denominator = sin_alpha*(pseudo_x - start) - cos_alpha*pseudo_y;
2041 if(denominator<0.0)
2042 {
2043 return -1.0;
2044 }
2045
2046 double numerator = -pseudo_y*start;
2047
2048 if(numerator < 1e-30)
2049 {
2050 return 0.0;
2051 }
2052
2053 if(denominator < 1e-30)
2054 {
2055 return -1.0;
2056 }
2057
2058 return numerator/denominator;
2059}
double start[6]
Definition exact_geodesic.cpp:1911

References start.

Referenced by compute_propagated_parameters().

+ Here is the caller graph for this function:

◆ compute_propagated_parameters()

unsigned igl::geodesic::GeodesicAlgorithmExact::compute_propagated_parameters ( double  pseudo_x,
double  pseudo_y,
double  d,
double  start,
double  end,
double  alpha,
double  L,
bool  first_interval,
bool  last_interval,
bool  turn_left,
bool  turn_right,
IntervalWithStop candidates 
)
inlineprivate
2725{
2726 assert(pseudo_y<=0.0);
2727 assert(d<GEODESIC_INF/10.0);
2728 assert(begin<=end);
2729 assert(first_interval ? (begin == 0.0) : true);
2730
2731 IntervalWithStop* p = candidates;
2732
2733 if(std::abs(pseudo_y) <= 1e-30) //pseudo-source is on the edge
2734 {
2735 if(first_interval && pseudo_x <= 0.0)
2736 {
2737 p->start() = 0.0;
2738 p->stop() = L;
2739 p->d() = d - pseudo_x;
2740 p->pseudo_x() = 0.0;
2741 p->pseudo_y() = 0.0;
2742 return 1;
2743 }
2744 else if(last_interval && pseudo_x >= end)
2745 {
2746 p->start() = 0.0;
2747 p->stop() = L;
2748 p->d() = d + pseudo_x-end;
2749 p->pseudo_x() = end*cos(alpha);
2750 p->pseudo_y() = -end*sin(alpha);
2751 return 1;
2752 }
2753 else if(pseudo_x >= begin && pseudo_x <= end)
2754 {
2755 p->start() = 0.0;
2756 p->stop() = L;
2757 p->d() = d;
2758 p->pseudo_x() = pseudo_x*cos(alpha);
2759 p->pseudo_y() = -pseudo_x*sin(alpha);
2760 return 1;
2761 }
2762 else
2763 {
2764 return 0;
2765 }
2766 }
2767
2768 double sin_alpha = sin(alpha);
2769 double cos_alpha = cos(alpha);
2770
2771 //important: for the first_interval, this function returns zero only if the new edge is "visible" from the source
2772 //if the new edge can be covered only after turn_over, the value is negative (-1.0)
2773 double L1 = compute_positive_intersection(begin,
2774 pseudo_x,
2775 pseudo_y,
2776 sin_alpha,
2777 cos_alpha);
2778
2779 if(L1 < 0 || L1 >= L)
2780 {
2781 if(first_interval && turn_left)
2782 {
2783 p->start() = 0.0;
2784 p->stop() = L;
2785 p->d() = d + sqrt(pseudo_x*pseudo_x + pseudo_y*pseudo_y);
2786 p->pseudo_y() = 0.0;
2787 p->pseudo_x() = 0.0;
2788 return 1;
2789 }
2790 else
2791 {
2792 return 0;
2793 }
2794 }
2795
2796 double L2 = compute_positive_intersection(end,
2797 pseudo_x,
2798 pseudo_y,
2799 sin_alpha,
2800 cos_alpha);
2801
2802 if(L2 < 0 || L2 >= L)
2803 {
2804 p->start() = L1;
2805 p->stop() = L;
2806 p->d() = d;
2807 p->pseudo_x() = cos_alpha*pseudo_x + sin_alpha*pseudo_y;
2808 p->pseudo_y() = -sin_alpha*pseudo_x + cos_alpha*pseudo_y;
2809
2810 return 1;
2811 }
2812
2813 p->start() = L1;
2814 p->stop() = L2;
2815 p->d() = d;
2816 p->pseudo_x() = cos_alpha*pseudo_x + sin_alpha*pseudo_y;
2817 p->pseudo_y() = -sin_alpha*pseudo_x + cos_alpha*pseudo_y;
2818 assert(p->pseudo_y() <= 0.0);
2819
2820 if(!(last_interval && turn_right))
2821 {
2822 return 1;
2823 }
2824 else
2825 {
2826 p = candidates + 1;
2827
2828 p->start() = L2;
2829 p->stop() = L;
2830 double dx = pseudo_x - end;
2831 p->d() = d + sqrt(dx*dx + pseudo_y*pseudo_y);
2832 p->pseudo_x() = end*cos_alpha;
2833 p->pseudo_y() = -end*sin_alpha;
2834
2835 return 2;
2836 }
2837}
EIGEN_DEVICE_FUNC const SqrtReturnType sqrt() const
Definition ArrayCwiseUnaryOps.h:152
EIGEN_DEVICE_FUNC const CosReturnType cos() const
Definition ArrayCwiseUnaryOps.h:202
EIGEN_DEVICE_FUNC const SinReturnType sin() const
Definition ArrayCwiseUnaryOps.h:220
double compute_positive_intersection(double start, double pseudo_x, double pseudo_y, double sin_alpha, double cos_alpha)
Definition exact_geodesic.cpp:2032
S::iterator end(S &sh, const PathTag &)
Definition geometry_traits.hpp:620
#define L(s)
Definition I18N.hpp:18

References compute_positive_intersection(), cos(), igl::geodesic::GEODESIC_INF, L, sin(), sqrt(), and igl::geodesic::Interval::start().

Referenced by propagate().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ construct_propagated_intervals()

void igl::geodesic::GeodesicAlgorithmExact::construct_propagated_intervals ( bool  invert,
edge_pointer  edge,
face_pointer  face,
IntervalWithStop candidates,
unsigned &  num_candidates,
interval_pointer  source_interval 
)
inlineprivate
2845{
2846 double edge_length = edge->length();
2847 double local_epsilon = SMALLEST_INTERVAL_RATIO * edge_length;
2848
2849 //kill very small intervals in order to avoid precision problems
2850 if(num_candidates == 2)
2851 {
2852 double start = std::min(candidates->start(), (candidates+1)->start());
2853 double stop = std::max(candidates->stop(), (candidates+1)->stop());
2854 if(candidates->stop()-candidates->start() < local_epsilon) // kill interval 0
2855 {
2856 *candidates = *(candidates+1);
2857 num_candidates = 1;
2858 candidates->start() = start;
2859 candidates->stop() = stop;
2860 }
2861 else if ((candidates+1)->stop() - (candidates+1)->start() < local_epsilon)
2862 {
2863 num_candidates = 1;
2864 candidates->start() = start;
2865 candidates->stop() = stop;
2866 }
2867 }
2868
2869 IntervalWithStop* first;
2870 IntervalWithStop* second;
2871 if(num_candidates == 1)
2872 {
2873 first = candidates;
2874 second = candidates;
2875 }
2876 else
2877 {
2878 if(candidates->start() <= (candidates+1)->start())
2879 {
2880 first = candidates;
2881 second = candidates+1;
2882 }
2883 else
2884 {
2885 first = candidates+1;
2886 second = candidates;
2887 }
2888 assert(first->stop() == second->start());
2889 }
2890
2891 if(first->start() < local_epsilon)
2892 {
2893 first->start() = 0.0;
2894 }
2895 if(edge_length - second->stop() < local_epsilon)
2896 {
2897 second->stop() = edge_length;
2898 }
2899
2900 //invert intervals if necessary; fill missing data and set pointers correctly
2901 Interval::DirectionType direction = edge->adjacent_faces()[0]->id() == face->id() ?
2904
2905 if(!invert) //in this case everything is straighforward, we do not have to invert the intervals
2906 {
2907 for(unsigned i=0; i<num_candidates; ++i)
2908 {
2909 IntervalWithStop* p = candidates + i;
2910
2911 p->next() = (i == num_candidates - 1) ? NULL : candidates + i + 1;
2912 p->edge() = edge;
2913 p->direction() = direction;
2914 p->source_index() = source_interval->source_index();
2915
2916 p->min() = 0.0; //it will be changed later on
2917
2918 assert(p->start() < p->stop());
2919 }
2920 }
2921 else //now we have to invert the intervals
2922 {
2923 for(unsigned i=0; i<num_candidates; ++i)
2924 {
2925 IntervalWithStop* p = candidates + i;
2926
2927 p->next() = (i == 0) ? NULL : candidates + i - 1;
2928 p->edge() = edge;
2929 p->direction() = direction;
2930 p->source_index() = source_interval->source_index();
2931
2932 double length = edge_length;
2933 p->pseudo_x() = length - p->pseudo_x();
2934
2935 double start = length - p->stop();
2936 p->stop() = length - p->start();
2937 p->start() = start;
2938
2939 p->min() = 0;
2940
2941 assert(p->start() < p->stop());
2942 assert(p->start() >= 0.0);
2943 assert(p->stop() <= edge->length());
2944 }
2945 }
2946}
DirectionType
Definition exact_geodesic.cpp:1201
@ FROM_FACE_1
Definition exact_geodesic.cpp:1203
@ FROM_FACE_0
Definition exact_geodesic.cpp:1202
double const SMALLEST_INTERVAL_RATIO
Definition exact_geodesic.cpp:36
double length(std::vector< SurfacePoint > &path)
Definition exact_geodesic.cpp:1682

References igl::geodesic::MeshElementBase::adjacent_faces(), igl::geodesic::Interval::direction(), igl::geodesic::Interval::edge(), igl::geodesic::Interval::FROM_FACE_0, igl::geodesic::Interval::FROM_FACE_1, igl::geodesic::MeshElementBase::id(), igl::geodesic::Edge::length(), igl::geodesic::length(), igl::geodesic::Interval::min(), igl::geodesic::Interval::next(), igl::geodesic::Interval::pseudo_x(), igl::geodesic::SMALLEST_INTERVAL_RATIO, igl::geodesic::Interval::source_index(), igl::geodesic::Interval::start(), start, and igl::geodesic::IntervalWithStop::stop().

Referenced by propagate().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ erase_from_queue()

bool igl::geodesic::GeodesicAlgorithmExact::erase_from_queue ( interval_pointer  p)
inlineprivate
2091{
2092 if(p->min() < GEODESIC_INF/10.0)// && p->min >= queue->begin()->first)
2093 {
2094 assert(m_queue.count(p)<=1); //the set is unique
2095
2096 IntervalQueue::iterator it = m_queue.find(p);
2097
2098 if(it != m_queue.end())
2099 {
2100 m_queue.erase(it);
2101 return true;
2102 }
2103 }
2104
2105 return false;
2106}

References igl::geodesic::GEODESIC_INF, m_queue, and igl::geodesic::Interval::min().

Referenced by update_list_and_queue().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ geodesic() [1/2]

void igl::geodesic::GeodesicAlgorithmBase::geodesic ( std::vector< SurfacePoint > &  sources,
std::vector< SurfacePoint > &  destinations,
std::vector< std::vector< SurfacePoint > > &  paths 
)
inlineinherited
1736{
1737 double const max_propagation_distance = GEODESIC_INF;
1738
1739 propagate(sources,
1740 max_propagation_distance,
1741 &destinations); //we use desinations as stop points
1742
1743 paths.resize(destinations.size());
1744
1745 for(unsigned i=0; i<paths.size(); ++i)
1746 {
1747 trace_back(destinations[i], paths[i]);
1748 }
1749}
virtual void propagate(std::vector< SurfacePoint > &sources, double max_propagation_distance=GEODESIC_INF, std::vector< SurfacePoint > *stop_points=NULL)=0
virtual void trace_back(SurfacePoint &destination, std::vector< SurfacePoint > &path)=0

References igl::geodesic::GEODESIC_INF, igl::geodesic::GeodesicAlgorithmBase::propagate(), and igl::geodesic::GeodesicAlgorithmBase::trace_back().

+ Here is the call graph for this function:

◆ geodesic() [2/2]

void igl::geodesic::GeodesicAlgorithmBase::geodesic ( SurfacePoint source,
SurfacePoint destination,
std::vector< SurfacePoint > &  path 
)
inlineinherited
1721{
1722 std::vector<SurfacePoint> sources(1, source);
1723 std::vector<SurfacePoint> stop_points(1, destination);
1724 double const max_propagation_distance = GEODESIC_INF;
1725
1726 propagate(sources,
1727 max_propagation_distance,
1728 &stop_points);
1729
1730 trace_back(destination, path);
1731}

References igl::geodesic::GEODESIC_INF, igl::geodesic::GeodesicAlgorithmBase::propagate(), and igl::geodesic::GeodesicAlgorithmBase::trace_back().

Referenced by igl::geodesic::GeodesicAlgorithmBase::trace_back().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ initialize_propagation_data()

void igl::geodesic::GeodesicAlgorithmExact::initialize_propagation_data ( )
inlineprivate
2281{
2282 clear();
2283
2284 IntervalWithStop candidate;
2285 std::vector<edge_pointer> edges_visible_from_source;
2286 for(unsigned i=0; i<m_sources.size(); ++i) //for all edges adjacent to the starting vertex
2287 {
2288 SurfacePoint* source = &m_sources[i];
2289
2290 edges_visible_from_source.clear();
2291 list_edges_visible_from_source(source->base_element(),
2292 edges_visible_from_source);
2293
2294 for(unsigned j=0; j<edges_visible_from_source.size(); ++j)
2295 {
2296 edge_pointer e = edges_visible_from_source[j];
2297 candidate.initialize(e, source, i);
2298 candidate.stop() = e->length();
2299 candidate.compute_min_distance(candidate.stop());
2300 candidate.direction() = Interval::FROM_SOURCE;
2301
2302 update_list_and_queue(interval_list(e), &candidate, 1);
2303 }
2304 }
2305}
double & length()
Definition exact_geodesic.cpp:484
void update_list_and_queue(list_pointer list, IntervalWithStop *candidates, unsigned num_candidates)
Definition exact_geodesic.cpp:2485
void clear()
Definition exact_geodesic.cpp:1865
void list_edges_visible_from_source(MeshElementBase *p, std::vector< edge_pointer > &storage)
Definition exact_geodesic.cpp:2061
@ FROM_SOURCE
Definition exact_geodesic.cpp:1204

References igl::geodesic::SurfacePoint::base_element(), clear(), igl::geodesic::Interval::compute_min_distance(), igl::geodesic::Interval::direction(), igl::geodesic::Interval::FROM_SOURCE, igl::geodesic::Interval::initialize(), interval_list(), igl::geodesic::Edge::length(), list_edges_visible_from_source(), m_sources, igl::geodesic::IntervalWithStop::stop(), and update_list_and_queue().

Referenced by propagate().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ intersect_intervals()

unsigned igl::geodesic::GeodesicAlgorithmExact::intersect_intervals ( interval_pointer  zero,
IntervalWithStop one 
)
inlineprivate
2110{
2111 assert(zero->edge()->id() == one->edge()->id());
2112 assert(zero->stop() > one->start() && zero->start() < one->stop());
2113 assert(one->min() < GEODESIC_INF/10.0);
2114
2115 double const local_epsilon = SMALLEST_INTERVAL_RATIO*one->edge()->length();
2116
2117 unsigned N=0;
2118 if(zero->min() > GEODESIC_INF/10.0)
2119 {
2120 start[0] = zero->start();
2121 if(zero->start() < one->start() - local_epsilon)
2122 {
2123 map[0] = OLD;
2124 start[1] = one->start();
2125 map[1] = NEW;
2126 N = 2;
2127 }
2128 else
2129 {
2130 map[0] = NEW;
2131 N = 1;
2132 }
2133
2134 if(zero->stop() > one->stop() + local_epsilon)
2135 {
2136 map[N] = OLD; //"zero" interval
2137 start[N++] = one->stop();
2138 }
2139
2140 start[N+1] = zero->stop();
2141 return N;
2142 }
2143
2144 double const local_small_epsilon = 1e-8*one->edge()->length();
2145
2146 double D = zero->d() - one->d();
2147 double x0 = zero->pseudo_x();
2148 double x1 = one->pseudo_x();
2149 double R0 = x0*x0 + zero->pseudo_y()*zero->pseudo_y();
2150 double R1 = x1*x1 + one->pseudo_y()*one->pseudo_y();
2151
2152 double inter[2]; //points of intersection
2153 char Ninter=0; //number of the points of the intersection
2154
2155 if(std::abs(D)<local_epsilon) //if d1 == d0, equation is linear
2156 {
2157 double denom = x1 - x0;
2158 if(std::abs(denom)>local_small_epsilon)
2159 {
2160 inter[0] = (R1 - R0)/(2.*denom); //one solution
2161 Ninter = 1;
2162 }
2163 }
2164 else
2165 {
2166 double D2 = D*D;
2167 double Q = 0.5*(R1-R0-D2);
2168 double X = x0 - x1;
2169
2170 double A = X*X - D2;
2171 double B = Q*X + D2*x0;
2172 double C = Q*Q - D2*R0;
2173
2174 if (std::abs(A)<local_small_epsilon) //if A == 0, linear equation
2175 {
2176 if(std::abs(B)>local_small_epsilon)
2177 {
2178 inter[0] = -C/B; //one solution
2179 Ninter = 1;
2180 }
2181 }
2182 else
2183 {
2184 double det = B*B-A*C;
2185 if(det>local_small_epsilon*local_small_epsilon) //two roots
2186 {
2187 det = sqrt(det);
2188 if(A>0.0) //make sure that the roots are ordered
2189 {
2190 inter[0] = (-B - det)/A;
2191 inter[1] = (-B + det)/A;
2192 }
2193 else
2194 {
2195 inter[0] = (-B + det)/A;
2196 inter[1] = (-B - det)/A;
2197 }
2198
2199 if(inter[1] - inter[0] > local_small_epsilon)
2200 {
2201 Ninter = 2;
2202 }
2203 else
2204 {
2205 Ninter = 1;
2206 }
2207 }
2208 else if(det>=0.0) //single root
2209 {
2210 inter[0] = -B/A;
2211 Ninter = 1;
2212 }
2213 }
2214 }
2215 //---------------------------find possible intervals---------------------------------------
2216 double left = std::max(zero->start(), one->start()); //define left and right boundaries of the intersection of the intervals
2217 double right = std::min(zero->stop(), one->stop());
2218
2219 double good_start[4]; //points of intersection within the (left, right) limits +"left" + "right"
2220 good_start[0] = left;
2221 char Ngood_start=1; //number of the points of the intersection
2222
2223 for(char i=0; i<Ninter; ++i) //for all points of intersection
2224 {
2225 double x = inter[i];
2226 if(x > left + local_epsilon && x < right - local_epsilon)
2227 {
2228 good_start[Ngood_start++] = x;
2229 }
2230 }
2231 good_start[Ngood_start++] = right;
2232
2233 MapType mid_map[3];
2234 for(char i=0; i<Ngood_start-1; ++i)
2235 {
2236 double mid = (good_start[i] + good_start[i+1])*0.5;
2237 mid_map[i] = zero->signal(mid) <= one->signal(mid) ? OLD : NEW;
2238 }
2239
2240 //-----------------------------------output----------------------------------
2241 N = 0;
2242 if(zero->start() < left - local_epsilon) //additional "zero" interval
2243 {
2244 if(mid_map[0] == OLD) //first interval in the map is already the old one
2245 {
2246 good_start[0] = zero->start();
2247 }
2248 else
2249 {
2250 map[N] = OLD; //"zero" interval
2251 start[N++] = zero->start();
2252 }
2253 }
2254
2255 for(long i=0;i<Ngood_start-1;++i) //for all intervals
2256 {
2257 MapType current_map = mid_map[i];
2258 if(N==0 || map[N-1] != current_map)
2259 {
2260 map[N] = current_map;
2261 start[N++] = good_start[i];
2262 }
2263 }
2264
2265 if(zero->stop() > one->stop() + local_epsilon)
2266 {
2267 if(N==0 || map[N-1] == NEW)
2268 {
2269 map[N] = OLD; //"zero" interval
2270 start[N++] = one->stop();
2271 }
2272 }
2273
2274 start[0] = zero->start(); // just to make sure that epsilons do not damage anything
2275 //start[N] = zero->stop();
2276
2277 return N;
2278}
MapType map[5]
Definition exact_geodesic.cpp:1910
MapType
Definition exact_geodesic.cpp:1909
@ X
Definition libslic3r.h:98
TCoord< P > x(const P &p)
Definition geometry_traits.hpp:297

References igl::geodesic::Interval::d(), igl::geodesic::Interval::edge(), igl::geodesic::GEODESIC_INF, igl::geodesic::MeshElementBase::id(), igl::geodesic::Edge::length(), map, igl::geodesic::Interval::min(), NEW, OLD, igl::geodesic::Interval::pseudo_x(), igl::geodesic::Interval::pseudo_y(), igl::geodesic::Interval::signal(), igl::geodesic::SMALLEST_INTERVAL_RATIO, sqrt(), igl::geodesic::Interval::start(), start, igl::geodesic::Interval::stop(), and igl::geodesic::IntervalWithStop::stop().

Referenced by update_list_and_queue().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ interval_list()

list_pointer igl::geodesic::GeodesicAlgorithmExact::interval_list ( edge_pointer  e)
inlineprivate
1877 {
1878 return &m_edge_interval_lists[e->id()];
1879 };

References igl::geodesic::MeshElementBase::id(), and m_edge_interval_lists.

Referenced by best_first_interval(), best_point_on_the_edge_set(), check_stop_conditions(), initialize_propagation_data(), propagate(), and visible_from_source().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ list_edges_visible_from_source()

void igl::geodesic::GeodesicAlgorithmExact::list_edges_visible_from_source ( MeshElementBase p,
std::vector< edge_pointer > &  storage 
)
inlineprivate
2063{
2064 assert(p->type() != UNDEFINED_POINT);
2065
2066 if(p->type() == FACE)
2067 {
2068 face_pointer f = static_cast<face_pointer>(p);
2069 for(unsigned i=0; i<3; ++i)
2070 {
2071 storage.push_back(f->adjacent_edges()[i]);
2072 }
2073 }
2074 else if(p->type() == EDGE)
2075 {
2076 edge_pointer e = static_cast<edge_pointer>(p);
2077 storage.push_back(e);
2078 }
2079 else //VERTEX
2080 {
2081 vertex_pointer v = static_cast<vertex_pointer>(p);
2082 for(unsigned i=0; i<v->adjacent_edges().size(); ++i)
2083 {
2084 storage.push_back(v->adjacent_edges()[i]);
2085 }
2086
2087 }
2088}

References igl::geodesic::MeshElementBase::adjacent_edges(), igl::geodesic::EDGE, igl::geodesic::FACE, igl::geodesic::SimpleVector< Data >::size(), igl::geodesic::MeshElementBase::type(), and igl::geodesic::UNDEFINED_POINT.

Referenced by initialize_propagation_data().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mesh()

geodesic::Mesh * igl::geodesic::GeodesicAlgorithmBase::mesh ( )
inlineinherited
1660{return m_mesh;};
geodesic::Mesh * m_mesh
Definition exact_geodesic.cpp:1676

References igl::geodesic::GeodesicAlgorithmBase::m_mesh.

Referenced by GeodesicAlgorithmExact().

+ Here is the caller graph for this function:

◆ name()

std::string igl::geodesic::GeodesicAlgorithmBase::name ( )
inlinevirtualinherited
1703{
1704 switch(m_type)
1705 {
1706 case EXACT:
1707 return "exact";
1708 case DIJKSTRA:
1709 return "dijkstra";
1710 case SUBDIVISION:
1711 return "subdivision";
1712 default:
1714 return "undefined";
1715 }
1716}

References igl::geodesic::GeodesicAlgorithmBase::DIJKSTRA, igl::geodesic::GeodesicAlgorithmBase::EXACT, igl::geodesic::GeodesicAlgorithmBase::m_type, igl::geodesic::GeodesicAlgorithmBase::SUBDIVISION, and igl::geodesic::GeodesicAlgorithmBase::UNDEFINED_ALGORITHM.

◆ possible_traceback_edges()

void igl::geodesic::GeodesicAlgorithmExact::possible_traceback_edges ( SurfacePoint point,
std::vector< edge_pointer > &  storage 
)
inlineprivate
1952{
1953 storage.clear();
1954
1955 if(point.type() == VERTEX)
1956 {
1957 vertex_pointer v = static_cast<vertex_pointer>(point.base_element());
1958 for(unsigned i=0; i<v->adjacent_faces().size(); ++i)
1959 {
1960 face_pointer f = v->adjacent_faces()[i];
1961 storage.push_back(f->opposite_edge(v));
1962 }
1963 }
1964 else if(point.type() == EDGE)
1965 {
1966 edge_pointer e = static_cast<edge_pointer>(point.base_element());
1967 for(unsigned i=0; i<e->adjacent_faces().size(); ++i)
1968 {
1969 face_pointer f = e->adjacent_faces()[i];
1970
1971 storage.push_back(f->next_edge(e,e->v0()));
1972 storage.push_back(f->next_edge(e,e->v1()));
1973 }
1974 }
1975 else
1976 {
1977 face_pointer f = static_cast<face_pointer>(point.base_element());
1978 storage.push_back(f->adjacent_edges()[0]);
1979 storage.push_back(f->adjacent_edges()[1]);
1980 storage.push_back(f->adjacent_edges()[2]);
1981 }
1982}
face_pointer_vector & adjacent_faces()
Definition exact_geodesic.cpp:348

References igl::geodesic::MeshElementBase::adjacent_edges(), igl::geodesic::MeshElementBase::adjacent_faces(), igl::geodesic::SurfacePoint::base_element(), igl::geodesic::EDGE, igl::geodesic::Face::next_edge(), igl::geodesic::Face::opposite_edge(), igl::geodesic::SimpleVector< Data >::size(), igl::geodesic::SurfacePoint::type(), igl::geodesic::Edge::v0(), igl::geodesic::Edge::v1(), and igl::geodesic::VERTEX.

Referenced by trace_back().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ print_statistics()

void igl::geodesic::GeodesicAlgorithmExact::print_statistics ( )
inlinevirtual

Reimplemented from igl::geodesic::GeodesicAlgorithmBase.

3134{
3136
3137 unsigned interval_counter = 0;
3138 for(unsigned i=0; i<m_edge_interval_lists.size(); ++i)
3139 {
3140 interval_counter += m_edge_interval_lists[i].number_of_intervals();
3141 }
3142 double intervals_per_edge = (double)interval_counter/(double)m_edge_interval_lists.size();
3143
3144 double memory = m_edge_interval_lists.size()*sizeof(IntervalList) +
3145 interval_counter*sizeof(Interval);
3146
3147 std::cout << "uses about " << memory/1e6 << "Mb of memory" <<std::endl;
3148 std::cout << interval_counter << " total intervals, or "
3149 << intervals_per_edge << " intervals per edge"
3150 << std::endl;
3151 std::cout << "maximum interval queue size is " << m_queue_max_size << std::endl;
3152 std::cout << "number of interval propagations is " << m_iterations << std::endl;
3153}
virtual void print_statistics()
Definition exact_geodesic.cpp:1651
unsigned m_iterations
Definition exact_geodesic.cpp:1915
unsigned m_queue_max_size
Definition exact_geodesic.cpp:1914

References m_edge_interval_lists, m_iterations, m_queue_max_size, and igl::geodesic::GeodesicAlgorithmBase::print_statistics().

+ Here is the call graph for this function:

◆ propagate()

void igl::geodesic::GeodesicAlgorithmExact::propagate ( std::vector< SurfacePoint > &  sources,
double  max_propagation_distance = GEODESIC_INF,
std::vector< SurfacePoint > *  stop_points = NULL 
)
inlinevirtual

Implements igl::geodesic::GeodesicAlgorithmBase.

2310{
2311 set_stop_conditions(stop_points, max_propagation_distance);
2312 set_sources(sources);
2314
2315 clock_t start = clock();
2316
2317 unsigned satisfied_index = 0;
2318
2319 m_iterations = 0; //for statistics
2320 m_queue_max_size = 0;
2321
2322 IntervalWithStop candidates[2];
2323
2324 while(!m_queue.empty())
2325 {
2326 m_queue_max_size = std::max(static_cast<unsigned int>(m_queue.size()), m_queue_max_size);
2327
2328 unsigned const check_period = 10;
2329 if(++m_iterations % check_period == 0) //check if we covered all required vertices
2330 {
2331 if (check_stop_conditions(satisfied_index))
2332 {
2333 break;
2334 }
2335 }
2336
2337 interval_pointer min_interval = *m_queue.begin();
2338 m_queue.erase(m_queue.begin());
2339 edge_pointer edge = min_interval->edge();
2340 list_pointer list = interval_list(edge);
2341
2342 assert(min_interval->d() < GEODESIC_INF);
2343
2344 bool const first_interval = min_interval->start() == 0.0;
2345 //bool const last_interval = min_interval->stop() == edge->length();
2346 bool const last_interval = min_interval->next() == NULL;
2347
2348 bool const turn_left = edge->v0()->saddle_or_boundary();
2349 bool const turn_right = edge->v1()->saddle_or_boundary();
2350
2351 for(unsigned i=0; i<edge->adjacent_faces().size(); ++i) //two possible faces to propagate
2352 {
2353 if(!edge->is_boundary()) //just in case, always propagate boundary edges
2354 {
2355 if((i == 0 && min_interval->direction() == Interval::FROM_FACE_0) ||
2356 (i == 1 && min_interval->direction() == Interval::FROM_FACE_1))
2357 {
2358 continue;
2359 }
2360 }
2361
2362 face_pointer face = edge->adjacent_faces()[i]; //if we come from 1, go to 2
2363 edge_pointer next_edge = face->next_edge(edge,edge->v0());
2364
2365 unsigned num_propagated = compute_propagated_parameters(min_interval->pseudo_x(),
2366 min_interval->pseudo_y(),
2367 min_interval->d(), //parameters of the interval
2368 min_interval->start(),
2369 min_interval->stop(), //start/end of the interval
2370 face->vertex_angle(edge->v0()), //corner angle
2371 next_edge->length(), //length of the new edge
2372 first_interval, //if it is the first interval on the edge
2373 last_interval,
2374 turn_left,
2375 turn_right,
2376 candidates); //if it is the last interval on the edge
2377 bool propagate_to_right = true;
2378
2379 if(num_propagated)
2380 {
2381 if(candidates[num_propagated-1].stop() != next_edge->length())
2382 {
2383 propagate_to_right = false;
2384 }
2385
2386 bool const invert = next_edge->v0()->id() != edge->v0()->id(); //if the origins coinside, do not invert intervals
2387
2388 construct_propagated_intervals(invert, //do not inverse
2389 next_edge,
2390 face,
2391 candidates,
2392 num_propagated,
2393 min_interval);
2394
2396 candidates,
2397 num_propagated);
2398 }
2399
2400 if(propagate_to_right)
2401 {
2402 //propogation to the right edge
2403 double length = edge->length();
2404 next_edge = face->next_edge(edge,edge->v1());
2405
2406 num_propagated = compute_propagated_parameters(length - min_interval->pseudo_x(),
2407 min_interval->pseudo_y(),
2408 min_interval->d(), //parameters of the interval
2409 length - min_interval->stop(),
2410 length - min_interval->start(), //start/end of the interval
2411 face->vertex_angle(edge->v1()), //corner angle
2412 next_edge->length(), //length of the new edge
2413 last_interval, //if it is the first interval on the edge
2414 first_interval,
2415 turn_right,
2416 turn_left,
2417 candidates); //if it is the last interval on the edge
2418
2419 if(num_propagated)
2420 {
2421 bool const invert = next_edge->v0()->id() != edge->v1()->id(); //if the origins coinside, do not invert intervals
2422
2423 construct_propagated_intervals(invert, //do not inverse
2424 next_edge,
2425 face,
2426 candidates,
2427 num_propagated,
2428 min_interval);
2429
2431 candidates,
2432 num_propagated);
2433 }
2434 }
2435 }
2436 }
2437
2439 clock_t stop = clock();
2440 m_time_consumed = (static_cast<double>(stop)-static_cast<double>(start))/CLOCKS_PER_SEC;
2441
2442/* for(unsigned i=0; i<m_edge_interval_lists.size(); ++i)
2443 {
2444 list_pointer list = &m_edge_interval_lists[i];
2445 interval_pointer p = list->first();
2446 assert(p->start() == 0.0);
2447 while(p->next())
2448 {
2449 assert(p->stop() == p->next()->start());
2450 assert(p->d() < GEODESIC_INF);
2451 p = p->next();
2452 }
2453 }*/
2454}
double m_time_consumed
Definition exact_geodesic.cpp:1678
void set_stop_conditions(std::vector< SurfacePoint > *stop_points, double stop_distance)
Definition exact_geodesic.cpp:1751
void set_sources(std::vector< SurfacePoint > &sources)
Definition exact_geodesic.cpp:1881
unsigned compute_propagated_parameters(double pseudo_x, double pseudo_y, double d, double start, double end, double alpha, double L, bool first_interval, bool last_interval, bool turn_left, bool turn_right, IntervalWithStop *candidates)
Definition exact_geodesic.cpp:2713
void initialize_propagation_data()
Definition exact_geodesic.cpp:2280
bool check_stop_conditions(unsigned &index)
Definition exact_geodesic.cpp:2457
void construct_propagated_intervals(bool invert, edge_pointer edge, face_pointer face, IntervalWithStop *candidates, unsigned &num_candidates, interval_pointer source_interval)
Definition exact_geodesic.cpp:2839
constexpr auto size(const C &c) -> decltype(c.size())
Definition span.hpp:183

References igl::geodesic::MeshElementBase::adjacent_faces(), check_stop_conditions(), compute_propagated_parameters(), construct_propagated_intervals(), igl::geodesic::Interval::d(), igl::geodesic::Interval::direction(), igl::geodesic::Interval::edge(), igl::geodesic::Interval::FROM_FACE_0, igl::geodesic::Interval::FROM_FACE_1, igl::geodesic::GEODESIC_INF, igl::geodesic::MeshElementBase::id(), initialize_propagation_data(), interval_list(), igl::geodesic::Edge::is_boundary(), igl::geodesic::Edge::length(), igl::geodesic::length(), m_iterations, igl::geodesic::GeodesicAlgorithmBase::m_propagation_distance_stopped, m_queue, m_queue_max_size, igl::geodesic::GeodesicAlgorithmBase::m_time_consumed, igl::min(), igl::geodesic::Interval::next(), igl::geodesic::Face::next_edge(), igl::geodesic::Interval::pseudo_x(), igl::geodesic::Interval::pseudo_y(), igl::geodesic::Vertex::saddle_or_boundary(), set_sources(), igl::geodesic::GeodesicAlgorithmBase::set_stop_conditions(), igl::geodesic::Interval::start(), start, igl::geodesic::Interval::stop(), update_list_and_queue(), igl::geodesic::Edge::v0(), igl::geodesic::Edge::v1(), and igl::geodesic::Face::vertex_angle().

Referenced by igl::exact_geodesic().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ set_sources()

void igl::geodesic::GeodesicAlgorithmExact::set_sources ( std::vector< SurfacePoint > &  sources)
inlineprivate
1882 {
1883 m_sources.initialize(sources);
1884 }
void initialize(std::vector< SurfacePoint > &sources)
Definition exact_geodesic.cpp:1481

References igl::geodesic::SortedSources::initialize(), and m_sources.

Referenced by propagate().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ set_stop_conditions()

void igl::geodesic::GeodesicAlgorithmBase::set_stop_conditions ( std::vector< SurfacePoint > *  stop_points,
double  stop_distance 
)
inlineprotectedinherited
1753{
1755
1756 if(!stop_points)
1757 {
1758 m_stop_vertices.clear();
1759 return;
1760 }
1761
1762 m_stop_vertices.resize(stop_points->size());
1763
1764 std::vector<vertex_pointer> possible_vertices;
1765 for(unsigned i = 0; i < stop_points->size(); ++i)
1766 {
1767 SurfacePoint* point = &(*stop_points)[i];
1768
1769 possible_vertices.clear();
1770 m_mesh->closest_vertices(point, &possible_vertices);
1771
1772 vertex_pointer closest_vertex = NULL;
1773 double min_distance = 1e100;
1774 for(unsigned j = 0; j < possible_vertices.size(); ++j)
1775 {
1776 double distance = point->distance(possible_vertices[j]);
1777 if(distance < min_distance)
1778 {
1779 min_distance = distance;
1780 closest_vertex = possible_vertices[j];
1781 }
1782 }
1783 assert(closest_vertex);
1784
1785 m_stop_vertices[i].first = closest_vertex;
1786 m_stop_vertices[i].second = min_distance;
1787 }
1788}
double m_max_propagation_distance
Definition exact_geodesic.cpp:1674
unsigned closest_vertices(SurfacePoint *p, std::vector< vertex_pointer > *storage=NULL)
Definition exact_geodesic.cpp:729

References igl::geodesic::Mesh::closest_vertices(), igl::geodesic::Point3D::distance(), igl::geodesic::GeodesicAlgorithmBase::m_max_propagation_distance, igl::geodesic::GeodesicAlgorithmBase::m_mesh, igl::geodesic::GeodesicAlgorithmBase::m_stop_vertices, and igl::geodesic::GeodesicAlgorithmBase::stop_distance().

Referenced by propagate().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ stop_distance()

double igl::geodesic::GeodesicAlgorithmBase::stop_distance ( )
inlineprotectedinherited
1666 {
1668 }

References igl::geodesic::GeodesicAlgorithmBase::m_max_propagation_distance.

Referenced by check_stop_conditions(), and igl::geodesic::GeodesicAlgorithmBase::set_stop_conditions().

+ Here is the caller graph for this function:

◆ trace_back()

void igl::geodesic::GeodesicAlgorithmExact::trace_back ( SurfacePoint destination,
std::vector< SurfacePoint > &  path 
)
inlinevirtual

Implements igl::geodesic::GeodesicAlgorithmBase.

3066{
3067 path.clear();
3068 double best_total_distance;
3069 double best_interval_position;
3070 unsigned source_index = std::numeric_limits<unsigned>::max();
3071 interval_pointer best_interval = best_first_interval(destination,
3072 best_total_distance,
3073 best_interval_position,
3074 source_index);
3075
3076 if(best_total_distance >= GEODESIC_INF/2.0) //unable to find the right path
3077 {
3078 return;
3079 }
3080
3081 path.push_back(destination);
3082
3083 if(best_interval) //if we did not hit the face source immediately
3084 {
3085 std::vector<edge_pointer> possible_edges;
3086 possible_edges.reserve(10);
3087
3088 while(visible_from_source(path.back()) < 0) //while this point is not in the direct visibility of some source (if we are inside the FACE, we obviously hit the source)
3089 {
3090 SurfacePoint& q = path.back();
3091
3092 possible_traceback_edges(q, possible_edges);
3093
3094 interval_pointer interval;
3095 double total_distance;
3096 double position;
3097
3099 possible_edges,
3100 interval,
3101 total_distance,
3102 position);
3103
3104 //std::cout << total_distance + length(path) << std::endl;
3105 assert(total_distance<GEODESIC_INF);
3106 source_index = interval->source_index();
3107
3108 edge_pointer e = interval->edge();
3109 double local_epsilon = SMALLEST_INTERVAL_RATIO*e->length();
3110 if(position < local_epsilon)
3111 {
3112 path.push_back(SurfacePoint(e->v0()));
3113 }
3114 else if(position > e->length()-local_epsilon)
3115 {
3116 path.push_back(SurfacePoint(e->v1()));
3117 }
3118 else
3119 {
3120 double normalized_position = position/e->length();
3121 path.push_back(SurfacePoint(e, normalized_position));
3122 }
3123 }
3124 }
3125
3126 SurfacePoint& source = static_cast<SurfacePoint&>(m_sources[source_index]);
3127 if(path.back().distance(&source) > 0)
3128 {
3129 path.push_back(source);
3130 }
3131}
long visible_from_source(SurfacePoint &point)
Definition exact_geodesic.cpp:1985
void possible_traceback_edges(SurfacePoint &point, std::vector< edge_pointer > &storage)
Definition exact_geodesic.cpp:1950
void best_point_on_the_edge_set(SurfacePoint &point, std::vector< edge_pointer > const &storage, interval_pointer &best_interval, double &best_total_distance, double &best_interval_position)
Definition exact_geodesic.cpp:1920

References best_first_interval(), best_point_on_the_edge_set(), igl::geodesic::Interval::edge(), igl::geodesic::GEODESIC_INF, igl::geodesic::Edge::length(), m_sources, possible_traceback_edges(), igl::geodesic::SMALLEST_INTERVAL_RATIO, igl::geodesic::Interval::source_index(), igl::geodesic::Edge::v0(), igl::geodesic::Edge::v1(), and visible_from_source().

Referenced by igl::exact_geodesic().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ type()

AlgorithmType igl::geodesic::GeodesicAlgorithmBase::type ( )
inlineinherited

◆ update_list_and_queue()

void igl::geodesic::GeodesicAlgorithmExact::update_list_and_queue ( list_pointer  list,
IntervalWithStop candidates,
unsigned  num_candidates 
)
inlineprivate
2488{
2489 assert(num_candidates <= 2);
2490 //assert(list->first() != NULL);
2491 edge_pointer edge = list->edge();
2492 double const local_epsilon = SMALLEST_INTERVAL_RATIO * edge->length();
2493
2494 if(list->first() == NULL)
2495 {
2496 interval_pointer* p = &list->first();
2497 IntervalWithStop* first;
2498 IntervalWithStop* second;
2499
2500 if(num_candidates == 1)
2501 {
2502 first = candidates;
2503 second = candidates;
2504 first->compute_min_distance(first->stop());
2505 }
2506 else
2507 {
2508 if(candidates->start() <= (candidates+1)->start())
2509 {
2510 first = candidates;
2511 second = candidates+1;
2512 }
2513 else
2514 {
2515 first = candidates+1;
2516 second = candidates;
2517 }
2518 assert(first->stop() == second->start());
2519
2520 first->compute_min_distance(first->stop());
2521 second->compute_min_distance(second->stop());
2522 }
2523
2524 if(first->start() > 0.0)
2525 {
2526 *p = m_memory_allocator.allocate();
2527 (*p)->initialize(edge);
2528 p = &(*p)->next();
2529 }
2530
2531 *p = m_memory_allocator.allocate();
2532 memcpy(*p,first,sizeof(Interval));
2533 m_queue.insert(*p);
2534
2535 if(num_candidates == 2)
2536 {
2537 p = &(*p)->next();
2538 *p = m_memory_allocator.allocate();
2539 memcpy(*p,second,sizeof(Interval));
2540 m_queue.insert(*p);
2541 }
2542
2543 if(second->stop() < edge->length())
2544 {
2545 p = &(*p)->next();
2546 *p = m_memory_allocator.allocate();
2547 (*p)->initialize(edge);
2548 (*p)->start() = second->stop();
2549 }
2550 else
2551 {
2552 (*p)->next() = NULL;
2553 }
2554 return;
2555 }
2556
2557 bool propagate_flag;
2558
2559 for(unsigned i=0; i<num_candidates; ++i) //for all new intervals
2560 {
2561 IntervalWithStop* q = &candidates[i];
2562
2563 interval_pointer previous = NULL;
2564
2565 interval_pointer p = list->first();
2566 assert(p->start() == 0.0);
2567
2568 while(p != NULL && p->stop() - local_epsilon < q->start())
2569 {
2570 p = p->next();
2571 }
2572
2573 while(p != NULL && p->start() < q->stop() - local_epsilon) //go through all old intervals
2574 {
2575 unsigned const N = intersect_intervals(p, q); //interset two intervals
2576
2577 if(N == 1)
2578 {
2579 if(map[0]==OLD) //if "p" is always better, we do not need to update anything)
2580 {
2581 if(previous) //close previous interval and put in into the queue
2582 {
2583 previous->next() = p;
2584 previous->compute_min_distance(p->start());
2585 m_queue.insert(previous);
2586 previous = NULL;
2587 }
2588
2589 p = p->next();
2590
2591 }
2592 else if(previous) //extend previous interval to cover everything; remove p
2593 {
2594 previous->next() = p->next();
2596 m_memory_allocator.deallocate(p);
2597
2598 p = previous->next();
2599 }
2600 else //p becomes "previous"
2601 {
2602 previous = p;
2603 interval_pointer next = p->next();
2605
2606 memcpy(previous,q,sizeof(Interval));
2607
2608 previous->start() = start[0];
2609 previous->next() = next;
2610
2611 p = next;
2612 }
2613 continue;
2614 }
2615
2616 //update_flag = true;
2617
2618 Interval swap(*p); //used for swapping information
2619 propagate_flag = erase_from_queue(p);
2620
2621 for(unsigned j=1; j<N; ++j) //no memory is needed for the first one
2622 {
2623 i_new[j] = m_memory_allocator.allocate(); //create new intervals
2624 }
2625
2626 if(map[0]==OLD) //finish previous, if any
2627 {
2628 if(previous)
2629 {
2630 previous->next() = p;
2631 previous->compute_min_distance(previous->stop());
2632 m_queue.insert(previous);
2633 previous = NULL;
2634 }
2635 i_new[0] = p;
2636 p->next() = i_new[1];
2637 p->start() = start[0];
2638 }
2639 else if(previous) //extend previous interval to cover everything; remove p
2640 {
2641 i_new[0] = previous;
2642 previous->next() = i_new[1];
2643 m_memory_allocator.deallocate(p);
2644 previous = NULL;
2645 }
2646 else //p becomes "previous"
2647 {
2648 i_new[0] = p;
2649 memcpy(p,q,sizeof(Interval));
2650
2651 p->next() = i_new[1];
2652 p->start() = start[0];
2653 }
2654
2655 assert(!previous);
2656
2657 for(unsigned j=1; j<N; ++j)
2658 {
2659 interval_pointer current_interval = i_new[j];
2660
2661 if(map[j] == OLD)
2662 {
2663 memcpy(current_interval,&swap,sizeof(Interval));
2664 }
2665 else
2666 {
2667 memcpy(current_interval,q,sizeof(Interval));
2668 }
2669
2670 if(j == N-1)
2671 {
2672 current_interval->next() = swap.next();
2673 }
2674 else
2675 {
2676 current_interval->next() = i_new[j+1];
2677 }
2678
2679 current_interval->start() = start[j];
2680 }
2681
2682 for(unsigned j=0; j<N; ++j) //find "min" and add the intervals to the queue
2683 {
2684 if(j==N-1 && map[j]==NEW)
2685 {
2686 previous = i_new[j];
2687 }
2688 else
2689 {
2690 interval_pointer current_interval = i_new[j];
2691
2692 current_interval->compute_min_distance(current_interval->stop()); //compute minimal distance
2693
2694 if(map[j]==NEW || (map[j]==OLD && propagate_flag))
2695 {
2696 m_queue.insert(current_interval);
2697 }
2698 }
2699 }
2700
2701 p = swap.next();
2702 }
2703
2704 if(previous) //close previous interval and put in into the queue
2705 {
2706 previous->compute_min_distance(previous->stop());
2707 m_queue.insert(previous);
2708 previous = NULL;
2709 }
2710 }
2711}
interval_pointer i_new[5]
Definition exact_geodesic.cpp:1912
bool erase_from_queue(interval_pointer p)
Definition exact_geodesic.cpp:2090
unsigned intersect_intervals(interval_pointer zero, IntervalWithStop *one)
Definition exact_geodesic.cpp:2108
interval_pointer & next()
Definition exact_geodesic.cpp:1305
double & start()
Definition exact_geodesic.cpp:1300
void compute_min_distance(double stop)
Definition exact_geodesic.cpp:1246
void swap(scoped_array< T > &a, scoped_array< T > &b)
Definition Memory.h:602

References igl::geodesic::Interval::compute_min_distance(), igl::geodesic::IntervalList::edge(), erase_from_queue(), igl::geodesic::IntervalList::first(), i_new, intersect_intervals(), igl::geodesic::Edge::length(), m_memory_allocator, m_queue, map, NEW, igl::geodesic::Interval::next(), OLD, igl::geodesic::SMALLEST_INTERVAL_RATIO, igl::geodesic::Interval::start(), start, igl::geodesic::Interval::stop(), and igl::geodesic::IntervalWithStop::stop().

Referenced by initialize_propagation_data(), and propagate().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ visible_from_source()

long igl::geodesic::GeodesicAlgorithmExact::visible_from_source ( SurfacePoint point)
inlineprivate
1986{
1987 assert(point.type() != UNDEFINED_POINT);
1988
1989 if(point.type() == EDGE)
1990 {
1991 edge_pointer e = static_cast<edge_pointer>(point.base_element());
1992 list_pointer list = interval_list(e);
1993 double position = std::min(point.distance(e->v0()), e->length());
1994 interval_pointer interval = list->covering_interval(position);
1995 //assert(interval);
1996 if(interval && interval->visible_from_source())
1997 {
1998 return (long)interval->source_index();
1999 }
2000 else
2001 {
2002 return -1;
2003 }
2004 }
2005 else if(point.type() == FACE)
2006 {
2007 return -1;
2008 }
2009 else if(point.type() == VERTEX)
2010 {
2011 vertex_pointer v = static_cast<vertex_pointer>(point.base_element());
2012 for(unsigned i=0; i<v->adjacent_edges().size(); ++i)
2013 {
2014 edge_pointer e = v->adjacent_edges()[i];
2015 list_pointer list = interval_list(e);
2016
2017 double position = e->v0()->id() == v->id() ? 0.0 : e->length();
2018 interval_pointer interval = list->covering_interval(position);
2019 if(interval && interval->visible_from_source())
2020 {
2021 return (long)interval->source_index();
2022 }
2023 }
2024
2025 return -1;
2026 }
2027
2028 assert(0);
2029 return 0;
2030}
unsigned & source_index()
Definition exact_geodesic.cpp:1309

References igl::geodesic::MeshElementBase::adjacent_edges(), igl::geodesic::SurfacePoint::base_element(), igl::geodesic::IntervalList::covering_interval(), igl::geodesic::Point3D::distance(), igl::geodesic::EDGE, igl::geodesic::FACE, igl::geodesic::MeshElementBase::id(), interval_list(), igl::geodesic::Edge::length(), igl::geodesic::SimpleVector< Data >::size(), igl::geodesic::Interval::source_index(), igl::geodesic::SurfacePoint::type(), igl::geodesic::UNDEFINED_POINT, igl::geodesic::Edge::v0(), igl::geodesic::VERTEX, and igl::geodesic::Interval::visible_from_source().

Referenced by trace_back().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Member Data Documentation

◆ i_new

interval_pointer igl::geodesic::GeodesicAlgorithmExact::i_new[5]
private

Referenced by update_list_and_queue().

◆ m_edge_interval_lists

std::vector<IntervalList> igl::geodesic::GeodesicAlgorithmExact::m_edge_interval_lists
private

◆ m_iterations

unsigned igl::geodesic::GeodesicAlgorithmExact::m_iterations
private

Referenced by print_statistics(), and propagate().

◆ m_max_propagation_distance

double igl::geodesic::GeodesicAlgorithmBase::m_max_propagation_distance
protectedinherited

◆ m_memory_allocator

MemoryAllocator<Interval> igl::geodesic::GeodesicAlgorithmExact::m_memory_allocator
private

Referenced by clear(), and update_list_and_queue().

◆ m_mesh

geodesic::Mesh* igl::geodesic::GeodesicAlgorithmBase::m_mesh
protectedinherited

◆ m_propagation_distance_stopped

double igl::geodesic::GeodesicAlgorithmBase::m_propagation_distance_stopped
protectedinherited

◆ m_queue

IntervalQueue igl::geodesic::GeodesicAlgorithmExact::m_queue
private

◆ m_queue_max_size

unsigned igl::geodesic::GeodesicAlgorithmExact::m_queue_max_size
private

Referenced by print_statistics(), and propagate().

◆ m_sources

SortedSources igl::geodesic::GeodesicAlgorithmExact::m_sources
private

◆ m_stop_vertices

std::vector<stop_vertex_with_distace_type> igl::geodesic::GeodesicAlgorithmBase::m_stop_vertices
protectedinherited

◆ m_time_consumed

double igl::geodesic::GeodesicAlgorithmBase::m_time_consumed
protectedinherited

◆ m_type

AlgorithmType igl::geodesic::GeodesicAlgorithmBase::m_type
protectedinherited

◆ map

MapType igl::geodesic::GeodesicAlgorithmExact::map[5]
private

◆ start

double igl::geodesic::GeodesicAlgorithmExact::start[6]
private

The documentation for this class was generated from the following file: