22 b.add_input<
decl::Geometry>(
"Points").description(
"Points to instance on");
23 b.add_input<
decl::Bool>(
"Selection").default_value(
true).field_on({0}).hide_value();
24 b.add_input<
decl::Geometry>(
"Instance").description(
"Geometry that is instanced on the points");
28 "Choose instances from the \"Instance\" input at each point instead of instancing the "
33 "Index of the instance used for each point. This is only used when Pick Instances "
34 "is on. By default the point index is used");
35 b.add_input<
decl::Rotation>(
"Rotation").field_on({0}).description(
"Rotation of the instances");
37 .default_value({1.0f, 1.0f, 1.0f})
40 .description(
"Scale of the instances");
54 const int domain_num = src_attributes.
domain_size(domain);
63 evaluator.set_selection(selection_field);
72 const IndexMask selection = evaluator.get_evaluated_selection_as_mask();
81 dst_component.
resize(start_len + select_len);
95 if (src_instances !=
nullptr &&
100 for (
const int src_instance_handle : src_references.
index_range()) {
102 const int dst_instance_handle = dst_component.
add_reference(reference);
103 handle_mapping[src_instance_handle] = dst_instance_handle;
107 const int full_instance_handle = dst_component.
add_reference(instance);
113 float4x4 &dst_transform = dst_transforms[range_i];
117 int dst_handle = empty_reference_handle;
119 const bool use_individual_instance = pick_instance[
i];
120 if (use_individual_instance) {
121 if (src_instances !=
nullptr) {
122 const int src_instances_num = src_instances->instances_num();
123 const int original_index =
indices[
i];
126 const int index =
mod_i(original_index, std::max(src_instances_num, 1));
127 if (index < src_instances_num) {
129 const int src_handle = src_instances->reference_handles()[index];
130 dst_handle = handle_mapping[src_handle];
139 dst_handle = full_instance_handle;
142 dst_handles[range_i] = dst_handle;
150 TIP_(
"Realized geometry is not used when pick instances is true"));
156 for (
const auto item : attributes_to_propagate.
items()) {
171 dst_attributes.
add(
id, AttrDomain::Instance, data_type,
init);
196 if (dst_instances ==
nullptr) {
198 instances_component.
replace(dst_instances);
202 GeometryComponent::Type::PointCloud,
203 GeometryComponent::Type::Curve};
207 GeometryComponent::Type::Instance,
210 attributes_to_propagate);
211 attributes_to_propagate.
remove(
"position");
212 attributes_to_propagate.
remove(
".reference_index");
215 if (geometry_set.
has(type)) {
223 attributes_to_propagate);
230 for (
const int layer_index : grease_pencil.layers().index_range()) {
231 const Layer &layer = grease_pencil.layer(layer_index);
232 const Drawing *drawing = grease_pencil.get_eval_drawing(layer);
233 if (drawing ==
nullptr) {
249 grease_pencil, AttrDomain::Point, layer_index);
255 attributes_to_propagate);
283 instances->remove_unused_references();
286 params.set_output(
"Instances", std::move(geometry_set));
294 ntype.
ui_name =
"Instance on Points";
296 "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
bool remove(const Key &key)
ItemIterator items() 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
Instances * get_for_write()
void replace(Instances *instances, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
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 eCustomDataType 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)
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 Map< StringRef, AttributeDomainAndType > &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
GeometryComponent & get_component_for_write(GeometryComponent::Type component_type)
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 ensure_owns_direct_data()
void gather_attributes_for_propagation(Span< GeometryComponent::Type > component_types, GeometryComponent::Type dst_component_type, bool include_instances, const AttributeFilter &attribute_filter, Map< StringRef, AttributeDomainAndType > &r_attributes) const
void modify_geometry_sets(ForeachSubGeometryCallback callback)
void remove_geometry_during_modify()
void replace_grease_pencil(GreasePencil *grease_pencil, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
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)