Geometry Nodes: simplify retrieving data of instance reference
Specifically it's now easier to get the name, geometry set and icon.
This commit is contained in:
parent
406554c11e
commit
7bce839e25
@ -86,6 +86,16 @@ class InstanceReference {
|
|||||||
GeometrySet &geometry_set();
|
GeometrySet &geometry_set();
|
||||||
const GeometrySet &geometry_set() const;
|
const GeometrySet &geometry_set() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts the instance reference to a geometry set, even if it was an object or collection
|
||||||
|
* before.
|
||||||
|
*
|
||||||
|
* \note Uses out-parameter to be able to use #GeometrySet forward declaration.
|
||||||
|
*/
|
||||||
|
void to_geometry_set(GeometrySet &r_geometry_set) const;
|
||||||
|
|
||||||
|
std::string name() const;
|
||||||
|
|
||||||
bool owns_direct_data() const;
|
bool owns_direct_data() const;
|
||||||
void ensure_owns_direct_data();
|
void ensure_owns_direct_data();
|
||||||
|
|
||||||
|
@ -3,13 +3,20 @@
|
|||||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
|
||||||
#include "BLI_array_utils.hh"
|
#include "BLI_array_utils.hh"
|
||||||
|
#include "BLI_listbase.h"
|
||||||
#include "BLI_rand.hh"
|
#include "BLI_rand.hh"
|
||||||
#include "BLI_task.hh"
|
#include "BLI_task.hh"
|
||||||
|
|
||||||
|
#include "DNA_collection_types.h"
|
||||||
|
#include "DNA_object_types.h"
|
||||||
|
|
||||||
#include "BKE_customdata.hh"
|
#include "BKE_customdata.hh"
|
||||||
#include "BKE_geometry_set.hh"
|
#include "BKE_geometry_set.hh"
|
||||||
|
#include "BKE_geometry_set_instances.hh"
|
||||||
#include "BKE_instances.hh"
|
#include "BKE_instances.hh"
|
||||||
|
|
||||||
|
#include "BLT_translation.hh"
|
||||||
|
|
||||||
namespace blender::bke {
|
namespace blender::bke {
|
||||||
|
|
||||||
InstanceReference::InstanceReference(GeometrySet geometry_set)
|
InstanceReference::InstanceReference(GeometrySet geometry_set)
|
||||||
@ -35,6 +42,67 @@ bool InstanceReference::owns_direct_data() const
|
|||||||
return geometry_set_->owns_direct_data();
|
return geometry_set_->owns_direct_data();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void convert_collection_to_instances(const Collection &collection,
|
||||||
|
bke::Instances &instances)
|
||||||
|
{
|
||||||
|
LISTBASE_FOREACH (CollectionChild *, collection_child, &collection.children) {
|
||||||
|
float4x4 transform = float4x4::identity();
|
||||||
|
transform.location() += float3(collection_child->collection->instance_offset);
|
||||||
|
transform.location() -= float3(collection.instance_offset);
|
||||||
|
const int handle = instances.add_reference(*collection_child->collection);
|
||||||
|
instances.add_instance(handle, transform);
|
||||||
|
}
|
||||||
|
|
||||||
|
LISTBASE_FOREACH (CollectionObject *, collection_object, &collection.gobject) {
|
||||||
|
float4x4 transform = float4x4::identity();
|
||||||
|
transform.location() -= float3(collection.instance_offset);
|
||||||
|
transform *= (collection_object->ob)->object_to_world();
|
||||||
|
const int handle = instances.add_reference(*collection_object->ob);
|
||||||
|
instances.add_instance(handle, transform);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void InstanceReference::to_geometry_set(GeometrySet &r_geometry_set) const
|
||||||
|
{
|
||||||
|
r_geometry_set.clear();
|
||||||
|
switch (type_) {
|
||||||
|
case Type::Object: {
|
||||||
|
const Object &object = this->object();
|
||||||
|
r_geometry_set = bke::object_get_evaluated_geometry_set(object);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Type::Collection: {
|
||||||
|
const Collection &collection = this->collection();
|
||||||
|
std::unique_ptr<bke::Instances> instances_ptr = std::make_unique<bke::Instances>();
|
||||||
|
convert_collection_to_instances(collection, *instances_ptr);
|
||||||
|
r_geometry_set.replace_instances(instances_ptr.release());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Type::GeometrySet: {
|
||||||
|
r_geometry_set = this->geometry_set();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Type::None: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string InstanceReference::name() const
|
||||||
|
{
|
||||||
|
switch (type_) {
|
||||||
|
case Type::Object:
|
||||||
|
return this->object().id.name + 2;
|
||||||
|
case Type::Collection:
|
||||||
|
return this->collection().id.name + 2;
|
||||||
|
case Type::GeometrySet:
|
||||||
|
return IFACE_("Geometry");
|
||||||
|
case Type::None:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
bool operator==(const InstanceReference &a, const InstanceReference &b)
|
bool operator==(const InstanceReference &a, const InstanceReference &b)
|
||||||
{
|
{
|
||||||
if (a.geometry_set_ && b.geometry_set_) {
|
if (a.geometry_set_ && b.geometry_set_) {
|
||||||
|
@ -12,6 +12,7 @@ struct Base;
|
|||||||
struct ListBase;
|
struct ListBase;
|
||||||
struct SpaceOutliner;
|
struct SpaceOutliner;
|
||||||
struct bContext;
|
struct bContext;
|
||||||
|
struct ID;
|
||||||
|
|
||||||
bool ED_outliner_collections_editor_poll(bContext *C);
|
bool ED_outliner_collections_editor_poll(bContext *C);
|
||||||
|
|
||||||
@ -47,3 +48,5 @@ void ED_outliner_select_sync_from_outliner(bContext *C, SpaceOutliner *space_out
|
|||||||
* Copy sync select dirty flag from window manager to all outliners to be synced lazily on draw.
|
* Copy sync select dirty flag from window manager to all outliners to be synced lazily on draw.
|
||||||
*/
|
*/
|
||||||
void ED_outliner_select_sync_flag_outliners(const bContext *C);
|
void ED_outliner_select_sync_flag_outliners(const bContext *C);
|
||||||
|
|
||||||
|
int ED_outliner_icon_from_id(const ID &id);
|
||||||
|
@ -4130,3 +4130,8 @@ void draw_outliner(const bContext *C)
|
|||||||
/** \} */
|
/** \} */
|
||||||
|
|
||||||
} // namespace blender::ed::outliner
|
} // namespace blender::ed::outliner
|
||||||
|
|
||||||
|
int ED_outliner_icon_from_id(const ID &id)
|
||||||
|
{
|
||||||
|
return blender::ed::outliner::tree_element_get_icon_from_id(&id);
|
||||||
|
}
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#include "DEG_depsgraph_query.hh"
|
#include "DEG_depsgraph_query.hh"
|
||||||
|
|
||||||
#include "ED_curves.hh"
|
#include "ED_curves.hh"
|
||||||
|
#include "ED_outliner.hh"
|
||||||
#include "ED_spreadsheet.hh"
|
#include "ED_spreadsheet.hh"
|
||||||
|
|
||||||
#include "NOD_geometry_nodes_lazy_function.hh"
|
#include "NOD_geometry_nodes_lazy_function.hh"
|
||||||
@ -42,6 +43,8 @@
|
|||||||
#include "RNA_access.hh"
|
#include "RNA_access.hh"
|
||||||
#include "RNA_enum_types.hh"
|
#include "RNA_enum_types.hh"
|
||||||
|
|
||||||
|
#include "UI_resources.hh"
|
||||||
|
|
||||||
#include "bmesh.hh"
|
#include "bmesh.hh"
|
||||||
|
|
||||||
#include "spreadsheet_data_source_geometry.hh"
|
#include "spreadsheet_data_source_geometry.hh"
|
||||||
@ -545,6 +548,26 @@ int VolumeDataSource::tot_rows() const
|
|||||||
return BKE_volume_num_grids(volume);
|
return BKE_volume_num_grids(volume);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int get_instance_reference_icon(const bke::InstanceReference &reference)
|
||||||
|
{
|
||||||
|
switch (reference.type()) {
|
||||||
|
case bke::InstanceReference::Type::Object: {
|
||||||
|
const Object &object = reference.object();
|
||||||
|
return ED_outliner_icon_from_id(object.id);
|
||||||
|
}
|
||||||
|
case bke::InstanceReference::Type::Collection: {
|
||||||
|
return ICON_OUTLINER_COLLECTION;
|
||||||
|
}
|
||||||
|
case bke::InstanceReference::Type::GeometrySet: {
|
||||||
|
return ICON_EMPTY_AXIS;
|
||||||
|
}
|
||||||
|
case bke::InstanceReference::Type::None: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ICON_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
bke::GeometrySet spreadsheet_get_display_geometry_set(const SpaceSpreadsheet *sspreadsheet,
|
bke::GeometrySet spreadsheet_get_display_geometry_set(const SpaceSpreadsheet *sspreadsheet,
|
||||||
Object *object_eval)
|
Object *object_eval)
|
||||||
{
|
{
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "BLI_resource_scope.hh"
|
#include "BLI_resource_scope.hh"
|
||||||
|
|
||||||
#include "BKE_geometry_set.hh"
|
#include "BKE_geometry_set.hh"
|
||||||
|
#include "BKE_instances.hh"
|
||||||
|
|
||||||
#include "spreadsheet_data_source.hh"
|
#include "spreadsheet_data_source.hh"
|
||||||
|
|
||||||
@ -109,6 +110,8 @@ class VolumeDataSource : public DataSource {
|
|||||||
int tot_rows() const override;
|
int tot_rows() const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int get_instance_reference_icon(const bke::InstanceReference &reference);
|
||||||
|
|
||||||
std::unique_ptr<DataSource> data_source_from_geometry(const bContext *C, Object *object_eval);
|
std::unique_ptr<DataSource> data_source_from_geometry(const bContext *C, Object *object_eval);
|
||||||
|
|
||||||
} // namespace blender::ed::spreadsheet
|
} // namespace blender::ed::spreadsheet
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "BKE_instances.hh"
|
#include "BKE_instances.hh"
|
||||||
|
|
||||||
#include "spreadsheet_column_values.hh"
|
#include "spreadsheet_column_values.hh"
|
||||||
|
#include "spreadsheet_data_source_geometry.hh"
|
||||||
#include "spreadsheet_layout.hh"
|
#include "spreadsheet_layout.hh"
|
||||||
|
|
||||||
#include "DNA_collection_types.h"
|
#include "DNA_collection_types.h"
|
||||||
@ -203,14 +204,14 @@ class SpreadsheetLayoutDrawer : public SpreadsheetDrawer {
|
|||||||
}
|
}
|
||||||
else if (data.type().is<bke::InstanceReference>()) {
|
else if (data.type().is<bke::InstanceReference>()) {
|
||||||
const bke::InstanceReference value = data.get<bke::InstanceReference>(real_index);
|
const bke::InstanceReference value = data.get<bke::InstanceReference>(real_index);
|
||||||
switch (value.type()) {
|
const std::string name = value.name();
|
||||||
case bke::InstanceReference::Type::Object: {
|
const int icon = get_instance_reference_icon(value);
|
||||||
const Object &object = value.object();
|
if (!name.empty()) {
|
||||||
uiDefIconTextBut(params.block,
|
uiDefIconTextBut(params.block,
|
||||||
UI_BTYPE_LABEL,
|
UI_BTYPE_LABEL,
|
||||||
0,
|
0,
|
||||||
ICON_OBJECT_DATA,
|
icon,
|
||||||
object.id.name + 2,
|
name.c_str(),
|
||||||
params.xmin,
|
params.xmin,
|
||||||
params.ymin,
|
params.ymin,
|
||||||
params.width,
|
params.width,
|
||||||
@ -219,44 +220,6 @@ class SpreadsheetLayoutDrawer : public SpreadsheetDrawer {
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
nullptr);
|
nullptr);
|
||||||
break;
|
|
||||||
}
|
|
||||||
case bke::InstanceReference::Type::Collection: {
|
|
||||||
Collection &collection = value.collection();
|
|
||||||
uiDefIconTextBut(params.block,
|
|
||||||
UI_BTYPE_LABEL,
|
|
||||||
0,
|
|
||||||
ICON_OUTLINER_COLLECTION,
|
|
||||||
collection.id.name + 2,
|
|
||||||
params.xmin,
|
|
||||||
params.ymin,
|
|
||||||
params.width,
|
|
||||||
params.height,
|
|
||||||
nullptr,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
nullptr);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case bke::InstanceReference::Type::GeometrySet: {
|
|
||||||
uiDefIconTextBut(params.block,
|
|
||||||
UI_BTYPE_LABEL,
|
|
||||||
0,
|
|
||||||
ICON_MESH_DATA,
|
|
||||||
"Geometry",
|
|
||||||
params.xmin,
|
|
||||||
params.ymin,
|
|
||||||
params.width,
|
|
||||||
params.height,
|
|
||||||
nullptr,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
nullptr);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case bke::InstanceReference::Type::None: {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (data.type().is<std::string>()) {
|
else if (data.type().is<std::string>()) {
|
||||||
|
@ -320,25 +320,6 @@ static int64_t get_final_points_num(const GatherTasks &tasks)
|
|||||||
return points_num;
|
return points_num;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void realize_collections(Collection &collection, bke::Instances &instances)
|
|
||||||
{
|
|
||||||
LISTBASE_FOREACH (CollectionChild *, collection_child, &collection.children) {
|
|
||||||
float4x4 transform = float4x4::identity();
|
|
||||||
transform.location() += float3(collection_child->collection->instance_offset);
|
|
||||||
transform.location() -= float3(collection.instance_offset);
|
|
||||||
const int handle = instances.add_reference(*collection_child->collection);
|
|
||||||
instances.add_instance(handle, transform);
|
|
||||||
}
|
|
||||||
|
|
||||||
LISTBASE_FOREACH (CollectionObject *, collection_object, &collection.gobject) {
|
|
||||||
float4x4 transform = float4x4::identity();
|
|
||||||
transform.location() -= float3(collection.instance_offset);
|
|
||||||
transform *= (collection_object->ob)->object_to_world();
|
|
||||||
const int handle = instances.add_reference(*collection_object->ob);
|
|
||||||
instances.add_instance(handle, transform);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void copy_transformed_positions(const Span<float3> src,
|
static void copy_transformed_positions(const Span<float3> src,
|
||||||
const float4x4 &transform,
|
const float4x4 &transform,
|
||||||
MutableSpan<float3> dst)
|
MutableSpan<float3> dst)
|
||||||
@ -500,33 +481,6 @@ static Vector<std::pair<int, GSpan>> prepare_attribute_fallbacks(
|
|||||||
return attributes_to_override;
|
return attributes_to_override;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bke::GeometrySet geometry_set_from_reference(const InstanceReference &reference)
|
|
||||||
{
|
|
||||||
switch (reference.type()) {
|
|
||||||
case InstanceReference::Type::Object: {
|
|
||||||
const Object &object = reference.object();
|
|
||||||
const bke::GeometrySet geometry_set = bke::object_get_evaluated_geometry_set(object);
|
|
||||||
return geometry_set;
|
|
||||||
}
|
|
||||||
case InstanceReference::Type::Collection: {
|
|
||||||
std::unique_ptr<bke::Instances> instances_ptr = std::make_unique<bke::Instances>();
|
|
||||||
realize_collections(reference.collection(), *instances_ptr);
|
|
||||||
bke::GeometrySet geometry_set;
|
|
||||||
geometry_set.replace_instances(instances_ptr.release());
|
|
||||||
return geometry_set;
|
|
||||||
}
|
|
||||||
case InstanceReference::Type::GeometrySet: {
|
|
||||||
const bke::GeometrySet geometry_set = reference.geometry_set();
|
|
||||||
return geometry_set;
|
|
||||||
}
|
|
||||||
case InstanceReference::Type::None: {
|
|
||||||
/* Return an empty GeometrySet for None type. */
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calls #fn for every geometry in the given #InstanceReference. Also passes on the transformation
|
* Calls #fn for every geometry in the given #InstanceReference. Also passes on the transformation
|
||||||
* that is applied to every instance.
|
* that is applied to every instance.
|
||||||
@ -538,7 +492,8 @@ static void foreach_geometry_in_reference(
|
|||||||
FunctionRef<void(const bke::GeometrySet &geometry_set, const float4x4 &transform, uint32_t id)>
|
FunctionRef<void(const bke::GeometrySet &geometry_set, const float4x4 &transform, uint32_t id)>
|
||||||
fn)
|
fn)
|
||||||
{
|
{
|
||||||
bke::GeometrySet geometry_set = geometry_set_from_reference(reference);
|
bke::GeometrySet geometry_set;
|
||||||
|
reference.to_geometry_set(geometry_set);
|
||||||
fn(geometry_set, base_transform, id);
|
fn(geometry_set, base_transform, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -770,8 +725,10 @@ static bool attribute_foreach(const bke::GeometrySet &geometry_set,
|
|||||||
IndexMask(IndexRange(instances.instances_num()));
|
IndexMask(IndexRange(instances.instances_num()));
|
||||||
indices.foreach_index([&](const int i) {
|
indices.foreach_index([&](const int i) {
|
||||||
const int child_depth_target = (0 == current_depth) ? instance_depth[i] : depth_target;
|
const int child_depth_target = (0 == current_depth) ? instance_depth[i] : depth_target;
|
||||||
bke::GeometrySet instance_geometry_set = geometry_set_from_reference(
|
const bke::InstanceReference &reference =
|
||||||
instances.references()[instances.reference_handles()[i]]);
|
instances.references()[instances.reference_handles()[i]];
|
||||||
|
bke::GeometrySet instance_geometry_set;
|
||||||
|
reference.to_geometry_set(instance_geometry_set);
|
||||||
/* Process child instances with a recursive call. */
|
/* Process child instances with a recursive call. */
|
||||||
if (current_depth != child_depth_target) {
|
if (current_depth != child_depth_target) {
|
||||||
child_has_component = child_has_component | attribute_foreach(instance_geometry_set,
|
child_has_component = child_has_component | attribute_foreach(instance_geometry_set,
|
||||||
|
Loading…
Reference in New Issue
Block a user