[Bf-blender-cvs] [19bab2a5360] master: Geometry Nodes: Object info node optional instance output

Hans Goudey noreply at git.blender.org
Fri Oct 15 21:21:18 CEST 2021


Commit: 19bab2a5360708242a5f6ea11b6e2ff03568a679
Author: Hans Goudey
Date:   Fri Oct 15 14:20:53 2021 -0500
Branches: master
https://developer.blender.org/rB19bab2a5360708242a5f6ea11b6e2ff03568a679

Geometry Nodes: Object info node optional instance output

The object info node output an instance as a performance optimization.
Before that optimization was (almost) invisible to the user, but now
that we aren't automatically realizing instances, it isn't intuitive
for a single object to become an instance.

I refactored the transform node so its ability to translate/transform
an entire geometry set was more usable from elsewhere and exposed the
function to get a geometry set from an object.

Differential Revision: https://developer.blender.org/D12833

===================================================================

M	source/blender/blenkernel/BKE_geometry_set_instances.hh
M	source/blender/blenkernel/intern/geometry_set_instances.cc
M	source/blender/nodes/geometry/node_geometry_util.hh
M	source/blender/nodes/geometry/nodes/node_geo_bounding_box.cc
M	source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cube.cc
M	source/blender/nodes/geometry/nodes/node_geo_object_info.cc
M	source/blender/nodes/geometry/nodes/node_geo_transform.cc

===================================================================

