40#include "RNA_prototypes.hh"
57 const char *engine_id = scene->
r.
engine;
81 *r_id =
static_cast<ID *
>(ob->
data);
98 *r_id = &linestyle->
id;
131 if (node->is_muted() || node->is_reroute()) {
132 if (node->is_group() && node->id) {
183 tt->
idname =
"ShaderNodeTree";
186 tt->
ui_icon = ICON_NODE_MATERIAL;
211 bNode *output_node =
nullptr;
214 if (!
ELEM(node->type_legacy,
223 if (output_node ==
nullptr) {
232 else if (node->custom1 == target) {
233 if (output_node ==
nullptr) {
252 if (
STREQ(sock->identifier, identifier)) {
296 switch (socket->
type) {
304 dst_rgba->
value[3] = 1.0f;
350 bool removed_link =
false;
353 const bool is_group = node->is_group() && (node->id !=
nullptr);
360 if (sock && sock->link && sock->link->fromnode->is_group_input()) {
384 bool link_added =
false;
387 const bool is_group = node->is_group() && (node->id !=
nullptr);
388 const bool is_group_output = node->is_group_output() && (node->flag &
NODE_DO_OUTPUT);
395 if (is_group || is_group_output) {
397 if (socket->link !=
nullptr && !(socket->link->flag &
NODE_LINK_MUTED)) {
458 if (node->is_group()) {
459 if (node->id !=
nullptr) {
473 LinkNode *group_interface_nodes =
nullptr;
481 if (node->is_group_input() || node->is_group_output()) {
492 ngroup->
runtime->nodes_by_id.clear();
506 if (glinks_first !=
nullptr) {
509 if (link->fromnode->is_group_input()) {
510 const char *identifier = link->fromsock->identifier;
513 tlink != glinks_first->
next;
516 if (tlink->tonode == gnode &&
STREQ(tlink->tosock->identifier, identifier)) {
518 *ntree, *tlink->fromnode, *tlink->fromsock, *link->tonode, *link->tosock);
527 tlink != glinks_first->
next;
530 if (tlink->fromnode == gnode) {
531 const char *identifier = tlink->fromsock->identifier;
535 if (link->tonode->is_group_output() && (link->tonode->flag &
NODE_DO_OUTPUT)) {
536 if (
STREQ(link->tosock->identifier, identifier)) {
538 *ntree, *link->fromnode, *link->fromsock, *tlink->tonode, *tlink->tosock);
546 while (group_interface_nodes) {
562 if (node->is_group() && node->id !=
nullptr) {
565 node_next = node->next;
574 node_next = node->next;
589 if (fromnode->
runtime->tmp_flag == -1 &&
595 if (tonode->
runtime->tmp_flag == -1 &&
607 bool (*node_filter)(
const bNode *node))
609 auto gather_branch_nodes = [](
bNode *fromnode,
bNode * ,
void *userdata) {
616 ntree, start_node, gather_branch_nodes, &branch_nodes, 0);
632 if (node->
runtime->tmp_flag >= 0) {
633 int id = node->
runtime->tmp_flag;
643 copy->runtime->tmp_flag = -2;
647 sock->link =
nullptr;
650 sock->link =
nullptr;
657 bool from_copy = link->fromnode->runtime->tmp_flag >= 0;
658 bool to_copy = link->tonode->runtime->tmp_flag >= 0;
659 if (from_copy && to_copy) {
660 bNode *from_node = nodes_copy[link->fromnode->runtime->tmp_flag];
661 bNode *to_node = nodes_copy[link->tonode->runtime->tmp_flag];
670 bNode *to_node = nodes_copy[link->tonode->runtime->tmp_flag];
678 else if (from_copy && branch_nodes.
contains(link->tonode)) {
679 bNode *from_node = nodes_copy[link->fromnode->runtime->tmp_flag];
696 bool modified =
false;
703 *ntree, *link->fromnode, *link->fromsock, *emission_node, *in_sock);
729 addnode->
runtime->tmp_flag = -2;
739 *tosock = addsock_out;
744 int *node_count = (
int *)userdata;
751 if (tonode->
runtime->tmp_flag == -1 && to_node_from_weight_tree) {
752 tonode->
runtime->tmp_flag = *node_count;
755 if (fromnode->
runtime->tmp_flag == -1 &&
758 fromnode->
runtime->tmp_flag = *node_count;
761 return to_node_from_weight_tree;
770 if (displace_output && displace_output->
link) {
772 displace_link = displace_output->
link;
773 displace_output->
link =
nullptr;
777 if (thickness_output && thickness_output->
link) {
779 thickness_link = thickness_output->
link;
780 thickness_output->
link =
nullptr;
784 node->runtime->tmp_flag = -1;
787 output_node->
runtime->tmp_flag = 0;
794 if (node->runtime->tmp_flag >= 0) {
795 int id = node->runtime->tmp_flag;
797 switch (node->type_legacy) {
804 nodes_copy[id]->runtime->tmp_flag = -2;
814 nodes_copy[id]->runtime->tmp_flag = -2;
821 bNode *fromnode, *tonode;
827 nodes_copy[id]->runtime->tmp_flag = -2;
832 nodes_copy[id]->runtime->tmp_flag = -2;
838 nodes_copy[id]->runtime->tmp_flag = -2;
843 if (!fac_sock->
link) {
853 nodes_copy[id]->runtime->tmp_flag = -2;
858 fromnode = nodes_copy[id_start];
859 tonode = nodes_copy[id_start + 1];
864 fromnode = nodes_copy[id_start + 2];
865 tonode = nodes_copy[id_start];
870 fromnode = nodes_copy[id_start + 3];
872 tonode = nodes_copy[id_start];
875 tonode = nodes_copy[id_start + 1];
888 if (node->runtime->tmp_flag >= 0) {
896 switch (node->type_legacy) {
902 tonode = nodes_copy[node->runtime->tmp_flag];
907 if (socket_index == 0) {
909 tonode = nodes_copy[node->runtime->tmp_flag + 2];
912 else if (socket_index == 1) {
914 tonode = nodes_copy[node->runtime->tmp_flag + 1];
919 tonode = nodes_copy[node->runtime->tmp_flag];
931 bNode *fromnode = sock->link->fromnode;
935 fromnode = nodes_copy[fromnode->
runtime->tmp_flag];
937 if (fromsock->
link) {
943 fromnode = nodes_copy[fromnode->
runtime->tmp_flag + 3];
945 if (fromsock->
link) {
976 if (fromsock->
link) {
988 *ntree, *fromnode, *fromsock, *tonode, *tosock);
1002 if (thickness_link) {
1051 shader_to_rgba_nodes.
append(node);
1055 for (
bNode *shader_to_rgba : shader_to_rgba_nodes) {
1057 if (closure_input->
link ==
nullptr) {
1069 int16_t depth_level = 0)
1073 max_depth = std::max(max_depth, depth_level);
1076 if (node->
runtime->tmp_flag >= depth_level) {
1080 node->
runtime->tmp_flag = std::max(node->
runtime->tmp_flag, depth_level);
1084 if (link ==
nullptr) {
1105 int factor_socket_index,
1111 if (factor_socket->
link ==
nullptr) {
1117 factor =
clamp_f(factor, 0.0f, 1.0f);
1122 float vfactor_copy[3];
1123 for (
int i = 0;
i < 3;
i++) {
1125 vfactor_copy[
i] =
clamp_f(vfactor[
i], 0.0f, 1.0f);
1128 vfactor_copy[
i] = vfactor[
i];
1131 if (vfactor_copy[0] == vfactor_copy[1] && vfactor_copy[0] == vfactor_copy[2]) {
1132 factor = vfactor_copy[0];
1136 if (factor == 1.0f && a_socket_index >= 0) {
1139 else if (factor == 0.0f && b_socket_index >= 0) {
1151 else if (node->typeinfo->type_legacy ==
SH_NODE_MIX) {
1156 for (
int i : {1, 4, 5, 6, 7}) {
1163 ntree, node, factor_socket, 4, 5, storage->
clamp_factor);
1165 int unused_factor_socket = factor_socket == 0 ? 1 : 0;
1166 for (
int i : {unused_factor_socket, 2, 3, 6, 7}) {
1174 for (
int i : {1, 2, 3, 4, 5}) {
1184 fromnode->
runtime->tmp_flag = 1;
1185 tonode->
runtime->tmp_flag = 1;
1196 bool changed =
false;
1199 node->runtime->tmp_flag = 0;
1204 output_node->
runtime->tmp_flag = 1;
1211 node->runtime->tmp_flag = 1;
1217 if (node->runtime->tmp_flag == 0) {
1252 int16_t max_depth = 0;
1254 node->runtime->tmp_flag = -1;
1264 for (
int depth = max_depth; depth >= 0; depth--) {
1289 node->runtime->need_exec = 1;
1303 if (ntree->
runtime->execdata) {
1304 return ntree->
runtime->execdata;
1319 if (
exec->threadstack) {
1330 exec->threadstack =
nullptr;
1345 ntree->
runtime->execdata =
nullptr;
SpaceNode * CTX_wm_space_node(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
ViewLayer * CTX_data_view_layer(const bContext *C)
void BKE_view_layer_synced_ensure(const Scene *scene, ViewLayer *view_layer)
Object * BKE_view_layer_active_object_get(const ViewLayer *view_layer)
@ LIB_ID_CREATE_NO_USER_REFCOUNT
Blender kernel freestyle line style functionality.
FreestyleLineStyle * BKE_linestyle_active_from_view_layer(struct ViewLayer *view_layer)
General operations, lookup, etc. for materials.
Material * BKE_object_material_get(Object *ob, short act)
#define NODE_CLASS_OUTPUT
#define NODE_CLASS_INTERFACE
#define NODE_CLASS_CONVERTER
#define NODE_CLASS_OP_VECTOR
#define NODE_CLASS_LAYOUT
#define NODE_CLASS_OP_COLOR
#define NODE_CLASS_TEXTURE
#define NODE_CLASS_SHADER
#define NODE_CLASS_SCRIPT
#define SH_NODE_MIX_SHADER
#define SH_NODE_BSDF_METALLIC
#define SH_NODE_VOLUME_COEFFICIENTS
#define SH_NODE_OUTPUT_WORLD
#define SH_NODE_BSDF_PRINCIPLED
#define SH_NODE_BSDF_SHEEN
#define SH_NODE_ADD_SHADER
#define SH_NODE_SUBSURFACE_SCATTERING
#define SH_NODE_VOLUME_ABSORPTION
#define SH_NODE_VECTOR_MATH
#define SH_NODE_BSDF_TOON
#define SH_NODE_BSDF_TRANSPARENT
#define SH_NODE_BSDF_DIFFUSE
#define SH_NODE_SHADERTORGB
#define SH_NODE_OUTPUT_MATERIAL
#define SH_NODE_BSDF_TRANSLUCENT
#define SH_NODE_BSDF_HAIR_PRINCIPLED
#define SH_NODE_BSDF_HAIR
#define SH_NODE_BACKGROUND
#define SH_NODE_BSDF_RAY_PORTAL
#define SH_NODE_BSDF_GLOSSY
#define SH_NODE_EEVEE_SPECULAR
#define SH_NODE_BSDF_GLASS
#define SH_NODE_VOLUME_PRINCIPLED
#define SH_NODE_BSDF_REFRACTION
#define SH_NODE_OUTPUT_LIGHT
#define SH_NODE_VOLUME_SCATTER
#define SH_NODE_OUTPUT_AOV
void BKE_ntree_update_after_single_tree_change(Main &bmain, bNodeTree &modified_tree, const NodeTreeUpdateExtraParams ¶ms={})
void BKE_ntree_update_tag_all(bNodeTree *ntree)
bool BKE_scene_use_shading_nodes_custom(Scene *scene)
void void void * BLI_linklist_pop(LinkNode **listp) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void void BLI_linklist_prepend(LinkNode **listp, void *ptr) ATTR_NONNULL(1)
void * BLI_findlink(const ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
#define LISTBASE_FOREACH(type, var, list)
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
void void BLI_freelistN(ListBase *listbase) ATTR_NONNULL(1)
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
#define LISTBASE_FOREACH_INDEX(type, var, list, index_var)
void BLI_remlink(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
MINLINE float clamp_f(float value, float min, float max)
MINLINE void copy_v4_v4(float r[4], const float a[4])
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void copy_v3_fl(float r[3], float f)
#define BLENDER_MAX_THREADS
@ NODE_VECTOR_MATH_DOT_PRODUCT
struct blender::bke::bNodeTreeType * ntreeType_Shader
bool contains(const Key &key) const
void append(const T &value)
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
void MEM_freeN(void *vmemh)
void node_tree_free_local_node(bNodeTree &ntree, bNode &node)
void node_tree_set_output(bNodeTree &ntree)
void node_tree_free_tree(bNodeTree &ntree)
void node_unique_id(bNodeTree &ntree, bNode &node)
bNode * node_copy(bNodeTree *dst_tree, const bNode &src_node, int flag, bool use_unique)
void node_remove_link(bNodeTree *ntree, bNodeLink &link)
void node_chain_iterator_backwards(const bNodeTree *ntree, const bNode *node_start, bool(*callback)(bNode *, bNode *, void *), void *userdata, int recursion_lvl)
void node_tree_type_add(bNodeTreeType &nt)
void node_internal_relink(bNodeTree &ntree, bNode &node)
const bNodeInstanceKey NODE_INSTANCE_KEY_BASE
void(*)(void *calldata, int nclass, StringRefNull name) bNodeClassCallback
bNode * node_add_static_node(const bContext *C, bNodeTree &ntree, int type)
bNodeLink & node_add_link(bNodeTree &ntree, bNode &fromnode, bNodeSocket &fromsock, bNode &tonode, bNodeSocket &tosock)
bool node_is_static_socket_type(const bNodeSocketType &stype)
void ntree_update_reroute_nodes(bNodeTree *ntree)
static void localize(bNodeTree *localtree, bNodeTree *ntree)
static void update(bNodeTree *ntree)
static void foreach_nodeclass(void *calldata, blender::bke::bNodeClassCallback func)
bNodeTreeExec * ntree_exec_begin(bNodeExecContext *context, bNodeTree *ntree, bNodeInstanceKey parent_key)
void ntree_exec_end(bNodeTreeExec *exec)
static bNodeSocket * ntree_shader_node_input_get(bNode *node, int n)
static bool ntree_shader_implicit_closure_cast(bNodeTree *ntree)
static bool ntree_branch_count_and_tag_nodes(bNode *fromnode, bNode *tonode, void *userdata)
bNodeTreeExec * ntreeShaderBeginExecTree_internal(bNodeExecContext *context, bNodeTree *ntree, bNodeInstanceKey parent_key)
static bool ntree_weight_tree_tag_nodes(bNode *fromnode, bNode *tonode, void *userdata)
static bNodeSocket * ntree_shader_node_find_output(bNode *node, const char *identifier)
static void ntree_weight_tree_merge_weight(bNodeTree *ntree, bNode *, bNodeSocket *fromsock, bNode **tonode, bNodeSocket **tosock)
static bool ntree_shader_expand_socket_default(bNodeTree *localtree, bNode *node, bNodeSocket *socket)
static void iter_shader_to_rgba_depth_count(bNode *node, int16_t &max_depth, int16_t depth_level=0)
static void ntree_shader_disconnect_inactive_mix_branches(bNodeTree *ntree)
static void ntree_shader_groups_expand_inputs(bNodeTree *localtree)
static void ntree_shader_shader_to_rgba_branches(bNodeTree *ntree)
static bNodeSocket * ntree_shader_node_find_input(bNode *node, const char *identifier)
static void ntree_shader_groups_flatten(bNodeTree *localtree)
static void shader_node_disconnect_inactive_mix_branch(bNodeTree *ntree, bNode *node, int factor_socket_index, int a_socket_index, int b_socket_index, bool clamp_factor)
static bool closure_node_filter(const bNode *node)
static void ntree_shader_weight_tree_invert(bNodeTree *ntree, bNode *output_node)
static bool shader_node_tree_socket_type_valid(blender::bke::bNodeTreeType *, blender::bke::bNodeSocketType *socket_type)
void register_node_tree_type_sh()
static void update(bNodeTree *ntree)
bNode * ntreeShaderOutputNode(bNodeTree *ntree, int target)
static bNodeSocket * ntree_shader_node_find_socket(ListBase *sockets, const char *identifier)
static void shader_get_from_context(const bContext *C, blender::bke::bNodeTreeType *, bNodeTree **r_ntree, ID **r_id, ID **r_from)
static bool shader_validate_link(eNodeSocketDatatype from, eNodeSocketDatatype to)
static void ntree_shader_pruned_unused(bNodeTree *ntree, bNode *output_node)
static void ntree_shader_unlink_hidden_value_sockets(bNode *group_node, bNodeSocket *isock)
static bool ntree_branch_node_tag(bNode *fromnode, bNode *tonode, void *)
static void ntree_shader_copy_branch(bNodeTree *ntree, bNode *start_node, bool(*node_filter)(const bNode *node))
bNodeTreeExec * ntreeShaderBeginExecTree(bNodeTree *ntree)
static void flatten_group_do(bNodeTree *ntree, bNode *gnode)
static bool shader_tree_poll(const bContext *C, blender::bke::bNodeTreeType *)
static void ntree_shader_groups_remove_muted_links(bNodeTree *ntree)
void ntreeShaderEndExecTree(bNodeTreeExec *exec)
static void shader_node_disconnect_input(bNodeTree *ntree, bNode *node, int index)
static bNodeSocket * ntree_shader_node_output_get(bNode *node, int n)
static void localize(bNodeTree *localtree, bNodeTree *)
void ntreeShaderEndExecTree_internal(bNodeTreeExec *exec)
static void foreach_nodeclass(void *calldata, blender::bke::bNodeClassCallback func)
void ntreeExecGPUNodes(bNodeTreeExec *exec, GPUMaterial *mat, bNode *output_node, const int *depth_level)
static void exec(void *data, int, bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
static void copy(bNodeTree *dest_ntree, bNode *dest_node, const bNode *src_node)
const char * RE_engine_id_CYCLES
struct bNodeTree * nodetree
struct bNodeTree * nodetree
struct bNodeTree * nodetree
struct bNodeSocket * next
bNodeTreeRuntimeHandle * runtime
bNodeRuntimeHandle * runtime
void(* update)(bNodeTree *ntree)
void(* foreach_nodeclass)(void *calldata, bNodeClassCallback func)
std::string ui_description
bool(* poll)(const bContext *C, bNodeTreeType *ntreetype)
void(* get_from_context)(const bContext *C, bNodeTreeType *ntreetype, bNodeTree **r_ntree, ID **r_id, ID **r_from)
void(* localize)(bNodeTree *localtree, bNodeTree *ntree)
bool(* validate_link)(eNodeSocketDatatype from, eNodeSocketDatatype to)
bool(* valid_socket_type)(bNodeTreeType *ntreetype, bNodeSocketType *socket_type)
bool(* node_filter)(const bNode *node)
void * ntreeGPUMaterialNodes