Cleanup: remove use of persistent data handles in geometry nodes

Those were mostly just left over from previous work on particle nodes.
They solved the problem of keeping a reference to an object over
multiple frames and in a cache. Currently, we do not have this problem
in geometry nodes, so we can also remove this layer of complexity
for now.
This commit is contained in:
2021-05-08 14:54:48 +02:00
parent 39044e68c2
commit 34439f05ab
11 changed files with 34 additions and 307 deletions

View File

@@ -1,153 +0,0 @@
/*
* 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.
*/
#pragma once
/** \file
* \ingroup bke
*
* A PersistentDataHandle is a weak reference to some data in a Blender file. The handle itself is
* just a number. A PersistentDataHandleMap is used to convert between handles and the actual data.
*/
#include "BLI_map.hh"
#include "DNA_ID.h"
struct Collection;
struct Object;
namespace blender::bke {
class PersistentDataHandleMap;
class PersistentDataHandle {
private:
/* Negative values indicate that the handle is "empty". */
int32_t handle_;
friend PersistentDataHandleMap;
protected:
PersistentDataHandle(int handle) : handle_(handle)
{
}
public:
PersistentDataHandle() : handle_(-1)
{
}
friend bool operator==(const PersistentDataHandle &a, const PersistentDataHandle &b)
{
return a.handle_ == b.handle_;
}
friend bool operator!=(const PersistentDataHandle &a, const PersistentDataHandle &b)
{
return !(a == b);
}
friend std::ostream &operator<<(std::ostream &stream, const PersistentDataHandle &a)
{
stream << a.handle_;
return stream;
}
uint64_t hash() const
{
return static_cast<uint64_t>(handle_);
}
};
class PersistentIDHandle : public PersistentDataHandle {
friend PersistentDataHandleMap;
using PersistentDataHandle::PersistentDataHandle;
};
class PersistentObjectHandle : public PersistentIDHandle {
friend PersistentDataHandleMap;
using PersistentIDHandle::PersistentIDHandle;
};
class PersistentCollectionHandle : public PersistentIDHandle {
friend PersistentDataHandleMap;
using PersistentIDHandle::PersistentIDHandle;
};
class PersistentDataHandleMap {
private:
Map<int32_t, ID *> id_by_handle_;
Map<ID *, int32_t> handle_by_id_;
public:
void add(int32_t handle, ID &id)
{
BLI_assert(handle >= 0);
handle_by_id_.add(&id, handle);
id_by_handle_.add(handle, &id);
}
PersistentIDHandle lookup(ID *id) const
{
const int handle = handle_by_id_.lookup_default(id, -1);
return PersistentIDHandle(handle);
}
PersistentObjectHandle lookup(Object *object) const
{
const int handle = handle_by_id_.lookup_default((ID *)object, -1);
return PersistentObjectHandle(handle);
}
PersistentCollectionHandle lookup(Collection *collection) const
{
const int handle = handle_by_id_.lookup_default((ID *)collection, -1);
return PersistentCollectionHandle(handle);
}
ID *lookup(const PersistentIDHandle &handle) const
{
ID *id = id_by_handle_.lookup_default(handle.handle_, nullptr);
return id;
}
Object *lookup(const PersistentObjectHandle &handle) const
{
ID *id = this->lookup((const PersistentIDHandle &)handle);
if (id == nullptr) {
return nullptr;
}
if (GS(id->name) != ID_OB) {
return nullptr;
}
return (Object *)id;
}
Collection *lookup(const PersistentCollectionHandle &handle) const
{
ID *id = this->lookup((const PersistentIDHandle &)handle);
if (id == nullptr) {
return nullptr;
}
if (GS(id->name) != ID_GR) {
return nullptr;
}
return (Collection *)id;
}
};
} // namespace blender::bke

View File

