Prusa Slicer 2.6.0
Loading...
Searching...
No Matches
Slic3r::KDTreeIndirect< ANumDimensions, ACoordType, ACoordinateFn > Class Template Reference

#include <src/libslic3r/KDTreeIndirect.hpp>

+ Inheritance diagram for Slic3r::KDTreeIndirect< ANumDimensions, ACoordType, ACoordinateFn >:
+ Collaboration diagram for Slic3r::KDTreeIndirect< ANumDimensions, ACoordType, ACoordinateFn >:

Public Types

enum  : size_t { npos = size_t(-1) }
 
using CoordinateFn = ACoordinateFn
 
using CoordType = ACoordType
 

Public Member Functions

 KDTreeIndirect (CoordinateFn coordinate)
 
 KDTreeIndirect (CoordinateFn coordinate, std::vector< size_t > indices)
 
 KDTreeIndirect (CoordinateFn coordinate, size_t num_indices)
 
 KDTreeIndirect (KDTreeIndirect &&rhs)
 
KDTreeIndirectoperator= (KDTreeIndirect &&rhs)
 
void clear ()
 
void build (size_t num_indices)
 
void build (std::vector< size_t > &indices)
 
template<typename CoordType >
unsigned int descent_mask (const CoordType &point_coord, const CoordType &search_radius, size_t idx, size_t dimension) const
 
template<typename Visitor >
void visit (Visitor &visitor) const
 

Public Attributes

CoordinateFn coordinate
 

Static Public Attributes

static constexpr size_t NumDimensions = ANumDimensions
 

Private Member Functions

void build_recursive (std::vector< size_t > &input, size_t node, const size_t dimension, const size_t left, const size_t right)
 
void partition_input (std::vector< size_t > &input, const size_t dimension, size_t left, size_t right, const size_t k) const
 
template<typename Visitor >
void visit_recursive (size_t node, size_t dimension, Visitor &visitor) const
 

Private Attributes

std::vector< size_t > m_nodes
 

Detailed Description

template<size_t ANumDimensions, typename ACoordType, typename ACoordinateFn>
class Slic3r::KDTreeIndirect< ANumDimensions, ACoordType, ACoordinateFn >

Member Typedef Documentation

◆ CoordinateFn

template<size_t ANumDimensions, typename ACoordType , typename ACoordinateFn >
using Slic3r::KDTreeIndirect< ANumDimensions, ACoordType, ACoordinateFn >::CoordinateFn = ACoordinateFn

◆ CoordType

template<size_t ANumDimensions, typename ACoordType , typename ACoordinateFn >
using Slic3r::KDTreeIndirect< ANumDimensions, ACoordType, ACoordinateFn >::CoordType = ACoordType

Member Enumeration Documentation

◆ anonymous enum

template<size_t ANumDimensions, typename ACoordType , typename ACoordinateFn >
anonymous enum : size_t
Enumerator
npos 
29 : size_t {
30 npos = size_t(-1)
31 };
@ npos
Definition KDTreeIndirect.hpp:30

Constructor & Destructor Documentation

◆ KDTreeIndirect() [1/4]

template<size_t ANumDimensions, typename ACoordType , typename ACoordinateFn >
Slic3r::KDTreeIndirect< ANumDimensions, ACoordType, ACoordinateFn >::KDTreeIndirect ( CoordinateFn  coordinate)
inline
CoordinateFn coordinate
Definition KDTreeIndirect.hpp:79

◆ KDTreeIndirect() [2/4]

template<size_t ANumDimensions, typename ACoordType , typename ACoordinateFn >
Slic3r::KDTreeIndirect< ANumDimensions, ACoordType, ACoordinateFn >::KDTreeIndirect ( CoordinateFn  coordinate,
std::vector< size_t >  indices 
)
inline
34: coordinate(coordinate) { this->build(indices); }
void build(size_t num_indices)
Definition KDTreeIndirect.hpp:40

References Slic3r::KDTreeIndirect< ANumDimensions, ACoordType, ACoordinateFn >::build().

+ Here is the call graph for this function:

◆ KDTreeIndirect() [3/4]

template<size_t ANumDimensions, typename ACoordType , typename ACoordinateFn >
Slic3r::KDTreeIndirect< ANumDimensions, ACoordType, ACoordinateFn >::KDTreeIndirect ( CoordinateFn  coordinate,
size_t  num_indices 
)
inline
35: coordinate(coordinate) { this->build(num_indices); }

