Blender V4.5
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 b.add_input<decl::Int>("Offset").supports_field().description(
17 "The number of corners to move around the face before finding the result, "
18 "circling around the start of the face if necessary");
19 b.add_output<decl::Int>("Corner Index")
20 .field_source_reference_all()
21 .description("The index of the offset corner");
22}
23
25 const Field<int> corner_index_;
26 const Field<int> offset_;
27
28 public:
30 : bke::MeshFieldInput(CPPType::get<int>(), "Offset Corner in Face"),
31 corner_index_(std::move(corner_index)),
32 offset_(std::move(offset))
33 {
35 }
36
38 const AttrDomain domain,
39 const IndexMask &mask) const final
40 {
41 const IndexRange corner_range(mesh.corners_num);
42 const OffsetIndices faces = mesh.faces();
43
44 const bke::MeshFieldContext context{mesh, domain};
45 fn::FieldEvaluator evaluator{context, &mask};
46 evaluator.add(corner_index_);
47 evaluator.add(offset_);
48 evaluator.evaluate();
49 const VArray<int> corner_indices = evaluator.get_evaluated<int>(0);
50 const VArray<int> offsets = evaluator.get_evaluated<int>(1);
51
52 const Span<int> corner_to_face = mesh.corner_to_face_map();
53
54 Array<int> offset_corners(mask.min_array_size());
55 mask.foreach_index_optimized<int>(GrainSize(2048), [&](const int selection_i) {
56 const int corner = corner_indices[selection_i];
57 const int offset = offsets[selection_i];
58 if (!corner_to_face.index_range().contains(corner)) {
59 offset_corners[selection_i] = 0;
60 return;
61 }
62 const IndexRange face = faces[corner_to_face[corner]];
63 const int corner_index_in_face = corner - face.start();
64 offset_corners[selection_i] = face.start() + math::mod_periodic<int>(
65 corner_index_in_face + offset, face.size());
66 });
67
68 return VArray<int>::ForContainer(std::move(offset_corners));
69 }
70
71 void for_each_field_input_recursive(FunctionRef<void(const FieldInput &)> fn) const override
72 {
73 corner_index_.node().for_each_field_input_recursive(fn);
74 offset_.node().for_each_field_input_recursive(fn);
75 }
76
78 {
79 return get_default_hash(offset_);
80 }
81
82 bool is_equal_to(const fn::FieldNode &other) const final
83 {
84 if (const OffsetCornerInFaceFieldInput *other_field =
85 dynamic_cast<const OffsetCornerInFaceFieldInput *>(&other))
86 {
87 return other_field->corner_index_ == corner_index_ && other_field->offset_ == offset_;
88 }
89 return false;
90 }
91
92 std::optional<AttrDomain> preferred_domain(const Mesh & /*mesh*/) const final
93 {
94 return AttrDomain::Corner;
95 }
96};
97
99{
100 params.set_output("Corner Index",
101 Field<int>(std::make_shared<OffsetCornerInFaceFieldInput>(
102 params.extract_input<Field<int>>("Corner Index"),
103 params.extract_input<Field<int>>("Offset"))));
104}
105
106static void node_register()
107{
108 static blender::bke::bNodeType ntype;
110 &ntype, "GeometryNodeOffsetCornerInFace", GEO_NODE_MESH_TOPOLOGY_OFFSET_CORNER_IN_FACE);
111 ntype.ui_name = "Offset Corner in Face";
112 ntype.ui_description = "Retrieve corners in the same face as another";
113 ntype.enum_name_legacy = "OFFSET_CORNER_IN_FACE";
114 ntype.nclass = NODE_CLASS_INPUT;
116 ntype.declare = node_declare;
118}
120
121} // namespace blender::nodes::node_geo_mesh_topology_offset_corner_in_face_cc
#define NODE_CLASS_INPUT
Definition BKE_node.hh:433
#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 ForContainer(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:2748
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:226
std::string ui_description
Definition BKE_node.hh:232
NodeGeometryExecFunction geometry_node_execute
Definition BKE_node.hh:347
const char * enum_name_legacy
Definition BKE_node.hh:235
NodeDeclareFunction declare
Definition BKE_node.hh:355