Merge branch 'blender-v5.0-release'

This commit is contained in:
Jacques Lucke
2025-10-13 18:25:36 +02:00
5 changed files with 85 additions and 6 deletions

View File

@@ -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);

View File

@@ -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

View File

@@ -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);

View File

@@ -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;

View File

@@ -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);
}