20 b.add_input<
decl::Bool>(
N_(
"End Vertex")).default_value(
false).hide_value().supports_field();
21 b.add_input<
decl::Float>(
N_(
"Edge Cost")).default_value(1.0f).hide_value().supports_field();
22 b.add_output<
decl::Int>(
N_(
"Next Vertex Index")).field_source();
35 for (
const int edge_i : edges.index_range()) {
36 const MEdge &edge = edges[edge_i];
54 std::priority_queue<VertPriority, std::vector<VertPriority>, std::greater<VertPriority>>
queue;
56 for (
const int start_vert_i : end_selection) {
57 r_cost[start_vert_i] = 0.0f;
58 queue.emplace(0.0f, start_vert_i);
61 while (!
queue.empty()) {
62 const float cost_i =
queue.top().first;
63 const int vert_i =
queue.top().second;
70 for (
const int edge_i : incident_edge_indices) {
71 const MEdge &edge = edges[edge_i];
72 const int neighbor_vert_i = edge.v1 + edge.v2 - vert_i;
76 const float edge_cost =
std::max(0.0f, input_cost[edge_i]);
77 const float new_neighbour_cost = cost_i + edge_cost;
78 if (new_neighbour_cost < r_cost[neighbor_vert_i]) {
79 r_cost[neighbor_vert_i] = new_neighbour_cost;
80 r_next_index[neighbor_vert_i] = vert_i;
81 queue.emplace(new_neighbour_cost, neighbor_vert_i);
95 end_selection_(end_selection),
110 if (
mesh ==
nullptr) {
115 edge_evaluator.add(cost_);
116 edge_evaluator.evaluate();
117 const VArray<float> input_cost = edge_evaluator.get_evaluated<
float>(0);
121 point_evaluator.add(end_selection_);
122 point_evaluator.evaluate();
123 const IndexMask end_selection = point_evaluator.get_evaluated_as_mask(0);
133 for (const int i : range) {
134 if (next_index[i] == -1) {
139 return component.attributes()->adapt_domain<
int>(
153 return other_field->end_selection_ == end_selection_ && other_field->cost_ == cost_;
167 end_selection_(end_selection),
170 category_ = Category::Generated;
182 if (
mesh ==
nullptr) {
187 edge_evaluator.add(cost_);
188 edge_evaluator.evaluate();
189 const VArray<float> input_cost = edge_evaluator.get_evaluated<
float>(0);
193 point_evaluator.add(end_selection_);
194 point_evaluator.evaluate();
195 const IndexMask end_selection = point_evaluator.get_evaluated_as_mask(0);
205 for (const int i : range) {
206 if (cost[i] == FLT_MAX) {
211 return component.attributes()->adapt_domain<
float>(
224 return other_field->end_selection_ == end_selection_ && other_field->cost_ == cost_;
236 std::make_shared<ShortestEdgePathsNextVertFieldInput>(end_selection, cost)};
237 Field<float> cost_field{std::make_shared<ShortestEdgePathsCostFieldInput>(end_selection, cost)};
238 params.set_output(
"Next Vertex Index", std::move(next_vert_field));
239 params.set_output(
"Total Cost", std::move(cost_field));
typedef float(TangentPoint)[2]
Low-level operations for curves.
@ GEO_COMPONENT_TYPE_MESH
#define GEO_NODE_INPUT_SHORTEST_EDGE_PATHS
void nodeRegisterType(struct bNodeType *ntype)
static uint8 component(Color32 c, uint i)
const Mesh * get_for_read() const
IndexRange index_range() const
static VArray ForContainer(ContainerT container)
Set< ComponentNode * > visited
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
void parallel_for(IndexRange range, int64_t grain_size, const Function &function)
uint64_t get_default_hash_2(const T1 &v1, const T2 &v2)
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
void geo_node_type_base(bNodeType *ntype, int type, const char *name, short nclass)
unsigned __int64 uint64_t
NodeGeometryExecFunction geometry_node_execute
NodeDeclareFunction declare