References Slic3r::KDTreeIndirect< ANumDimensions, ACoordType, ACoordinateFn >::build().

+ Here is the call graph for this function:

◆ KDTreeIndirect() [4/4]

template<size_t ANumDimensions, typename ACoordType , typename ACoordinateFn >
Slic3r::KDTreeIndirect< ANumDimensions, ACoordType, ACoordinateFn >::KDTreeIndirect ( KDTreeIndirect< ANumDimensions, ACoordType, ACoordinateFn > &&  rhs)
inline
36: m_nodes(std::move(rhs.m_nodes)), coordinate(std::move(rhs.coordinate)) {}
std::vector< size_t > m_nodes
Definition KDTreeIndirect.hpp:189

Member Function Documentation

◆ build() [1/2]

template<size_t ANumDimensions, typename ACoordType , typename ACoordinateFn >
void Slic3r::KDTreeIndirect< ANumDimensions, ACoordType, ACoordinateFn >::build ( size_t  num_indices)
inline
41 {
42 std::vector<size_t> indices;
43 indices.reserve(num_indices);
44 for (size_t i = 0; i < num_indices; ++ i)
45 indices.emplace_back(i);
46 this->build(indices);
47 }

References Slic3r::KDTreeIndirect< ANumDimensions, ACoordType, ACoordinateFn >::build().

Referenced by Slic3r::KDTreeIndirect< ANumDimensions, ACoordType, ACoordinateFn >::KDTreeIndirect(), Slic3r::KDTreeIndirect< ANumDimensions, ACoordType, ACoordinateFn >::KDTreeIndirect(), and Slic3r::KDTreeIndirect< ANumDimensions, ACoordType, ACoordinateFn >::build().

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

◆ build() [2/2]

template<size_t ANumDimensions, typename ACoordType , typename ACoordinateFn >
void Slic3r::KDTreeIndirect< ANumDimensions, ACoordType, ACoordinateFn >::build ( std::vector< size_t > &  indices)
inline
50 {
51 if (indices.empty())
52 clear();
53 else {
54 // Allocate enough memory for a full binary tree.
55 m_nodes.assign(next_highest_power_of_2(indices.size() + 1), npos);
56 build_recursive(indices, 0, 0, 0, indices.size() - 1);
57 }
58 indices.clear();
59 }
void build_recursive(std::vector< size_t > &input, size_t node, const size_t dimension, const size_t left, const size_t right)
Definition KDTreeIndirect.hpp:83
void clear()
Definition KDTreeIndirect.hpp:38
uint16_t next_highest_power_of_2(uint16_t v)
Definition Utils.hpp:125

References Slic3r::KDTreeIndirect< ANumDimensions, ACoordType, ACoordinateFn >::build_recursive(), Slic3r::KDTreeIndirect< ANumDimensions, ACoordType, ACoordinateFn >::clear(), Slic3r::KDTreeIndirect< ANumDimensions, ACoordType, ACoordinateFn >::m_nodes, Slic3r::next_highest_power_of_2(), and Slic3r::KDTreeIndirect< ANumDimensions, ACoordType, ACoordinateFn >::npos.

+ Here is the call graph for this function:

◆ build_recursive()

template<size_t ANumDimensions, typename ACoordType , typename ACoordinateFn >
void Slic3r::KDTreeIndirect< ANumDimensions, ACoordType, ACoordinateFn >::build_recursive ( std::vector< size_t > &  input,
size_t  node,
const size_t  dimension,
const size_t  left,
const size_t  right 
)
inlineprivate
84 {
85 if (left > right)
86 return;
87
88 assert(node < m_nodes.size());
89
90 if (left == right) {
91 // Insert a node into the balanced tree.
92 m_nodes[node] = input[left];
93 return;
94 }
95
96 // Partition the input to left / right pieces of the same length to produce a balanced tree.
97 size_t center = (left + right) / 2;
98 partition_input(input, dimension, left, right, center);
99 // Insert a node into the tree.
100 m_nodes[node] = input[center];
101 // Build up the left / right subtrees.
102 size_t next_dimension = dimension;
103 if (++ next_dimension == NumDimensions)
104 next_dimension = 0;
105 if (center > left)
106 build_recursive(input, node * 2 + 1, next_dimension, left, center - 1);
107 build_recursive(input, node * 2 + 2, next_dimension, center + 1, right);
108 }
static constexpr size_t NumDimensions
Definition KDTreeIndirect.hpp:25
void partition_input(std::vector< size_t > &input, const size_t dimension, size_t left, size_t right, const size_t k) const
Definition KDTreeIndirect.hpp:114
static int input(void)

