Prusa Slicer 2.6.0
Loading...
Searching...
No Matches
Slic3r::astar Namespace Reference

Classes

struct  QNode
 
struct  TracerTraits_
 

Typedefs

template<class T >
using remove_cvref_t = std::remove_cv_t< std::remove_reference_t< T > >
 
template<class T >
using TracerNodeT = typename TracerTraits_< remove_cvref_t< T > >::Node
 

Functions

template<class Tracer , class It , class NodeMap = std::unordered_map<size_t, QNode<Tracer>>>
bool search_route (const Tracer &tracer, const TracerNodeT< Tracer > &source, It out, NodeMap &&cached_nodes={})
 

Variables

constexpr auto Unassigned = std::numeric_limits<size_t>::max()
 

Typedef Documentation

◆ remove_cvref_t

template<class T >
using Slic3r::astar::remove_cvref_t = typedef std::remove_cv_t<std::remove_reference_t<T> >

◆ TracerNodeT

template<class T >
using Slic3r::astar::TracerNodeT = typedef typename TracerTraits_<remove_cvref_t<T> >::Node

Function Documentation

◆ search_route()

template<class Tracer , class It , class NodeMap = std::unordered_map<size_t, QNode<Tracer>>>
bool Slic3r::astar::search_route ( const Tracer &  tracer,
const TracerNodeT< Tracer > &  source,
It  out,
NodeMap &&  cached_nodes = {} 
)
103 {})
104{
105 using Node = TracerNodeT<Tracer>;
106 using QNode = QNode<Tracer>;
107 using TracerTraits = TracerTraits_<remove_cvref_t<Tracer>>;
108
109 struct LessPred { // Comparison functor needed by the priority queue
110 NodeMap &m;
111 bool operator ()(size_t node_a, size_t node_b) {
112 return m[node_a].f() < m[node_b].f();
113 }
114 };
115
116 auto qopen = make_mutable_priority_queue<size_t, true>(
117 [&cached_nodes](size_t el, size_t qidx) {
118 cached_nodes[el].queue_id = qidx;
119 },
120 LessPred{cached_nodes});
121
122 QNode initial{source, /*parent = */ Unassigned, /*g = */0.f};
123 size_t source_id = TracerTraits::unique_id(tracer, source);
124 cached_nodes[source_id] = initial;
125 qopen.push(source_id);
126
127 size_t goal_id = TracerTraits::goal_heuristic(tracer, source) < 0.f ?
128 source_id :
130
131 while (goal_id == Unassigned && !qopen.empty()) {
132 size_t q_id = qopen.top();
133 qopen.pop();
134 QNode &q = cached_nodes[q_id];
135
136 // This should absolutely be initialized in the cache already
137 assert(!std::isinf(q.g));
138
139 TracerTraits::foreach_reachable(tracer, q.node, [&](const Node &succ_nd) {
140 if (goal_id != Unassigned)
141 return true;
142
143 float h = TracerTraits::goal_heuristic(tracer, succ_nd);
144 float dst = TracerTraits::distance(tracer, q.node, succ_nd);
145 size_t succ_id = TracerTraits::unique_id(tracer, succ_nd);
146 QNode qsucc_nd{succ_nd, q_id, q.g + dst, h};
147
148 if (h < 0.f) {
149 goal_id = succ_id;
150 cached_nodes[succ_id] = qsucc_nd;
151 } else {
152 // If succ_id is not in cache, it gets created with g = infinity
153 QNode &prev_nd = cached_nodes[succ_id];
154
155 if (qsucc_nd.g < prev_nd.g) {
156 // new route is better, apply it:
157
158 // Save the old queue id, it would be lost after the next line
159 size_t queue_id = prev_nd.queue_id;
160
161 // The cache needs to be updated either way
162 prev_nd = qsucc_nd;
163
164 if (queue_id == InvalidQueueID)
165 // was in closed or unqueued, rescheduling
166 qopen.push(succ_id);
167 else // was in open, updating
168 qopen.update(queue_id);
169 }
170 }
171
172 return goal_id != Unassigned;
173 });
174 }
175
176 // Write the output, do not reverse. Clients can do so if they need to.
177 if (goal_id != Unassigned) {
178 const QNode *q = &cached_nodes[goal_id];
179 while (q->parent != Unassigned) {
180 assert(!std::isinf(q->g)); // Uninitialized nodes are NOT allowed
181
182 *out = q->node;
183 ++out;
184 q = &cached_nodes[q->parent];
185 }
186 }
187
188 return goal_id != Unassigned;
189}
constexpr auto Unassigned
Definition AStar.hpp:59

Variable Documentation

◆ Unassigned

constexpr auto Slic3r::astar::Unassigned = std::numeric_limits<size_t>::max()
constexpr