Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/compositor/operations')
-rw-r--r--source/blender/compositor/operations/COM_BokehImageOperation.h2
-rw-r--r--source/blender/compositor/operations/COM_DilateErodeOperation.cpp12
-rw-r--r--source/blender/compositor/operations/COM_DirectionalBlurOperation.cpp4
-rw-r--r--source/blender/compositor/operations/COM_MathBaseOperation.cpp9
-rw-r--r--source/blender/compositor/operations/COM_MathBaseOperation.h4
-rw-r--r--source/blender/compositor/operations/COM_SocketProxyOperation.cpp4
-rw-r--r--source/blender/compositor/operations/COM_SocketProxyOperation.h9
-rw-r--r--source/blender/compositor/operations/COM_SunBeamsOperation.cpp308
-rw-r--r--source/blender/compositor/operations/COM_SunBeamsOperation.h48
9 files changed, 382 insertions, 18 deletions
diff --git a/source/blender/compositor/operations/COM_BokehImageOperation.h b/source/blender/compositor/operations/COM_BokehImageOperation.h
index f1f0f1ed11c..3cf9afda32a 100644
--- a/source/blender/compositor/operations/COM_BokehImageOperation.h
+++ b/source/blender/compositor/operations/COM_BokehImageOperation.h
@@ -88,7 +88,7 @@ private:
bool m_deleteData;
/**
- * @brief detemine the coordinate of a flap cornder
+ * @brief determine the coordinate of a flap cornder
*
* @param r result in bokehimage space are stored [x,y]
* @param flapNumber the flap number to calculate
diff --git a/source/blender/compositor/operations/COM_DilateErodeOperation.cpp b/source/blender/compositor/operations/COM_DilateErodeOperation.cpp
index b54e47c136d..cbf4ce693d9 100644
--- a/source/blender/compositor/operations/COM_DilateErodeOperation.cpp
+++ b/source/blender/compositor/operations/COM_DilateErodeOperation.cpp
@@ -371,7 +371,7 @@ void *DilateStepOperation::initializeTileData(rcti *rect)
float *rectf = result->buffer;
// temp holds maxima for every step in the algorithm, buf holds a
- // single row or column of input values, padded with MAXFLOATs to
+ // single row or column of input values, padded with FLT_MAX's to
// simplify the logic.
float *temp = (float *)MEM_mallocN(sizeof(float) * (2 * window - 1), "dilate erode temp");
float *buf = (float *)MEM_mallocN(sizeof(float) * (max(bwidth, bheight) + 5 * half_window), "dilate erode buf");
@@ -380,7 +380,7 @@ void *DilateStepOperation::initializeTileData(rcti *rect)
// first pass, horizontal dilate/erode
for (y = ymin; y < ymax; y++) {
for (x = 0; x < bwidth + 5 * half_window; x++) {
- buf[x] = -MAXFLOAT;
+ buf[x] = -FLT_MAX;
}
for (x = xmin; x < xmax; ++x) {
buf[x - rect->xmin + window - 1] = buffer[4 * (y * width + x)];
@@ -405,7 +405,7 @@ void *DilateStepOperation::initializeTileData(rcti *rect)
// second pass, vertical dilate/erode
for (x = 0; x < bwidth; x++) {
for (y = 0; y < bheight + 5 * half_window; y++) {
- buf[y] = -MAXFLOAT;
+ buf[y] = -FLT_MAX;
}
for (y = ymin; y < ymax; y++) {
buf[y - rect->ymin + window - 1] = rectf[(y - ymin) * bwidth + x];
@@ -498,7 +498,7 @@ void *ErodeStepOperation::initializeTileData(rcti *rect)
float *rectf = result->buffer;
// temp holds maxima for every step in the algorithm, buf holds a
- // single row or column of input values, padded with MAXFLOATs to
+ // single row or column of input values, padded with FLT_MAX's to
// simplify the logic.
float *temp = (float *)MEM_mallocN(sizeof(float) * (2 * window - 1), "dilate erode temp");
float *buf = (float *)MEM_mallocN(sizeof(float) * (max(bwidth, bheight) + 5 * half_window), "dilate erode buf");
@@ -507,7 +507,7 @@ void *ErodeStepOperation::initializeTileData(rcti *rect)
// first pass, horizontal dilate/erode
for (y = ymin; y < ymax; y++) {
for (x = 0; x < bwidth + 5 * half_window; x++) {
- buf[x] = MAXFLOAT;
+ buf[x] = FLT_MAX;
}
for (x = xmin; x < xmax; ++x) {
buf[x - rect->xmin + window - 1] = buffer[4 * (y * width + x)];
@@ -532,7 +532,7 @@ void *ErodeStepOperation::initializeTileData(rcti *rect)
// second pass, vertical dilate/erode
for (x = 0; x < bwidth; x++) {
for (y = 0; y < bheight + 5 * half_window; y++) {
- buf[y] = MAXFLOAT;
+ buf[y] = FLT_MAX;
}
for (y = ymin; y < ymax; y++) {
buf[y - rect->ymin + window - 1] = rectf[(y - ymin) * bwidth + x];
diff --git a/source/blender/compositor/operations/COM_DirectionalBlurOperation.cpp b/source/blender/compositor/operations/COM_DirectionalBlurOperation.cpp
index 0cea2a7183f..67f52934b13 100644
--- a/source/blender/compositor/operations/COM_DirectionalBlurOperation.cpp
+++ b/source/blender/compositor/operations/COM_DirectionalBlurOperation.cpp
@@ -109,8 +109,8 @@ void DirectionalBlurOperation::executeOpenCL(OpenCLDevice *device,
cl_kernel directionalBlurKernel = device->COM_clCreateKernel("directionalBlurKernel", NULL);
cl_int iterations = pow(2.0f, this->m_data->iter);
- cl_float2 ltxy = {this->m_tx, this->m_ty};
- cl_float2 centerpix = {this->m_center_x_pix, this->m_center_y_pix};
+ cl_float2 ltxy = {{this->m_tx, this->m_ty}};
+ cl_float2 centerpix = {{this->m_center_x_pix, this->m_center_y_pix}};
cl_float lsc = this->m_sc;
cl_float lrot = this->m_rot;
diff --git a/source/blender/compositor/operations/COM_MathBaseOperation.cpp b/source/blender/compositor/operations/COM_MathBaseOperation.cpp
index cbc60b5091d..32a1e77b9a7 100644
--- a/source/blender/compositor/operations/COM_MathBaseOperation.cpp
+++ b/source/blender/compositor/operations/COM_MathBaseOperation.cpp
@@ -335,12 +335,11 @@ void MathModuloOperation::executePixelSampled(float output[4], float x, float y,
void MathAbsoluteOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
{
- float inputValue1[4];
+ float inputValue1[4];
- this->m_inputValue1Operation->readSampled(inputValue1, x, y, sampler);
+ this->m_inputValue1Operation->readSampled(inputValue1, x, y, sampler);
- output[0] = fabs(inputValue1[0]);
+ output[0] = fabs(inputValue1[0]);
- clampIfNeeded(output);
+ clampIfNeeded(output);
}
-
diff --git a/source/blender/compositor/operations/COM_MathBaseOperation.h b/source/blender/compositor/operations/COM_MathBaseOperation.h
index 05d2bb054d3..32cd19f1fb9 100644
--- a/source/blender/compositor/operations/COM_MathBaseOperation.h
+++ b/source/blender/compositor/operations/COM_MathBaseOperation.h
@@ -165,8 +165,8 @@ public:
class MathAbsoluteOperation : public MathBaseOperation {
public:
- MathAbsoluteOperation() : MathBaseOperation() {}
- void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
+ MathAbsoluteOperation() : MathBaseOperation() {}
+ void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
};
#endif
diff --git a/source/blender/compositor/operations/COM_SocketProxyOperation.cpp b/source/blender/compositor/operations/COM_SocketProxyOperation.cpp
index da345b282fd..21d2f28332e 100644
--- a/source/blender/compositor/operations/COM_SocketProxyOperation.cpp
+++ b/source/blender/compositor/operations/COM_SocketProxyOperation.cpp
@@ -22,7 +22,9 @@
#include "COM_SocketProxyOperation.h"
-SocketProxyOperation::SocketProxyOperation(DataType type) : NodeOperation()
+SocketProxyOperation::SocketProxyOperation(DataType type, bool use_conversion) :
+ NodeOperation(),
+ m_use_conversion(use_conversion)
{
this->addInputSocket(type);
this->addOutputSocket(type);
diff --git a/source/blender/compositor/operations/COM_SocketProxyOperation.h b/source/blender/compositor/operations/COM_SocketProxyOperation.h
index 9733a1fbeec..c9d6cb6ef9e 100644
--- a/source/blender/compositor/operations/COM_SocketProxyOperation.h
+++ b/source/blender/compositor/operations/COM_SocketProxyOperation.h
@@ -27,9 +27,16 @@
class SocketProxyOperation : public NodeOperation {
public:
- SocketProxyOperation(DataType type);
+ SocketProxyOperation(DataType type, bool use_conversion);
bool isProxyOperation() const { return true; }
+ bool useDatatypeConversion() const { return m_use_conversion; }
+
+ bool getUseConversion() const { return m_use_conversion; }
+ void setUseConversion(bool use_conversion) { m_use_conversion = use_conversion; }
+
+private:
+ bool m_use_conversion;
};
#endif
diff --git a/source/blender/compositor/operations/COM_SunBeamsOperation.cpp b/source/blender/compositor/operations/COM_SunBeamsOperation.cpp
new file mode 100644
index 00000000000..9a34dccacb1
--- /dev/null
+++ b/source/blender/compositor/operations/COM_SunBeamsOperation.cpp
@@ -0,0 +1,308 @@
+/*
+ * Copyright 2014, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor:
+ * Lukas Toenne
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "COM_SunBeamsOperation.h"
+
+SunBeamsOperation::SunBeamsOperation() : NodeOperation()
+{
+ this->addInputSocket(COM_DT_COLOR);
+ this->addOutputSocket(COM_DT_COLOR);
+ this->setResolutionInputSocketIndex(0);
+
+ this->setComplex(true);
+}
+
+void SunBeamsOperation::initExecution()
+{
+ /* convert to pixels */
+ this->m_source_px[0] = this->m_data.source[0] * this->getWidth();
+ this->m_source_px[1] = this->m_data.source[1] * this->getHeight();
+ this->m_ray_length_px = this->m_data.ray_length * max(this->getWidth(), this->getHeight());
+}
+
+/**
+ * Defines a line accumulator for a specific sector,
+ * given by the four matrix entries that rotate from buffer space into the sector
+ *
+ * (x,y) is used to designate buffer space coordinates
+ * (u,v) is used to designate sector space coordinates
+ *
+ * For a target point (x,y) the sector should be chosen such that
+ * ``u >= v >= 0``
+ * This removes the need to handle all sorts of special cases.
+ */
+template <int fxx, int fxy, int fyx, int fyy>
+struct BufferLineAccumulator {
+
+ /* utility functions implementing the matrix transform to/from sector space */
+
+ static inline void buffer_to_sector(int x, int y, int &u, int &v)
+ {
+ u = x * fxx + y * fyx;
+ v = x * fxy + y * fyy;
+ }
+
+ static inline void buffer_to_sector(float x, float y, float &u, float &v)
+ {
+ u = x * fxx + y * fyx;
+ v = x * fxy + y * fyy;
+ }
+
+ static inline void sector_to_buffer(int u, int v, int &x, int &y)
+ {
+ x = u * fxx + v * fxy;
+ y = u * fyx + v * fyy;
+ }
+
+ static inline void sector_to_buffer(float u, float v, float &x, float &y)
+ {
+ x = u * fxx + v * fxy;
+ y = u * fyx + v * fyy;
+ }
+
+ /**
+ * Set up the initial buffer pointer and calculate necessary variables for looping.
+ *
+ * Note that sector space is centered around the "source" point while the loop starts
+ * at dist_min from the target pt. This way the loop can be canceled as soon as it runs
+ * out of the buffer rect, because no pixels further along the line can contribute.
+ *
+ * \param x, y Start location in the buffer
+ * \param num Total steps in the loop
+ * \param v, dv Vertical offset in sector space, for line offset perpendicular to the loop axis
+ */
+ static float *init_buffer_iterator(MemoryBuffer *input, const float source[2], const float pt_ofs[2],
+ float dist_min, float dist_max,
+ int &x, int &y, int &num, float &v, float &dv, float &falloff_factor)
+ {
+ float pu, pv;
+ buffer_to_sector(pt_ofs[0], pt_ofs[1], pu, pv);
+
+ /* line angle */
+ float tan_phi = pv / pu;
+ float dr = sqrtf(tan_phi * tan_phi + 1.0f);
+ float cos_phi = 1.0f / dr;
+
+ /* clamp u range to avoid influence of pixels "behind" the source */
+ float umin = max_ff(pu - cos_phi * dist_min, 0.0f);
+ float umax = max_ff(pu - cos_phi * dist_max, 0.0f);
+ v = umin * tan_phi;
+ dv = tan_phi;
+
+ int start = (int)floorf(umax);
+ int end = (int)ceilf(umin);
+ num = end - start;
+
+ sector_to_buffer(end, (int)ceilf(v), x, y);
+ x += (int)source[0];
+ y += (int)source[1];
+
+ falloff_factor = dist_max > dist_min ? dr / (float)(dist_max - dist_min) : 0.0f;
+
+ float *iter = input->getBuffer() + COM_NUMBER_OF_CHANNELS * (x + input->getWidth() * y);
+ return iter;
+ }
+
+ /**
+ * Perform the actual accumulation along a ray segment from source to pt.
+ * Only pixels withing dist_min..dist_max contribute.
+ *
+ * The loop runs backwards(!) over the primary sector space axis u, i.e. increasing distance to pt.
+ * After each step it decrements v by dv < 1, adding a buffer shift when necessary.
+ */
+ static void eval(MemoryBuffer *input, float output[4], const float pt_ofs[2], const float source[2],
+ float dist_min, float dist_max)
+ {
+ rcti rect = *input->getRect();
+ int buffer_width = input->getWidth();
+ int x, y, num;
+ float v, dv;
+ float falloff_factor;
+
+ /* initialise the iteration variables */
+ float *buffer = init_buffer_iterator(input, source, pt_ofs, dist_min, dist_max, x, y, num, v, dv, falloff_factor);
+
+ int tot = 0;
+
+ /* v_local keeps track of when to decrement v (see below) */
+ float v_local = v - floorf(v);
+
+ for (int i = 0; i < num; i++) {
+ /* range check, abort when running beyond the image border */
+ if (x < rect.xmin || x >= rect.xmax || y < rect.ymin || y >= rect.ymax)
+ break;
+
+ float f = 1.0f - (float)i * falloff_factor;
+ madd_v4_v4fl(output, buffer, buffer[3] * f * f);
+ /* TODO implement proper filtering here, see
+ * http://en.wikipedia.org/wiki/Lanczos_resampling
+ * http://en.wikipedia.org/wiki/Sinc_function
+ *
+ * using lanczos with x = distance from the line segment,
+ * normalized to a == 0.5f, could give a good result
+ *
+ * for now just count samples and divide equally at the end ...
+ */
+ tot++;
+
+ /* decrement u */
+ x -= fxx;
+ y -= fyx;
+ buffer -= (fxx + fyx * buffer_width) * COM_NUMBER_OF_CHANNELS;
+
+ /* decrement v (in steps of dv < 1) */
+ v_local -= dv;
+ if (v_local < 0.0f) {
+ v_local += 1.0f;
+
+ x -= fxy;
+ y -= fyy;
+ buffer -= (fxy + fyy * buffer_width) * COM_NUMBER_OF_CHANNELS;
+ }
+ }
+
+ /* normalize */
+ if (num > 0) {
+ mul_v4_fl(output, 1.0f / (float)num);
+ }
+ }
+};
+
+/**
+ * Dispatch function which selects an appropriate accumulator based on the sector of the target point,
+ * relative to the source.
+ *
+ * The BufferLineAccumulator defines the actual loop over the buffer, with an efficient inner loop
+ * due to using compile time constants instead of a local matrix variable defining the sector space.
+ */
+static void accumulate_line(MemoryBuffer *input, float output[4], const float co[2], const float source[2],
+ float dist_min, float dist_max)
+{
+ /* coordinates relative to source */
+ float pt_ofs[2] = {co[0] - source[0], co[1] - source[1]};
+
+ /* The source sectors are defined like so:
+ *
+ * \ 3 | 2 /
+ * \ | /
+ * 4 \ | / 1
+ * \|/
+ * -----------
+ * /|\
+ * 5 / | \ 8
+ * / | \
+ * / 6 | 7 \
+ *
+ * The template arguments encode the transformation into "sector space",
+ * by means of rotation/mirroring matrix elements.
+ */
+
+ if (fabsf(pt_ofs[1]) > fabsf(pt_ofs[0])) {
+ if (pt_ofs[0] > 0.0f) {
+ if (pt_ofs[1] > 0.0f) {
+ /* 2 */
+ BufferLineAccumulator<0, 1, 1, 0>::eval(input, output, pt_ofs, source, dist_min, dist_max);
+ }
+ else {
+ /* 7 */
+ BufferLineAccumulator<0, 1, -1, 0>::eval(input, output, pt_ofs, source, dist_min, dist_max);
+ }
+ }
+ else {
+ if (pt_ofs[1] > 0.0f) {
+ /* 3 */
+ BufferLineAccumulator<0, -1, 1, 0>::eval(input, output, pt_ofs, source, dist_min, dist_max);
+ }
+ else {
+ /* 6 */
+ BufferLineAccumulator<0, -1, -1, 0>::eval(input, output, pt_ofs, source, dist_min, dist_max);
+ }
+ }
+ }
+ else {
+ if (pt_ofs[0] > 0.0f) {
+ if (pt_ofs[1] > 0.0f) {
+ /* 1 */
+ BufferLineAccumulator< 1, 0, 0, 1>::eval(input, output, pt_ofs, source, dist_min, dist_max);
+ }
+ else {
+ /* 8 */
+ BufferLineAccumulator< 1, 0, 0, -1>::eval(input, output, pt_ofs, source, dist_min, dist_max);
+ }
+ }
+ else {
+ if (pt_ofs[1] > 0.0f) {
+ /* 4 */
+ BufferLineAccumulator<-1, 0, 0, 1>::eval(input, output, pt_ofs, source, dist_min, dist_max);
+ }
+ else {
+ /* 5 */
+ BufferLineAccumulator<-1, 0, 0, -1>::eval(input, output, pt_ofs, source, dist_min, dist_max);
+ }
+ }
+ }
+}
+
+void *SunBeamsOperation::initializeTileData(rcti *rect)
+{
+ void *buffer = getInputOperation(0)->initializeTileData(NULL);
+ return buffer;
+}
+
+void SunBeamsOperation::executePixel(float output[4], int x, int y, void *data)
+{
+ const float co[2] = {(float)x, (float)y};
+
+ accumulate_line((MemoryBuffer *)data, output, co, this->m_source_px, 0.0f, this->m_ray_length_px);
+}
+
+static void calc_ray_shift(rcti *rect, float x, float y, const float source[2], float ray_length)
+{
+ float co[2] = {(float)x, (float)y};
+ float dir[2], dist;
+
+ /* move (x,y) vector toward the source by ray_length distance */
+ sub_v2_v2v2(dir, co, source);
+ dist = normalize_v2(dir);
+ mul_v2_fl(dir, min_ff(dist, ray_length));
+ sub_v2_v2(co, dir);
+
+ int ico[2] = {(int)co[0], (int)co[1]};
+ BLI_rcti_do_minmax_v(rect, ico);
+}
+
+bool SunBeamsOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output)
+{
+ /* Enlarges the rect by moving each corner toward the source.
+ * This is the maximum distance that pixels can influence each other
+ * and gives a rect that contains all possible accumulated pixels.
+ */
+ rcti rect = *input;
+ calc_ray_shift(&rect, input->xmin, input->ymin, this->m_source_px, this->m_ray_length_px);
+ calc_ray_shift(&rect, input->xmin, input->ymax, this->m_source_px, this->m_ray_length_px);
+ calc_ray_shift(&rect, input->xmax, input->ymin, this->m_source_px, this->m_ray_length_px);
+ calc_ray_shift(&rect, input->xmax, input->ymax, this->m_source_px, this->m_ray_length_px);
+
+ return NodeOperation::determineDependingAreaOfInterest(&rect, readOperation, output);
+}
+
diff --git a/source/blender/compositor/operations/COM_SunBeamsOperation.h b/source/blender/compositor/operations/COM_SunBeamsOperation.h
new file mode 100644
index 00000000000..ef80a31fe40
--- /dev/null
+++ b/source/blender/compositor/operations/COM_SunBeamsOperation.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2014, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor:
+ * Lukas Toenne
+ */
+
+#ifndef _COM_SunBeamsOperation_h
+#define _COM_SunBeamsOperation_h
+
+#include "COM_NodeOperation.h"
+
+class SunBeamsOperation : public NodeOperation {
+public:
+ SunBeamsOperation();
+
+ void executePixel(float output[4], int x, int y, void *data);
+
+ void initExecution();
+
+ void *initializeTileData(rcti *rect);
+
+ bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output);
+
+ void setData(const NodeSunBeams &data) { m_data = data; }
+
+private:
+ NodeSunBeams m_data;
+
+ float m_source_px[2];
+ float m_ray_length_px;
+};
+
+#endif