The general idea is to keep the 'old', C-style MEM_callocN signature, and slowly replace most of its usages with the new, C++-style type-safer template version. * `MEM_cnew<T>` allocation version is renamed to `MEM_callocN<T>`. * `MEM_cnew_array<T>` allocation version is renamed to `MEM_calloc_arrayN<T>`. * `MEM_cnew<T>` duplicate version is renamed to `MEM_dupallocN<T>`. Similar templates type-safe version of `MEM_mallocN` will be added soon as well. Following discussions in !134452. NOTE: For now static type checking in `MEM_callocN` and related are slightly different for Windows MSVC. This compiler seems to consider structs using the `DNA_DEFINE_CXX_METHODS` macro as non-trivial (likely because their default copy constructors are deleted). So using checks on trivially constructible/destructible instead on this compiler/system. Pull Request: https://projects.blender.org/blender/blender/pulls/134771
113 lines
2.7 KiB
C++
113 lines
2.7 KiB
C++
/* SPDX-FileCopyrightText: 2006 Blender Authors
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
|
|
/** \file
|
|
* \ingroup texnodes
|
|
*/
|
|
|
|
#include "BKE_image.hh"
|
|
#include "BLI_math_vector.h"
|
|
#include "BLI_threads.h"
|
|
#include "IMB_imbuf.hh"
|
|
#include "node_texture_util.hh"
|
|
#include "node_util.hh"
|
|
|
|
static blender::bke::bNodeSocketTemplate outputs[] = {
|
|
{SOCK_RGBA, N_("Image")},
|
|
{-1, ""},
|
|
};
|
|
|
|
static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack ** /*in*/, short /*thread*/)
|
|
{
|
|
float x = p->co[0];
|
|
float y = p->co[1];
|
|
Image *ima = (Image *)node->id;
|
|
ImageUser *iuser = (ImageUser *)node->storage;
|
|
|
|
if (ima) {
|
|
ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, nullptr);
|
|
if (ibuf) {
|
|
float xsize, ysize;
|
|
float xoff, yoff;
|
|
int px, py;
|
|
|
|
const float *result;
|
|
|
|
xsize = ibuf->x / 2;
|
|
ysize = ibuf->y / 2;
|
|
xoff = yoff = -1;
|
|
|
|
px = int((x - xoff) * xsize);
|
|
py = int((y - yoff) * ysize);
|
|
|
|
if ((!xsize) || (!ysize)) {
|
|
return;
|
|
}
|
|
|
|
if (!ibuf->float_buffer.data) {
|
|
BLI_thread_lock(LOCK_IMAGE);
|
|
if (!ibuf->float_buffer.data) {
|
|
IMB_float_from_byte(ibuf);
|
|
}
|
|
BLI_thread_unlock(LOCK_IMAGE);
|
|
}
|
|
|
|
while (px < 0) {
|
|
px += ibuf->x;
|
|
}
|
|
while (py < 0) {
|
|
py += ibuf->y;
|
|
}
|
|
while (px >= ibuf->x) {
|
|
px -= ibuf->x;
|
|
}
|
|
while (py >= ibuf->y) {
|
|
py -= ibuf->y;
|
|
}
|
|
|
|
result = ibuf->float_buffer.data + py * ibuf->x * 4 + px * 4;
|
|
copy_v4_v4(out, result);
|
|
|
|
BKE_image_release_ibuf(ima, ibuf, nullptr);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void exec(void *data,
|
|
int /*thread*/,
|
|
bNode *node,
|
|
bNodeExecData *execdata,
|
|
bNodeStack **in,
|
|
bNodeStack **out)
|
|
{
|
|
tex_output(node, execdata, in, out[0], &colorfn, static_cast<TexCallData *>(data));
|
|
}
|
|
|
|
static void init(bNodeTree * /*ntree*/, bNode *node)
|
|
{
|
|
ImageUser *iuser = MEM_callocN<ImageUser>("node image user");
|
|
node->storage = iuser;
|
|
iuser->sfra = 1;
|
|
iuser->flag |= IMA_ANIM_ALWAYS;
|
|
}
|
|
|
|
void register_node_type_tex_image()
|
|
{
|
|
static blender::bke::bNodeType ntype;
|
|
|
|
tex_node_type_base(&ntype, "TextureNodeImage", TEX_NODE_IMAGE);
|
|
ntype.ui_name = "Image";
|
|
ntype.enum_name_legacy = "IMAGE";
|
|
ntype.nclass = NODE_CLASS_INPUT;
|
|
blender::bke::node_type_socket_templates(&ntype, nullptr, outputs);
|
|
ntype.initfunc = init;
|
|
blender::bke::node_type_storage(
|
|
ntype, "ImageUser", node_free_standard_storage, node_copy_standard_storage);
|
|
ntype.exec_fn = exec;
|
|
ntype.labelfunc = node_image_label;
|
|
ntype.flag |= NODE_PREVIEW;
|
|
|
|
blender::bke::node_register_type(ntype);
|
|
}
|