References Slic3r::KDTreeIndirect< ANumDimensions, ACoordType, ACoordinateFn >::build_recursive(), input(), Slic3r::KDTreeIndirect< ANumDimensions, ACoordType, ACoordinateFn >::m_nodes, Slic3r::KDTreeIndirect< ANumDimensions, ACoordType, ACoordinateFn >::NumDimensions, and Slic3r::KDTreeIndirect< ANumDimensions, ACoordType, ACoordinateFn >::partition_input().

Referenced by Slic3r::KDTreeIndirect< ANumDimensions, ACoordType, ACoordinateFn >::build(), and Slic3r::KDTreeIndirect< ANumDimensions, ACoordType, ACoordinateFn >::build_recursive().

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

◆ clear()

template<size_t ANumDimensions, typename ACoordType , typename ACoordinateFn >
void Slic3r::KDTreeIndirect< ANumDimensions, ACoordType, ACoordinateFn >::clear ( )
inline
38{ m_nodes.clear(); }

References Slic3r::KDTreeIndirect< ANumDimensions, ACoordType, ACoordinateFn >::m_nodes.

Referenced by Slic3r::KDTreeIndirect< ANumDimensions, ACoordType, ACoordinateFn >::build().

+ Here is the caller graph for this function:

◆ descent_mask()

template<size_t ANumDimensions, typename ACoordType , typename ACoordinateFn >
template<typename CoordType >
unsigned int Slic3r::KDTreeIndirect< ANumDimensions, ACoordType, ACoordinateFn >::descent_mask ( const CoordType point_coord,
const CoordType search_radius,
size_t  idx,
size_t  dimension 
) const
inline
63 {
64 CoordType dist = point_coord - this->coordinate(idx, dimension);
65 return (dist * dist < search_radius + CoordType(EPSILON)) ?
66 // The plane intersects a hypersphere centered at point_coord of search_radius.
68 // The plane does not intersect the hypersphere.
69 (dist > CoordType(0)) ? (unsigned int)(VisitorReturnMask::CONTINUE_RIGHT) : (unsigned int)(VisitorReturnMask::CONTINUE_LEFT);
70 }
ACoordType CoordType
Definition KDTreeIndirect.hpp:27
static constexpr double EPSILON
Definition libslic3r.h:51
T dist(const boost::polygon::point_data< T > &p1, const boost::polygon::point_data< T > &p2)
Definition Geometry.cpp:280
VisitorReturnMask
Definition KDTreeIndirect.hpp:14

References Slic3r::CONTINUE_LEFT, Slic3r::CONTINUE_RIGHT, Slic3r::KDTreeIndirect< ANumDimensions, ACoordType, ACoordinateFn >::coordinate, and EPSILON.

◆ operator=()

template<size_t ANumDimensions, typename ACoordType , typename ACoordinateFn >
KDTreeIndirect & Slic3r::KDTreeIndirect< ANumDimensions, ACoordType, ACoordinateFn >::operator= ( KDTreeIndirect< ANumDimensions, ACoordType, ACoordinateFn > &&  rhs)
inline

◆ partition_input()

