Blender V4.3
COM_PlaneCornerPinOperation.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2014 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
7
8namespace blender::compositor {
9
10constexpr int LOWER_LEFT_CORNER_INDEX = 0;
11constexpr int LOWER_RIGHT_CORNER_INDEX = 1;
12constexpr int UPPER_RIGHT_CORNER_INDEX = 2;
13constexpr int UPPER_LEFT_CORNER_INDEX = 3;
14
15static bool check_corners(float corners[4][2])
16{
17 int i, next, prev;
18 float cross = 0.0f;
19
20 for (i = 0; i < 4; i++) {
21 float v1[2], v2[2], cur_cross;
22
23 next = (i + 1) % 4;
24 prev = (4 + i - 1) % 4;
25
26 sub_v2_v2v2(v1, corners[i], corners[prev]);
27 sub_v2_v2v2(v2, corners[next], corners[i]);
28
29 cur_cross = cross_v2v2(v1, v2);
30 if (fabsf(cur_cross) <= FLT_EPSILON) {
31 return false;
32 }
33
34 if (cross == 0.0f) {
35 cross = cur_cross;
36 }
37 else if (cross * cur_cross < 0.0f) {
38 return false;
39 }
40 }
41
42 return true;
43}
44
45static void set_default_corner(const int corner_idx, float r_corner[2])
46{
47 BLI_assert(corner_idx >= 0 && corner_idx < 4);
48 switch (corner_idx) {
50 r_corner[0] = 0.0f;
51 r_corner[1] = 0.0f;
52 break;
54 r_corner[0] = 1.0f;
55 r_corner[1] = 0.0f;
56 break;
58 r_corner[0] = 1.0f;
59 r_corner[1] = 1.0f;
60 break;
62 r_corner[0] = 0.0f;
63 r_corner[1] = 1.0f;
64 break;
65 }
66}
67
68static void read_input_corners(NodeOperation *op, const int first_input_idx, float r_corners[4][2])
69{
70 for (const int i : IndexRange(4)) {
71 NodeOperation *input = op->get_input_operation(i + first_input_idx);
72 if (input->get_flags().is_constant_operation) {
73 ConstantOperation *corner_input = static_cast<ConstantOperation *>(input);
74 copy_v2_v2(r_corners[i], corner_input->get_constant_elem());
75 }
76 else {
77 set_default_corner(i, r_corners[i]);
78 }
79 }
80
81 /* Convexity check: concave corners need to be prevented, otherwise
82 * #BKE_tracking_homography_between_two_quads will freeze. */
83 if (!check_corners(r_corners)) {
84 /* Revert to default corners. There could be a more elegant solution,
85 * this prevents freezing at least. */
86 for (const int i : IndexRange(4)) {
87 set_default_corner(i, r_corners[i]);
88 }
89 }
90}
91
92/* ******** PlaneCornerPinMaskOperation ******** */
93
101
103{
104 float corners[4][2];
105 read_input_corners(this, 0, corners);
106 calculate_corners(corners, true, 0);
107}
108
109void PlaneCornerPinMaskOperation::determine_canvas(const rcti &preferred_area, rcti &r_area)
110{
111 /* Determine input canvases. */
112 PlaneDistortMaskOperation::determine_canvas(preferred_area, r_area);
113 r_area = preferred_area;
114}
115
117 const rcti & /*output_area*/,
118 rcti &r_input_area)
119{
120 /* All corner inputs are used as constants. */
122}
123
124/* ******** PlaneCornerPinWarpImageOperation ******** */
125
133
135{
136 float corners[4][2];
137 read_input_corners(this, 1, corners);
138 calculate_corners(corners, true, 0);
139}
140
142 const rcti &output_area,
143 rcti &r_input_area)
144{
145 if (input_idx == 0) {
146 PlaneDistortWarpImageOperation::get_area_of_interest(input_idx, output_area, r_input_area);
147 }
148 else {
149 /* Corner inputs are used as constants. */
151 }
152}
153
154} // namespace blender::compositor
#define BLI_assert(a)
Definition BLI_assert.h:50
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE float cross_v2v2(const float a[2], const float b[2]) ATTR_WARN_UNUSED_RESULT
MINLINE void sub_v2_v2v2(float r[2], const float a[2], const float b[2])
ATTR_WARN_UNUSED_RESULT const BMVert * v2
virtual const float * get_constant_elem()=0
NodeOperation contains calculation logic.
NodeOperation * get_input_operation(int index)
void add_input_socket(DataType datatype, ResizeMode resize_mode=ResizeMode::Center)
virtual void determine_canvas(const rcti &preferred_area, rcti &r_area)
void get_area_of_interest(int input_idx, const rcti &output_area, rcti &r_input_area) override
Get input operation area being read by this operation on rendering given output area.
void determine_canvas(const rcti &preferred_area, rcti &r_area) override
void get_area_of_interest(int input_idx, const rcti &output_area, rcti &r_input_area) override
Get input operation area being read by this operation on rendering given output area.
virtual void calculate_corners(const float corners[4][2], bool normalized, int sample)
void calculate_corners(const float corners[4][2], bool normalized, int sample) override
void get_area_of_interest(int input_idx, const rcti &output_area, rcti &r_input_area) override
Get input operation area being read by this operation on rendering given output area.
#define fabsf(x)
@ Vector
Vector data type.
ccl_device_inline float cross(const float2 a, const float2 b)
static ulong * next
constexpr rcti COM_CONSTANT_INPUT_AREA_OF_INTEREST
Definition COM_defines.h:90
static void read_input_corners(NodeOperation *op, const int first_input_idx, float r_corners[4][2])
static bool check_corners(float corners[4][2])
static void set_default_corner(const int corner_idx, float r_corner[2])