Cleanup: Geometry Nodes: move functions to a more reusable place

This commit is contained in:
Jacques Lucke
2023-09-24 21:06:37 +02:00
parent 4aaae8d0a6
commit 7015d83368
3 changed files with 114 additions and 84 deletions

View File

@@ -4,7 +4,11 @@
#pragma once
#include <optional>
#include "BLI_compute_context.hh"
#include "BLI_vector_set.hh"
#include "ED_node_c.hh"
struct SpaceNode;
@@ -13,6 +17,7 @@ struct Main;
struct bNodeSocket;
struct bNodeTree;
struct rcti;
struct NodesModifierData;
namespace blender::ed::space_node {
@@ -33,4 +38,19 @@ void node_insert_on_link_flags_clear(bNodeTree &node_tree);
*/
void node_socket_draw(bNodeSocket *sock, const rcti *rect, const float color[4], float scale);
struct ObjectAndModifier {
const Object *object;
const NodesModifierData *nmd;
};
/**
* Finds the context-modifier for the node editor.
*/
std::optional<ObjectAndModifier> get_modifier_for_node_editor(const SpaceNode &snode);
/**
* Used to get the compute context for the (nested) node group that is currently edited.
* Returns true on success.
*/
[[nodiscard]] bool push_compute_context_for_tree_path(
const SpaceNode &snode, ComputeContextBuilder &compute_context_builder);
} // namespace blender::ed::space_node

View File

@@ -14,12 +14,15 @@
#include "DNA_gpencil_legacy_types.h"
#include "DNA_light_types.h"
#include "DNA_material_types.h"
#include "DNA_modifier_types.h"
#include "DNA_node_types.h"
#include "DNA_object_types.h"
#include "DNA_world_types.h"
#include "MEM_guardedalloc.h"
#include "BKE_asset.h"
#include "BKE_compute_contexts.hh"
#include "BKE_context.h"
#include "BKE_gpencil_legacy.h"
#include "BKE_idprop.h"
@@ -28,6 +31,7 @@
#include "BKE_lib_remap.h"
#include "BKE_node.hh"
#include "BKE_node_runtime.hh"
#include "BKE_node_tree_zones.hh"
#include "BKE_screen.h"
#include "ED_node.hh"
@@ -241,6 +245,91 @@ float2 space_node_group_offset(const SpaceNode &snode)
return float2(0);
}
std::optional<ObjectAndModifier> get_modifier_for_node_editor(const SpaceNode &snode)
{
if (snode.id == nullptr) {
return std::nullopt;
}
if (GS(snode.id->name) != ID_OB) {
return std::nullopt;
}
const Object *object = reinterpret_cast<Object *>(snode.id);
const NodesModifierData *used_modifier = nullptr;
if (snode.flag & SNODE_PIN) {
LISTBASE_FOREACH (const ModifierData *, md, &object->modifiers) {
if (md->type == eModifierType_Nodes) {
const NodesModifierData *nmd = reinterpret_cast<const NodesModifierData *>(md);
/* Would be good to store the name of the pinned modifier in the node editor. */
if (nmd->node_group == snode.nodetree) {
used_modifier = nmd;
break;
}
}
}
}
else {
LISTBASE_FOREACH (const ModifierData *, md, &object->modifiers) {
if (md->type == eModifierType_Nodes) {
const NodesModifierData *nmd = reinterpret_cast<const NodesModifierData *>(md);
if (nmd->node_group == snode.nodetree) {
if (md->flag & eModifierFlag_Active) {
used_modifier = nmd;
break;
}
}
}
}
}
if (used_modifier == nullptr) {
return std::nullopt;
}
return ObjectAndModifier{object, used_modifier};
}
bool push_compute_context_for_tree_path(const SpaceNode &snode,
ComputeContextBuilder &compute_context_builder)
{
Vector<const bNodeTreePath *> tree_path;
LISTBASE_FOREACH (const bNodeTreePath *, item, &snode.treepath) {
tree_path.append(item);
}
if (tree_path.is_empty()) {
return true;
}
for (const int i : tree_path.index_range().drop_back(1)) {
bNodeTree *tree = tree_path[i]->nodetree;
const char *group_node_name = tree_path[i + 1]->node_name;
const bNode *group_node = nodeFindNodebyName(tree, group_node_name);
if (group_node == nullptr) {
return false;
}
const bke::bNodeTreeZones *tree_zones = tree->zones();
if (tree_zones == nullptr) {
return false;
}
const Vector<const bke::bNodeTreeZone *> zone_stack = tree_zones->get_zone_stack_for_node(
group_node->identifier);
for (const bke::bNodeTreeZone *zone : zone_stack) {
switch (zone->output_node->type) {
case GEO_NODE_SIMULATION_OUTPUT: {
compute_context_builder.push<bke::SimulationZoneComputeContext>(*zone->output_node);
break;
}
case GEO_NODE_REPEAT_OUTPUT: {
/* Only show data from the first iteration for now. */
const int repeat_iteration = 0;
compute_context_builder.push<bke::RepeatZoneComputeContext>(*zone->output_node,
repeat_iteration);
break;
}
}
}
compute_context_builder.push<bke::NodeGroupComputeContext>(*group_node);
}
return true;
}
/* ******************** default callbacks for node space ***************** */
static SpaceLink *node_create(const ScrArea * /*area*/, const Scene * /*scene*/)

