Merge branch 'blender-v5.0-release'
This commit is contained in:
@@ -36,7 +36,8 @@ BLI_CPP_TYPE_MAKE(Image *, CPPTypeFlags::BasicType)
|
||||
BLI_CPP_TYPE_MAKE(Material *, CPPTypeFlags::BasicType)
|
||||
|
||||
BLI_CPP_TYPE_MAKE(MStringProperty, CPPTypeFlags::None);
|
||||
BLI_CPP_TYPE_MAKE(blender::nodes::MenuValue, CPPTypeFlags::EqualityComparable);
|
||||
BLI_CPP_TYPE_MAKE(blender::nodes::MenuValue,
|
||||
CPPTypeFlags::Hashable | CPPTypeFlags::EqualityComparable);
|
||||
BLI_CPP_TYPE_MAKE(blender::nodes::BundlePtr, CPPTypeFlags::EqualityComparable);
|
||||
BLI_CPP_TYPE_MAKE(blender::nodes::ClosurePtr, CPPTypeFlags::EqualityComparable);
|
||||
BLI_CPP_TYPE_MAKE(blender::nodes::ListPtr, CPPTypeFlags::EqualityComparable);
|
||||
|
||||
@@ -143,6 +143,7 @@ set(LIB
|
||||
PRIVATE bf::geometry
|
||||
PRIVATE bf::intern::guardedalloc
|
||||
PRIVATE bf::extern::fmtlib
|
||||
PRIVATE bf::extern::xxhash
|
||||
PRIVATE bf::nodes
|
||||
PRIVATE bf::render
|
||||
PRIVATE bf::windowmanager
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "BLI_array.hh"
|
||||
#include "NOD_socket_usage_inference_fwd.hh"
|
||||
|
||||
struct NodesModifierData;
|
||||
struct NodesModifierDataBlock;
|
||||
struct Object;
|
||||
@@ -28,6 +31,18 @@ void MOD_nodes_update_interface(Object *object, NodesModifierData *nmd);
|
||||
|
||||
namespace blender {
|
||||
|
||||
class NodesModifierUsageInferenceCache {
|
||||
private:
|
||||
uint64_t input_values_hash_ = 0;
|
||||
|
||||
public:
|
||||
Array<nodes::socket_usage_inference::SocketUsage> inputs;
|
||||
Array<nodes::socket_usage_inference::SocketUsage> outputs;
|
||||
|
||||
void ensure(const NodesModifierData &nmd);
|
||||
void reset();
|
||||
};
|
||||
|
||||
struct NodesModifierRuntime {
|
||||
/**
|
||||
* Contains logged information from the last evaluation.
|
||||
@@ -42,6 +57,11 @@ struct NodesModifierRuntime {
|
||||
* used by the evaluated modifier.
|
||||
*/
|
||||
std::shared_ptr<bke::bake::ModifierCache> cache;
|
||||
/**
|
||||
* Cache the usage of the node group inputs and outputs to accelerate drawing the UI when no
|
||||
* properties change.
|
||||
*/
|
||||
NodesModifierUsageInferenceCache usage_cache;
|
||||
};
|
||||
|
||||
void nodes_modifier_data_block_destruct(NodesModifierDataBlock *data_block, bool do_id_user);
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <fmt/format.h>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <xxhash.h>
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
@@ -451,6 +452,7 @@ void MOD_nodes_update_interface(Object *object, NodesModifierData *nmd)
|
||||
update_id_properties_from_node_group(nmd);
|
||||
update_bakes_from_node_group(*nmd);
|
||||
update_panels_from_node_group(*nmd);
|
||||
nmd->runtime->usage_cache.reset();
|
||||
|
||||
DEG_id_tag_update(&object->id, ID_RECALC_GEOMETRY);
|
||||
}
|
||||
@@ -1952,6 +1954,63 @@ static void modify_geometry_set(ModifierData *md,
|
||||
modifyGeometry(md, ctx, *geometry_set);
|
||||
}
|
||||
|
||||
void NodesModifierUsageInferenceCache::ensure(const NodesModifierData &nmd)
|
||||
{
|
||||
if (!nmd.node_group) {
|
||||
this->reset();
|
||||
return;
|
||||
}
|
||||
if (ID_MISSING(&nmd.node_group->id)) {
|
||||
this->reset();
|
||||
return;
|
||||
}
|
||||
const bNodeTree &tree = *nmd.node_group;
|
||||
tree.ensure_interface_cache();
|
||||
tree.ensure_topology_cache();
|
||||
ResourceScope scope;
|
||||
const Vector<nodes::InferenceValue> group_input_values =
|
||||
nodes::get_geometry_nodes_input_inference_values(tree, nmd.settings.properties, scope);
|
||||
|
||||
/* Compute the hash of the input values. This has to be done everytime currently, because there
|
||||
* is no reliable callback yet that is called any of the modifier properties changes. */
|
||||
XXH3_state_t *state = XXH3_createState();
|
||||
XXH3_64bits_reset(state);
|
||||
BLI_SCOPED_DEFER([&]() { XXH3_freeState(state); });
|
||||
for (const int input_i : IndexRange(nmd.node_group->interface_inputs().size())) {
|
||||
const nodes::InferenceValue &value = group_input_values[input_i];
|
||||
XXH3_64bits_update(state, &input_i, sizeof(input_i));
|
||||
if (value.is_primitive_value()) {
|
||||
const void *value_ptr = value.get_primitive_ptr();
|
||||
const bNodeTreeInterfaceSocket &io_socket = *nmd.node_group->interface_inputs()[input_i];
|
||||
const CPPType &base_type = *io_socket.socket_typeinfo()->base_cpp_type;
|
||||
uint64_t value_hash = base_type.hash_or_fallback(value_ptr, 0);
|
||||
XXH3_64bits_update(state, &value_hash, sizeof(value_hash));
|
||||
}
|
||||
}
|
||||
const uint64_t new_input_values_hash = XXH3_64bits_digest(state);
|
||||
if (new_input_values_hash == input_values_hash_) {
|
||||
if (this->inputs.size() == tree.interface_inputs().size() &&
|
||||
this->outputs.size() == tree.interface_outputs().size())
|
||||
{
|
||||
/* The cache is up to date, so return early. */
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* Compute the new usage inference result. */
|
||||
this->inputs.reinitialize(tree.interface_inputs().size());
|
||||
this->outputs.reinitialize(tree.interface_outputs().size());
|
||||
nodes::socket_usage_inference::infer_group_interface_usage(
|
||||
tree, group_input_values, inputs, outputs);
|
||||
input_values_hash_ = new_input_values_hash;
|
||||
}
|
||||
|
||||
void NodesModifierUsageInferenceCache::reset()
|
||||
{
|
||||
input_values_hash_ = 0;
|
||||
this->inputs = {};
|
||||
this->outputs = {};
|
||||
}
|
||||
|
||||
static void panel_draw(const bContext *C, Panel *panel)
|
||||
{
|
||||
uiLayout *layout = panel->layout;
|
||||
|
||||
@@ -1008,11 +1008,9 @@ void draw_geometry_nodes_modifier_ui(const bContext &C, PointerRNA *modifier_ptr
|
||||
}
|
||||
|
||||
if (nmd.node_group != nullptr && nmd.settings.properties != nullptr) {
|
||||
nmd.node_group->ensure_interface_cache();
|
||||
ctx.input_usages.reinitialize(nmd.node_group->interface_inputs().size());
|
||||
ctx.output_usages.reinitialize(nmd.node_group->interface_outputs().size());
|
||||
nodes::socket_usage_inference::infer_group_interface_usage(
|
||||
*nmd.node_group, ctx.properties, ctx.input_usages, ctx.output_usages);
|
||||
nmd.runtime->usage_cache.ensure(nmd);
|
||||
ctx.input_usages = nmd.runtime->usage_cache.inputs;
|
||||
ctx.output_usages = nmd.runtime->usage_cache.outputs;
|
||||
draw_interface_panel_content(ctx, &layout, nmd.node_group->tree_interface.root_panel);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user