36#include "RNA_prototypes.hh"
65 Args *data = (Args *)arg;
68 if (sock != data->sock) {
91 if (
ELEM(
nullptr, sock, defname)) {
107 Args *data = (Args *)arg;
110 if (sock != data->sock) {
121 const char defname[],
132 if (
ELEM(
nullptr, sock, defname)) {
228 node->storage = nimf;
277 src_sock && dest_sock;
294 if (sock->storage ==
nullptr) {
305 ntree->ensure_topology_cache();
307 if (sock->is_logically_linked()) {
308 const bNodeSocket *from_socket = sock->logically_linked_sockets()[0];
309 if (sock->type != from_socket->
type) {
338 const bool is_multiview = (scene->r.scemode &
R_MULTIVIEW) != 0;
351 if (!save_as_render) {
368 uiItemO(layout,
IFACE_(
"Add Input"), ICON_ADD,
"NODE_OT_output_file_add_socket");
383 "active_input_index",
401 "active_input_index",
423 if (active_input_ptr.
data) {
431 "NODE_OT_output_file_remove_active_socket",
446 "NODE_OT_output_file_remove_active_socket",
466 const bool use_node_format =
RNA_boolean_get(&active_input_ptr,
"use_node_format");
468 if (!use_node_format) {
481 const bool use_color_management =
RNA_boolean_get(&active_input_ptr,
"save_as_render");
486 if (!use_color_management) {
511 for (
const bNodeSocket *input : node->input_sockets()) {
538 if (result.is_single_value()) {
551 const auto &
format = socket.use_node_format ? node_storage(
bnode()).format : socket.format;
552 const bool save_as_render = socket.use_node_format ? node_storage(
bnode()).save_as_render :
553 socket.save_as_render;
564 const int2 size = result.domain().size;
566 image_path,
format, size, save_as_render);
580 const char *base_path,
581 const char *layer_name)
591 const int2 size = result.domain().size;
593 image_path,
format, size,
true);
616 const char *write_view = store_views_in_single_file ?
"" :
view;
622 image_path,
format, size,
true);
626 const char *pass_view = store_views_in_single_file ?
view :
"";
642 const char *pass_name,
643 const char *view_name)
652 float *buffer =
nullptr;
653 if (result.is_single_value()) {
661 switch (result.type()) {
662 case ResultType::Color:
666 if (result.meta_data.is_cryptomatte_layer()) {
667 file_output.
add_pass(pass_name, view_name,
"rgba", buffer);
670 file_output.
add_pass(pass_name, view_name,
"RGBA", buffer);
673 case ResultType::Vector:
674 if (result.meta_data.is_4d_vector) {
675 file_output.
add_pass(pass_name, view_name,
"XYZW", buffer);
681 case ResultType::Float:
682 file_output.
add_pass(pass_name, view_name,
"V", buffer);
697 switch (result.type()) {
698 case ResultType::Float: {
700 size_t(size.x) * size.y,
sizeof(
float),
"File Output Inflated Buffer."));
702 const float value = result.get_float_value();
704 for (const int64_t y : sub_y_range) {
705 for (const int64_t x : IndexRange(size.x)) {
706 buffer[y * size.x + x] = value;
712 case ResultType::Vector:
713 case ResultType::Color: {
715 size_t(size.x) * size.y,
sizeof(
float[4]),
"File Output Inflated Buffer."));
717 const float4 value = result.type() == ResultType::Color ? result.get_color_value() :
718 result.get_vector_value();
720 for (const int64_t y : sub_y_range) {
721 for (const int64_t x : IndexRange(size.x)) {
722 copy_v4_v4(buffer + ((y * size.x + x) * 4), value);
746 const int2 size = result.domain().size;
747 switch (result.type()) {
748 case ResultType::Color:
749 file_output.
add_view(view_name, 4, buffer);
751 case ResultType::Vector:
752 file_output.
add_view(view_name, 3, float4_to_float3_image(size, buffer));
754 case ResultType::Float:
755 file_output.
add_view(view_name, 1, buffer);
769 size_t(size.x) * size.y,
sizeof(
float[3]),
"File Output Vector Buffer."));
772 for (const int64_t y : sub_y_range) {
773 for (const int64_t x : IndexRange(size.x)) {
774 for (int i = 0; i < 3; i++) {
775 const int pixel_index = y * size.x + x;
776 float3_image[pixel_index * 3 + i] = float4_image[pixel_index * 4 + i];
790 StringRef cryptomatte_layer_name = bke::cryptomatte::BKE_cryptomatte_extract_layer_name(name);
792 if (result.meta_data.is_cryptomatte_layer()) {
794 bke::cryptomatte::BKE_cryptomatte_meta_data_key(cryptomatte_layer_name,
"name"),
795 cryptomatte_layer_name);
798 if (!result.meta_data.cryptomatte.manifest.empty()) {
800 bke::cryptomatte::BKE_cryptomatte_meta_data_key(cryptomatte_layer_name,
"manifest"),
801 result.meta_data.cryptomatte.manifest);
804 if (!result.meta_data.cryptomatte.hash.empty()) {
806 bke::cryptomatte::BKE_cryptomatte_meta_data_key(cryptomatte_layer_name,
"hash"),
807 result.meta_data.cryptomatte.hash);
810 if (!result.meta_data.cryptomatte.conversion.empty()) {
812 bke::cryptomatte::BKE_cryptomatte_meta_data_key(cryptomatte_layer_name,
"conversion"),
813 result.meta_data.cryptomatte.conversion);
840 context().get_frame_number(),
842 use_file_extension(),
855 context().get_frame_number(),
857 use_file_extension(),
869 return node_storage(bnode()).base_path;
875 return context().get_render_data().scemode &
R_EXTENSION;
881 if (!is_multi_view_scene()) {
890 return context().get_render_data().scemode &
R_MULTIVIEW;
908 ntype.
draw_buttons = file_ns::node_composit_buts_file_output;
913 &ntype,
"NodeImageMultiFile", file_ns::free_output_file, file_ns::copy_output_file);
914 ntype.
updatefunc = file_ns::update_output_file;
Scene * CTX_data_scene(const bContext *C)
const char * BKE_main_blendfile_path_from_global()
#define NODE_CLASS_OUTPUT
#define NODE_STORAGE_FUNCS(StorageT)
void BKE_ntree_update_tag_socket_property(bNodeTree *ntree, bNodeSocket *socket)
int BKE_scene_multiview_num_views_get(const RenderData *rd)
const char * BKE_scene_multiview_view_suffix_get(const RenderData *rd, const char *viewname)
#define BLI_assert_unreachable()
File and directory operations.
#define LISTBASE_FOREACH(type, var, list)
void * BLI_findlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
int BLI_findindex(const struct ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
#define BLI_path_join(...)
int BLI_path_slash_ensure(char *path, size_t path_maxncpy) ATTR_NONNULL(1)
#define STRNCPY(dst, src)
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
#define STRNCPY_UTF8(dst, src)
size_t void BLI_uniquename_cb(UniquenameCheckCallback unique_check, void *arg, const char *defname, char delim, char *name, size_t name_maxncpy) ATTR_NONNULL(1
@ R_IMF_IMTYPE_MULTILAYER
@ R_IMF_COLOR_MANAGEMENT_FOLLOW_SCENE
void GPU_memory_barrier(eGPUBarrier barrier)
@ GPU_BARRIER_TEXTURE_UPDATE
void * GPU_texture_read(GPUTexture *texture, eGPUDataFormat data_format, int mip_level)
Contains defines and structs used throughout the imbuf module.
Read Guarded memory(de)allocation.
void uiItemL(uiLayout *layout, const char *name, int icon)
void uiItemFullO(uiLayout *layout, const char *opname, const char *name, int icon, IDProperty *properties, wmOperatorCallContext context, eUI_Item_Flag flag, PointerRNA *r_opptr)
uiLayout * uiLayoutRow(uiLayout *layout, bool align)
void uiTemplateImageSettings(uiLayout *layout, PointerRNA *imfptr, bool color_management)
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
void uiItemS(uiLayout *layout)
void uiItemFullO_ptr(uiLayout *layout, wmOperatorType *ot, const char *name, int icon, IDProperty *properties, wmOperatorCallContext context, eUI_Item_Flag flag, PointerRNA *r_opptr)
void uiTemplateList(uiLayout *layout, const bContext *C, const char *listtype_name, const char *list_id, PointerRNA *dataptr, const char *propname, PointerRNA *active_dataptr, const char *active_propname, const char *item_dyntip_propname, int rows, int maxrows, int layout_type, int columns, enum uiTemplateListFlags flags)
void uiItemO(uiLayout *layout, const char *name, int icon, const char *opname)
void uiLayoutSetPropDecorate(uiLayout *layout, bool is_sep)
uiLayout * uiLayoutColumn(uiLayout *layout, bool align)
void uiTemplateImageFormatViews(uiLayout *layout, PointerRNA *imfptr, PointerRNA *ptr)
@ UI_TEMPLATE_LIST_FLAG_NONE
void uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, eUI_Item_Flag flag, const char *name, int icon)
@ UI_ITEM_R_SPLIT_EMPTY_NAME
constexpr const char * data() const
void execute_single_layer_multi_view_exr(const Result &result, const ImageFormatData &format, const char *base_path, const char *layer_name)
bool use_file_extension()
void execute_multi_layer()
float * inflate_result(const Result &result, const int2 size)
void get_single_layer_image_base_path(const char *base_name, char *base_path)
void get_single_layer_image_path(const char *base_path, const ImageFormatData &format, char *image_path)
const char * get_base_path()
void add_pass_for_result(FileOutput &file_output, const Result &result, const char *pass_name, const char *view_name)
void execute_single_layer()
void get_multi_layer_exr_image_path(const char *base_path, const char *view, char *image_path)
void add_meta_data_for_result(FileOutput &file_output, const Result &result, const char *name)
void add_view_for_result(FileOutput &file_output, const Result &result, const char *view_name)
float * float4_to_float3_image(int2 size, float *float4_image)
bool is_multi_view_scene()
FileOutputOperation(Context &context, DNode node)
virtual RenderContext * render_context() const
virtual StringRef get_view_name() const =0
void add_view(const char *view_name)
void add_pass(const char *pass_name, const char *view_name, const char *channels, float *buffer)
void add_meta_data(std::string key, std::string value)
const bNode & bnode() const
const DNode & node() const
Result & get_input(StringRef identifier) const
InputDescriptor & get_input_descriptor(StringRef identifier)
Context & context() const
virtual Domain compute_domain()
FileOutput & get_file_output(std::string path, ImageFormatData format, int2 size, bool save_as_render)
const Domain & domain() const
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
void MEM_freeN(void *vmemh)
void *(* MEM_dupallocN)(const void *vmemh)
void node_modify_socket_type_static(bNodeTree *ntree, bNode *node, bNodeSocket *sock, int type, int subtype)
bNodeSocket * node_add_static_socket(bNodeTree *ntree, bNode *node, eNodeSocketInOut in_out, int type, int subtype, const char *identifier, const char *name)
void node_remove_socket(bNodeTree *ntree, bNode *node, bNodeSocket *sock)
void node_type_storage(bNodeType *ntype, const char *storagename, void(*freefunc)(bNode *node), void(*copyfunc)(bNodeTree *dest_ntree, bNode *dest_node, const bNode *src_node))
void node_register_type(bNodeType *ntype)
static void free_output_file(bNode *node)
static void copy_output_file(bNodeTree *, bNode *dest_node, const bNode *src_node)
static void init_output_file(const bContext *C, PointerRNA *ptr)
static void update_output_file(bNodeTree *ntree, bNode *node)
static void node_composit_buts_file_output(uiLayout *layout, bContext *, PointerRNA *ptr)
static NodeOperation * get_compositor_operation(Context &context, DNode node)
static void node_composit_buts_file_output_ex(uiLayout *layout, bContext *C, PointerRNA *ptr)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
void ntreeCompositOutputFileUniqueLayer(ListBase *list, bNodeSocket *sock, const char defname[], char delim)
void ntreeCompositOutputFileSetPath(bNode *node, bNodeSocket *sock, const char *name)
void register_node_type_cmp_output_file()
int ntreeCompositOutputFileRemoveActiveSocket(bNodeTree *ntree, bNode *node)
static bool unique_path_unique_check(void *arg, const char *name)
void ntreeCompositOutputFileSetLayer(bNode *node, bNodeSocket *sock, const char *name)
static bool unique_layer_unique_check(void *arg, const char *name)
bNodeSocket * ntreeCompositOutputFileAddSocket(bNodeTree *ntree, bNode *node, const char *name, const ImageFormatData *im_format)
void ntreeCompositOutputFileUniquePath(ListBase *list, bNodeSocket *sock, const char defname[], char delim)
void cmp_node_type_base(blender::bke::bNodeType *ntype, int type, const char *name, short nclass)
void cmp_node_update_default(bNodeTree *, bNode *node)
PointerRNA RNA_pointer_get(PointerRNA *ptr, const char *name)
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
int RNA_int_get(PointerRNA *ptr, const char *name)
bool RNA_property_collection_lookup_int(PointerRNA *ptr, PropertyRNA *prop, int key, PointerRNA *r_ptr)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
void RNA_enum_set(PointerRNA *ptr, const char *name, int value)
int RNA_enum_get(PointerRNA *ptr, const char *name)
struct ImageFormatData im_format
struct bNodeSocket * next
NodeGetCompositorOperationFunction get_compositor_operation
void(* draw_buttons_ex)(uiLayout *, bContext *C, PointerRNA *ptr)
void(* draw_buttons)(uiLayout *, bContext *C, PointerRNA *ptr)
void(* updatefunc)(bNodeTree *ntree, bNode *node)
void(* initfunc_api)(const bContext *C, PointerRNA *ptr)
wmOperatorType * WM_operatortype_find(const char *idname, bool quiet)