24 b.add_output<
decl::Int>(
"Next Vertex Index").field_source().reference_pass_all();
25 b.add_output<
decl::Float>(
"Total Cost").field_source().reference_pass_all();
40 std::priority_queue<VertPriority, std::vector<VertPriority>, std::greater<VertPriority>> queue;
43 r_cost[start_vert_i] = 0.0f;
44 queue.emplace(0.0f, start_vert_i);
51 for (const int vert_i : range) {
52 for (const int edge_i : vert_to_edge.offsets[vert_i]) {
53 other_vertex[edge_i] = bke::mesh::edge_other_vert(edges[vert_to_edge.data[edge_i]],
59 while (!queue.empty()) {
60 const float cost_i = queue.top().first;
61 const int vert_i = queue.top().second;
67 for (
const int index : vert_to_edge.offsets[vert_i]) {
68 const int edge_i = vert_to_edge.data[index];
69 const int neighbor_vert_i = other_vertex[index];
73 const float edge_cost = std::max(0.0f, input_cost[edge_i]);
74 const float new_neighbor_cost = cost_i + edge_cost;
75 if (new_neighbor_cost < r_cost[neighbor_vert_i]) {
76 r_cost[neighbor_vert_i] = new_neighbor_cost;
77 r_next_index[neighbor_vert_i] = vert_i;
78 queue.emplace(new_neighbor_cost, neighbor_vert_i);
91 : bke::MeshFieldInput(
CPPType::get<
int>(),
"Shortest Edge Paths Next Vertex Field"),
92 end_selection_(end_selection),
95 category_ = Category::Generated;
99 const AttrDomain domain,
104 edge_evaluator.
add(cost_);
105 edge_evaluator.evaluate();
106 const VArray<float> input_cost = edge_evaluator.get_evaluated<
float>(0);
110 point_evaluator.
add(end_selection_);
111 point_evaluator.evaluate();
112 const IndexMask end_selection = point_evaluator.get_evaluated_as_mask(0);
118 array_utils::fill_index_range<int>(next_index);
119 return mesh.attributes().adapt_domain<
int>(
127 edges, mesh.verts_num, vert_to_edge_offset_data, vert_to_edge_indices);
128 shortest_paths(mesh, vert_to_edge, end_selection, input_cost, next_index, cost);
131 for (const int i : range) {
132 if (next_index[i] == -1) {
137 return mesh.attributes().adapt_domain<
int>(
157 return other_field->end_selection_ == end_selection_ && other_field->cost_ == cost_;
164 return AttrDomain::Point;
175 : bke::MeshFieldInput(
CPPType::get<
float>(),
"Shortest Edge Paths Cost Field"),
176 end_selection_(end_selection),
179 category_ = Category::Generated;
183 const AttrDomain domain,
188 edge_evaluator.
add(cost_);
189 edge_evaluator.evaluate();
190 const VArray<float> input_cost = edge_evaluator.get_evaluated<
float>(0);
194 point_evaluator.
add(end_selection_);
195 point_evaluator.evaluate();
196 const IndexMask end_selection = point_evaluator.get_evaluated_as_mask(0);
199 return mesh.attributes().adapt_domain<
float>(
210 edges, mesh.verts_num, vert_to_edge_offset_data, vert_to_edge_indices);
211 shortest_paths(mesh, vert_to_edge, end_selection, input_cost, next_index, cost);
213 threading::parallel_for(cost.index_range(), 1024, [&](
const IndexRange range) {
214 for (const int i : range) {
215 if (cost[i] == FLT_MAX) {
220 return mesh.attributes().adapt_domain<
float>(
240 return other_field->end_selection_ == end_selection_ && other_field->cost_ == cost_;
247 return AttrDomain::Point;
257 std::make_shared<ShortestEdgePathsNextVertFieldInput>(end_selection, cost)};
258 Field<float> cost_field{std::make_shared<ShortestEdgePathsCostFieldInput>(end_selection, cost)};
259 params.set_output(
"Next Vertex Index", std::move(next_vert_field));
260 params.set_output(
"Total Cost", std::move(cost_field));
268 &ntype, GEO_NODE_INPUT_SHORTEST_EDGE_PATHS,
"Shortest Edge Paths",
NODE_CLASS_INPUT);
#define NOD_REGISTER_NODE(REGISTER_FUNC)
IndexRange index_range() const
int add(GField field, GVArray *varray_ptr)
virtual void for_each_field_input_recursive(FunctionRef< void(const FieldInput &)> fn) const
const FieldNode & node() const
void foreach_index(Fn &&fn) const
local_group_size(16, 16) .push_constant(Type b
Set< ComponentNode * > visited
draw_view in_light_buf[] float
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
void node_register_type(bNodeType *ntype)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
uint64_t get_default_hash(const T &v)
void geo_node_type_base(blender::bke::bNodeType *ntype, int type, const char *name, short nclass)
unsigned __int64 uint64_t
NodeGeometryExecFunction geometry_node_execute
NodeDeclareFunction declare
IndexRange index_range() const