Blender  V3.3
COM_OutputFileNode.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2011 Blender Foundation. */
3 
4 #include "COM_OutputFileNode.h"
5 
6 namespace blender::compositor {
7 
8 OutputFileNode::OutputFileNode(bNode *editor_node) : Node(editor_node)
9 {
10  /* pass */
11 }
12 
13 void OutputFileNode::add_input_sockets(OutputOpenExrMultiLayerOperation &operation) const
14 {
15  for (NodeInput *input : inputs_) {
16  NodeImageMultiFileSocket *sockdata =
17  (NodeImageMultiFileSocket *)input->get_bnode_socket()->storage;
18  /* NOTE: layer becomes an empty placeholder if the input is not linked. */
19  operation.add_layer(sockdata->layer, input->get_data_type(), input->is_linked());
20  }
21 }
22 
23 void OutputFileNode::map_input_sockets(NodeConverter &converter,
24  OutputOpenExrMultiLayerOperation &operation) const
25 {
26  bool preview_added = false;
27  int index = 0;
28  for (NodeInput *input : inputs_) {
29  converter.map_input_socket(input, operation.get_input_socket(index++));
30 
31  if (!preview_added) {
32  converter.add_node_input_preview(input);
33  preview_added = true;
34  }
35  }
36 }
37 
38 void OutputFileNode::add_preview_to_first_linked_input(NodeConverter &converter) const
39 {
40  if (get_input_sockets().is_empty()) {
41  return;
42  }
43 
44  NodeInput *first_socket = this->get_input_socket(0);
45  if (first_socket->is_linked()) {
46  converter.add_node_input_preview(first_socket);
47  }
48 }
49 
51  const CompositorContext &context) const
52 {
54  const bool is_multiview = (context.get_render_data()->scemode & R_MULTIVIEW) != 0;
55 
56  add_preview_to_first_linked_input(converter);
57 
58  if (!context.is_rendering()) {
59  /* only output files when rendering a sequence -
60  * otherwise, it overwrites the output files just
61  * scrubbing through the timeline when the compositor updates.
62  */
63  return;
64  }
65 
66  if (storage->format.imtype == R_IMF_IMTYPE_MULTILAYER) {
67  const bool use_half_float = (storage->format.depth == R_IMF_CHAN_DEPTH_16);
68  /* single output operation for the multilayer file */
69  OutputOpenExrMultiLayerOperation *output_operation;
70 
71  if (is_multiview && storage->format.views_format == R_IMF_VIEWS_MULTIVIEW) {
72  output_operation = new OutputOpenExrMultiLayerMultiViewOperation(context.get_scene(),
73  context.get_render_data(),
74  context.get_bnodetree(),
75  storage->base_path,
76  storage->format.exr_codec,
77  use_half_float,
78  context.get_view_name());
79  }
80  else {
81  output_operation = new OutputOpenExrMultiLayerOperation(context.get_scene(),
82  context.get_render_data(),
83  context.get_bnodetree(),
84  storage->base_path,
85  storage->format.exr_codec,
86  use_half_float,
87  context.get_view_name());
88  }
89  converter.add_operation(output_operation);
90 
91  /* First add all inputs. Inputs are stored in a Vector and can be moved to a different
92  * memory address during this time. */
93  add_input_sockets(*output_operation);
94  /* After adding the sockets the memory addresses will stick. */
95  map_input_sockets(converter, *output_operation);
96  }
97  else { /* single layer format */
98  for (NodeInput *input : inputs_) {
99  if (input->is_linked()) {
100  NodeImageMultiFileSocket *sockdata =
101  (NodeImageMultiFileSocket *)input->get_bnode_socket()->storage;
102  ImageFormatData *format = (sockdata->use_node_format ? &storage->format :
103  &sockdata->format);
104  char path[FILE_MAX];
105 
106  /* combine file path for the input */
107  BLI_join_dirfile(path, FILE_MAX, storage->base_path, sockdata->path);
108 
109  NodeOperation *output_operation = nullptr;
110 
111  if (is_multiview && format->views_format == R_IMF_VIEWS_MULTIVIEW) {
112  output_operation = new OutputOpenExrSingleLayerMultiViewOperation(
113  context.get_scene(),
114  context.get_render_data(),
115  context.get_bnodetree(),
116  input->get_data_type(),
117  format,
118  path,
119  context.get_view_name(),
120  sockdata->save_as_render);
121  }
122  else if ((!is_multiview) || (format->views_format == R_IMF_VIEWS_INDIVIDUAL)) {
123  output_operation = new OutputSingleLayerOperation(context.get_scene(),
124  context.get_render_data(),
125  context.get_bnodetree(),
126  input->get_data_type(),
127  format,
128  path,
129  context.get_view_name(),
130  sockdata->save_as_render);
131  }
132  else { /* R_IMF_VIEWS_STEREO_3D */
133  output_operation = new OutputStereoOperation(context.get_scene(),
134  context.get_render_data(),
135  context.get_bnodetree(),
136  input->get_data_type(),
137  format,
138  path,
139  sockdata->layer,
140  context.get_view_name(),
141  sockdata->save_as_render);
142  }
143 
144  converter.add_operation(output_operation);
145  converter.map_input_socket(input, output_operation->get_input_socket(0));
146  }
147  }
148  }
149 }
150 
151 } // namespace blender::compositor
#define FILE_MAX
void BLI_join_dirfile(char *__restrict dst, size_t maxlen, const char *__restrict dir, const char *__restrict file) ATTR_NONNULL()
Definition: path_util.c:1531
#define R_MULTIVIEW
#define R_IMF_IMTYPE_MULTILAYER
@ R_IMF_CHAN_DEPTH_16
@ R_IMF_VIEWS_MULTIVIEW
@ R_IMF_VIEWS_INDIVIDUAL
Overall context of the compositor.
void add_operation(NodeOperation *operation)
void map_input_socket(NodeInput *node_socket, NodeOperationInput *operation_socket)
NodeInput are sockets that can receive data/input.
Definition: COM_Node.h:190
NodeOperation contains calculation logic.
NodeOperationInput * get_input_socket(unsigned int index)
const Vector< NodeInput * > & get_input_sockets() const
get access to the vector of input sockets
Definition: COM_Node.h:100
bNode * get_bnode() const
get the reference to the SDNA bNode struct
Definition: COM_Node.h:64
NodeInput * get_input_socket(unsigned int index) const
Definition: COM_Node.cc:89
Vector< NodeInput * > inputs_
the list of actual input-sockets
Definition: COM_Node.h:50
void convert_to_operations(NodeConverter &converter, const CompositorContext &context) const override
convert node to operation
void add_layer(const char *name, DataType datatype, bool use_layer)
ccl_global KernelShaderEvalInput * input
format
Definition: logImageCore.h:38
ImageFormatData format
void * storage