Blender
V5.0
source
blender
compositor
intern
operation.cc
Go to the documentation of this file.
1
/* SPDX-FileCopyrightText: 2023 Blender Authors
2
*
3
* SPDX-License-Identifier: GPL-2.0-or-later */
4
5
#include <limits>
6
#include <memory>
7
8
#include "
BLI_map.hh
"
9
#include "
BLI_string_ref.hh
"
10
11
#include "
COM_context.hh
"
12
#include "
COM_conversion_operation.hh
"
13
#include "
COM_domain.hh
"
14
#include "
COM_input_descriptor.hh
"
15
#include "
COM_operation.hh
"
16
#include "
COM_realize_on_domain_operation.hh
"
17
#include "
COM_result.hh
"
18
#include "
COM_simple_operation.hh
"
19
20
namespace
blender::compositor
{
21
22
Operation::Operation
(
Context
&
context
) : context_(
context
) {}
23
24
Operation::~Operation
() =
default
;
25
26
void
Operation::evaluate
()
27
{
28
evaluate_input_processors();
29
30
execute
();
31
32
compute_preview
();
33
34
release_inputs();
35
36
context
().
evaluate_operation_post
();
37
}
38
39
Result
&
Operation::get_result
(
StringRef
identifier)
40
{
41
return
results_.lookup(identifier);
42
}
43
44
void
Operation::map_input_to_result
(
StringRef
identifier,
Result
*
result
)
45
{
46
results_mapped_to_inputs_.add_new(identifier,
result
);
47
}
48
49
void
Operation::free_results
()
50
{
51
for
(
Result
&
result
: results_.values()) {
52
result
.free();
53
}
54
}
55
56
Domain
Operation::compute_domain
()
57
{
58
/* Default to an identity domain in case no domain input was found, most likely because all
59
* inputs are single values. */
60
Domain
operation_domain =
Domain::identity
();
61
int
current_domain_priority = std::numeric_limits<int>::max();
62
63
/* Go over the inputs and find the domain of the non single value input with the highest domain
64
* priority. */
65
for
(
StringRef
identifier : input_descriptors_.keys()) {
66
const
Result
&
result
=
get_input
(identifier);
67
const
InputDescriptor
&
descriptor
=
get_input_descriptor
(identifier);
68
69
/* A single value input can't be a domain input. */
70
if
(
result
.is_single_value() ||
descriptor
.expects_single_value) {
71
continue
;
72
}
73
74
/* An input that skips operation domain realization can't be a domain input. */
75
if
(
descriptor
.realization_mode !=
InputRealizationMode::OperationDomain
) {
76
continue
;
77
}
78
79
/* Notice that the lower the domain priority value is, the higher the priority is, hence the
80
* less than comparison. */
81
if
(
descriptor
.domain_priority < current_domain_priority) {
82
operation_domain =
result
.domain();
83
current_domain_priority =
descriptor
.domain_priority;
84
}
85
}
86
87
return
operation_domain;
88
}
89
90
void
Operation::add_and_evaluate_input_processors
()
91
{
92
/* Each input processor type is added to all inputs entirely before the next type. This is done
93
* because the construction of the input processors may depend on the result of previous input
94
* processors for all inputs. For instance, the realize on domain input processor considers the
95
* value of all inputs, so previous input processors for all inputs needs to be added and
96
* evaluated first. */
97
98
for
(
const
StringRef
&identifier : results_mapped_to_inputs_.keys()) {
99
SimpleOperation
*conversion =
ConversionOperation::construct_if_needed
(
100
context
(),
get_input
(identifier),
get_input_descriptor
(identifier));
101
add_and_evaluate_input_processor
(identifier, conversion);
102
}
103
104
for
(
const
StringRef
&identifier : results_mapped_to_inputs_.keys()) {
105
SimpleOperation
*realize_on_domain =
RealizeOnDomainOperation::construct_if_needed
(
106
context
(),
get_input
(identifier),
get_input_descriptor
(identifier),
compute_domain
());
107
add_and_evaluate_input_processor
(identifier, realize_on_domain);
108
}
109
}
110
111
void
Operation::add_and_evaluate_input_processor
(
StringRef
identifier,
SimpleOperation
*processor)
112
{
113
/* Allow null inputs to facilitate construct_if_needed pattern of addition. For instance, see the
114
* implementation of the add_and_evaluate_input_processors method. */
115
if
(!processor) {
116
return
;
117
}
118
119
ProcessorsVector
&processors = input_processors_.lookup_or_add_default(identifier);
120
121
/* Get the result that should serve as the input for the processor. This is either the result
122
* mapped to the input or the result of the last processor depending on whether this is the first
123
* processor or not. */
124
Result
&
result
= processors.
is_empty
() ?
get_input
(identifier) : processors.
last
()->get_result();
125
126
/* Map the input result of the processor and add it to the processors vector. */
127
processor->
map_input_to_result
(&
result
);
128
processors.
append
(std::unique_ptr<SimpleOperation>(processor));
129
130
/* Switch the result mapped to the input to be the output result of the processor. */
131
switch_result_mapped_to_input
(identifier, &processor->
get_result
());
132
133
processor->
evaluate
();
134
}
135
136
void
Operation::compute_preview
() {};
137
138
Result
&
Operation::get_input
(
StringRef
identifier)
const
139
{
140
return
*results_mapped_to_inputs_.lookup(identifier);
141
}
142
143
void
Operation::switch_result_mapped_to_input
(
StringRef
identifier,
Result
*
result
)
144
{
145
results_mapped_to_inputs_.lookup(identifier) =
result
;
146
}
147
148
void
Operation::populate_result
(
StringRef
identifier,
Result
result
)
149
{
150
results_.add_new(identifier,
result
);
151
}
152
153
void
Operation::declare_input_descriptor
(
StringRef
identifier,
InputDescriptor
descriptor
)
154
{
155
input_descriptors_.add_new(identifier,
descriptor
);
156
}
157
158
InputDescriptor
&
Operation::get_input_descriptor
(
StringRef
identifier)
159
{
160
return
input_descriptors_.lookup(identifier);
161
}
162
163
Context
&
Operation::context
()
const
164
{
165
return
context_;
166
}
167
168
void
Operation::evaluate_input_processors()
169
{
170
if
(!input_processors_added_) {
171
add_and_evaluate_input_processors
();
172
input_processors_added_ =
true
;
173
return
;
174
}
175
176
for
(
const
ProcessorsVector
&processors : input_processors_.values()) {
177
for
(
const
std::unique_ptr<SimpleOperation> &processor : processors) {
178
processor->evaluate();
179
}
180
}
181
}
182
183
void
Operation::release_inputs()
184
{
185
for
(Result *
result
: results_mapped_to_inputs_.values()) {
186
result
->release();
187
}
188
}
189
190
}
// namespace blender::compositor
result
double result
Definition
BLI_expr_pylike_eval_test.cc:351
BLI_map.hh
BLI_string_ref.hh
COM_context.hh
COM_conversion_operation.hh
COM_domain.hh
COM_input_descriptor.hh
COM_operation.hh
COM_realize_on_domain_operation.hh
COM_result.hh
COM_simple_operation.hh
blender::StringRef
Definition
BLI_string_ref.hh:150
blender::Vector::append
void append(const T &value)
Definition
BLI_vector.hh:489
blender::Vector::last
const T & last(const int64_t n=0) const
Definition
BLI_vector.hh:740
blender::Vector::is_empty
bool is_empty() const
Definition
BLI_vector.hh:783
blender::compositor::Context
Definition
COM_context.hh:44
blender::compositor::Context::evaluate_operation_post
virtual void evaluate_operation_post() const
Definition
compositor/intern/context.cc:65
blender::compositor::ConversionOperation::construct_if_needed
static SimpleOperation * construct_if_needed(Context &context, const Result &input_result, const InputDescriptor &input_descriptor)
Definition
conversion_operation.cc:119
blender::compositor::Domain
Definition
COM_domain.hh:145
blender::compositor::Domain::identity
static Domain identity()
Definition
domain.cc:36
blender::compositor::InputDescriptor
Definition
COM_input_descriptor.hh:44
blender::compositor::Operation::get_result
Result & get_result(StringRef identifier)
Definition
operation.cc:39
blender::compositor::Operation::~Operation
virtual ~Operation()
blender::compositor::Operation::populate_result
void populate_result(StringRef identifier, Result result)
Definition
operation.cc:148
blender::compositor::Operation::Operation
Operation(Context &context)
Definition
operation.cc:22
blender::compositor::Operation::free_results
void free_results()
Definition
operation.cc:49
blender::compositor::Operation::compute_preview
virtual void compute_preview()
Definition
operation.cc:136
blender::compositor::Operation::add_and_evaluate_input_processor
void add_and_evaluate_input_processor(StringRef identifier, SimpleOperation *processor)
Definition
operation.cc:111
blender::compositor::Operation::execute
virtual void execute()=0
blender::compositor::Operation::context
Context & context() const
Definition
operation.cc:163
blender::compositor::Operation::switch_result_mapped_to_input
void switch_result_mapped_to_input(StringRef identifier, Result *result)
Definition
operation.cc:143
blender::compositor::Operation::evaluate
virtual void evaluate()
Definition
operation.cc:26
blender::compositor::Operation::get_input
Result & get_input(StringRef identifier) const
Definition
operation.cc:138
blender::compositor::Operation::map_input_to_result
void map_input_to_result(StringRef identifier, Result *result)
Definition
operation.cc:44
blender::compositor::Operation::compute_domain
virtual Domain compute_domain()
Definition
operation.cc:56
blender::compositor::Operation::get_input_descriptor
InputDescriptor & get_input_descriptor(StringRef identifier)
Definition
operation.cc:158
blender::compositor::Operation::add_and_evaluate_input_processors
virtual void add_and_evaluate_input_processors()
Definition
operation.cc:90
blender::compositor::Operation::declare_input_descriptor
void declare_input_descriptor(StringRef identifier, InputDescriptor descriptor)
Definition
operation.cc:153
blender::compositor::RealizeOnDomainOperation::construct_if_needed
static SimpleOperation * construct_if_needed(Context &context, const Result &input_result, const InputDescriptor &input_descriptor, const Domain &operation_domain)
Definition
realize_on_domain_operation.cc:279
blender::compositor::Result
Definition
COM_result.hh:100
blender::compositor::SimpleOperation
Definition
COM_simple_operation.hh:21
blender::compositor::SimpleOperation::map_input_to_result
void map_input_to_result(Result *result)
Definition
simple_operation.cc:20
blender::compositor::SimpleOperation::get_result
Result & get_result()
Definition
simple_operation.cc:15
descriptor
descriptor
Definition
logImageCore.h:141
blender::compositor
Definition
BKE_node.hh:77
blender::compositor::InputRealizationMode::OperationDomain
@ OperationDomain
Definition
COM_input_descriptor.hh:25
blender::compositor::ProcessorsVector
Vector< std::unique_ptr< SimpleOperation > > ProcessorsVector
Definition
COM_operation.hh:25
Generated on
for Blender by
doxygen
1.16.1