View File

@@ -15,6 +15,7 @@
#include "DNA_modifier_types.h"
#include "DNA_space_types.h"
#include "ED_node.hh"
#include "ED_viewer_path.hh"
#include "MOD_nodes.hh"
@@ -480,52 +481,6 @@ GeoTreeLog &GeoModifierLog::get_tree_log(const ComputeContextHash &compute_conte
return reduced_tree_log;
}
struct ObjectAndModifier {
const Object *object;
const NodesModifierData *nmd;
};
static std::optional<ObjectAndModifier> get_modifier_for_node_editor(const SpaceNode &snode)
{
if (snode.id == nullptr) {
return std::nullopt;
}
if (GS(snode.id->name) != ID_OB) {
return std::nullopt;
}
const Object *object = reinterpret_cast<Object *>(snode.id);
const NodesModifierData *used_modifier = nullptr;
if (snode.flag & SNODE_PIN) {
LISTBASE_FOREACH (const ModifierData *, md, &object->modifiers) {
if (md->type == eModifierType_Nodes) {
const NodesModifierData *nmd = reinterpret_cast<const NodesModifierData *>(md);
/* Would be good to store the name of the pinned modifier in the node editor. */
if (nmd->node_group == snode.nodetree) {
used_modifier = nmd;
break;
}
}
}
}
else {
LISTBASE_FOREACH (const ModifierData *, md, &object->modifiers) {
if (md->type == eModifierType_Nodes) {
const NodesModifierData *nmd = reinterpret_cast<const NodesModifierData *>(md);
if (nmd->node_group == snode.nodetree) {
if (md->flag & eModifierFlag_Active) {
used_modifier = nmd;
break;
}
}
}
}
}
if (used_modifier == nullptr) {
return std::nullopt;
}
return ObjectAndModifier{object, used_modifier};
}
static void find_tree_zone_hash_recursive(
const bNodeTreeZone &zone,
ComputeContextBuilder &compute_context_builder,
@@ -553,46 +508,11 @@ static void find_tree_zone_hash_recursive(
Map<const bNodeTreeZone *, ComputeContextHash> GeoModifierLog::
get_context_hash_by_zone_for_node_editor(const SpaceNode &snode, StringRefNull modifier_name)
{
Vector<const bNodeTreePath *> tree_path;
LISTBASE_FOREACH (const bNodeTreePath *, item, &snode.treepath) {
tree_path.append(item);
}
if (tree_path.is_empty()) {
return {};
}
ComputeContextBuilder compute_context_builder;
compute_context_builder.push<bke::ModifierComputeContext>(modifier_name);
for (const int i : tree_path.index_range().drop_back(1)) {
bNodeTree *tree = tree_path[i]->nodetree;
const char *group_node_name = tree_path[i + 1]->node_name;
const bNode *group_node = nodeFindNodebyName(tree, group_node_name);
if (group_node == nullptr) {
return {};
}
const bNodeTreeZones *tree_zones = tree->zones();
if (tree_zones == nullptr) {
return {};
}
const Vector<const bNodeTreeZone *> zone_stack = tree_zones->get_zone_stack_for_node(
group_node->identifier);
for (const bNodeTreeZone *zone : zone_stack) {
switch (zone->output_node->type) {
case GEO_NODE_SIMULATION_OUTPUT: {
compute_context_builder.push<bke::SimulationZoneComputeContext>(*zone->output_node);
break;
}
case GEO_NODE_REPEAT_OUTPUT: {
/* Only show data from the first iteration for now. */
const int repeat_iteration = 0;
compute_context_builder.push<bke::RepeatZoneComputeContext>(*zone->output_node,
repeat_iteration);
break;
}
}
}
compute_context_builder.push<bke::NodeGroupComputeContext>(*group_node);
if (!ed::space_node::push_compute_context_for_tree_path(snode, compute_context_builder)) {
return {};
}
const bNodeTreeZones *tree_zones = snode.edittree->zones();
@@ -610,7 +530,8 @@ Map<const bNodeTreeZone *, ComputeContextHash> GeoModifierLog::
Map<const bNodeTreeZone *, GeoTreeLog *> GeoModifierLog::get_tree_log_by_zone_for_node_editor(
const SpaceNode &snode)
{
std::optional<ObjectAndModifier> object_and_modifier = get_modifier_for_node_editor(snode);
std::optional<ed::space_node::ObjectAndModifier> object_and_modifier =
ed::space_node::get_modifier_for_node_editor(snode);
if (!object_and_modifier) {
return {};
}