template<size_t ANumDimensions, typename ACoordType , typename ACoordinateFn >
void Slic3r::KDTreeIndirect< ANumDimensions, ACoordType, ACoordinateFn >::partition_input ( std::vector< size_t > &  input,
const size_t  dimension,
size_t  left,
size_t  right,
const size_t  k 
) const
inlineprivate
115 {
116 while (left < right) {
117 size_t center = (left + right) / 2;
118 CoordType pivot;
119 {
120 // Bubble sort the input[left], input[center], input[right], so that a median of the three values
121 // will end up in input[center].
122 CoordType left_value = this->coordinate(input[left], dimension);
123 CoordType center_value = this->coordinate(input[center], dimension);
124 CoordType right_value = this->coordinate(input[right], dimension);
125 if (left_value > center_value) {
126 std::swap(input[left], input[center]);
127 std::swap(left_value, center_value);
128 }
129 if (left_value > right_value) {
130 std::swap(input[left], input[right]);
131 right_value = left_value;
132 }
133 if (center_value > right_value) {
134 std::swap(input[center], input[right]);
135 center_value = right_value;
136 }
137 pivot = center_value;
138 }
139 if (right <= left + 2)
140 // The <left, right> interval is already sorted.
141 break;
142 size_t i = left;
143 size_t j = right - 1;
144 std::swap(input[center], input[j]);
145 // Partition the set based on the pivot.
146 for (;;) {
147 // Skip left points that are already at correct positions.
148 // Search will certainly stop at position (right - 1), which stores the pivot.
149 while (this->coordinate(input[++ i], dimension) < pivot) ;
150 // Skip right points that are already at correct positions.
151 while (this->coordinate(input[-- j], dimension) > pivot && i < j) ;
152 if (i >= j)
153 break;
154 std::swap(input[i], input[j]);
155 }
156 // Restore pivot to the center of the sequence.
157 std::swap(input[i], input[right - 1]);
158 // Which side the kth element is in?
159 if (k < i)
160 right = i - 1;
161 else if (k == i)
162 // Sequence is partitioned, kth element is at its place.
163 break;
164 else
165 left = i + 1;
166 }
167 }

References Slic3r::KDTreeIndirect< ANumDimensions, ACoordType, ACoordinateFn >::coordinate, and input().

Referenced by Slic3r::KDTreeIndirect< ANumDimensions, ACoordType, ACoordinateFn >::build_recursive().

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

◆ visit()

template<size_t ANumDimensions, typename ACoordType , typename ACoordinateFn >
template<typename Visitor >
void Slic3r::KDTreeIndirect< ANumDimensions, ACoordType, ACoordinateFn >::visit ( Visitor &  visitor) const
inline
75 {
76 visit_recursive(0, 0, visitor);
77 }
void visit_recursive(size_t node, size_t dimension, Visitor &visitor) const
Definition KDTreeIndirect.hpp:170

References Slic3r::KDTreeIndirect< ANumDimensions, ACoordType, ACoordinateFn >::visit_recursive().

Referenced by Slic3r::find_closest_points().

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

◆ visit_recursive()

template<size_t ANumDimensions, typename ACoordType , typename ACoordinateFn >
template<typename Visitor >
void Slic3r::KDTreeIndirect< ANumDimensions, ACoordType, ACoordinateFn >::visit_recursive ( size_t  node,
size_t  dimension,
Visitor &  visitor 
) const
inlineprivate
171 {
172 assert(! m_nodes.empty());
173 if (node >= m_nodes.size() || m_nodes[node] == npos)
174 return;
175
176 // Left / right child node index.
177 size_t left = node * 2 + 1;
178 size_t right = left + 1;
179 unsigned int mask = visitor(m_nodes[node], dimension);
180 if ((mask & (unsigned int)VisitorReturnMask::STOP) == 0) {
181 size_t next_dimension = (++ dimension == NumDimensions) ? 0 : dimension;
182 if (mask & (unsigned int)VisitorReturnMask::CONTINUE_LEFT)
183 visit_recursive(left, next_dimension, visitor);
184 if (mask & (unsigned int)VisitorReturnMask::CONTINUE_RIGHT)
185 visit_recursive(right, next_dimension, visitor);
186 }
187 }

References Slic3r::CONTINUE_LEFT, Slic3r::CONTINUE_RIGHT, Slic3r::KDTreeIndirect< ANumDimensions, ACoordType, ACoordinateFn >::m_nodes, Slic3r::KDTreeIndirect< ANumDimensions, ACoordType, ACoordinateFn >::npos, Slic3r::KDTreeIndirect< ANumDimensions, ACoordType, ACoordinateFn >::NumDimensions, Slic3r::STOP, and Slic3r::KDTreeIndirect< ANumDimensions, ACoordType, ACoordinateFn >::visit_recursive().

Referenced by Slic3r::KDTreeIndirect< ANumDimensions, ACoordType, ACoordinateFn >::visit(), and Slic3r::KDTreeIndirect< ANumDimensions, ACoordType, ACoordinateFn >::visit_recursive().

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

Member Data Documentation

◆ coordinate

◆ m_nodes

◆ NumDimensions

template<size_t ANumDimensions, typename ACoordType , typename ACoordinateFn >
constexpr size_t Slic3r::KDTreeIndirect< ANumDimensions, ACoordType, ACoordinateFn >::NumDimensions = ANumDimensions
staticconstexpr

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