Add basic UI support for multiple simulations in a group

Just allows multiple simulation "frames"/regions/contexts to be drawn
in the editor, doesn't include any changes to caching yet.
This commit is contained in:
Hans Goudey 2022-12-01 19:49:05 -06:00
parent 0019d6cc8f
commit 7469e19446
4 changed files with 53 additions and 9 deletions

View File

@ -57,6 +57,8 @@ struct NodeIDEquality {
namespace blender::bke {
using NodeIDVectorSet = VectorSet<bNode *, DefaultProbingStrategy, NodeIDHash, NodeIDEquality>;
class bNodeTreeRuntime : NonCopyable, NonMovable {
public:
/**
@ -82,7 +84,7 @@ class bNodeTreeRuntime : NonCopyable, NonMovable {
* allow simpler and more cache friendly iteration. Supports lookup by integer or by node.
* Unlike other caches, this is maintained eagerly while changing the tree.
*/
VectorSet<bNode *, DefaultProbingStrategy, NodeIDHash, NodeIDEquality> nodes_by_id;
NodeIDVectorSet nodes_by_id;
/** Execution data.
*
@ -341,12 +343,14 @@ inline blender::Span<bNode *> bNodeTree::all_nodes()
inline bNode *bNodeTree::node_by_id(const int32_t identifier)
{
BLI_assert(identifier >= 0);
bNode *const *node = this->runtime->nodes_by_id.lookup_key_ptr_as(identifier);
return node ? *node : nullptr;
}
inline const bNode *bNodeTree::node_by_id(const int32_t identifier) const
{
BLI_assert(identifier >= 0);
const bNode *const *node = this->runtime->nodes_by_id.lookup_key_ptr_as(identifier);
return node ? *node : nullptr;
}

View File

@ -3037,13 +3037,16 @@ static void node_draw_sub_context_frames(TreeDrawContext &tree_draw_ctx,
{
const Span<const bNode *> all_simulation_inputs = ntree.nodes_by_type(
"GeometryNodeSimulationInput");
const Span<const bNode *> all_simulation_outputs = ntree.nodes_by_type(
"GeometryNodeSimulationOutput");
if (all_simulation_inputs.is_empty() || all_simulation_outputs.is_empty()) {
if (all_simulation_inputs.is_empty()) {
return;
}
Vector<SubContext> sub_contexts;
sub_contexts.append({float3(0.0f, 0.0f, 0.0f), all_simulation_inputs, all_simulation_outputs});
for (const bNode *sim_input : all_simulation_inputs) {
const auto &storage = *static_cast<const NodeGeometrySimulationInput *>(sim_input->storage);
if (const bNode *sim_output = ntree.node_by_id(storage.output_node_id)) {
sub_contexts.append({float3(0.0f, 0.0f, 0.0f), {sim_input}, {sim_output}});
}
}
for (SubContext &sub_context : sub_contexts) {
const Span<const bNode *> context_inputs = sub_context.input_nodes;

View File

@ -1551,7 +1551,7 @@ typedef struct NodeGeometryUVUnwrap {
} NodeGeometryUVUnwrap;
typedef struct NodeGeometrySimulationInput {
int8_t dummy;
int32_t output_node_id;
} NodeGeometrySimulationInput;
typedef struct NodeGeometrySimulationOutput {

View File

@ -5,6 +5,9 @@
#include "DEG_depsgraph_query.h"
#include "UI_interface.h"
#include "UI_resources.h"
#include "node_geometry_util.hh"
namespace blender::nodes::node_geo_simulation_input_cc {
@ -20,16 +23,49 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Geometry>(N_("Geometry"));
}
static void node_init(bNodeTree * /*tree*/, bNode *node)
static void node_layout(uiLayout * /*layout*/, bContext * /*C*/, PointerRNA * /*ptr*/)
{
// const NodeGeometrySimulationInput &storage = node_storage(
// *static_cast<const bNode *>(ptr->data));
// const bNodeTree &node_tree = *reinterpret_cast<const bNodeTree *>(ptr->owner_id);
// const bNode *sim_output = node_tree.node_by_id(storage.output_node_id);
// if (sim_output) {
// uiItemL(layout, sim_output->name, ICON_PHYSICS);
// }
}
static void node_init(bNodeTree *tree, bNode *node)
{
NodeGeometrySimulationInput *data = MEM_cnew<NodeGeometrySimulationInput>(__func__);
data->dummy = false;
VectorSet<int32_t> sim_output_ids;
Set<int32_t> sim_input_output_ids;
for (bNode *other_node : tree->all_nodes()) {
if (other_node->type == GEO_NODE_SIMULATION_INPUT && other_node != node) {
const NodeGeometrySimulationInput &storage = node_storage(*other_node);
sim_input_output_ids.add_new(storage.output_node_id);
}
else if (other_node->type == GEO_NODE_SIMULATION_OUTPUT) {
sim_output_ids.add_new(other_node->identifier);
}
}
sim_output_ids.remove_if(
[&](const int32_t identifier) { return sim_input_output_ids.contains(identifier); });
if (sim_output_ids.size() == 1) {
data->output_node_id = sim_output_ids[0];
}
else {
data->output_node_id = 0;
}
node->storage = data;
}
static void node_geo_exec(GeoNodeExecParams params)
{
const NodeGeometrySimulationInput &storage = node_storage(params.node());
// const NodeGeometrySimulationInput &storage = node_storage(params.node());
const Scene *scene = DEG_get_input_scene(params.depsgraph());
const float scene_ctime = BKE_scene_ctime_get(scene);
const int scene_frame = int(scene_ctime);
@ -85,6 +121,7 @@ void register_node_type_geo_simulation_input()
ntype.initfunc = file_ns::node_init;
ntype.geometry_node_execute = file_ns::node_geo_exec;
ntype.declare = file_ns::node_declare;
ntype.draw_buttons = file_ns::node_layout;
node_type_storage(&ntype,
"NodeGeometrySimulationInput",
node_free_standard_storage,