19 .
description(
"The edge to retrieve data from. Defaults to the edge from the context");
21 "Values that sort the corners attached to the edge");
25 .
description(
"Which of the sorted corners to output");
27 .field_source_reference_all()
29 "A corner of the input edge in its face's winding order, chosen by the sort index");
30 b.add_output<
decl::Int>(
"Total").field_source().reference_pass({0}).description(
31 "The number of faces or corners connected to each edge");
41 : bke::MeshFieldInput(
CPPType::get<int>(),
"Corner of Edge"),
42 edge_index_(std::move(edge_index)),
43 sort_index_(std::move(sort_index)),
44 sort_weight_(std::move(sort_weight))
50 const AttrDomain domain,
62 evaluator.add(edge_index_);
63 evaluator.add(sort_index_);
65 const VArray<int> edge_indices = evaluator.get_evaluated<
int>(0);
66 const VArray<int> indices_in_sort = evaluator.get_evaluated<
int>(1);
70 corner_evaluator.add(sort_weight_);
71 corner_evaluator.evaluate();
72 const VArray<float> all_sort_weights = corner_evaluator.get_evaluated<
float>(0);
73 const bool use_sorting = !all_sort_weights.
is_single();
82 for (
const int selection_i : segment) {
83 const int edge_i = edge_indices[selection_i];
84 const int index_in_sort = indices_in_sort[selection_i];
86 corner_of_edge[selection_i] = 0;
90 const Span<int> corners = edge_to_corner_map[edge_i];
91 if (corners.is_empty()) {
92 corner_of_edge[selection_i] = 0;
96 const int index_in_sort_wrapped =
mod_i(index_in_sort, corners.size());
110 std::stable_sort(sort_indices.
begin(), sort_indices.
end(), [&](
int a,
int b) {
111 return sort_weights[a] < sort_weights[b];
113 corner_of_edge[selection_i] = corners[sort_indices[index_in_sort_wrapped]];
116 corner_of_edge[selection_i] = corners[index_in_sort_wrapped];
126 edge_index_.node().for_each_field_input_recursive(fn);
133 return AttrDomain::Edge;
145 const AttrDomain domain,
148 if (domain != AttrDomain::Edge) {
158 return 2345897985577;
168 return AttrDomain::Edge;
175 if (
params.output_is_required(
"Total")) {
176 params.set_output(
"Total",
177 Field<int>(std::make_shared<bke::EvaluateAtIndexInput>(
179 Field<int>(std::make_shared<CornersOfEdgeCountInput>()),
182 if (
params.output_is_required(
"Corner Index")) {
183 params.set_output(
"Corner Index",
184 Field<int>(std::make_shared<CornersOfEdgeInput>(
195 ntype.
ui_name =
"Corners of Edge";
196 ntype.
ui_description =
"Retrieve face corners connected to edges";
#define GEO_NODE_MESH_TOPOLOGY_CORNERS_OF_EDGE
MINLINE int mod_i(int i, int n)
@ NODE_DEFAULT_INPUT_INDEX_FIELD
#define NOD_REGISTER_NODE(REGISTER_FUNC)
MutableSpan< T > as_mutable_span()
void reinitialize(const int64_t new_size)
constexpr bool contains(int64_t value) const
constexpr int64_t size() const
void materialize_compressed(const IndexMask &mask, MutableSpan< T > r_span) const
static VArray ForContainer(ContainerT container)
virtual void for_each_field_input_recursive(FunctionRef< void(const FieldInput &)> fn) const
const FieldNode & node() const
static IndexMask from_indices(Span< T > indices, IndexMaskMemory &memory)
ccl_device_inline float2 mask(const MaskType mask, const float2 a)
void count_indices(Span< int > indices, MutableSpan< int > counts)
void fill_index_range(MutableSpan< T > span, const T start=0)
GroupedSpan< int > build_edge_to_corner_map(Span< int > corner_edges, int edges_num, Array< int > &r_offsets, Array< int > &r_indices)
void node_register_type(bNodeType &ntype)
static void node_geo_exec(GeoNodeExecParams params)
static void node_declare(NodeDeclarationBuilder &b)
static void node_register()
void geo_node_type_base(blender::bke::bNodeType *ntype, std::string idname, const std::optional< int16_t > legacy_type)
unsigned __int64 uint64_t
std::string ui_description
NodeGeometryExecFunction geometry_node_execute
const char * enum_name_legacy
NodeDeclareFunction declare