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:
-rw-r--r--source/blender/blenlib/BLI_math_base.h2
-rw-r--r--source/blender/blenlib/intern/math_base_inline.c7
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex.c69
-rw-r--r--source/blender/imbuf/intern/rectop.c33
4 files changed, 62 insertions, 49 deletions
diff --git a/source/blender/blenlib/BLI_math_base.h b/source/blender/blenlib/BLI_math_base.h
index 67c1ffcebc0..04cf0b9d275 100644
--- a/source/blender/blenlib/BLI_math_base.h
+++ b/source/blender/blenlib/BLI_math_base.h
@@ -213,6 +213,8 @@ MINLINE int is_power_of_2_i(int n);
MINLINE int power_of_2_max_i(int n);
MINLINE int power_of_2_min_i(int n);
+MINLINE int divide_round_i(int a, int b);
+
MINLINE float shell_angle_to_dist(const float angle);
#if (defined(WIN32) || defined(WIN64)) && !defined(FREE_WINDOWS)
diff --git a/source/blender/blenlib/intern/math_base_inline.c b/source/blender/blenlib/intern/math_base_inline.c
index d7c950f651a..61af5b5079a 100644
--- a/source/blender/blenlib/intern/math_base_inline.c
+++ b/source/blender/blenlib/intern/math_base_inline.c
@@ -145,6 +145,13 @@ MINLINE int power_of_2_min_i(int n)
return n;
}
+/* integer division that rounds 0.5 up, particularly useful for color blending
+ * with integers, to avoid gradual darkening when rounding down */
+MINLINE int divide_round_i(int a, int b)
+{
+ return (2*a + b)/(2*b);
+}
+
MINLINE unsigned int highest_order_bit_i(unsigned int n)
{
n |= (n >> 1);
diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c
index d0f1bb882a3..7cc224db085 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex.c
@@ -256,9 +256,9 @@ static void do_shared_vertex_tesscol(Mesh *me)
scol = scolmain;
while (a--) {
if (scol[0] > 1) {
- scol[1] /= scol[0];
- scol[2] /= scol[0];
- scol[3] /= scol[0];
+ scol[1] = divide_round_i(scol[1], scol[0]);
+ scol[2] = divide_round_i(scol[2], scol[0]);
+ scol[3] = divide_round_i(scol[3], scol[0]);
}
scol += 4;
}
@@ -287,7 +287,7 @@ static void do_shared_vertexcol(Mesh *me, int do_tessface)
{
const int use_face_sel = (me->editflag & ME_EDIT_PAINT_FACE_SEL);
MPoly *mp;
- float (*scol)[4];
+ int (*scol)[4];
int i, j, has_shared = 0;
/* if no mloopcol: do not do */
@@ -295,7 +295,7 @@ static void do_shared_vertexcol(Mesh *me, int do_tessface)
if (me->mloopcol == NULL || me->totvert == 0 || me->totpoly == 0) return;
- scol = MEM_callocN(sizeof(float) * me->totvert * 5, "scol");
+ scol = MEM_callocN(sizeof(int) * me->totvert * 5, "scol");
for (i = 0, mp = me->mpoly; i < me->totpoly; i++, mp++) {
if ((use_face_sel == FALSE) || (mp->flag & ME_FACE_SEL)) {
@@ -305,7 +305,7 @@ static void do_shared_vertexcol(Mesh *me, int do_tessface)
scol[ml->v][0] += lcol->r;
scol[ml->v][1] += lcol->g;
scol[ml->v][2] += lcol->b;
- scol[ml->v][3] += 1.0f;
+ scol[ml->v][3] += 1;
has_shared = 1;
}
}
@@ -313,8 +313,10 @@ static void do_shared_vertexcol(Mesh *me, int do_tessface)
if (has_shared) {
for (i = 0; i < me->totvert; i++) {
- if (scol[i][3] != 0.0f) {
- mul_v3_fl(scol[i], 1.0f / scol[i][3]);
+ if (scol[i][3] != 0) {
+ scol[i][0] = divide_round_i(scol[i][0], scol[i][3]);
+ scol[i][1] = divide_round_i(scol[i][1], scol[i][3]);
+ scol[i][2] = divide_round_i(scol[i][2], scol[i][3]);
}
}
@@ -613,9 +615,9 @@ BLI_INLINE unsigned int mcol_blend(unsigned int col1, unsigned int col2, int fac
cp2 = (unsigned char *)&col2;
cp = (unsigned char *)&col;
- cp[0] = (mfac * cp1[0] + fac * cp2[0]) / 255;
- cp[1] = (mfac * cp1[1] + fac * cp2[1]) / 255;
- cp[2] = (mfac * cp1[2] + fac * cp2[2]) / 255;
+ cp[0] = divide_round_i((mfac * cp1[0] + fac * cp2[0]), 255);
+ cp[1] = divide_round_i((mfac * cp1[1] + fac * cp2[1]), 255);
+ cp[2] = divide_round_i((mfac * cp1[2] + fac * cp2[2]), 255);
cp[3] = 255;
return col;
@@ -635,11 +637,11 @@ BLI_INLINE unsigned int mcol_add(unsigned int col1, unsigned int col2, int fac)
cp2 = (unsigned char *)&col2;
cp = (unsigned char *)&col;
- temp = cp1[0] + ((fac * cp2[0]) / 255);
+ temp = cp1[0] + divide_round_i((fac * cp2[0]), 255);
cp[0] = (temp > 254) ? 255 : temp;
- temp = cp1[1] + ((fac * cp2[1]) / 255);
+ temp = cp1[1] + divide_round_i((fac * cp2[1]), 255);
cp[1] = (temp > 254) ? 255 : temp;
- temp = cp1[2] + ((fac * cp2[2]) / 255);
+ temp = cp1[2] + divide_round_i((fac * cp2[2]), 255);
cp[2] = (temp > 254) ? 255 : temp;
cp[3] = 255;
@@ -660,11 +662,11 @@ BLI_INLINE unsigned int mcol_sub(unsigned int col1, unsigned int col2, int fac)
cp2 = (unsigned char *)&col2;
cp = (unsigned char *)&col;
- temp = cp1[0] - ((fac * cp2[0]) / 255);
+ temp = cp1[0] - divide_round_i((fac * cp2[0]), 255);
cp[0] = (temp < 0) ? 0 : temp;
- temp = cp1[1] - ((fac * cp2[1]) / 255);
+ temp = cp1[1] - divide_round_i((fac * cp2[1]), 255);
cp[1] = (temp < 0) ? 0 : temp;
- temp = cp1[2] - ((fac * cp2[2]) / 255);
+ temp = cp1[2] - divide_round_i((fac * cp2[2]), 255);
cp[2] = (temp < 0) ? 0 : temp;
cp[3] = 255;
@@ -688,9 +690,9 @@ BLI_INLINE unsigned int mcol_mul(unsigned int col1, unsigned int col2, int fac)
cp = (unsigned char *)&col;
/* first mul, then blend the fac */
- cp[0] = (mfac * cp1[0] + fac * ((cp2[0] * cp1[0]) / 255)) / 255;
- cp[1] = (mfac * cp1[1] + fac * ((cp2[1] * cp1[1]) / 255)) / 255;
- cp[2] = (mfac * cp1[2] + fac * ((cp2[2] * cp1[2]) / 255)) / 255;
+ cp[0] = divide_round_i(mfac * cp1[0] * 255 + fac * cp2[0] * cp1[0], 255*255);
+ cp[1] = divide_round_i(mfac * cp1[1] * 255 + fac * cp2[1] * cp1[1], 255*255);
+ cp[2] = divide_round_i(mfac * cp1[2] * 255 + fac * cp2[2] * cp1[2], 255*255);
cp[3] = 255;
return col;
@@ -721,9 +723,9 @@ BLI_INLINE unsigned int mcol_lighten(unsigned int col1, unsigned int col2, int f
return col1;
}
- cp[0] = (mfac * cp1[0] + fac * cp2[0]) / 255;
- cp[1] = (mfac * cp1[1] + fac * cp2[1]) / 255;
- cp[2] = (mfac * cp1[2] + fac * cp2[2]) / 255;
+ cp[0] = divide_round_i(mfac * cp1[0] + fac * cp2[0], 255);
+ cp[1] = divide_round_i(mfac * cp1[1] + fac * cp2[1], 255);
+ cp[2] = divide_round_i(mfac * cp1[2] + fac * cp2[2], 255);
cp[3] = 255;
return col;
@@ -754,9 +756,9 @@ BLI_INLINE unsigned int mcol_darken(unsigned int col1, unsigned int col2, int fa
return col1;
}
- cp[0] = (mfac * cp1[0] + fac * cp2[0]) / 255;
- cp[1] = (mfac * cp1[1] + fac * cp2[1]) / 255;
- cp[2] = (mfac * cp1[2] + fac * cp2[2]) / 255;
+ cp[0] = divide_round_i((mfac * cp1[0] + fac * cp2[0]), 255);
+ cp[1] = divide_round_i((mfac * cp1[1] + fac * cp2[1]), 255);
+ cp[2] = divide_round_i((mfac * cp1[2] + fac * cp2[2]), 255);
cp[3] = 255;
return col;
}
@@ -2790,6 +2792,7 @@ static void vpaint_paint_poly(VPaint *vp, VPaintData *vpd, Mesh *me,
unsigned int *lcolorig = ((unsigned int *)vp->vpaint_prev) + mpoly->loopstart;
float alpha;
int i, j;
+ int totloop = mpoly->totloop;
int brush_alpha_pressure_i = (int)(brush_alpha_pressure * 255.0f);
@@ -2798,7 +2801,7 @@ static void vpaint_paint_poly(VPaint *vp, VPaintData *vpd, Mesh *me,
unsigned int tcol;
char *col;
- for (j = 0; j < mpoly->totloop; j++) {
+ for (j = 0; j < totloop; j++) {
col = (char *)(lcol + j);
blend[0] += col[0];
blend[1] += col[1];
@@ -2806,10 +2809,10 @@ static void vpaint_paint_poly(VPaint *vp, VPaintData *vpd, Mesh *me,
blend[3] += col[3];
}
- blend[0] /= mpoly->totloop;
- blend[1] /= mpoly->totloop;
- blend[2] /= mpoly->totloop;
- blend[3] /= mpoly->totloop;
+ blend[0] = divide_round_i(blend[0], totloop);
+ blend[1] = divide_round_i(blend[1], totloop);
+ blend[2] = divide_round_i(blend[2], totloop);
+ blend[3] = divide_round_i(blend[3], totloop);
col = (char *)&tcol;
col[0] = blend[0];
col[1] = blend[1];
@@ -2820,7 +2823,7 @@ static void vpaint_paint_poly(VPaint *vp, VPaintData *vpd, Mesh *me,
}
ml = me->mloop + mpoly->loopstart;
- for (i = 0; i < mpoly->totloop; i++, ml++) {
+ for (i = 0; i < totloop; i++, ml++) {
float rgba[4];
unsigned int paintcol;
alpha = calc_vp_alpha_col_dl(vp, vc, vpd->vpimat,
@@ -2851,7 +2854,7 @@ static void vpaint_paint_poly(VPaint *vp, VPaintData *vpd, Mesh *me,
ml = me->mloop + mpoly->loopstart;
mlc = me->mloopcol + mpoly->loopstart;
- for (j = 0; j < mpoly->totloop; j++, ml++, mlc++) {
+ for (j = 0; j < totloop; j++, ml++, mlc++) {
if (ml->v == mf->v1) {
MESH_MLOOPCOL_TO_MCOL(mlc, mc + 0);
}
diff --git a/source/blender/imbuf/intern/rectop.c b/source/blender/imbuf/intern/rectop.c
index 79bf9eba1cc..d9375e3919b 100644
--- a/source/blender/imbuf/intern/rectop.c
+++ b/source/blender/imbuf/intern/rectop.c
@@ -34,6 +34,7 @@
#include <stdlib.h>
#include "BLI_utildefines.h"
+#include "BLI_math_base.h"
#include "BLI_math_color.h"
#include "BLI_math_vector.h"
@@ -54,20 +55,20 @@ static void blend_color_mix(char cp[3], const char cp1[3], const char cp2[3], co
* errors that can turn colors black fast after repeated blending */
const int mfac = 255 - fac;
- cp[0] = (mfac * cp1[0] + fac * cp2[0]) / 255;
- cp[1] = (mfac * cp1[1] + fac * cp2[1]) / 255;
- cp[2] = (mfac * cp1[2] + fac * cp2[2]) / 255;
+ cp[0] = divide_round_i((mfac * cp1[0] + fac * cp2[0]), 255);
+ cp[1] = divide_round_i((mfac * cp1[1] + fac * cp2[1]), 255);
+ cp[2] = divide_round_i((mfac * cp1[2] + fac * cp2[2]), 255);
}
static void blend_color_add(char cp[3], const char cp1[3], const char cp2[3], const int fac)
{
int temp;
- temp = cp1[0] + ((fac * cp2[0]) / 255);
+ temp = cp1[0] + divide_round_i(fac * cp2[0], 255);
if (temp > 254) cp[0] = 255; else cp[0] = temp;
- temp = cp1[1] + ((fac * cp2[1]) / 255);
+ temp = cp1[1] + divide_round_i(fac * cp2[1] , 255);
if (temp > 254) cp[1] = 255; else cp[1] = temp;
- temp = cp1[2] + ((fac * cp2[2]) / 255);
+ temp = cp1[2] + divide_round_i(fac * cp2[2] , 255);
if (temp > 254) cp[2] = 255; else cp[2] = temp;
}
@@ -75,11 +76,11 @@ static void blend_color_sub(char cp[3], const char cp1[3], const char cp2[3], co
{
int temp;
- temp = cp1[0] - ((fac * cp2[0]) / 255);
+ temp = cp1[0] - divide_round_i(fac * cp2[0], 255);
if (temp < 0) cp[0] = 0; else cp[0] = temp;
- temp = cp1[1] - ((fac * cp2[1]) / 255);
+ temp = cp1[1] - divide_round_i(fac * cp2[1], 255);
if (temp < 0) cp[1] = 0; else cp[1] = temp;
- temp = cp1[2] - ((fac * cp2[2]) / 255);
+ temp = cp1[2] - divide_round_i(fac * cp2[2], 255);
if (temp < 0) cp[2] = 0; else cp[2] = temp;
}
@@ -88,9 +89,9 @@ static void blend_color_mul(char cp[3], const char cp1[3], const char cp2[3], co
int mfac = 255 - fac;
/* first mul, then blend the fac */
- cp[0] = (mfac * cp1[0] + fac * ((cp1[0] * cp2[0]) / 255)) / 255;
- cp[1] = (mfac * cp1[1] + fac * ((cp1[1] * cp2[1]) / 255)) / 255;
- cp[2] = (mfac * cp1[2] + fac * ((cp1[2] * cp2[2]) / 255)) / 255;
+ cp[0] = divide_round_i((mfac * cp1[0] * 255) + (fac * cp1[0] * cp2[0]), 255*255);
+ cp[1] = divide_round_i((mfac * cp1[1] * 255) + (fac * cp1[1] * cp2[1]), 255*255);
+ cp[2] = divide_round_i((mfac * cp1[2] * 255) + (fac * cp1[2] * cp2[2]), 255*255);
}
static void blend_color_lighten(char cp[3], const char cp1[3], const char cp2[3], const int fac)
@@ -123,7 +124,7 @@ static void blend_color_darken(char cp[3], const char cp1[3], const char cp2[3],
static void blend_color_erase_alpha(char cp[4], const char cp1[4], const char cp2[4], const int fac)
{
- int temp = (cp1[3] - fac * cp2[3] / 255);
+ int temp = divide_round_i(cp1[3] - fac * cp2[3], 255);
cp[0] = cp1[0];
cp[1] = cp1[1];
@@ -133,7 +134,7 @@ static void blend_color_erase_alpha(char cp[4], const char cp1[4], const char cp
static void blend_color_add_alpha(char cp[4], const char cp1[4], const char cp2[4], const int fac)
{
- int temp = (cp1[3] + fac * cp2[3] / 255);
+ int temp = divide_round_i(cp1[3] + fac * cp2[3], 255);
cp[0] = cp1[0];
cp[1] = cp1[1];
@@ -175,11 +176,11 @@ unsigned int IMB_blend_color(unsigned int src1, unsigned int src2, int fac, IMB_
}
if (mode == IMB_BLEND_ERASE_ALPHA) {
- temp = (cp1[3] - fac * cp2[3] / 255);
+ temp = divide_round_i(cp1[3] - fac * cp2[3], 255);
cp[3] = (temp < 0) ? 0 : temp;
}
else { /* this does ADD_ALPHA also */
- temp = (cp1[3] + fac * cp2[3] / 255);
+ temp = divide_round_i(cp1[3] + fac * cp2[3], 255);
cp[3] = (temp > 255) ? 255 : temp;
}