Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/nodes/geometry/nodes/node_geo_point_instance.cc')
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_point_instance.cc63
1 files changed, 49 insertions, 14 deletions
diff --git a/source/blender/nodes/geometry/nodes/node_geo_point_instance.cc b/source/blender/nodes/geometry/nodes/node_geo_point_instance.cc
index 6d979e3b7da..e030bc3eec6 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_point_instance.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_point_instance.cc
@@ -25,6 +25,7 @@
static bNodeSocketTemplate geo_node_point_instance_in[] = {
{SOCK_GEOMETRY, N_("Geometry")},
{SOCK_OBJECT, N_("Object")},
+ {SOCK_COLLECTION, N_("Collection")},
{-1, ""},
};
@@ -35,9 +36,21 @@ static bNodeSocketTemplate geo_node_point_instance_out[] = {
namespace blender::nodes {
+static void geo_node_point_instance_update(bNodeTree *UNUSED(tree), bNode *node)
+{
+ bNodeSocket *object_socket = (bNodeSocket *)BLI_findlink(&node->inputs, 1);
+ bNodeSocket *collection_socket = object_socket->next;
+
+ GeometryNodePointInstanceType type = (GeometryNodePointInstanceType)node->custom1;
+
+ nodeSetSocketAvailability(object_socket, type == GEO_NODE_POINT_INSTANCE_TYPE_OBJECT);
+ nodeSetSocketAvailability(collection_socket, type == GEO_NODE_POINT_INSTANCE_TYPE_COLLECTION);
+}
+
static void add_instances_from_geometry_component(InstancesComponent &instances,
const GeometryComponent &src_geometry,
- Object *object)
+ Object *object,
+ Collection *collection)
{
Float3ReadAttribute positions = src_geometry.attribute_get_for_read<float3>(
"position", ATTR_DOMAIN_POINT, {0, 0, 0});
@@ -47,30 +60,51 @@ static void add_instances_from_geometry_component(InstancesComponent &instances,
"scale", ATTR_DOMAIN_POINT, {1, 1, 1});
for (const int i : IndexRange(positions.size())) {
- instances.add_instance(object, positions[i], rotations[i], scales[i]);
+ if (object != nullptr) {
+ instances.add_instance(object, positions[i], rotations[i], scales[i]);
+ }
+ if (collection != nullptr) {
+ instances.add_instance(collection, positions[i], rotations[i], scales[i]);
+ }
}
}
static void geo_node_point_instance_exec(GeoNodeExecParams params)
{
+ GeometryNodePointInstanceType type = (GeometryNodePointInstanceType)params.node().custom1;
GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
GeometrySet geometry_set_out;
- bke::PersistentObjectHandle object_handle = params.extract_input<bke::PersistentObjectHandle>(
- "Object");
- Object *object = params.handle_map().lookup(object_handle);
+ Object *object = nullptr;
+ Collection *collection = nullptr;
- if (object != nullptr && object != params.self_object()) {
- InstancesComponent &instances = geometry_set_out.get_component_for_write<InstancesComponent>();
- if (geometry_set.has<MeshComponent>()) {
- add_instances_from_geometry_component(
- instances, *geometry_set.get_component_for_read<MeshComponent>(), object);
- }
- if (geometry_set.has<PointCloudComponent>()) {
- add_instances_from_geometry_component(
- instances, *geometry_set.get_component_for_read<PointCloudComponent>(), object);
+ if (type == GEO_NODE_POINT_INSTANCE_TYPE_OBJECT) {
+ bke::PersistentObjectHandle object_handle = params.extract_input<bke::PersistentObjectHandle>(
+ "Object");
+ object = params.handle_map().lookup(object_handle);
+ /* Avoid accidental recursion of instances. */
+ if (object == params.self_object()) {
+ object = nullptr;
}
}
+ else if (type == GEO_NODE_POINT_INSTANCE_TYPE_COLLECTION) {
+ bke::PersistentCollectionHandle collection_handle =
+ params.extract_input<bke::PersistentCollectionHandle>("Collection");
+ collection = params.handle_map().lookup(collection_handle);
+ }
+
+ InstancesComponent &instances = geometry_set_out.get_component_for_write<InstancesComponent>();
+ if (geometry_set.has<MeshComponent>()) {
+ add_instances_from_geometry_component(
+ instances, *geometry_set.get_component_for_read<MeshComponent>(), object, collection);
+ }
+ if (geometry_set.has<PointCloudComponent>()) {
+ add_instances_from_geometry_component(
+ instances,
+ *geometry_set.get_component_for_read<PointCloudComponent>(),
+ object,
+ collection);
+ }
params.set_output("Geometry", std::move(geometry_set_out));
}
@@ -82,6 +116,7 @@ void register_node_type_geo_point_instance()
geo_node_type_base(&ntype, GEO_NODE_POINT_INSTANCE, "Point Instance", NODE_CLASS_GEOMETRY, 0);
node_type_socket_templates(&ntype, geo_node_point_instance_in, geo_node_point_instance_out);
+ node_type_update(&ntype, blender::nodes::geo_node_point_instance_update);
ntype.geometry_node_execute = blender::nodes::geo_node_point_instance_exec;
nodeRegisterType(&ntype);
}