Blender  V2.93
COM_PlaneCornerPinOperation.cc
Go to the documentation of this file.
1 /* This program is free software; you can redistribute it and/or
2  * modify it under the terms of the GNU General Public License
3  * as published by the Free Software Foundation; either version 2
4  * of the License, or (at your option) any later version.
5  *
6  * This program is distributed in the hope that it will be useful,
7  * but WITHOUT ANY WARRANTY; without even the implied warranty of
8  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9  * GNU General Public License for more details.
10  *
11  * You should have received a copy of the GNU General Public License
12  * along with this program; if not, write to the Free Software Foundation,
13  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
14  *
15  * Copyright 2014, Blender Foundation.
16  */
17 
20 
21 #include "MEM_guardedalloc.h"
22 
23 #include "BLI_listbase.h"
24 #include "BLI_math.h"
25 #include "BLI_math_color.h"
26 
27 #include "BKE_node.h"
28 
29 namespace blender::compositor {
30 
31 static bool check_corners(float corners[4][2])
32 {
33  int i, next, prev;
34  float cross = 0.0f;
35 
36  for (i = 0; i < 4; i++) {
37  float v1[2], v2[2], cur_cross;
38 
39  next = (i + 1) % 4;
40  prev = (4 + i - 1) % 4;
41 
42  sub_v2_v2v2(v1, corners[i], corners[prev]);
43  sub_v2_v2v2(v2, corners[next], corners[i]);
44 
45  cur_cross = cross_v2v2(v1, v2);
46  if (fabsf(cur_cross) <= FLT_EPSILON) {
47  return false;
48  }
49 
50  if (cross == 0.0f) {
51  cross = cur_cross;
52  }
53  else if (cross * cur_cross < 0.0f) {
54  return false;
55  }
56  }
57 
58  return true;
59 }
60 
61 static void readCornersFromSockets(rcti *rect, SocketReader *readers[4], float corners[4][2])
62 {
63  for (int i = 0; i < 4; i++) {
64  float result[4] = {0.0f, 0.0f, 0.0f, 0.0f};
65  readers[i]->readSampled(result, rect->xmin, rect->ymin, PixelSampler::Nearest);
66  corners[i][0] = result[0];
67  corners[i][1] = result[1];
68  }
69 
70  /* convexity check:
71  * concave corners need to be prevented, otherwise
72  * BKE_tracking_homography_between_two_quads will freeze
73  */
74  if (!check_corners(corners)) {
75  /* simply revert to default corners
76  * there could be a more elegant solution,
77  * this prevents freezing at least.
78  */
79  corners[0][0] = 0.0f;
80  corners[0][1] = 0.0f;
81  corners[1][0] = 1.0f;
82  corners[1][1] = 0.0f;
83  corners[2][0] = 1.0f;
84  corners[2][1] = 1.0f;
85  corners[3][0] = 0.0f;
86  corners[3][1] = 1.0f;
87  }
88 }
89 
90 /* ******** PlaneCornerPinMaskOperation ******** */
91 
93 {
98 
99  /* XXX this is stupid: we need to make this "complex",
100  * so we can use the initializeTileData function
101  * to read corners from input sockets ...
102  */
103  flags.complex = true;
104 }
105 
107 {
109 
110  initMutex();
111 }
112 
114 {
116 
117  deinitMutex();
118 }
119 
121 {
123 
124  /* get corner values once, by reading inputs at (0,0)
125  * XXX this assumes invariable values (no image inputs),
126  * we don't have a nice generic system for that yet
127  */
128  lockMutex();
129  if (!m_corners_ready) {
130  SocketReader *readers[4] = {
135  };
136  float corners[4][2];
137  readCornersFromSockets(rect, readers, corners);
138  calculateCorners(corners, true, 0);
139 
140  m_corners_ready = true;
141  }
142  unlockMutex();
143 
144  return data;
145 }
146 
147 void PlaneCornerPinMaskOperation::determineResolution(unsigned int resolution[2],
148  unsigned int preferredResolution[2])
149 {
150  resolution[0] = preferredResolution[0];
151  resolution[1] = preferredResolution[1];
152 }
153 
154 /* ******** PlaneCornerPinWarpImageOperation ******** */
155 
157 {
162 }
163 
165 {
167 
168  initMutex();
169 }
170 
172 {
174 
175  deinitMutex();
176 }
177 
179 {
181 
182  /* get corner values once, by reading inputs at (0,0)
183  * XXX this assumes invariable values (no image inputs),
184  * we don't have a nice generic system for that yet
185  */
186  lockMutex();
187  if (!m_corners_ready) {
188  /* corner sockets start at index 1 */
189  SocketReader *readers[4] = {
194  };
195  float corners[4][2];
196  readCornersFromSockets(rect, readers, corners);
197  calculateCorners(corners, true, 0);
198 
199  m_corners_ready = true;
200  }
201  unlockMutex();
202 
203  return data;
204 }
205 
207  rcti *input, ReadBufferOperation *readOperation, rcti *output)
208 {
209  for (int i = 0; i < 4; i++) {
210  if (getInputOperation(i + 1)->determineDependingAreaOfInterest(input, readOperation, output)) {
211  return true;
212  }
213  }
214 
215  /* XXX this is bad, but unavoidable with the current design:
216  * we don't know the actual corners and matrix at this point,
217  * so all we can do is get the full input image
218  */
219  output->xmin = 0;
220  output->ymin = 0;
221  output->xmax = getInputOperation(0)->getWidth();
222  output->ymax = getInputOperation(0)->getHeight();
223  return true;
224 #if 0
226  input, readOperation, output);
227 #endif
228 }
229 
230 } // namespace blender::compositor
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])
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble v1
Read Guarded memory(de)allocation.
ATTR_WARN_UNUSED_RESULT const BMVert * v2
#define output
NodeOperation contains calculation logic.
virtual void * initializeTileData(rcti *)
void readSampled(float result[4], float x, float y, PixelSampler sampler)
void addInputSocket(DataType datatype, ResizeMode resize_mode=ResizeMode::Center)
NodeOperation * getInputOperation(unsigned int inputSocketindex)
SocketReader * getInputSocketReader(unsigned int inputSocketindex)
void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]) override
determine the resolution of this node
bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) override
void calculateCorners(const float corners[4][2], bool normalized, int sample)
bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) override
void calculateCorners(const float corners[4][2], bool normalized, int sample)
@ Vector
Vector data type.
#define fabsf(x)
static ulong * next
static void readCornersFromSockets(rcti *rect, SocketReader *readers[4], float corners[4][2])
static bool check_corners(float corners[4][2])
int ymin
Definition: DNA_vec_types.h:80
int xmin
Definition: DNA_vec_types.h:79
__forceinline avxf cross(const avxf &a, const avxf &b)
Definition: util_avxf.h:119