[Bf-blender-cvs] [17a5db7303d] master: Geometry Nodes: Add geometry instances data to the spreadsheet

Hans Goudey noreply at git.blender.org
Fri Mar 19 20:30:56 CET 2021


Commit: 17a5db7303df52c319ea34cecea25442932cfe03
Author: Hans Goudey
Date:   Fri Mar 19 15:30:41 2021 -0400
Branches: master
https://developer.blender.org/rB17a5db7303df52c319ea34cecea25442932cfe03

Geometry Nodes: Add geometry instances data to the spreadsheet

This patch adds data about instances generated by geometry nodes
to the spreadsheet. The transform data is decomposed into position,
rotation, and scale, and there is a name column to display the name
of the instanced object or collection.

This data is implemented specifically for the spreadsheet, because
we're not sure that we want to expose this data as attributes for the
use elsewhere.

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

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

M	release/scripts/startup/bl_ui/space_spreadsheet.py
M	source/blender/editors/space_spreadsheet/spreadsheet_column_layout.cc
M	source/blender/editors/space_spreadsheet/spreadsheet_column_layout.hh
M	source/blender/editors/space_spreadsheet/spreadsheet_from_geometry.cc
M	source/blender/makesrna/intern/rna_space.c

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

diff --git a/release/scripts/startup/bl_ui/space_spreadsheet.py b/release/scripts/startup/bl_ui/space_spreadsheet.py
index a12fe68c9a5..db9133456a7 100644
--- a/release/scripts/startup/bl_ui/space_spreadsheet.py
+++ b/release/scripts/startup/bl_ui/space_spreadsheet.py
@@ -34,7 +34,8 @@ class SPREADSHEET_HT_header(bpy.types.Header):
         layout.prop(space, "object_eval_state", text="")
         if space.object_eval_state != "ORIGINAL":
             layout.prop(space, "geometry_component_type", text="")
-        layout.prop(space, "attribute_domain", text="")
+        if space.geometry_component_type != 'INSTANCES':
+            layout.prop(space, "attribute_domain", text="")
 
         if used_id:
             layout.label(text=used_id.name, icon="OBJECT_DATA")
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_column_layout.cc b/source/blender/editors/space_spreadsheet/spreadsheet_column_layout.cc
index 4faf0cac2c0..00724ffd4b0 100644
--- a/source/blender/editors/space_spreadsheet/spreadsheet_column_layout.cc
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_column_layout.cc
@@ -52,10 +52,15 @@ class ColumnLayoutDrawer : public SpreadsheetDrawer {
     const int minimum_column_width = 3 * UI_UNIT_X;
     const int header_name_padding = UI_UNIT_X;
     for (const SpreadsheetColumn *column : column_layout_.columns) {
-      StringRefNull name = column->name();
-      const int name_width = BLF_width(fontid, name.data(), name.size());
-      const int width = std::max(name_width + header_name_padding, minimum_column_width);
-      column_widths_.append(width);
+      if (column->default_width == 0.0f) {
+        StringRefNull name = column->name();
+        const int name_width = BLF_width(fontid, name.data(), name.size());
+        const int width = std::max(name_width + header_name_padding, minimum_column_width);
+        column_widths_.append(width);
+      }
+      else {
+        column_widths_.append(column->default_width * UI_UNIT_X);
+      }
     }
   }
 
@@ -172,6 +177,42 @@ class ColumnLayoutDrawer : public SpreadsheetDrawer {
                        0,
                        nullptr);
     }
+    else if (std::holds_alternative<ObjectCellValue>(cell_value.value)) {
+      const ObjectCellValue value = *std::get_if<ObjectCellValue>(&cell_value.value);
+      uiDefIconTextBut(params.block,
+                       UI_BTYPE_LABEL,
+                       0,
+                       ICON_OBJECT_DATA,
+                       reinterpret_cast<const ID *const>(value.object)->name + 2,
+                       params.xmin,
+                       params.ymin,
+                       params.width,
+                       params.height,
+                       nullptr,
+                       0,
+                       0,
+                       0,
+                       0,
+                       nullptr);
+    }
+    else if (std::holds_alternative<CollectionCellValue>(cell_value.value)) {
+      const CollectionCellValue value = *std::get_if<CollectionCellValue>(&cell_value.value);
+      uiDefIconTextBut(params.block,
+                       UI_BTYPE_LABEL,
+                       0,
+                       ICON_OUTLINER_COLLECTION,
+                       reinterpret_cast<const ID *const>(value.collection)->name + 2,
+                       params.xmin,
+                       params.ymin,
+                       params.width,
+                       params.height,
+                       nullptr,
+                       0,
+                       0,
+                       0,
+                       0,
+                       nullptr);
+    }
   }
 
   int column_width(int column_index) const final
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_column_layout.hh b/source/blender/editors/space_spreadsheet/spreadsheet_column_layout.hh
index a3832f42f30..a01e251d764 100644
--- a/source/blender/editors/space_spreadsheet/spreadsheet_column_layout.hh
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_column_layout.hh
@@ -20,8 +20,19 @@
 
 #include "spreadsheet_draw.hh"
 