@@ -406,7 +406,6 @@ set(SRC
BKE_paint.h
BKE_particle.h
BKE_pbvh.h
BKE_persistent_data_handle.hh
BKE_pointcache.h
BKE_pointcloud.h
BKE_preferences.h

View File

@@ -93,9 +93,6 @@ using blender::Span;
using blender::StringRef;
using blender::StringRefNull;
using blender::Vector;
using blender::bke::PersistentCollectionHandle;
using blender::bke::PersistentDataHandleMap;
using blender::bke::PersistentObjectHandle;
using blender::fn::GMutablePointer;
using blender::fn::GPointer;
using blender::nodes::GeoNodeExecParams;
@@ -284,9 +281,7 @@ struct SocketPropertyType {
IDProperty *(*create_default_ui_prop)(const bNodeSocket &socket, const char *name);
PropertyType (*rna_subtype_get)(const bNodeSocket &socket);
bool (*is_correct_type)(const IDProperty &property);
void (*init_cpp_value)(const IDProperty &property,
const PersistentDataHandleMap &handles,
void *r_value);
void (*init_cpp_value)(const IDProperty &property, void *r_value);
};
static IDProperty *socket_add_property(IDProperty *settings_prop_group,
@@ -379,9 +374,7 @@ static const SocketPropertyType *get_socket_property_type(const bNodeSocket &bso
return (PropertyType)((bNodeSocketValueFloat *)socket.default_value)->subtype;
},
[](const IDProperty &property) { return ELEM(property.type, IDP_FLOAT, IDP_DOUBLE); },
[](const IDProperty &property,
const PersistentDataHandleMap &UNUSED(handles),
void *r_value) {
[](const IDProperty &property, void *r_value) {
if (property.type == IDP_FLOAT) {
*(float *)r_value = IDP_Float(&property);
}
@@ -422,9 +415,7 @@ static const SocketPropertyType *get_socket_property_type(const bNodeSocket &bso
return (PropertyType)((bNodeSocketValueInt *)socket.default_value)->subtype;
},
[](const IDProperty &property) { return property.type == IDP_INT; },
[](const IDProperty &property,
const PersistentDataHandleMap &UNUSED(handles),
void *r_value) { *(int *)r_value = IDP_Int(&property); },
[](const IDProperty &property, void *r_value) { *(int *)r_value = IDP_Int(&property); },
};
return &int_type;
}
@@ -467,9 +458,9 @@ static const SocketPropertyType *get_socket_property_type(const bNodeSocket &bso
return property.type == IDP_ARRAY && property.subtype == IDP_FLOAT &&
property.len == 3;
},
[](const IDProperty &property,
const PersistentDataHandleMap &UNUSED(handles),
void *r_value) { copy_v3_v3((float *)r_value, (const float *)IDP_Array(&property)); },
[](const IDProperty &property, void *r_value) {
copy_v3_v3((float *)r_value, (const float *)IDP_Array(&property));
},
};
return &vector_type;
}
@@ -499,9 +490,9 @@ static const SocketPropertyType *get_socket_property_type(const bNodeSocket &bso
},
nullptr,
[](const IDProperty &property) { return property.type == IDP_INT; },
[](const IDProperty &property,
const PersistentDataHandleMap &UNUSED(handles),
void *r_value) { *(bool *)r_value = IDP_Int(&property) != 0; },
[](const IDProperty &property, void *r_value) {
*(bool *)r_value = IDP_Int(&property) != 0;
},
};
return &boolean_type;
}
@@ -521,9 +512,9 @@ static const SocketPropertyType *get_socket_property_type(const bNodeSocket &bso
},
nullptr,
[](const IDProperty &property) { return property.type == IDP_STRING; },
[](const IDProperty &property,
const PersistentDataHandleMap &UNUSED(handles),
void *r_value) { new (r_value) std::string(IDP_String(&property)); },
[](const IDProperty &property, void *r_value) {
new (r_value) std::string(IDP_String(&property));
},
};
return &string_type;
}
@@ -540,10 +531,10 @@ static const SocketPropertyType *get_socket_property_type(const bNodeSocket &bso
nullptr,
nullptr,
[](const IDProperty &property) { return property.type == IDP_ID; },
[](const IDProperty &property, const PersistentDataHandleMap &handles, void *r_value) {
[](const IDProperty &property, void *r_value) {
ID *id = IDP_Id(&property);
Object *object = (id && GS(id->name) == ID_OB) ? (Object *)id : nullptr;
new (r_value) PersistentObjectHandle(handles.lookup(object));
*(Object **)r_value = object;
},
};
return &object_type;
@@ -561,10 +552,10 @@ static const SocketPropertyType *get_socket_property_type(const bNodeSocket &bso
nullptr,
nullptr,
[](const IDProperty &property) { return property.type == IDP_ID; },
[](const IDProperty &property, const PersistentDataHandleMap &handles, void *r_value) {
[](const IDProperty &property, void *r_value) {
ID *id = IDP_Id(&property);
Collection *collection = (id && GS(id->name) == ID_GR) ? (Collection *)id : nullptr;
new (r_value) PersistentCollectionHandle(handles.lookup(collection));
*(Collection **)r_value = collection;
},
};
return &collection_type;
@@ -652,7 +643,6 @@ void MOD_nodes_init(Main *bmain, NodesModifierData *nmd)
}
static void initialize_group_input(NodesModifierData &nmd,
const PersistentDataHandleMap &handle_map,
const bNodeSocket &socket,
const CPPType &cpp_type,
void *r_value)
@@ -676,22 +666,7 @@ static void initialize_group_input(NodesModifierData &nmd,
blender::nodes::socket_cpp_value_get(socket, r_value);
return;
}
property_type->init_cpp_value(*property, handle_map, r_value);
}
static void fill_data_handle_map(const NodesModifierSettings &settings,
const DerivedNodeTree &tree,
PersistentDataHandleMap &handle_map)
{
Set<ID *> used_ids;
find_used_ids_from_settings(settings, used_ids);
find_used_ids_from_nodes(*tree.root_context().tree().btree(), used_ids);
int current_handle = 0;
for (ID *id : used_ids) {
handle_map.add(current_handle, *id);
current_handle++;
}
property_type->init_cpp_value(*property, r_value);
}
static void reset_tree_ui_storage(Span<const blender::nodes::NodeTreeRef *> trees,
@@ -879,9 +854,6 @@ static GeometrySet compute_geometry(const DerivedNodeTree &tree,
blender::LinearAllocator<> &allocator = scope.linear_allocator();
blender::nodes::MultiFunctionByNode mf_by_node = get_multi_function_per_node(tree, scope);
PersistentDataHandleMap handle_map;
fill_data_handle_map(nmd->settings, tree, handle_map);
Map<DOutputSocket, GMutablePointer> group_inputs;
const DTreeContext *root_context = &tree.root_context();
@@ -907,7 +879,7 @@ static GeometrySet compute_geometry(const DerivedNodeTree &tree,
for (const OutputSocketRef *socket : remaining_input_sockets) {
const CPPType &cpp_type = *blender::nodes::socket_cpp_type_get(*socket->typeinfo());
void *value_in = allocator.allocate(cpp_type.size(), cpp_type.alignment());
initialize_group_input(*nmd, handle_map, *socket->bsocket(), cpp_type, value_in);
initialize_group_input(*nmd, *socket->bsocket(), cpp_type, value_in);
group_inputs.add_new({root_context, socket}, {cpp_type, value_in});
}
}
@@ -936,7 +908,6 @@ static GeometrySet compute_geometry(const DerivedNodeTree &tree,
eval_params.input_values = group_inputs;
eval_params.output_sockets = group_outputs;
eval_params.mf_by_node = &mf_by_node;
eval_params.handle_map = &handle_map;
eval_params.modifier_ = nmd;
eval_params.depsgraph = ctx->depsgraph;
eval_params.self_object = ctx->object;

View File

@@ -26,8 +26,6 @@
namespace blender::modifiers::geometry_nodes {
using bke::PersistentCollectionHandle;
using bke::PersistentObjectHandle;
using fn::CPPType;
using fn::GValueMap;
using nodes::GeoNodeExecParams;
@@ -96,7 +94,6 @@ class GeometryNodesEvaluator {
Vector<DInputSocket> group_outputs_;
blender::nodes::MultiFunctionByNode &mf_by_node_;
const blender::nodes::DataTypeConversions &conversions_;
const PersistentDataHandleMap &handle_map_;
const Object *self_object_;
const ModifierData *modifier_;
Depsgraph *depsgraph_;
@@ -108,7 +105,6 @@ class GeometryNodesEvaluator {
group_outputs_(std::move(params.output_sockets)),
mf_by_node_(*params.mf_by_node),
conversions_(blender::nodes::get_implicit_type_conversions()),
handle_map_(*params.handle_map),
self_object_(params.self_object),
modifier_(&params.modifier_->modifier),
depsgraph_(params.depsgraph),
@@ -237,7 +233,6 @@ class GeometryNodesEvaluator {
GValueMap<StringRef> node_outputs_map{allocator_};
NodeParamsProvider params_provider;
params_provider.dnode = node;
params_provider.handle_map = &handle_map_;
params_provider.self_object = self_object_;
params_provider.depsgraph = depsgraph_;
params_provider.allocator = &allocator_;
@@ -412,20 +407,7 @@ class GeometryNodesEvaluator {
bNodeSocket *bsocket = socket->bsocket();
const CPPType &type = *blender::nodes::socket_cpp_type_get(*socket->typeinfo());
void *buffer = allocator_.allocate(type.size(), type.alignment());
if (bsocket->type == SOCK_OBJECT) {
Object *object = socket->default_value<bNodeSocketValueObject>()->value;
PersistentObjectHandle object_handle = handle_map_.lookup(object);
new (buffer) PersistentObjectHandle(object_handle);
}
else if (bsocket->type == SOCK_COLLECTION) {
Collection *collection = socket->default_value<bNodeSocketValueCollection>()->value;
PersistentCollectionHandle collection_handle = handle_map_.lookup(collection);
new (buffer) PersistentCollectionHandle(collection_handle);
}
else {
blender::nodes::socket_cpp_value_get(*bsocket, buffer);
}
if (type == required_type) {
return {type, buffer};

View File

@@ -23,14 +23,11 @@
#include "FN_generic_pointer.hh"
#include "BKE_persistent_data_handle.hh"
#include "DNA_modifier_types.h"
namespace blender::modifiers::geometry_nodes {
using namespace nodes::derived_node_tree_types;
using bke::PersistentDataHandleMap;
using fn::GMutablePointer;
using fn::GPointer;
@@ -42,7 +39,6 @@ struct GeometryNodesEvaluationParams {
Map<DOutputSocket, GMutablePointer> input_values;
Vector<DInputSocket> output_sockets;
nodes::MultiFunctionByNode *mf_by_node;
const PersistentDataHandleMap *handle_map;
const NodesModifierData *modifier_;
Depsgraph *depsgraph;
Object *self_object;

View File

@@ -22,7 +22,6 @@
#include "BKE_geometry_set.hh"
#include "BKE_geometry_set_instances.hh"
#include "BKE_node_ui_storage.hh"
#include "BKE_persistent_data_handle.hh"
#include "DNA_node_types.h"
@@ -36,8 +35,6 @@ namespace blender::nodes {
using bke::geometry_set_realize_instances;
using bke::OutputAttribute;
using bke::OutputAttribute_Typed;
using bke::PersistentDataHandleMap;
using bke::PersistentObjectHandle;
using bke::ReadAttributeLookup;
using bke::WriteAttributeLookup;
using fn::CPPType;
@@ -63,7 +60,6 @@ using fn::GVMutableArrayPtr;
class GeoNodeExecParamsProvider {
public:
DNode dnode;
const PersistentDataHandleMap *handle_map = nullptr;
const Object *self_object = nullptr;
const ModifierData *modifier = nullptr;
Depsgraph *depsgraph = nullptr;
@@ -190,11 +186,6 @@ class GeoNodeExecParams {
return *provider_->dnode->bnode();
}
const PersistentDataHandleMap &handle_map() const
{
return *provider_->handle_map;
}
const Object *self_object() const
{
return provider_->self_object;

View File

@@ -42,9 +42,7 @@ namespace blender::nodes {
static void geo_node_collection_info_exec(GeoNodeExecParams params)
{
bke::PersistentCollectionHandle collection_handle =
params.extract_input<bke::PersistentCollectionHandle>("Collection");
Collection *collection = params.handle_map().lookup(collection_handle);
Collection *collection = params.get_input<Collection *>("Collection");
GeometrySet geometry_set_out;

View File

@@ -47,9 +47,7 @@ static void geo_node_object_info_exec(GeoNodeExecParams params)
const bool transform_space_relative = (node_storage->transform_space ==
GEO_NODE_TRANSFORM_SPACE_RELATIVE);
bke::PersistentObjectHandle object_handle = params.extract_input<bke::PersistentObjectHandle>(
"Object");
Object *object = params.handle_map().lookup(object_handle);
Object *object = params.get_input<Object *>("Object");
float3 location = {0, 0, 0};
float3 rotation = {0, 0, 0};

View File

@@ -14,8 +14,6 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "BKE_persistent_data_handle.hh"
#include "DNA_collection_types.h"
#include "BLI_hash.h"
@@ -68,9 +66,7 @@ static void geo_node_point_instance_update(bNodeTree *UNUSED(tree), bNode *node)
static void get_instance_references__object(const GeoNodeExecParams &params,
MutableSpan<InstanceReference> r_references)
{
bke::PersistentObjectHandle object_handle = params.get_input<bke::PersistentObjectHandle>(
"Object");
Object *object = params.handle_map().lookup(object_handle);
Object *object = params.get_input<Object *>("Object");
if (object == params.self_object()) {
object = nullptr;
}
@@ -86,9 +82,7 @@ static void get_instance_references__collection(const GeoNodeExecParams &params,
const bNode &node = params.node();
NodeGeometryPointInstance *node_storage = (NodeGeometryPointInstance *)node.storage;
bke::PersistentCollectionHandle collection_handle =
params.get_input<bke::PersistentCollectionHandle>("Collection");
Collection *collection = params.handle_map().lookup(collection_handle);
Collection *collection = params.get_input<Collection *>("Collection");
if (collection == nullptr) {
return;
}

View File

@@ -133,11 +133,11 @@ static void geo_node_switch_exec(GeoNodeExecParams params)
break;
}
case SOCK_OBJECT: {
output_input<bke::PersistentObjectHandle>(params, input, "_007", "Output_007");
output_input<Object *>(params, input, "_007", "Output_007");
break;
}
case SOCK_COLLECTION: {
output_input<bke::PersistentCollectionHandle>(params, input, "_008", "Output_008");
output_input<Collection *>(params, input, "_008", "Output_008");
break;
}
default:

View File

@@ -35,7 +35,6 @@
#include "BKE_geometry_set.hh"
#include "BKE_lib_id.h"
#include "BKE_node.h"
#include "BKE_persistent_data_handle.hh"
#include "DNA_collection_types.h"
@@ -632,63 +631,15 @@ static bNodeSocketType *make_socket_type_string()
return socktype;
}
class ObjectSocketMultiFunction : public blender::fn::MultiFunction {
private:
Object *object_;
public:
ObjectSocketMultiFunction(Object *object) : object_(object)
{
static blender::fn::MFSignature signature = create_signature();
this->set_signature(&signature);
}
static blender::fn::MFSignature create_signature()
{
blender::fn::MFSignatureBuilder signature{"Object Socket"};
signature.depends_on_context();
signature.single_output<blender::bke::PersistentObjectHandle>("Object");
return signature.build();
}
void call(blender::IndexMask mask,
blender::fn::MFParams params,
blender::fn::MFContext context) const override
{
blender::MutableSpan output =
params.uninitialized_single_output<blender::bke::PersistentObjectHandle>(0, "Object");
/* Try to get a handle map, so that the object can be converted to a handle. */
const blender::bke::PersistentDataHandleMap *handle_map =
context.get_global_context<blender::bke::PersistentDataHandleMap>(
"PersistentDataHandleMap");
if (handle_map == nullptr) {
/* Return empty handles when there is no handle map. */
output.fill_indices(mask, blender::bke::PersistentObjectHandle());
return;
}
blender::bke::PersistentObjectHandle handle = handle_map->lookup(object_);
for (int64_t i : mask) {
output[i] = handle;
}
}
};
MAKE_CPP_TYPE(PersistentObjectHandle, blender::bke::PersistentObjectHandle);
MAKE_CPP_TYPE(PersistentCollectionHandle, blender::bke::PersistentCollectionHandle);
MAKE_CPP_TYPE(Object, Object *)
MAKE_CPP_TYPE(Collection, Collection *)
static bNodeSocketType *make_socket_type_object()
{
bNodeSocketType *socktype = make_standard_socket_type(SOCK_OBJECT, PROP_NONE);
socktype->get_cpp_type = []() {
/* Objects are not passed along as raw pointers, but as handles. */
return &blender::fn::CPPType::get<blender::bke::PersistentObjectHandle>();
};
socktype->expand_in_mf_network = [](blender::nodes::SocketMFNetworkBuilder &builder) {
Object *object = builder.socket_default_value<bNodeSocketValueObject>()->value;
builder.construct_generator_fn<ObjectSocketMultiFunction>(object);
socktype->get_cpp_type = []() { return &blender::fn::CPPType::get<Object *>(); };
socktype->get_cpp_value = [](const bNodeSocket &socket, void *r_value) {
*(Object **)r_value = ((bNodeSocketValueObject *)socket.default_value)->value;
};
return socktype;
}
@@ -706,9 +657,9 @@ static bNodeSocketType *make_socket_type_geometry()
static bNodeSocketType *make_socket_type_collection()
{
bNodeSocketType *socktype = make_standard_socket_type(SOCK_COLLECTION, PROP_NONE);
socktype->get_cpp_type = []() {
/* Objects are not passed along as raw pointers, but as handles. */
return &blender::fn::CPPType::get<blender::bke::PersistentCollectionHandle>();
socktype->get_cpp_type = []() { return &blender::fn::CPPType::get<Collection *>(); };
socktype->get_cpp_value = [](const bNodeSocket &socket, void *r_value) {
*(Collection **)r_value = ((bNodeSocketValueCollection *)socket.default_value)->value;
};
return socktype;
}