[Bf-blender-cvs] [74de45712d9] temp-spreadsheet-instances: Add columns for instance data to the spreadsheet

Hans Goudey noreply at git.blender.org
Thu Mar 18 01:22:28 CET 2021


Commit: 74de45712d9210e115d6abf681dee0693c36d7f0
Author: Hans Goudey
Date:   Wed Mar 17 20:22:18 2021 -0400
Branches: temp-spreadsheet-instances
https://developer.blender.org/rB74de45712d9210e115d6abf681dee0693c36d7f0

Add columns for instance data to the spreadsheet

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

M	release/scripts/startup/bl_ui/space_spreadsheet.py
M	source/blender/blenlib/BLI_float4x4.hh
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/blenlib/BLI_float4x4.hh b/source/blender/blenlib/BLI_float4x4.hh
index d6d759ccfe4..722d863c7af 100644
--- a/source/blender/blenlib/BLI_float4x4.hh
+++ b/source/blender/blenlib/BLI_float4x4.hh
@@ -79,6 +79,25 @@ struct float4x4 {
     return m * float3(v);
   }
 
+  float3 translation() const
+  {
+    return float3(values[3]);
+  }
+
+  float3 to_euler() const
+  {
+    float3 euler;
+    mat4_to_eul(euler, values);
+    return euler;
+  }
+
+  float3 scale() const
+  {
+    float3 scale;
+    mat4_to_size(scale, values);
+    return scale;
+  }
+
   float4x4 inverted() const
   {
     float4x4 result;
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_column_layout.cc b/source/blender/editors/space_spreadsheet/spreadsheet_column_layout.cc
index 4faf0cac2c0..acd6330de41 100644
--- a/source/blender/editors/space_spreadsheet/spreadsheet_column_layout.cc
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_column_layout.cc
@@ -172,6 +172,24 @@ class ColumnLayoutDrawer : public SpreadsheetDrawer {
                        0,
                        nullptr);
     }
+    else if (std::holds_alternative<IconText>(cell_value.value)) {
+      const IconText value = *std::get_if<IconText>(&cell_value.value);
+      uiDefIconTextBut(params.block,
+                       UI_BTYPE_LABEL,
+                       0,
+                       value.icon_id,
+                       value.string.data(),
+                       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..b36689760ed 100644
--- a/source/blender/editors/space_spreadsheet/spreadsheet_column_layout.hh
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_column_layout.hh
@@ -22,6 +22,11 @@
 
 namespace blender::ed::spreadsheet {
 
+struct IconText {
+  int icon_id;
+  StringRefNull string;
+};
+
 /**
  * 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 +35,7 @@ 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, IconText>;
 
   VariantType value;
 };
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_from_geometry.cc b/source/blender/editors/space_spreadsheet/spreadsheet_from_geometry.cc
index 0ba405d97e0..e6ee0ce0432 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"
@@ -28,6 +29,8 @@
 
 #include "DEG_depsgraph_query.h"
 
+#include "UI_resources.h"
+
 #include "bmesh.h"
 
 #include "spreadsheet_from_geometry.hh"
@@ -38,6 +41,82 @@ namespace blender::ed::spreadsheet {
 using blender::bke::ReadAttribute;
 using blender::bke::ReadAttributePtr;
 
+static StringRefNull instance_data_name(const InstancedData &data)
+{
+  switch (data.type) {
+    case INSTANCE_DATA_TYPE_OBJECT: {
+      const ID *id = reinterpret_cast<const ID *>(data.data.object);
+      return id->name + 2;
+    }
+    case INSTANCE_DATA_TYPE_COLLECTION: {
+      const ID *id = reinterpret_cast<const ID *>(data.data.object);
+      return id->name + 2;
+    }
+  }
+  return nullptr;
+}
+
+static int instance_data_icon_id(const InstancedData &data)
+{
+  switch (data.type) {
+    case INSTANCE_DATA_TYPE_OBJECT: {
+      return ICON_OBJECT_DATA;
+    }
+    case INSTANCE_DATA_TYPE_COLLECTION: {
+      return ICON_OUTLINER_COLLECTION;
+    }
+  }
+  return ICON_BLANK1;
+}
+
+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];
+        r_cell_value.value = IconText{instance_data_icon_id(data), instance_data_name(data)};
+      }));
+
+  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();
+}
+
 static Vector<std::string> get_sorted_attribute_names_to_display(
     const GeometryComponent &component, const AttributeDomain domain)
 {
@@ -342,6 +421,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