40#include "RNA_prototypes.hh"
57 const char *engine_id = scene->r.engine;
81 *r_id =
static_cast<ID *
>(ob->
data);
106 *r_id = &scene->world->id;
107 *r_ntree = scene->world->nodetree;
132 if (node->is_group() && node->id) {
180 "shader node tree type");
186 tt->
ui_icon = ICON_NODE_MATERIAL;
211 bNode *output_node =
nullptr;
219 if (output_node ==
nullptr) {
228 else if (node->custom1 == target) {
229 if (output_node ==
nullptr) {
248 if (
STREQ(sock->identifier, identifier)) {
292 switch (socket->
type) {
300 dst_rgba->
value[3] = 1.0f;
346 bool removed_link =
false;
380 bool link_added =
false;
391 if (is_group || is_group_output) {
393 if (socket->link !=
nullptr && !(socket->link->flag &
NODE_LINK_MUTED)) {
448 if (node->id !=
nullptr) {
462 LinkNode *group_interface_nodes =
nullptr;
481 ngroup->
runtime->nodes_by_id.clear();
495 if (glinks_first !=
nullptr) {
502 tlink != glinks_first->
next;
505 if (tlink->tonode == gnode &&
STREQ(tlink->tosock->identifier, identifier)) {
507 ntree, tlink->fromnode, tlink->fromsock, link->tonode, link->tosock);
516 tlink != glinks_first->
next;
519 if (tlink->fromnode == gnode) {
525 if (
STREQ(link->tosock->identifier, identifier)) {
527 ntree, link->fromnode, link->fromsock, tlink->tonode, tlink->tosock);
535 while (group_interface_nodes) {
554 node_next = node->next;
563 node_next = node->next;
578 if (fromnode->
runtime->tmp_flag == -1 &&
584 if (tonode->
runtime->tmp_flag == -1 &&
596 bool (*node_filter)(
const bNode *node))
598 auto gather_branch_nodes = [](
bNode *fromnode,
bNode * ,
void *userdata) {
605 ntree, start_node, gather_branch_nodes, &branch_nodes, 0);
609 node->runtime->tmp_flag = -1;
621 if (node->runtime->tmp_flag >= 0) {
622 int id = node->runtime->tmp_flag;
632 copy->runtime->tmp_flag = -2;
633 copy->runtime->original = node->runtime->original;
636 sock->link =
nullptr;
639 sock->link =
nullptr;
646 bool from_copy = link->fromnode->runtime->tmp_flag >= 0;
647 bool to_copy = link->tonode->runtime->tmp_flag >= 0;
648 if (from_copy && to_copy) {
649 bNode *from_node = nodes_copy[link->fromnode->runtime->tmp_flag];
650 bNode *to_node = nodes_copy[link->tonode->runtime->tmp_flag];
659 bNode *to_node = nodes_copy[link->tonode->runtime->tmp_flag];
666 else if (from_copy && branch_nodes.
contains(link->tonode)) {
667 bNode *from_node = nodes_copy[link->fromnode->runtime->tmp_flag];
684 bool modified =
false;
697 fprintf(stderr,
"Shader Nodetree Error: Invalid implicit socket conversion\n");
717 addnode->
runtime->tmp_flag = -2;
726 *tosock = addsock_out;
731 int *node_count = (
int *)userdata;
732 bool to_node_from_weight_tree =
ELEM(tonode->
type,
738 if (tonode->
runtime->tmp_flag == -1 && to_node_from_weight_tree) {
739 tonode->
runtime->tmp_flag = *node_count;
742 if (fromnode->
runtime->tmp_flag == -1 &&
743 ELEM(fromnode->
type, SH_NODE_ADD_SHADER, SH_NODE_MIX_SHADER))
745 fromnode->
runtime->tmp_flag = *node_count;
748 return to_node_from_weight_tree;
757 if (displace_output && displace_output->
link) {
759 displace_link = displace_output->
link;
760 displace_output->
link =
nullptr;
764 if (thickness_output && thickness_output->
link) {
766 thickness_link = thickness_output->
link;
767 thickness_output->
link =
nullptr;
771 node->runtime->tmp_flag = -1;
774 output_node->
runtime->tmp_flag = 0;
781 if (node->runtime->tmp_flag >= 0) {
782 int id = node->runtime->tmp_flag;
784 switch (node->type) {
791 nodes_copy[id]->runtime->tmp_flag = -2;
801 nodes_copy[id]->runtime->tmp_flag = -2;
808 bNode *fromnode, *tonode;
814 nodes_copy[id]->runtime->tmp_flag = -2;
819 nodes_copy[id]->runtime->tmp_flag = -2;
825 nodes_copy[id]->runtime->tmp_flag = -2;
830 if (!fac_sock->
link) {
840 nodes_copy[id]->runtime->tmp_flag = -2;
845 fromnode = nodes_copy[id_start];
846 tonode = nodes_copy[id_start + 1];
851 fromnode = nodes_copy[id_start + 2];
852 tonode = nodes_copy[id_start];
857 fromnode = nodes_copy[id_start + 3];
859 tonode = nodes_copy[id_start];
862 tonode = nodes_copy[id_start + 1];
875 if (node->runtime->tmp_flag >= 0) {
883 switch (node->type) {
889 tonode = nodes_copy[node->runtime->tmp_flag];
894 if (socket_index == 0) {
896 tonode = nodes_copy[node->runtime->tmp_flag + 2];
899 else if (socket_index == 1) {
901 tonode = nodes_copy[node->runtime->tmp_flag + 1];
906 tonode = nodes_copy[node->runtime->tmp_flag];
918 bNode *fromnode = sock->link->fromnode;
920 switch (fromnode->
type) {
922 fromnode = nodes_copy[fromnode->
runtime->tmp_flag];
924 if (fromsock->
link) {
930 fromnode = nodes_copy[fromnode->
runtime->tmp_flag + 3];
932 if (fromsock->
link) {
961 fromsock->
flag &= ~SOCK_UNAVAIL;
962 if (fromsock->
link) {
982 ntree, displace_link->
fromnode, displace_link->
fromsock, output_node, displace_output);
984 if (thickness_link) {
986 ntree, thickness_link->
fromnode, thickness_link->
fromsock, output_node, thickness_output);
993 switch (node->type) {
1029 shader_to_rgba_nodes.
append(node);
1033 for (
bNode *shader_to_rgba : shader_to_rgba_nodes) {
1035 if (closure_input->
link ==
nullptr) {
1051 max_depth = std::max(max_depth, depth_level);
1054 if (node->runtime->tmp_flag >= depth_level) {
1058 node->runtime->tmp_flag = std::max(node->runtime->tmp_flag, depth_level);
1062 if (link ==
nullptr) {
1083 int factor_socket_index,
1089 if (factor_socket->
link ==
nullptr) {
1095 factor =
clamp_f(factor, 0.0f, 1.0f);
1100 float vfactor_copy[3];
1101 for (
int i = 0; i < 3; i++) {
1103 vfactor_copy[i] =
clamp_f(vfactor[i], 0.0f, 1.0f);
1106 vfactor_copy[i] = vfactor[i];
1109 if (vfactor_copy[0] == vfactor_copy[1] && vfactor_copy[0] == vfactor_copy[2]) {
1110 factor = vfactor_copy[0];
1114 if (factor == 1.0f && a_socket_index >= 0) {
1117 else if (factor == 0.0f && b_socket_index >= 0) {
1126 if (node->typeinfo->type == SH_NODE_MIX_SHADER) {
1129 else if (node->typeinfo->type == SH_NODE_MIX) {
1134 for (
int i : {1, 4, 5, 6, 7}) {
1141 ntree, node, factor_socket, 4, 5, storage->
clamp_factor);
1143 int unused_factor_socket = factor_socket == 0 ? 1 : 0;
1144 for (
int i : {unused_factor_socket, 2, 3, 6, 7}) {
1152 for (
int i : {1, 2, 3, 4, 5}) {
1162 fromnode->
runtime->tmp_flag = 1;
1163 tonode->
runtime->tmp_flag = 1;
1174 bool changed =
false;
1177 node->runtime->tmp_flag = 0;
1182 output_node->
runtime->tmp_flag = 1;
1189 node->runtime->tmp_flag = 1;
1195 if (node->runtime->tmp_flag == 0) {
1221 if (output !=
nullptr) {
1232 node->runtime->tmp_flag = -1;
1234 if (output !=
nullptr) {
1242 for (
int depth = max_depth; depth >= 0; depth--) {
1268 node->runtime->need_exec = 1;
1282 if (ntree->
runtime->execdata) {
1283 return ntree->
runtime->execdata;
1286 context.previews = ntree->
previews;
1300 if (
exec->threadstack) {
1311 exec->threadstack =
nullptr;
1326 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.
struct Material * BKE_object_material_get(struct Object *ob, short act)
#define SH_NODE_MIX_SHADER
#define SH_NODE_BSDF_METALLIC
#define NODE_CLASS_OUTPUT
#define SH_NODE_OUTPUT_WORLD
#define NODE_CLASS_INTERFACE
#define NODE_CUSTOM_GROUP
#define SH_NODE_BSDF_PRINCIPLED
#define NODE_CLASS_CONVERTER
#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 NODE_GROUP_OUTPUT
#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 NODE_CLASS_OP_VECTOR
#define SH_NODE_EEVEE_SPECULAR
#define NODE_CLASS_LAYOUT
#define NODE_CLASS_OP_COLOR
#define SH_NODE_BSDF_GLASS
#define SH_NODE_VOLUME_PRINCIPLED
#define NODE_CLASS_TEXTURE
#define SH_NODE_BSDF_REFRACTION
#define SH_NODE_OUTPUT_LIGHT
#define NODE_CLASS_SHADER
#define SH_NODE_VOLUME_SCATTER
#define SH_NODE_OUTPUT_AOV
#define NODE_CLASS_SCRIPT
void BKE_ntree_update_tag_all(bNodeTree *ntree)
void BKE_ntree_update_main_tree(Main *bmain, bNodeTree *ntree, NodeTreeUpdateExtraParams *params)
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)
#define LISTBASE_FOREACH(type, var, list)
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
void * BLI_findlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
#define LISTBASE_FOREACH_INDEX(type, var, list, index_var)
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void BLI_remlink(struct 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 STRNCPY(dst, src)
#define BLENDER_MAX_THREADS
@ NODE_VECTOR_MATH_DOT_PRODUCT
bool contains(const Key &key) const
void append(const T &value)
FreestyleLineStyle linestyle
draw_view in_light_buf[] float
void MEM_freeN(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
void node_tree_set_output(bNodeTree *ntree)
bNode * node_add_static_node(const bContext *C, bNodeTree *ntree, int type)
void node_internal_relink(bNodeTree *ntree, bNode *node)
bNode * node_copy(bNodeTree *dst_tree, const bNode &src_node, int flag, bool use_unique)
bNodeLink * node_add_link(bNodeTree *ntree, bNode *fromnode, bNodeSocket *fromsock, bNode *tonode, bNodeSocket *tosock)
void node_chain_iterator_backwards(const bNodeTree *ntree, const bNode *node_start, bool(*callback)(bNode *, bNode *, void *), void *userdata, int recursion_lvl)
bool node_is_static_socket_type(const bNodeSocketType *stype)
void(*)(void *calldata, int nclass, const char *name) bNodeClassCallback
void node_tree_type_add(bNodeTreeType *nt)
const bNodeInstanceKey NODE_INSTANCE_KEY_BASE
void node_remove_link(bNodeTree *ntree, bNodeLink *link)
void node_tree_free_tree(bNodeTree *ntree)
void node_tree_free_local_node(bNodeTree *ntree, bNode *node)
void node_unique_id(bNodeTree *ntree, bNode *node)
void ntree_update_reroute_nodes(bNodeTree *ntree)
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)
blender::bke::bNodeTreeType * ntreeType_Shader
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, 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 bNodeSocket * next
bNodeTreeRuntimeHandle * runtime
NodeInstanceHashHandle * previews
bNodeRuntimeHandle * runtime
void(* update)(bNodeTree *ntree)
void(* foreach_nodeclass)(void *calldata, bNodeClassCallback func)
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