diff --git a/source/blender/blenkernel/BKE_geometry_set_instances.hh b/source/blender/blenkernel/BKE_geometry_set_instances.hh
index 653450c7d8e..d7a60162e81 100644
--- a/source/blender/blenkernel/BKE_geometry_set_instances.hh
+++ b/source/blender/blenkernel/BKE_geometry_set_instances.hh
@@ -20,6 +20,8 @@
 
 namespace blender::bke {
 
+GeometrySet object_get_evaluated_geometry_set(const Object &object);
+
 /**
  * Used to keep track of a group of instances using the same geometry data.
  */
diff --git a/source/blender/blenkernel/intern/geometry_set_instances.cc b/source/blender/blenkernel/intern/geometry_set_instances.cc
index 77348c3d22c..d92df386575 100644
--- a/source/blender/blenkernel/intern/geometry_set_instances.cc
+++ b/source/blender/blenkernel/intern/geometry_set_instances.cc
@@ -56,7 +56,7 @@ static void add_final_mesh_as_geometry_component(const Object &object, GeometryS
 /**
  * \note This doesn't extract instances from the "dupli" system for non-geometry-nodes instances.
  */
-static GeometrySet object_get_geometry_set_for_read(const Object &object)
+GeometrySet object_get_evaluated_geometry_set(const Object &object)
 {
   if (object.type == OB_MESH && object.mode == OB_MODE_EDIT) {
     GeometrySet geometry_set;
@@ -100,7 +100,7 @@ static void geometry_set_collect_recursive_object(const Object &object,
                                                   const float4x4 &transform,
                                                   Vector<GeometryInstanceGroup> &r_sets)
 {
-  GeometrySet instance_geometry_set = object_get_geometry_set_for_read(object);
+  GeometrySet instance_geometry_set = object_get_evaluated_geometry_set(object);
   geometry_set_collect_recursive(instance_geometry_set, transform, r_sets);
 
   if (object.type == OB_EMPTY) {
@@ -628,14 +628,14 @@ void InstancesComponent::foreach_referenced_geometry(
     switch (reference.type()) {
       case InstanceReference::Type::Object: {
         const Object &object = reference.object();
-        const GeometrySet object_geometry_set = object_get_geometry_set_for_read(object);
+        const GeometrySet object_geometry_set = object_get_evaluated_geometry_set(object);
         callback(object_geometry_set);
         break;
       }
       case InstanceReference::Type::Collection: {
         Collection &collection = reference.collection();
         FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (&collection, object) {
-          const GeometrySet object_geometry_set = object_get_geometry_set_for_read(*object);
+          const GeometrySet object_geometry_set = object_get_evaluated_geometry_set(*object);
           callback(object_geometry_set);
         }
         FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
@@ -676,7 +676,7 @@ void InstancesComponent::ensure_geometry_instances()
         /* Create a new reference that contains the geometry set of the object. We may want to
          * treat e.g. lamps and similar object types separately here. */
         const Object &object = reference.object();
-        GeometrySet object_geometry_set = object_get_geometry_set_for_read(object);
+        GeometrySet object_geometry_set = object_get_evaluated_geometry_set(object);
         if (object_geometry_set.has_instances()) {
           InstancesComponent &component =
               object_geometry_set.get_component_for_write<InstancesComponent>();
diff --git a/source/blender/nodes/geometry/node_geometry_util.hh b/source/blender/nodes/geometry/node_geometry_util.hh
index 21404525748..f382ff6c132 100644
--- a/source/blender/nodes/geometry/node_geometry_util.hh
+++ b/source/blender/nodes/geometry/node_geometry_util.hh
@@ -50,11 +50,15 @@ void update_attribute_input_socket_availabilities(bNode &node,
 Array<uint32_t> get_geometry_element_ids_as_uints(const GeometryComponent &component,
                                                   const AttributeDomain domain);
 
-void transform_mesh(Mesh *mesh,
+void transform_mesh(Mesh &mesh,
                     const float3 translation,
                     const float3 rotation,
                     const float3 scale);
 
+void transform_geometry_set(GeometrySet &geometry,
+                            const float4x4 &transform,
+                            const Depsgraph &depsgraph);
+
 Mesh *create_line_mesh(const float3 start, const float3 delta, const int count);
 
 Mesh *create_grid_mesh(const int verts_x,
diff --git a/source/blender/nodes/geometry/nodes/node_geo_bounding_box.cc b/source/blender/nodes/geometry/nodes/node_geo_bounding_box.cc
index fdc6b12095c..8b90595a641 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_bounding_box.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_bounding_box.cc
@@ -153,7 +153,7 @@ static void geo_node_bounding_box_exec(GeoNodeExecParams params)
     const float3 scale = max - min;
     const float3 center = min + scale / 2.0f;
     Mesh *mesh = create_cuboid_mesh(scale, 2, 2, 2);
-    transform_mesh(mesh, center, float3(0), float3(1));
+    transform_mesh(*mesh, center, float3(0), float3(1));
     params.set_output("Bounding Box", GeometrySet::create_with_mesh(mesh));
     params.set_output("Min", min);
     params.set_output("Max", max);
diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cube.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cube.cc
index af8ce02b3c1..5a520d36296 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cube.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cube.cc
@@ -456,12 +456,12 @@ static Mesh *create_cube_mesh(const float3 size,
     }
     if (verts_y == 1) { /* XZ plane. */
       Mesh *mesh = create_grid_mesh(verts_x, verts_z, size.x, size.z);
-      transform_mesh(mesh, float3(0), float3(M_PI_2, 0.0f, 0.0f), float3(1));
+      transform_mesh(*mesh, float3(0), float3(M_PI_2, 0.0f, 0.0f), float3(1));
       return mesh;
     }
     /* YZ plane. */
     Mesh *mesh = create_grid_mesh(verts_z, verts_y, size.z, size.y);
-    transform_mesh(mesh, float3(0), float3(0.0f, M_PI_2, 0.0f), float3(1));
+    transform_mesh(*mesh, float3(0), float3(0.0f, M_PI_2, 0.0f), float3(1));
     return mesh;
   }
 
diff --git a/source/blender/nodes/geometry/nodes/node_geo_object_info.cc b/source/blender/nodes/geometry/nodes/node_geo_object_info.cc
index 389acc40f0f..e61709ed86a 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_object_info.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_object_info.cc
@@ -26,6 +26,10 @@ namespace blender::nodes {
 static void geo_node_object_info_declare(NodeDeclarationBuilder &b)
 {
   b.add_input<decl::Object>("Object").hide_label();
+  b.add_input<decl::Bool>("As Instance")
+      .description(
+          "Output the entire object as single instance. "
+          "This allows instancing non-geometry object types");
   b.add_output<decl::Vector>("Location");
   b.add_output<decl::Vector>("Rotation");
   b.add_output<decl::Vector>("Scale");
@@ -54,12 +58,11 @@ static void geo_node_object_info_exec(GeoNodeExecParams params)
   const Object *self_object = params.self_object();
 
   if (object != nullptr) {
-    float transform[4][4];
-    mul_m4_m4m4(transform, self_object->imat, object->obmat);
+    const float4x4 transform = float4x4(self_object->imat) * float4x4(object->obmat);
 
     float quaternion[4];
     if (transform_space_relative) {
-      mat4_decompose(location, quaternion, scale, transform);
+      mat4_decompose(location, quaternion, scale, transform.values);
     }
     else {
       mat4_decompose(location, quaternion, scale, object->obmat);
@@ -67,16 +70,23 @@ static void geo_node_object_info_exec(GeoNodeExecParams params)
     quat_to_eul(rotation, quaternion);
 
     if (object != self_object) {
-      InstancesComponent &instances = geometry_set.get_component_for_write<InstancesComponent>();
-      const int handle = instances.add_reference(*object);
-
-      if (transform_space_relative) {
-        instances.add_instance(handle, transform);
+      if (params.get_input<bool>("As Instance")) {
+        InstancesComponent &instances = geometry_set.get_component_for_write<InstancesComponent>();
+        const int handle = instances.add_reference(*object);
+        if (transform_space_relative) {
+          instances.add_instance(handle, transform);
+        }
+        else {
+          float unit_transform[4][4];
+          unit_m4(unit_transform);
+          instances.add_instance(handle, unit_transform);
+        }
       }
       else {
-        float unit_transform[4][4];
-        unit_m4(unit_transform);
-        instances.add_instance(handle, unit_transform);
+        geometry_set = bke::object_get_evaluated_geometry_set(*object);
+        if (transform_space_relative) {
+          transform_geometry_set(geometry_set, transform, *params.depsgraph());
+        }
       }
     }
   }
diff --git a/source/blender/nodes/geometry/nodes/node_geo_transform.cc b/source/blender/nodes/geometry/nodes/node_geo_transform.cc
index d5eb067cad0..005714a9580 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_transform.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_transform.cc
@@ -25,6 +25,7 @@
 #include "DNA_volume_types.h"
 
 #include "BKE_mesh.h"
+#include "BKE_pointcloud.h"
 #include "BKE_spline.hh"
 #include "BKE_volume.h"
 
@@ -55,112 +56,142 @@ static bool use_translate(const float3 rotation, const float3 scale)
   return true;
 }
 
-void transform_mesh(Mesh *mesh,
+static void translate_mesh(Mesh &mesh, const float3 translation)
+{
+  if (!translation.is_zero()) {
+    BKE_mesh_translate(&mesh, translation, false);
+  }
+}
+
+static void transform_mesh(Mesh &mesh, const float4x4 &transform)
+{
+  BKE_mesh_transform(&mesh, transform.values, false);
+  BKE_mesh_normals_tag_dirty(&mesh);
+}
+
+void transform_mesh(Mesh &mesh,
                     const float3 translation,
                     const float3 rotation,
                     const float3 scale)
 {
-  /* Use only translation if rotation and scale are zero. */
-  if (use_translate(rotation, scale)) {
-    if (!translation.is_zero()) {
-      BKE_mesh_translate(mesh, translation, false);
-    }
-  }
-  else {
-    const float4x4 matrix = float4x4::from_loc_eul_scale(translation, rota

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list