This repository has been archived on 2023-10-09. You can view files and clone it, but cannot push or open issues or pull requests.
Files
blender-archive/source/blender/nodes/texture/node_texture_util.c
Campbell Barton c434782e3a File headers: SPDX License migration
Use a shorter/simpler license convention, stops the header taking so
much space.

Follow the SPDX license specification: https://spdx.org/licenses

- C/C++/objc/objc++
- Python
- Shell Scripts
- CMake, GNUmakefile

While most of the source tree has been included

- `./extern/` was left out.
- `./intern/cycles` & `./intern/atomic` are also excluded because they
  use different header conventions.

doc/license/SPDX-license-identifiers.txt has been added to list SPDX all
used identifiers.

See P2788 for the script that automated these edits.

Reviewed By: brecht, mont29, sergey

Ref D14069
2022-02-11 09:14:36 +11:00

160 lines
3.9 KiB
C

/* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright 2005 Blender Foundation. All rights reserved. */
/** \file
* \ingroup nodes
*/
/*
* HOW TEXTURE NODES WORK
*
* In contrast to Shader nodes, which place a color into the output
* stack when executed, Texture nodes place a TexDelegate* there. To
* obtain a color value from this, a node further up the chain reads
* the TexDelegate* from its input stack, and uses tex_call_delegate to
* retrieve the color from the delegate.
*
* comments: (ton)
*
* This system needs recode, a node system should rely on the stack, and
* callbacks for nodes only should evaluate own node, not recursively go
* over other previous ones.
*/
#include "node_texture_util.h"
bool tex_node_poll_default(bNodeType *UNUSED(ntype),
bNodeTree *ntree,
const char **r_disabled_hint)
{
if (!STREQ(ntree->idname, "TextureNodeTree")) {
*r_disabled_hint = TIP_("Not a texture node tree");
return false;
}
return true;
}
void tex_node_type_base(struct bNodeType *ntype, int type, const char *name, short nclass)
{
node_type_base(ntype, type, name, nclass);
ntype->poll = tex_node_poll_default;
ntype->insert_link = node_insert_link_default;
}
static void tex_call_delegate(TexDelegate *dg, float *out, TexParams *params, short thread)
{
if (dg->node->need_exec) {
dg->fn(out, params, dg->node, dg->in, thread);
}
}
static void tex_input(float *out, int sz, bNodeStack *in, TexParams *params, short thread)
{
TexDelegate *dg = in->data;
if (dg) {
tex_call_delegate(dg, in->vec, params, thread);
if (in->hasoutput && in->sockettype == SOCK_FLOAT) {
in->vec[1] = in->vec[2] = in->vec[0];
}
}
memcpy(out, in->vec, sz * sizeof(float));
}
void tex_input_vec(float *out, bNodeStack *in, TexParams *params, short thread)
{
tex_input(out, 3, in, params, thread);
}
void tex_input_rgba(float *out, bNodeStack *in, TexParams *params, short thread)
{
tex_input(out, 4, in, params, thread);
if (in->hasoutput && in->sockettype == SOCK_FLOAT) {
out[1] = out[2] = out[0];
out[3] = 1;
}
if (in->hasoutput && in->sockettype == SOCK_VECTOR) {
out[0] = out[0] * 0.5f + 0.5f;
out[1] = out[1] * 0.5f + 0.5f;
out[2] = out[2] * 0.5f + 0.5f;
out[3] = 1;
}
}
float tex_input_value(bNodeStack *in, TexParams *params, short thread)
{
float out[4];
tex_input_vec(out, in, params, thread);
return out[0];
}
void params_from_cdata(TexParams *out, TexCallData *in)
{
out->co = in->co;
out->dxt = in->dxt;
out->dyt = in->dyt;
out->previewco = in->co;
out->osatex = in->osatex;
out->cfra = in->cfra;
out->mtex = in->mtex;
}
void tex_output(bNode *node,
bNodeExecData *execdata,
bNodeStack **in,
bNodeStack *out,
TexFn texfn,
TexCallData *cdata)
{
TexDelegate *dg;
if (node->flag & NODE_MUTED) {
/* do not add a delegate if the node is muted */
return;
}
if (!out->data) {
/* Freed in tex_end_exec (node.cc) */
dg = out->data = MEM_mallocN(sizeof(TexDelegate), "tex delegate");
}
else {
dg = out->data;
}
dg->cdata = cdata;
dg->fn = texfn;
dg->node = node;
dg->preview = execdata->preview;
memcpy(dg->in, in, MAX_SOCKET * sizeof(bNodeStack *));
dg->type = out->sockettype;
}
void ntreeTexCheckCyclics(struct bNodeTree *ntree)
{
bNode *node;
for (node = ntree->nodes.first; node; node = node->next) {
if (node->type == TEX_NODE_TEXTURE && node->id) {
/* custom2 stops the node from rendering */
if (node->custom1) {
node->custom2 = 1;
node->custom1 = 0;
}
else {
Tex *tex = (Tex *)node->id;
node->custom2 = 0;
node->custom1 = 1;
if (tex->use_nodes && tex->nodetree) {
ntreeTexCheckCyclics(tex->nodetree);
}
node->custom1 = 0;
}
}
}
}