Blender V5.0
node_texture_util.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2005 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9/*
10 * HOW TEXTURE NODES WORK
11 *
12 * In contrast to Shader nodes, which place a color into the output
13 * stack when executed, Texture nodes place a TexDelegate* there. To
14 * obtain a color value from this, a node further up the chain reads
15 * the TexDelegate* from its input stack, and uses tex_call_delegate to
16 * retrieve the color from the delegate.
17 *
18 * comments: (ton)
19 *
20 * This system needs recode, a node system should rely on the stack, and
21 * callbacks for nodes only should evaluate their own node, not recursively go
22 * over other previous ones.
23 */
24
25#include "BLI_listbase.h"
26
27#include "BKE_node_runtime.hh"
28
29#include "NOD_texture.h"
30
31#include "node_texture_util.hh"
32#include "node_util.hh"
33#include <optional>
34
36 const bNodeTree *ntree,
37 const char **r_disabled_hint)
38{
39 if (!STREQ(ntree->idname, "TextureNodeTree")) {
40 *r_disabled_hint = RPT_("Not a texture node tree");
41 return false;
42 }
43 return true;
44}
45
47 std::string idname,
48 const std::optional<int16_t> legacy_type)
49{
50 blender::bke::node_type_base(*ntype, idname, legacy_type);
51
54}
55
56static void tex_call_delegate(TexDelegate *dg, float *out, TexParams *params, short thread)
57{
58 if (dg->node->runtime->need_exec) {
59 dg->fn(out, params, dg->node, dg->in, thread);
60 }
61}
62
63static void tex_input(float *out, int num, bNodeStack *in, TexParams *params, short thread)
64{
65 TexDelegate *dg = static_cast<TexDelegate *>(in->data);
66 if (dg) {
68
69 if (in->hasoutput && in->sockettype == SOCK_FLOAT) {
70 in->vec[1] = in->vec[2] = in->vec[0];
71 }
72 }
73 memcpy(out, in->vec, num * sizeof(float));
74}
75
77{
79}
80
82{
84
85 if (in->hasoutput && in->sockettype == SOCK_FLOAT) {
86 out[1] = out[2] = out[0];
87 out[3] = 1;
88 }
89
90 if (in->hasoutput && in->sockettype == SOCK_VECTOR) {
91 out[0] = out[0] * 0.5f + 0.5f;
92 out[1] = out[1] * 0.5f + 0.5f;
93 out[2] = out[2] * 0.5f + 0.5f;
94 out[3] = 1;
95 }
96}
97
99{
100 float out[4];
102 return out[0];
103}
104
106{
107 out->co = in->co;
108 out->previewco = in->co;
109 out->cfra = in->cfra;
110 out->mtex = in->mtex;
111}
112
113void tex_output(bNode *node,
114 bNodeExecData * /*execdata*/,
115 bNodeStack **in,
117 TexFn texfn,
118 TexCallData *cdata)
119{
120 TexDelegate *dg;
121
122 if (node->is_muted()) {
123 /* do not add a delegate if the node is muted */
124 return;
125 }
126
127 if (!out->data) {
128 /* Freed in tex_end_exec (node.cc) */
129 dg = MEM_callocN<TexDelegate>("tex delegate");
130 out->data = dg;
131 }
132 else {
133 dg = static_cast<TexDelegate *>(out->data);
134 }
135
136 dg->cdata = cdata;
137 dg->fn = texfn;
138 dg->node = node;
139 memcpy(dg->in, in, MAX_SOCKET * sizeof(bNodeStack *));
140 dg->type = out->sockettype;
141}
142
144{
145 LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
146
147 if (node->type_legacy == TEX_NODE_TEXTURE && node->id) {
148 /* custom2 stops the node from rendering */
149 if (node->custom1) {
150 node->custom2 = 1;
151 node->custom1 = 0;
152 }
153 else {
154 Tex *tex = (Tex *)node->id;
155
156 node->custom2 = 0;
157
158 node->custom1 = 1;
159 if (tex->use_nodes && tex->nodetree) {
161 }
162 node->custom1 = 0;
163 }
164 }
165 }
166}
#define MAX_SOCKET
Definition BKE_node.hh:28
#define TEX_NODE_TEXTURE
#define LISTBASE_FOREACH(type, var, list)
ATTR_WARN_UNUSED_RESULT const size_t num
#define STREQ(a, b)
#define RPT_(msgid)
@ SOCK_VECTOR
@ SOCK_FLOAT
#define in
#define out
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
void node_type_base(bNodeType &ntype, std::string idname, std::optional< int16_t > legacy_type=std::nullopt)
Definition node.cc:5099
static void texfn(float *result, TexParams *p, bNode *node, bNodeStack **in, MapFn map_inputs, short thread)
void tex_output(bNode *node, bNodeExecData *, bNodeStack **in, bNodeStack *out, TexFn texfn, TexCallData *cdata)
void tex_input_vec(float *out, bNodeStack *in, TexParams *params, short thread)
float tex_input_value(bNodeStack *in, TexParams *params, short thread)
bool tex_node_poll_default(const blender::bke::bNodeType *, const bNodeTree *ntree, const char **r_disabled_hint)
void tex_input_rgba(float *out, bNodeStack *in, TexParams *params, short thread)
static void tex_call_delegate(TexDelegate *dg, float *out, TexParams *params, short thread)
void tex_node_type_base(blender::bke::bNodeType *ntype, std::string idname, const std::optional< int16_t > legacy_type)
void params_from_cdata(TexParams *out, TexCallData *in)
void ntreeTexCheckCyclics(bNodeTree *ntree)
static void tex_input(float *out, int num, bNodeStack *in, TexParams *params, short thread)
void(*)(float *out, TexParams *params, bNode *node, bNodeStack **in, short thread) TexFn
bool node_insert_link_default(blender::bke::NodeInsertLinkParams &)
Definition node_util.cc:266
bNodeStack * in[MAX_SOCKET]
TexCallData * cdata
char use_nodes
struct bNodeTree * nodetree
char idname[64]
ListBase nodes
bNodeRuntimeHandle * runtime
Defines a node type.
Definition BKE_node.hh:238
bool(* insert_link)(NodeInsertLinkParams &params)
Definition BKE_node.hh:333
bool(* poll)(const bNodeType *ntype, const bNodeTree *nodetree, const char **r_disabled_hint)
Definition BKE_node.hh:321