+struct Object;
+struct Collection;
+
 namespace blender::ed::spreadsheet {
 
+struct ObjectCellValue {
+  const Object *object;
+};
+
+struct CollectionCellValue {
+  const Collection *collection;
+};
+
 /**
  * This is a small type that can hold the value of a cell in a spreadsheet. This type allows us to
  * decouple the drawing of individual cells from the code that generates the data to be displayed.
@@ -30,7 +41,8 @@ class CellValue {
  public:
   /* The implementation just uses a `std::variant` for simplicity. It can be encapsulated better,
    * but it's not really worth the complixity for now. */
-  using VariantType = std::variant<std::monostate, int, float, bool>;
+  using VariantType =
+      std::variant<std::monostate, int, float, bool, ObjectCellValue, CollectionCellValue>;
 
   VariantType value;
 };
@@ -56,6 +68,9 @@ class SpreadsheetColumn {
   {
     return name_;
   }
+
+  /* The default width of newly created columns, in UI units. */
+  float default_width = 0.0f;
 };
 
 /* Utility class for the function below. */
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_from_geometry.cc b/source/blender/editors/space_spreadsheet/spreadsheet_from_geometry.cc
index 0ba405d97e0..f5a4f09a5a2 100644
--- a/source/blender/editors/space_spreadsheet/spreadsheet_from_geometry.cc
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_from_geometry.cc
@@ -21,6 +21,7 @@
 #include "BKE_mesh_wrapper.h"
 #include "BKE_modifier.h"
 
+#include "DNA_ID.h"
 #include "DNA_mesh_types.h"
 #include "DNA_meshdata_types.h"
 #include "DNA_space_types.h"
@@ -38,6 +39,66 @@ namespace blender::ed::spreadsheet {
 using blender::bke::ReadAttribute;
 using blender::bke::ReadAttributePtr;
 
+static void add_columns_for_instances(const InstancesComponent &instances_component,
+                                      SpreadsheetColumnLayout &column_layout,
+                                      ResourceCollector &resources)
+{
+  Span<InstancedData> instance_data = instances_component.instanced_data();
+  Span<float4x4> transforms = instances_component.transforms();
+
+  Vector<std::unique_ptr<SpreadsheetColumn>> &columns =
+      resources.construct<Vector<std::unique_ptr<SpreadsheetColumn>>>("columns");
+
+  columns.append(spreadsheet_column_from_function(
+      "Name", [instance_data](int index, CellValue &r_cell_value) {
+        const InstancedData &data = instance_data[index];
+        if (data.type == INSTANCE_DATA_TYPE_OBJECT) {
+          if (data.data.object != nullptr) {
+            r_cell_value.value = ObjectCellValue{data.data.object};
+          }
+        }
+        else if (data.type == INSTANCE_DATA_TYPE_COLLECTION) {
+          if (data.data.collection != nullptr) {
+            r_cell_value.value = CollectionCellValue{data.data.collection};
+          }
+        }
+      }));
+
+  columns.last()->default_width = 8.0f;
+
+  static std::array<char, 3> axis_char = {'X', 'Y', 'Z'};
+  for (const int i : {0, 1, 2}) {
+    std::string name = std::string("Position ") + axis_char[i];
+    columns.append(spreadsheet_column_from_function(
+        name, [transforms, i](int index, CellValue &r_cell_value) {
+          r_cell_value.value = transforms[index].translation()[i];
+        }));
+  }
+
+  for (const int i : {0, 1, 2}) {
+    std::string name = std::string("Rotation ") + axis_char[i];
+    columns.append(spreadsheet_column_from_function(
+        name, [transforms, i](int index, CellValue &r_cell_value) {
+          r_cell_value.value = transforms[index].to_euler()[i];
+        }));
+  }
+
+  for (const int i : {0, 1, 2}) {
+    std::string name = std::string("Scale ") + axis_char[i];
+    columns.append(spreadsheet_column_from_function(
+        name, [transforms, i](int index, CellValue &r_cell_value) {
+          r_cell_value.value = transforms[index].scale()[i];
+        }));
+  }
+
+  for (std::unique_ptr<SpreadsheetColumn> &column : columns) {
+    column_layout.columns.append(column.get());
+  }
+
+  column_layout.row_indices = instance_data.index_range().as_span();
+  column_layout.tot_rows = instances_component.instances_amount();
+}
+
 static Vector<std::string> get_sorted_attribute_names_to_display(
     const GeometryComponent &component, const AttributeDomain domain)
 {
@@ -342,6 +403,12 @@ void spreadsheet_columns_from_geometry(const bContext *C,
   if (component == nullptr) {
     return;
   }
+  if (component_type == GEO_COMPONENT_TYPE_INSTANCES) {
+    add_columns_for_instances(
+        *static_cast<const InstancesComponent *>(component), column_layout, resources);
+    return;
+  }
+
   if (!component->attribute_domain_supported(domain)) {
     return;
   }
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index c0b40bfd526..730a272d250 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -7320,6 +7320,11 @@ static void rna_def_space_spreadsheet(BlenderRNA *brna)
        ICON_POINTCLOUD_DATA,
        "Point Cloud",
        "Point cloud component containing only point data"},
+      {GEO_COMPONENT_TYPE_INSTANCES,
+       "INSTANCES",
+       ICON_EMPTY_AXIS,
+       "Instances",
+       "Instances of objects or collections"},
       {0, NULL, 0, NULL, NULL},
   };



More information about the Bf-blender-cvs mailing list