Blender V4.3
COM_MaskOperation.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2012 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include "COM_MaskOperation.h"
6
7#include "BKE_lib_id.hh"
8#include "BKE_mask.h"
9
10namespace blender::compositor {
11
25
27{
28 if (mask_ && raster_mask_handles_[0] == nullptr) {
29 if (raster_mask_handle_tot_ == 1) {
31
34 }
35 else {
36 /* make a throw away copy of the mask */
37 const float frame = float(frame_number_) - frame_shutter_;
38 const float frame_step = (frame_shutter_ * 2.0f) / raster_mask_handle_tot_;
39 float frame_iter = frame;
40
41 Mask *mask_temp = (Mask *)BKE_id_copy_ex(
43
44 /* trick so we can get unkeyed edits to display */
45 {
46 LISTBASE_FOREACH (MaskLayer *, masklay, &mask_temp->masklayers) {
49 BKE_mask_layer_shape_from_mask(masklay, masklay_shape);
50 }
51 }
52
53 for (uint i = 0; i < raster_mask_handle_tot_; i++) {
55
56 /* re-eval frame info */
57 BKE_mask_evaluate(mask_temp, frame_iter, true);
58
60 mask_temp,
63 true,
64 true,
66
67 frame_iter += frame_step;
68 }
69
70 BKE_id_free(nullptr, &mask_temp->id);
71 }
72 }
73}
74
84
85void MaskOperation::determine_canvas(const rcti &preferred_area, rcti &r_area)
86{
87 if (!mask_ || mask_width_ == 0 || mask_height_ == 0) {
88 r_area = COM_AREA_NONE;
89 }
90 else {
91 r_area = preferred_area;
92 r_area.xmax = r_area.xmin + mask_width_;
93 r_area.ymax = r_area.ymin + mask_height_;
94 }
95}
96
98 const rcti &area,
99 Span<MemoryBuffer *> /*inputs*/)
100{
101 Vector<MaskRasterHandle *> handles = get_non_null_handles();
102 if (handles.is_empty()) {
103 output->fill(area, COM_VALUE_ZERO);
104 return;
105 }
106
107 float xy[2];
108 for (BuffersIterator<float> it = output->iterate_with({}, area); !it.is_end(); ++it) {
109 xy[0] = it.x * mask_width_inv_ + mask_px_ofs_[0];
110 xy[1] = it.y * mask_height_inv_ + mask_px_ofs_[1];
111 *it.out = 0.0f;
112 for (MaskRasterHandle *handle : handles) {
113 *it.out += BKE_maskrasterize_handle_sample(handle, xy);
114 }
115
116 /* Until we get better falloff. */
117 *it.out /= raster_mask_handle_tot_;
118 }
119}
120
121Vector<MaskRasterHandle *> MaskOperation::get_non_null_handles() const
122{
124 for (int i = 0; i < raster_mask_handle_tot_; i++) {
126 if (handle == nullptr) {
127 continue;
128 }
129 handles.append(handle);
130 }
131 return handles;
132}
133
134} // namespace blender::compositor
@ LIB_ID_COPY_LOCALIZE
@ LIB_ID_COPY_NO_ANIMDATA
void BKE_id_free(Main *bmain, void *idv)
ID * BKE_id_copy_ex(Main *bmain, const ID *id, ID **new_id_p, int flag)
Definition lib_id.cc:760
void BKE_maskrasterize_handle_free(MaskRasterHandle *mr_handle)
float BKE_maskrasterize_handle_sample(MaskRasterHandle *mr_handle, const float xy[2])
MaskRasterHandle * BKE_maskrasterize_handle_new(void)
void BKE_mask_evaluate(struct Mask *mask, float ctime, bool do_newframe)
void BKE_mask_layer_shape_from_mask(struct MaskLayer *masklay, struct MaskLayerShape *masklay_shape)
void BKE_maskrasterize_handle_init(MaskRasterHandle *mr_handle, struct Mask *mask, int width, int height, bool do_aspect_correct, bool do_mask_aa, bool do_feather)
struct MaskLayerShape * BKE_mask_layer_shape_verify_frame(struct MaskLayer *masklay, int frame)
#define LISTBASE_FOREACH(type, var, list)
unsigned int uint
struct MaskRasterHandle * raster_mask_handles_[CMP_NODE_MASK_MBLUR_SAMPLES_MAX]
void update_memory_buffer_partial(MemoryBuffer *output, const rcti &area, Span< MemoryBuffer * > inputs) override
void determine_canvas(const rcti &preferred_area, rcti &r_area) override
a MemoryBuffer contains access to the data
void add_output_socket(DataType datatype)
draw_view in_light_buf[] float
constexpr float COM_VALUE_ZERO[1]
Definition COM_defines.h:64
constexpr rcti COM_AREA_NONE
Definition COM_defines.h:89
typename BuffersIteratorBuilder< T >::Iterator BuffersIterator
ListBase masklayers
int ymin
int ymax
int xmin
int xmax
ParamHandle ** handles
int xy[2]
Definition wm_draw.cc:170