Blender V5.0
node_geo_mesh_topology_offset_corner_in_face.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include "DNA_mesh_types.h"
6
8
10
12{
13 b.add_input<decl::Int>("Corner Index")
14 .implicit_field(NODE_DEFAULT_INPUT_INDEX_FIELD)
15 .description("The corner to retrieve data from. Defaults to the corner from the context")
16 .structure_type(StructureType::Field);
17 b.add_input<decl::Int>("Offset").supports_field().description(
18 "The number of corners to move around the face before finding the result, "
19 "circling around the start of the face if necessary");
20 b.add_output<decl::Int>("Corner Index")
21 .field_source_reference_all()
22 .description("The index of the offset corner");
23}
24
26 const Field<int> corner_index_;
27 const Field<int> offset_;
28
29 public:
31 : bke::MeshFieldInput(CPPType::get<int>(), "Offset Corner in Face"),
32 corner_index_(std::move(corner_index)),
33 offset_(std::move(offset))
34 {
36 }
37
39 const AttrDomain domain,
40 const IndexMask &mask) const final
41 {
42 const IndexRange corner_range(mesh.corners_num);
43 const OffsetIndices faces = mesh.faces();
44
45 const bke::MeshFieldContext context{mesh, domain};
46 fn::FieldEvaluator evaluator{context, &mask};
47 evaluator.add(corner_index_);
48 evaluator.add(offset_);
49 evaluator.evaluate();
50 const VArray<int> corner_indices = evaluator.get_evaluated<int>(0);
51 const VArray<int> offsets = evaluator.get_evaluated<int>(1);
52
53 const Span<int> corner_to_face = mesh.corner_to_face_map();
54
55 Array<int> offset_corners(mask.min_array_size());
56 mask.foreach_index_optimized<int>(GrainSize(2048), [&](const int selection_i) {
57 const int corner = corner_indices[selection_i];
58 const int offset = offsets[selection_i];
59 if (!corner_to_face.index_range().contains(corner)) {
60 offset_corners[selection_i] = 0;
61 return;
62 }
63 const IndexRange face = faces[corner_to_face[corner]];
64 const int corner_index_in_face = corner - face.start();
65 offset_corners[selection_i] = face.start() + math::mod_periodic<int>(
66 corner_index_in_face + offset, face.size());
67 });
68
69 return VArray<int>::from_container(std::move(offset_corners));
70 }
71
72 void for_each_field_input_recursive(FunctionRef<void(const FieldInput &)> fn) const override
73 {
74 corner_index_.node().for_each_field_input_recursive(fn);
75 offset_.node().for_each_field_input_recursive(fn);
76 }
77
79 {
80 return get_default_hash(offset_);
81 }
82
83 bool is_equal_to(const fn::FieldNode &other) const final
84 {
85 if (const OffsetCornerInFaceFieldInput *other_field =
86 dynamic_cast<const OffsetCornerInFaceFieldInput *>(&other))
87 {
88 return other_field->corner_index_ == corner_index_ && other_field->offset_ == offset_;
89 }
90 return false;
91 }
92
93 std::optional<AttrDomain> preferred_domain(const Mesh & /*mesh*/) const final
94 {
95 return AttrDomain::Corner;
96 }
97};
98
100{
101 params.set_output("Corner Index",
102 Field<int>(std::make_shared<OffsetCornerInFaceFieldInput>(
103 params.extract_input<Field<int>>("Corner Index"),
104 params.extract_input<Field<int>>("Offset"))));
105}
106
107static void node_register()
108{
109 static blender::bke::bNodeType ntype;
111 &ntype, "GeometryNodeOffsetCornerInFace", GEO_NODE_MESH_TOPOLOGY_OFFSET_CORNER_IN_FACE);
112 ntype.ui_name = "Offset Corner in Face";
113 ntype.ui_description = "Retrieve corners in the same face as another";
114 ntype.enum_name_legacy = "OFFSET_CORNER_IN_FACE";
115 ntype.nclass = NODE_CLASS_INPUT;
117 ntype.declare = node_declare;
119}
121
122} // namespace blender::nodes::node_geo_mesh_topology_offset_corner_in_face_cc
#define NODE_CLASS_INPUT
Definition BKE_node.hh:447
#define GEO_NODE_MESH_TOPOLOGY_OFFSET_CORNER_IN_FACE
#define final(a, b, c)
Definition BLI_hash.h:19
#define NOD_REGISTER_NODE(REGISTER_FUNC)
unsigned long long int uint64_t
constexpr int64_t size() const
constexpr int64_t start() const
static VArray from_container(ContainerT container)
FieldInput(const CPPType &type, std::string debug_name="")
Definition field.cc:677
int add(GField field, GVArray *varray_ptr)
Definition field.cc:751
const GVArray & get_evaluated(const int field_index) const
Definition FN_field.hh:448
GVArray get_varray_for_context(const Mesh &mesh, const AttrDomain domain, const IndexMask &mask) const final
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
ccl_device_inline float2 mask(const MaskType mask, const float2 a)
static char faces[256]
void node_register_type(bNodeType &ntype)
Definition node.cc:2416
T mod_periodic(const T &a, const T &b)
uint64_t get_default_hash(const T &v, const Args &...args)
Definition BLI_hash.hh:233
void geo_node_type_base(blender::bke::bNodeType *ntype, std::string idname, const std::optional< int16_t > legacy_type)
Defines a node type.
Definition BKE_node.hh:238
std::string ui_description
Definition BKE_node.hh:244
NodeGeometryExecFunction geometry_node_execute
Definition BKE_node.hh:354
const char * enum_name_legacy
Definition BKE_node.hh:247
NodeDeclareFunction declare
Definition BKE_node.hh:362