This repository has been archived on 2023-10-09. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
blender-archive/source/blender/nodes/geometry/node_geometry_tree.cc
Hans Goudey 39dfa015a0 Geometry Nodes: Add node editor option to edit "Operator" node groups
This functions as a way to avoid having the context affect which node
groups are displayed. This is necessary since there is no concept of an
active operator and most node groups could be used as an operator.

It was considered to make this a more general "No Context" option for
the node editor. That still might happen eventually, but we want to
encourage users to use the modifier context since it allows the
various inspection features to work properly.
2023-03-27 10:02:15 -04:00

133 lines
4.3 KiB
C++

/* SPDX-License-Identifier: GPL-2.0-or-later */
#include <cstring>
#include "MEM_guardedalloc.h"
#include "NOD_geometry.h"
#include "BKE_context.h"
#include "BKE_layer.h"
#include "BKE_node.h"
#include "BKE_object.h"
#include "BLT_translation.h"
#include "DNA_modifier_types.h"
#include "DNA_node_types.h"
#include "DNA_space_types.h"
#include "RNA_access.h"
#include "RNA_prototypes.h"
#include "UI_resources.h"
#include "node_common.h"
#include "node_geometry_register.hh"
bNodeTreeType *ntreeType_Geometry;
static void geometry_node_tree_get_from_context(
const bContext *C, bNodeTreeType * /*treetype*/, bNodeTree **r_ntree, ID **r_id, ID **r_from)
{
const SpaceNode *snode = CTX_wm_space_node(C);
if (snode->geometry_nodes_type == SNODE_GEOMETRY_OPERATOR) {
*r_ntree = snode->nodetree;
return;
}
const Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
BKE_view_layer_synced_ensure(scene, view_layer);
Object *ob = BKE_view_layer_active_object_get(view_layer);
if (ob == nullptr) {
return;
}
const ModifierData *md = BKE_object_active_modifier(ob);
if (md == nullptr) {
return;
}
if (md->type == eModifierType_Nodes) {
const NodesModifierData *nmd = reinterpret_cast<const NodesModifierData *>(md);
if (nmd->node_group != nullptr) {
*r_from = &ob->id;
*r_id = &ob->id;
*r_ntree = nmd->node_group;
}
}
}
static void geometry_node_tree_update(bNodeTree *ntree)
{
ntreeSetOutput(ntree);
/* Needed to give correct types to reroutes. */
ntree_update_reroute_nodes(ntree);
}
static void foreach_nodeclass(Scene * /*scene*/, void *calldata, bNodeClassCallback func)
{
func(calldata, NODE_CLASS_INPUT, N_("Input"));
func(calldata, NODE_CLASS_GEOMETRY, N_("Geometry"));
func(calldata, NODE_CLASS_ATTRIBUTE, N_("Attribute"));
func(calldata, NODE_CLASS_OP_COLOR, N_("Color"));
func(calldata, NODE_CLASS_OP_VECTOR, N_("Vector"));
func(calldata, NODE_CLASS_CONVERTER, N_("Converter"));
func(calldata, NODE_CLASS_LAYOUT, N_("Layout"));
}
static bool geometry_node_tree_validate_link(eNodeSocketDatatype type_a,
eNodeSocketDatatype type_b)
{
/* Geometry, string, object, material, texture and collection sockets can only be connected to
* themselves. The other types can be converted between each other. */
if (ELEM(type_a, SOCK_FLOAT, SOCK_VECTOR, SOCK_RGBA, SOCK_BOOLEAN, SOCK_INT) &&
ELEM(type_b, SOCK_FLOAT, SOCK_VECTOR, SOCK_RGBA, SOCK_BOOLEAN, SOCK_INT)) {
return true;
}
return type_a == type_b;
}
static bool geometry_node_tree_socket_type_valid(bNodeTreeType * /*treetype*/,
bNodeSocketType *socket_type)
{
return nodeIsStaticSocketType(socket_type) && ELEM(socket_type->type,
SOCK_FLOAT,
SOCK_VECTOR,
SOCK_RGBA,
SOCK_BOOLEAN,
SOCK_INT,
SOCK_STRING,
SOCK_OBJECT,
SOCK_GEOMETRY,
SOCK_COLLECTION,
SOCK_TEXTURE,
SOCK_IMAGE,
SOCK_MATERIAL);
}
void register_node_tree_type_geo()
{
bNodeTreeType *tt = ntreeType_Geometry = static_cast<bNodeTreeType *>(
MEM_callocN(sizeof(bNodeTreeType), "geometry node tree type"));
tt->type = NTREE_GEOMETRY;
strcpy(tt->idname, "GeometryNodeTree");
strcpy(tt->group_idname, "GeometryNodeGroup");
strcpy(tt->ui_name, N_("Geometry Node Editor"));
tt->ui_icon = ICON_GEOMETRY_NODES;
strcpy(tt->ui_description, N_("Geometry nodes"));
tt->rna_ext.srna = &RNA_GeometryNodeTree;
tt->update = geometry_node_tree_update;
tt->get_from_context = geometry_node_tree_get_from_context;
tt->foreach_nodeclass = foreach_nodeclass;
tt->valid_socket_type = geometry_node_tree_socket_type_valid;
tt->validate_link = geometry_node_tree_validate_link;
ntreeTypeAdd(tt);
}