[Bf-blender-cvs] [6c11b320c41] master: Geometry Nodes: Scale Instances Node

Erik Abrahamsson noreply at git.blender.org
Wed Oct 13 16:10:21 CEST 2021


Commit: 6c11b320c410255bbad358595af2044da016b9c5
Author: Erik Abrahamsson
Date:   Wed Oct 13 09:08:02 2021 -0500
Branches: master
https://developer.blender.org/rB6c11b320c410255bbad358595af2044da016b9c5

Geometry Nodes: Scale Instances Node

Adds a node that can scale a geometry's instances. With "Local" turned
on, the instance is scaled individually from the center point input,
while when local space is turned off, it's more like the transform
node, except it scales outward from the center point instead of only
from the origin.

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

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

M	release/scripts/startup/nodeitems_builtins.py
M	source/blender/blenkernel/BKE_node.h
M	source/blender/blenkernel/intern/node.cc
M	source/blender/nodes/CMakeLists.txt
M	source/blender/nodes/NOD_geometry.h
M	source/blender/nodes/NOD_static_types.h
A	source/blender/nodes/geometry/nodes/node_geo_scale_instances.cc

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

diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py
index 0bc4f6af997..dfe33199f28 100644
--- a/release/scripts/startup/nodeitems_builtins.py
+++ b/release/scripts/startup/nodeitems_builtins.py
@@ -683,6 +683,7 @@ geometry_node_categories = [
         NodeItem("GeometryNodeSeparateGeometry"),
         NodeItem("GeometryNodeSetPosition"),
         NodeItem("GeometryNodeRealizeInstances"),
+        NodeItem("GeometryNodeScaleInstances"),
         NodeItem("GeometryNodeTranslateInstances"),
     ]),
     GeometryNodeCategory("GEO_INPUT", "Input", items=geometry_input_node_items),
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 45001ba6fcb..4c1c49555b8 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -1533,6 +1533,7 @@ int ntreeTexExecTree(struct bNodeTree *ntree,
 #define GEO_NODE_INPUT_MATERIAL_INDEX 1118
 #define GEO_NODE_SET_MATERIAL_INDEX 1119
 #define GEO_NODE_TRANSLATE_INSTANCES 1120
+#define GEO_NODE_SCALE_INSTANCES 1121
 
 /** \} */
 
diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc
index 5dc8909a45f..283e28ed54f 100644
--- a/source/blender/blenkernel/intern/node.cc
+++ b/source/blender/blenkernel/intern/node.cc
@@ -5810,6 +5810,7 @@ static void registerGeometryNodes()
   register_node_type_geo_raycast();
   register_node_type_geo_realize_instances();
   register_node_type_geo_sample_texture();
+  register_node_type_geo_scale_instances();
   register_node_type_geo_separate_components();
   register_node_type_geo_separate_geometry();
   register_node_type_geo_set_curve_handles();
diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt
index e4153b7381b..e543db92b9f 100644
--- a/source/blender/nodes/CMakeLists.txt
+++ b/source/blender/nodes/CMakeLists.txt
@@ -253,6 +253,7 @@ set(SRC
   geometry/nodes/node_geo_points_to_volume.cc
   geometry/nodes/node_geo_proximity.cc
   geometry/nodes/node_geo_realize_instances.cc
+  geometry/nodes/node_geo_scale_instances.cc
   geometry/nodes/node_geo_separate_components.cc
   geometry/nodes/node_geo_separate_geometry.cc
   geometry/nodes/node_geo_set_curve_handles.cc
diff --git a/source/blender/nodes/NOD_geometry.h b/source/blender/nodes/NOD_geometry.h
index 2da9466ae16..3b0816300f5 100644
--- a/source/blender/nodes/NOD_geometry.h
+++ b/source/blender/nodes/NOD_geometry.h
@@ -130,6 +130,7 @@ void register_node_type_geo_proximity(void);
 void register_node_type_geo_raycast(void);
 void register_node_type_geo_realize_instances(void);
 void register_node_type_geo_sample_texture(void);
+void register_node_type_geo_scale_instances(void);
 void register_node_type_geo_select_by_handle_type(void);
 void register_node_type_geo_separate_components(void);
 void register_node_type_geo_separate_geometry(void);
diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h
index aca018b5fe9..010327a1ac1 100644
--- a/source/blender/nodes/NOD_static_types.h
+++ b/source/blender/nodes/NOD_static_types.h
@@ -381,6 +381,7 @@ DefNode(GeometryNode, GEO_NODE_POINTS_TO_VERTICES, 0, "POINTS_TO_VERTICES", Poin
 DefNode(GeometryNode, GEO_NODE_POINTS_TO_VOLUME, def_geo_points_to_volume, "POINTS_TO_VOLUME", PointsToVolume, "Points to Volume", "")
 DefNode(GeometryNode, GEO_NODE_PROXIMITY, def_geo_proximity, "PROXIMITY", Proximity, "Geometry Proximity", "")
 DefNode(GeometryNode, GEO_NODE_REALIZE_INSTANCES, 0, "REALIZE_INSTANCES", RealizeInstances, "Realize Instances", "")
+DefNode(GeometryNode, GEO_NODE_SCALE_INSTANCES, 0, "SCALE_INSTANCES", ScaleInstances, "Scale Instances", "")
 DefNode(GeometryNode, GEO_NODE_SEPARATE_COMPONENTS, 0, "SEPARATE_COMPONENTS", SeparateComponents, "Separate Components", "")
 DefNode(GeometryNode, GEO_NODE_SEPARATE_GEOMETRY, def_geo_separate_geometry, "SEPARATE_GEOMETRY", SeparateGeometry, "Separate Geometry", "")
 DefNode(GeometryNode, GEO_NODE_SET_CURVE_HANDLES, def_geo_curve_set_handle_positions, "SET_CURVE_HANDLES", SetCurveHandlePositions, "Set Handle Positions", "")
diff --git a/source/blender/nodes/geometry/nodes/node_geo_scale_instances.cc b/source/blender/nodes/geometry/nodes/node_geo_scale_instances.cc
new file mode 100644
index 00000000000..33897ef354d
--- /dev/null
+++ b/source/blender/nodes/geometry/nodes/node_geo_scale_instances.cc
@@ -0,0 +1,95 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "BLI_task.hh"
+
+#include "node_geometry_util.hh"
+
+namespace blender::nodes {
+
+static void geo_node_scale_instances_declare(NodeDeclarationBuilder &b)
+{
+  b.add_input<decl::Geometry>("Geometry");
+  b.add_input<decl::Bool>("Selection").default_value(true).hide_value().supports_field();
+  b.add_input<decl::Vector>("Scale").subtype(PROP_XYZ).default_value({1, 1, 1}).supports_field();
+  b.add_input<decl::Vector>("Center").subtype(PROP_TRANSLATION).supports_field();
+  b.add_input<decl::Bool>("Local Space").default_value(true).supports_field();
+  b.add_output<decl::Geometry>("Geometry");
+};
+
+static void scale_instances(GeoNodeExecParams &params, InstancesComponent &instances_component)
+{
+  GeometryComponentFieldContext field_context{instances_component, ATTR_DOMAIN_POINT};
+
+  fn::FieldEvaluator selection_evaluator{field_context, instances_component.instances_amount()};
+  selection_evaluator.add(params.extract_input<Field<bool>>("Selection"));
+  selection_evaluator.evaluate();
+  const IndexMask selection = selection_evaluator.get_evaluated_as_mask(0);
+
+  fn::FieldEvaluator transforms_evaluator{field_context, &selection};
+  transforms_evaluator.add(params.extract_input<Field<float3>>("Scale"));
+  transforms_evaluator.add(params.extract_input<Field<float3>>("Center"));
+  transforms_evaluator.add(params.extract_input<Field<bool>>("Local Space"));
+  transforms_evaluator.evaluate();
+  const VArray<float3> &scales = transforms_evaluator.get_evaluated<float3>(0);
+  const VArray<float3> &pivots = transforms_evaluator.get_evaluated<float3>(1);
+  const VArray<bool> &local_spaces = transforms_evaluator.get_evaluated<bool>(2);
+
+  MutableSpan<float4x4> instance_transforms = instances_component.instance_transforms();
+
+  threading::parallel_for(selection.index_range(), 512, [&](IndexRange range) {
+    for (const int i_selection : range) {
+      const int i = selection[i_selection];
+      const float3 pivot = pivots[i];
+      float4x4 &instance_transform = instance_transforms[i];
+
+      if (local_spaces[i]) {
+        instance_transform *= float4x4::from_location(pivot);
+        rescale_m4(instance_transform.values, scales[i]);
+        instance_transform *= float4x4::from_location(-pivot);
+      }
+      else {
+        const float4x4 original_transform = instance_transform;
+        instance_transform = float4x4::from_location(pivot);
+        rescale_m4(instance_transform.values, scales[i]);
+        instance_transform *= float4x4::from_location(-pivot);
+        instance_transform *= original_transform;
+      }
+    }
+  });
+}
+
+static void geo_node_scale_instances_exec(GeoNodeExecParams params)
+{
+  GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry");
+  if (geometry_set.has_instances()) {
+    InstancesComponent &instances = geometry_set.get_component_for_write<InstancesComponent>();
+    scale_instances(params, instances);
+  }
+  params.set_output("Geometry", std::move(geometry_set));
+}
+
+}  // namespace blender::nodes
+
+void register_node_type_geo_scale_instances()
+{
+  static bNodeType ntype;
+
+  geo_node_type_base(&ntype, GEO_NODE_SCALE_INSTANCES, "Scale Instances", NODE_CLASS_GEOMETRY, 0);
+  ntype.geometry_node_execute = blender::nodes::geo_node_scale_instances_exec;
+  ntype.declare = blender::nodes::geo_node_scale_instances_declare;
+  nodeRegisterType(&ntype);
+}



More information about the Bf-blender-cvs mailing list