16 const int start_in_range = start_index - range.
first();
17 const int offset_in_range = start_in_range + offset;
18 const int mod_offset = offset_in_range % range.
size();
19 if (mod_offset >= 0) {
20 return range[mod_offset];
22 return range.
last(-(mod_offset + 1));
33 .
description(
"The index of the control point to evaluate. Defaults to the current index");
35 "The number of control points along the curve to traverse");
37 .field_source_reference_all()
39 "Whether the input control point plus the offset is a valid index of the "
42 .field_source_reference_all()
44 "The index of the control point plus the offset within the entire "
55 : GeometryFieldInput(
CPPType::get<
int>(),
"Offset Point in Curve"),
56 index_(std::move(index)),
57 offset_(std::move(offset))
76 evaluator.
add(index_);
77 evaluator.
add(offset_);
83 mask.foreach_index([&](
const int i_selection) {
85 const int i_curve = parent_curves[i_point];
86 const IndexRange curve_points = points_by_curve[i_curve];
87 const int offset_point = i_point + offsets[i_selection];
89 if (cyclic[i_curve]) {
91 curve_points, i_point, offsets[i_selection]);
102 index_.node().for_each_field_input_recursive(
fn);
103 offset_.node().for_each_field_input_recursive(
fn);
114 : GeometryFieldInput(
CPPType::get<bool>(),
"Offset Valid"),
115 index_(std::move(index)),
116 offset_(std::move(offset))
135 evaluator.
add(index_);
136 evaluator.
add(offset_);
142 mask.foreach_index([&](
const int i_selection) {
143 const int i_point =
indices[i_selection];
145 output[i_selection] =
false;
149 const int i_curve = parent_curves[i_point];
150 const IndexRange curve_points = points_by_curve[i_curve];
151 if (cyclic[i_curve]) {
152 output[i_selection] =
true;
155 output[i_selection] = curve_points.
contains(i_point + offsets[i_selection]);
162 index_.node().for_each_field_input_recursive(
fn);
163 offset_.node().for_each_field_input_recursive(
fn);
172 if (
params.output_is_required(
"Point Index")) {
173 Field<int> curve_point_field{std::make_shared<ControlPointNeighborFieldInput>(index, offset)};
174 params.set_output(
"Point Index", std::move(curve_point_field));
176 if (
params.output_is_required(
"Is Valid Offset")) {
177 Field<bool> valid_field{std::make_shared<OffsetValidFieldInput>(index, offset)};
178 params.set_output(
"Is Valid Offset", std::move(valid_field));
Low-level operations for curves.
#define GEO_NODE_OFFSET_POINT_IN_CURVE
#define NOD_REGISTER_NODE(REGISTER_FUNC)
constexpr int64_t first() const
constexpr int64_t last(const int64_t n=0) const
constexpr int64_t size() const
constexpr bool contains(int64_t value) const
static VArray ForContainer(ContainerT container)
Array< int > point_to_curve_map() const
OffsetIndices< int > points_by_curve() const
IndexRange points_range() const
VArray< bool > cyclic() const
int add(GField field, GVArray *varray_ptr)
const GVArray & get_evaluated(const int field_index) const
local_group_size(16, 16) .push_constant(Type b
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
ccl_device_inline float4 mask(const int4 mask, const float4 a)
void node_register_type(bNodeType *ntype)
static void node_geo_exec(GeoNodeExecParams params)
static void node_declare(NodeDeclarationBuilder &b)
static void node_register()
int apply_offset_in_cyclic_range(IndexRange range, int start_index, int offset)
void geo_node_type_base(blender::bke::bNodeType *ntype, int type, const char *name, short nclass)
NodeGeometryExecFunction geometry_node_execute
NodeDeclareFunction declare