68 if (sock_iter != sock) {
70 if (sockdata->
path == name) {
83 if (
ELEM(
nullptr, sock, defname)) {
94 sizeof(sockdata->
path));
103 if (sock_iter != sock) {
105 if (sockdata->
layer == name) {
114 const char defname[],
118 if (
ELEM(
nullptr, sock, defname)) {
129 sizeof(sockdata->
layer));
268 src_sock && dest_sock;
285 if (sock->storage ==
nullptr) {
296 ntree->ensure_topology_cache();
298 if (sock->is_logically_linked()) {
299 const bNodeSocket *from_socket = sock->logically_linked_sockets()[0];
300 if (sock->type != from_socket->
type) {
342 if (!save_as_render) {
359 layout->
op(
"NODE_OT_output_file_add_socket",
IFACE_(
"Add Input"), ICON_ADD);
361 row = &layout->
row(
false);
374 "active_input_index",
392 "active_input_index",
413 if (active_input_ptr.
data) {
418 row = &
col->row(
false);
420 row->
op(
"NODE_OT_output_file_remove_active_socket",
429 col->label(
IFACE_(
"File Subpath:"), ICON_NONE);
430 row = &
col->row(
false);
432 row->
op(
"NODE_OT_output_file_remove_active_socket",
442 col->label(
IFACE_(
"Format:"), ICON_NONE);
443 col->prop(&active_input_ptr,
449 const bool use_node_format =
RNA_boolean_get(&active_input_ptr,
"use_node_format");
451 if (!use_node_format) {
456 column->
prop(&active_input_ptr,
463 const bool use_color_management =
RNA_boolean_get(&active_input_ptr,
"save_as_render");
468 if (!use_color_management) {
493 if (!is_socket_available(input)) {
530 if (
result.is_single_value()) {
541 "Invalid path template in File Output node. Skipping writing file.");
550 const auto &
format = socket.use_node_format ? node_storage(
bnode()).format : socket.format;
551 const bool save_as_render = socket.use_node_format ? node_storage(
bnode()).save_as_render :
552 socket.save_as_render;
579 const char *base_path,
580 const char *layer_name)
587 const char *path_view = has_views ?
"" :
context().get_view_name().data();
600 const char *view_name = has_views ?
context().get_view_name().data() :
"";
614 const char *
view =
context().get_view_name().data();
619 const char *write_view = store_views_in_single_file ?
"" :
view;
623 nullptr,
RPT_ERROR,
"Invalid path template in File Output node. Skipping writing file.");
634 const char *pass_view = store_views_in_single_file ?
view :
"";
654 const char *pass_name,
655 const char *view_name)
664 float *buffer =
nullptr;
665 if (
result.is_single_value()) {
684 if (
result.meta_data.is_cryptomatte_layer()) {
685 file_output.
add_pass(pass_name, view_name,
"rgba", buffer);
688 file_output.
add_pass(pass_name, view_name,
"RGBA", buffer);
694 if (!
result.is_single_value() &&
this->context().use_gpu() &&
700 file_output.
add_pass(pass_name, view_name,
"XYZ", buffer);
704 file_output.
add_pass(pass_name, view_name,
"XYZW", buffer);
707 file_output.
add_pass(pass_name, view_name,
"V", buffer);
710 file_output.
add_pass(pass_name, view_name,
"XY", buffer);
713 file_output.
add_pass(pass_name, view_name,
"XY", buffer);
716 file_output.
add_pass(pass_name, view_name,
"V", buffer);
719 file_output.
add_pass(pass_name, view_name,
"V", buffer);
745 const float value = float(
result.get_single_value<
int32_t>());
755 const float value = float(
result.get_single_value<
bool>());
770 float *buffer =
nullptr;
783 file_output.
add_view(view_name, 4, buffer);
786 file_output.
add_view(view_name, 4, buffer);
791 if (!
result.is_single_value() &&
this->context().use_gpu() &&
797 file_output.
add_view(view_name, 3, buffer);
801 file_output.
add_view(view_name, 1, buffer);
818 "File Output Vector Buffer.");
821 for (
int i = 0;
i < 3;
i++) {
823 float3_image[pixel_index * 3 +
i] = float4_image[pixel_index * 4 +
i];
837 if (
result.meta_data.is_cryptomatte_layer()) {
840 cryptomatte_layer_name);
843 if (!
result.meta_data.cryptomatte.manifest.empty()) {
846 result.meta_data.cryptomatte.manifest);
849 if (!
result.meta_data.cryptomatte.hash.empty()) {
852 result.meta_data.cryptomatte.hash);
855 if (!
result.meta_data.cryptomatte.conversion.empty()) {
858 result.meta_data.cryptomatte.conversion);
887 node_base_path,
FILE_MAX, template_variables);
889 r_base_path[0] =
'\0';
900 sub_path,
FILE_MAX, template_variables);
902 r_base_path[0] =
'\0';
956 const bool apply_template,
968 apply_template ? &template_variables :
nullptr,
976 r_image_path[0] =
'\0';
989 return node_storage(
bnode()).base_path;
1028 ntype.
ui_name =
"File Output";
1032 ntype.
draw_buttons = file_ns::node_composit_buts_file_output;
1037 ntype,
"NodeImageMultiFile", file_ns::free_output_file, file_ns::copy_output_file);
1038 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)
#define CMP_NODE_OUTPUT_FILE
void BKE_ntree_update_tag_socket_property(bNodeTree *ntree, bNodeSocket *socket)
blender::bke::path_templates::VariableMap BKE_build_template_variables_for_render_path(const RenderData *render_data)
void BKE_report(ReportList *reports, eReportType type, const char *message)
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()
int BLI_findindex(const ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void * BLI_findlink(const ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
#define LISTBASE_FOREACH(type, var, list)
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
int BLI_listbase_count(const 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)
char * STRNCPY(char(&dst)[N], const char *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(blender::FunctionRef< bool(blender::StringRefNull)> unique_check, const char *defname, char delim, char *name, size_t name_maxncpy) ATTR_NONNULL(2
@ 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)
size_t GPU_texture_component_len(eGPUTextureFormat format)
eGPUTextureFormat GPU_texture_format(const GPUTexture *texture)
Read Guarded memory(de)allocation.
#define NOD_REGISTER_NODE(REGISTER_FUNC)
void uiTemplateImageSettings(uiLayout *layout, PointerRNA *imfptr, bool color_management)
void uiTemplateList(uiLayout *layout, const bContext *C, const char *listtype_name, const char *list_id, PointerRNA *dataptr, blender::StringRefNull 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 uiTemplateImageFormatViews(uiLayout *layout, PointerRNA *imfptr, PointerRNA *ptr)
@ UI_TEMPLATE_LIST_FLAG_NONE
@ UI_ITEM_R_SPLIT_EMPTY_NAME
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
void uiLayoutSetPropDecorate(uiLayout *layout, bool is_sep)
BMesh const char void * data
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
static const CPPType & get()
void fill_assign_n(const void *value, void *dst, int64_t n) const
const CPPType * type() const
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 DNode & node() const
const bNode & bnode() const
NodeOperation(Context &context, DNode node)
Context & context() const
virtual Domain compute_domain()
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()
bool get_multi_layer_exr_image_path(const char *base_path, const char *view, const bool apply_template, char *r_image_path)
void get_single_layer_image_path(const char *base_path, const ImageFormatData &format, char *r_image_path)
float * inflate_result(const Result &result, const int2 size)
const char * get_base_path()
void add_pass_for_result(FileOutput &file_output, const Result &result, const char *pass_name, const char *view_name)
bool get_single_layer_image_base_path(const char *base_name, char *r_base_path)
void execute_single_layer()
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)
float length(VecOp< float, D >) RET
void * MEM_callocN(size_t len, const char *str)
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
void * MEM_dupallocN(const void *vmemh)
void MEM_freeN(void *vmemh)
StringRef BKE_cryptomatte_extract_layer_name(StringRef render_pass_name)
std::string BKE_cryptomatte_meta_data_key(StringRef layer_name, StringRefNull key_name)
void node_modify_socket_type_static(bNodeTree *ntree, bNode *node, bNodeSocket *sock, int type, int subtype)
void node_remove_socket(bNodeTree &ntree, bNode &node, bNodeSocket &sock)
void node_register_type(bNodeType &ntype)
bNodeSocket * node_add_static_socket(bNodeTree &ntree, bNode &node, eNodeSocketInOut in_out, int type, int subtype, StringRefNull identifier, StringRefNull name)
void node_type_storage(bNodeType &ntype, std::optional< StringRefNull > storagename, void(*freefunc)(bNode *node), void(*copyfunc)(bNodeTree *dest_ntree, bNode *dest_node, const bNode *src_node))
void parallel_for(const int2 range, const Function &function)
bool is_socket_available(const bNodeSocket *socket)
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)
VecBase< int32_t, 2 > int2
VecBase< float, 2 > float2
static bool unique_path_unique_check(ListBase *lb, bNodeSocket *sock, const blender::StringRef name)
void ntreeCompositOutputFileUniqueLayer(ListBase *list, bNodeSocket *sock, const char defname[], char delim)
void ntreeCompositOutputFileSetPath(bNode *node, bNodeSocket *sock, const char *name)
static bool unique_layer_unique_check(ListBase *lb, bNodeSocket *sock, const blender::StringRef name)
int ntreeCompositOutputFileRemoveActiveSocket(bNodeTree *ntree, bNode *node)
static void register_node_type_cmp_output_file()
void ntreeCompositOutputFileSetLayer(bNode *node, bNodeSocket *sock, 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, std::string idname, const std::optional< int16_t > legacy_type)
void cmp_node_update_default(bNodeTree *, bNode *node)
blender::Vector< Error > BKE_path_apply_template(char *path, int path_max_length, const VariableMap &template_variables)
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
std::string ui_description
NodeGetCompositorOperationFunction get_compositor_operation
void(* draw_buttons_ex)(uiLayout *, bContext *C, PointerRNA *ptr)
const char * enum_name_legacy
void(* draw_buttons)(uiLayout *, bContext *C, PointerRNA *ptr)
void(* updatefunc)(bNodeTree *ntree, bNode *node)
void(* initfunc_api)(const bContext *C, PointerRNA *ptr)
PointerRNA op(wmOperatorType *ot, std::optional< blender::StringRef > name, int icon, wmOperatorCallContext context, eUI_Item_Flag flag)
void label(blender::StringRef name, int icon)
uiLayout & column(bool align)
void separator(float factor=1.0f, LayoutSeparatorType type=LayoutSeparatorType::Auto)
uiLayout & row(bool align)
void prop(PointerRNA *ptr, PropertyRNA *prop, int index, int value, eUI_Item_Flag flag, std::optional< blender::StringRef > name_opt, int icon, std::optional< blender::StringRef > placeholder=std::nullopt)
static pxr::UsdShadeInput get_input(const pxr::UsdShadeShader &usd_shader, const pxr::TfToken &input_name)
wmOperatorType * WM_operatortype_find(const char *idname, bool quiet)