Removes various image filtering/mipmapping leftovers from pre-2.80 days. Code: removes all mipmap handling from ImBuf (which is about half of ImBuf struct size), removes now unused "sample procedural texture with mipmaps" code, now-unused FELINE filter, etc. The osatex parameter to various CPU texture sampling functions is never actually used, which means none of the mipmap code was ever executing. User visible part: there were settings on the legacy Texture data block (as used by Brushes etc.), under Sampling section: "MIP Map", "Gaussian Filter", "Filter Type", "Eccentricity", "Minimum Size" -- they had no effect anywhere, so they are gone, and what remains is only "Interpolation" and "Size". RNA / Python API part: removes the ImageTexture RNA properties corresponding to the above: filter_type, use_mipmap, use_mipmap_gauss, filter_lightprobes, filter_eccentricity, use_filter_size_min. Pull Request: https://projects.blender.org/blender/blender/pulls/139978
167 lines
4.0 KiB
C++
167 lines
4.0 KiB
C++
/* SPDX-FileCopyrightText: 2005 Blender Authors
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
|
|
/** \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 their own node, not recursively go
|
|
* over other previous ones.
|
|
*/
|
|
|
|
#include "BLI_listbase.h"
|
|
|
|
#include "BKE_node_runtime.hh"
|
|
|
|
#include "NOD_texture.h"
|
|
|
|
#include "node_texture_util.hh"
|
|
#include "node_util.hh"
|
|
#include <optional>
|
|
|
|
bool tex_node_poll_default(const blender::bke::bNodeType * /*ntype*/,
|
|
const bNodeTree *ntree,
|
|
const char **r_disabled_hint)
|
|
{
|
|
if (!STREQ(ntree->idname, "TextureNodeTree")) {
|
|
*r_disabled_hint = RPT_("Not a texture node tree");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void tex_node_type_base(blender::bke::bNodeType *ntype,
|
|
std::string idname,
|
|
const std::optional<int16_t> legacy_type)
|
|
{
|
|
blender::bke::node_type_base(*ntype, idname, legacy_type);
|
|
|
|
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->runtime->need_exec) {
|
|
dg->fn(out, params, dg->node, dg->in, thread);
|
|
}
|
|
}
|
|
|
|
static void tex_input(float *out, int num, bNodeStack *in, TexParams *params, short thread)
|
|
{
|
|
TexDelegate *dg = static_cast<TexDelegate *>(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, num * 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->previewco = in->co;
|
|
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->is_muted()) {
|
|
/* do not add a delegate if the node is muted */
|
|
return;
|
|
}
|
|
|
|
if (!out->data) {
|
|
/* Freed in tex_end_exec (node.cc) */
|
|
dg = MEM_callocN<TexDelegate>("tex delegate");
|
|
out->data = dg;
|
|
}
|
|
else {
|
|
dg = static_cast<TexDelegate *>(out->data);
|
|
}
|
|
|
|
dg->cdata = cdata;
|
|
dg->fn = texfn;
|
|
dg->node = node;
|
|
memcpy(dg->in, in, MAX_SOCKET * sizeof(bNodeStack *));
|
|
dg->type = out->sockettype;
|
|
}
|
|
|
|
void ntreeTexCheckCyclics(bNodeTree *ntree)
|
|
{
|
|
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
|
|
|
|
if (node->type_legacy == 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;
|
|
}
|
|
}
|
|
}
|
|
}
|