23 b.add_input<
decl::Geometry>(
"Points").description(
"Points to instance on");
24 b.add_input<
decl::Bool>(
"Selection").default_value(
true).field_on({0}).hide_value();
25 b.add_input<
decl::Geometry>(
"Instance").description(
"Geometry that is instanced on the points");
29 "Choose instances from the \"Instance\" input at each point instead of instancing the "
34 "Index of the instance used for each point. This is only used when Pick Instances "
35 "is on. By default the point index is used");
36 b.add_input<
decl::Rotation>(
"Rotation").field_on({0}).description(
"Rotation of the instances");
38 .default_value({1.0f, 1.0f, 1.0f})
41 .description(
"Scale of the instances");
55 const int domain_num = src_attributes.
domain_size(domain);
64 evaluator.set_selection(selection_field);
73 const IndexMask selection = evaluator.get_evaluated_selection_as_mask();
82 dst_component.
resize(start_len + select_len);
96 if (src_instances !=
nullptr &&
101 for (
const int src_instance_handle : src_references.
index_range()) {
103 const int dst_instance_handle = dst_component.
add_reference(reference);
104 handle_mapping[src_instance_handle] = dst_instance_handle;
108 const int full_instance_handle = dst_component.
add_reference(instance);
114 float4x4 &dst_transform = dst_transforms[range_i];
118 int dst_handle = empty_reference_handle;
120 const bool use_individual_instance = pick_instance[
i];
121 if (use_individual_instance) {
122 if (src_instances !=
nullptr) {
123 const int src_instances_num = src_instances->instances_num();
124 const int original_index =
indices[
i];
127 const int index =
mod_i(original_index, std::max(src_instances_num, 1));
128 if (index < src_instances_num) {
130 const int src_handle = src_instances->reference_handles()[index];
131 dst_handle = handle_mapping[src_handle];
140 dst_handle = full_instance_handle;
143 dst_handles[range_i] = dst_handle;
151 TIP_(
"Realized geometry is not used when pick instances is true"));
157 for (
const int i : attributes_to_propagate.
names.index_range()) {
158 if (
ELEM(attributes_to_propagate.
names[
i],
"position",
".reference_index")) {
175 dst_attributes.
add(
id, AttrDomain::Instance, data_type,
init);
198 GeometryComponent::Type::PointCloud,
199 GeometryComponent::Type::Curve};
203 GeometryComponent::Type::Instance,
206 attributes_to_propagate);
209 if (geometry_set.
has(type)) {
217 attributes_to_propagate);
224 for (
const int layer_index : grease_pencil.layers().index_range()) {
225 const Layer &layer = grease_pencil.layer(layer_index);
226 const Drawing *drawing = grease_pencil.get_eval_drawing(layer);
227 if (drawing ==
nullptr) {
237 instances_per_layer->
add_instance(handle, layer_transform);
243 grease_pencil, AttrDomain::Point, layer_index);
249 attributes_to_propagate);
252 instances_per_layer->
add_instance(handle, layer_transform);
266 geometry_set.
keep_only({GeometryComponent::Type::Edit});
275 instances->remove_unused_references();
278 params.set_output(
"Instances", std::move(geometry_set));
286 ntype.
ui_name =
"Instance on Points";
288 "Generate a reference to geometry at each of the input points, without duplicating its "
Low-level operations for curves.
Low-level operations for grease pencil.
#define NODE_CLASS_GEOMETRY
#define GEO_NODE_INSTANCE_ON_POINTS
MINLINE int mod_i(int i, int n)
void mul_m4_m4_post(float R[4][4], const float B[4][4])
@ NODE_DEFAULT_INPUT_ID_INDEX_FIELD
#define NOD_REGISTER_NODE(REGISTER_FUNC)
constexpr MutableSpan slice(const int64_t start, const int64_t size) const
void reinitialize(const int64_t new_size)
GMutableSpan slice(const int64_t start, int64_t size) const
const void * data() const
GSpan get_internal_span() const
constexpr int64_t size() const
constexpr int64_t size() const
constexpr IndexRange index_range() const
T get_internal_single() const
bool contains(StringRef attribute_id) const
GAttributeReader lookup(const StringRef attribute_id) const
int domain_size(const AttrDomain domain) const
AttributeAccessor attributes() const
virtual std::optional< AttributeAccessor > attributes() const
MutableSpan< int > reference_handles_for_write()
int add_reference(const InstanceReference &reference)
void add_instance(int instance_handle, const float4x4 &transform)
void resize(int capacity)
bke::MutableAttributeAccessor attributes_for_write()
int instances_num() const
MutableSpan< float4x4 > transforms_for_write()
bool add(const StringRef attribute_id, const AttrDomain domain, const AttrType data_type, const AttributeInit &initializer)
GSpanAttributeWriter lookup_for_write_span(StringRef attribute_id)
const bke::CurvesGeometry & strokes() const
float4x4 local_transform() const
IndexRange index_range() const
void foreach_index(Fn &&fn) const
void gather(const GVArray &src, const IndexMask &indices, GMutableSpan dst, int64_t grain_size=4096)
void node_register_type(bNodeType &ntype)
void copy_attributes(const AttributeAccessor src_attributes, AttrDomain src_domain, AttrDomain dst_domain, const AttributeFilter &attribute_filter, MutableAttributeAccessor dst_attributes)
bke::GeometrySet join_geometries(Span< bke::GeometrySet > geometries, const bke::AttributeFilter &attribute_filter, const std::optional< Span< bke::GeometryComponent::Type > > &component_types_to_join=std::nullopt, bool allow_merging_instance_references=true)
void foreach_real_geometry(bke::GeometrySet &geometry, FunctionRef< void(bke::GeometrySet &geometry_set)> fn)
MatT from_loc_rot_scale(const typename MatT::loc_type &location, const RotationT &rotation, const VecBase< typename MatT::base_type, ScaleDim > &scale)
static void node_geo_exec(GeoNodeExecParams params)
static void node_declare(NodeDeclarationBuilder &b)
static void add_instances_from_component(bke::Instances &dst_component, const AttributeAccessor &src_attributes, const GeometrySet &instance, const fn::FieldContext &field_context, const GeoNodeExecParams ¶ms, const bke::GeometrySet::GatheredAttributes &attributes_to_propagate)
static void node_register()
MatBase< float, 4, 4 > float4x4
VecBase< float, 3 > float3
void geo_node_type_base(blender::bke::bNodeType *ntype, std::string idname, const std::optional< int16_t > legacy_type)
static void init(bNodeTree *, bNode *node)
const c_style_mat & ptr() const
const ImplicitSharingInfo * sharing_info
Vector< AttributeDomainAndType, 16 > kinds
VectorSet< StringRef, 16 > names
void keep_only(Span< GeometryComponent::Type > component_types)
GeometryComponent & get_component_for_write(GeometryComponent::Type component_type)
void replace_instances(Instances *instances, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
Instances * get_instances_for_write()
const GreasePencil * get_grease_pencil() const
bool has(const GeometryComponent::Type component_type) const
const GeometryComponent * get_component(GeometryComponent::Type component_type) const
bool has_realized_data() const
const Instances * get_instances() const
bool has_grease_pencil() const
void gather_attributes_for_propagation(Span< GeometryComponent::Type > component_types, GeometryComponent::Type dst_component_type, bool include_instances, const AttributeFilter &attribute_filter, GatheredAttributes &r_attributes) const
void ensure_owns_direct_data()
std::string ui_description
NodeGeometryExecFunction geometry_node_execute
const char * enum_name_legacy
NodeDeclareFunction declare
static GeometrySet from_instances(Instances *instances, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)