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:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2010-02-15 15:57:16 +0300
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2010-02-15 15:57:16 +0300
commit5e58daa0983ac7ed58dfde5df578bd5d01b306a3 (patch)
treea3b2ae66f1d61683f6665d235725dafe556e892d /source/blender
parentc864df6cfef875101f9b24650f0bac2d553c7d8a (diff)
Fix #21078: image paint undo didn't work correct with wrap option, moved
wrapping code to paint_image.c so it can be used for the undo push.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/editors/sculpt_paint/paint_image.c100
-rw-r--r--source/blender/imbuf/IMB_imbuf.h2
-rw-r--r--source/blender/imbuf/intern/rectop.c39
3 files changed, 89 insertions, 52 deletions
diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c
index f72699a5d7e..4ca46df6672 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.c
@@ -144,6 +144,11 @@ typedef struct ImagePaintPartialRedraw {
int enabled;
} ImagePaintPartialRedraw;
+typedef struct ImagePaintRegion {
+ int destx, desty;
+ int srcx, srcy;
+ int width, height;
+} ImagePaintRegion;
/* ProjectionPaint defines */
@@ -3981,10 +3986,68 @@ static void imapaint_lift_soften(ImBuf *ibuf, ImBuf *ibufb, int *pos, short toru
}
}
+static void imapaint_set_region(ImagePaintRegion *region, int destx, int desty, int srcx, int srcy, int width, int height)
+{
+ region->destx= destx;
+ region->desty= desty;
+ region->srcx= srcx;
+ region->srcy= srcy;
+ region->width= width;
+ region->height= height;
+}
+
+static int imapaint_torus_split_region(ImagePaintRegion region[4], ImBuf *dbuf, ImBuf *sbuf)
+{
+ int destx= region->destx;
+ int desty= region->desty;
+ int srcx= region->srcx;
+ int srcy= region->srcy;
+ int width= region->width;
+ int height= region->height;
+ int origw, origh, w, h, tot= 0;
+
+ /* convert destination and source coordinates to be within image */
+ destx = destx % dbuf->x;
+ if (destx < 0) destx += dbuf->x;
+ desty = desty % dbuf->y;
+ if (desty < 0) desty += dbuf->y;
+ srcx = srcx % sbuf->x;
+ if (srcx < 0) srcx += sbuf->x;
+ srcy = srcy % sbuf->y;
+ if (srcy < 0) srcy += sbuf->y;
+
+ /* clip width of blending area to destination imbuf, to avoid writing the
+ same pixel twice */
+ origw = w = (width > dbuf->x)? dbuf->x: width;
+ origh = h = (height > dbuf->y)? dbuf->y: height;
+
+ /* clip within image */
+ IMB_rectclip(dbuf, sbuf, &destx, &desty, &srcx, &srcy, &w, &h);
+ imapaint_set_region(&region[tot++], destx, desty, srcx, srcy, w, h);
+
+ /* do 3 other rects if needed */
+ if (w < origw)
+ imapaint_set_region(&region[tot++], (destx+w)%dbuf->x, desty, (srcx+w)%sbuf->x, srcy, origw-w, h);
+ if (h < origh)
+ imapaint_set_region(&region[tot++], destx, (desty+h)%dbuf->y, srcx, (srcy+h)%sbuf->y, w, origh-h);
+ if ((w < origw) && (h < origh))
+ imapaint_set_region(&region[tot++], (destx+w)%dbuf->x, (desty+h)%dbuf->y, (srcx+w)%sbuf->x, (srcy+h)%sbuf->y, origw-w, origh-h);
+
+ return tot;
+}
+
static void imapaint_lift_smear(ImBuf *ibuf, ImBuf *ibufb, int *pos)
{
- IMB_rectblend_torus(ibufb, ibuf, 0, 0, pos[0], pos[1],
- ibufb->x, ibufb->y, IMB_BLEND_COPY_RGB);
+ ImagePaintRegion region[4];
+ int a, tot;
+
+ imapaint_set_region(region, 0, 0, pos[0], pos[1], ibufb->x, ibufb->y);
+ tot= imapaint_torus_split_region(region, ibuf, ibufb);
+
+ for(a=0; a<tot; a++)
+ IMB_rectblend(ibufb, ibuf, region[a].destx, region[a].desty,
+ region[a].srcx, region[a].srcy,
+ region[a].width, region[a].height, IMB_BLEND_COPY_RGB);
}
static ImBuf *imapaint_lift_clone(ImBuf *ibuf, ImBuf *ibufb, int *pos)
@@ -4014,12 +4077,14 @@ static void imapaint_convert_brushco(ImBuf *ibufb, float *pos, int *ipos)
static int imapaint_paint_op(void *state, ImBuf *ibufb, float *lastpos, float *pos)
{
ImagePaintState *s= ((ImagePaintState*)state);
- ImBuf *clonebuf= NULL;
+ ImBuf *clonebuf= NULL, *frombuf;
+ ImagePaintRegion region[4];
short torus= s->brush->flag & BRUSH_TORUS;
short blend= s->blend;
float *offset= s->brush->clone.offset;
float liftpos[2];
int bpos[2], blastpos[2], bliftpos[2];
+ int a, tot;
imapaint_convert_brushco(ibufb, pos, bpos);
@@ -4042,16 +4107,29 @@ static int imapaint_paint_op(void *state, ImBuf *ibufb, float *lastpos, float *p
clonebuf= imapaint_lift_clone(s->clonecanvas, ibufb, bliftpos);
}
- imapaint_dirty_region(s->image, s->canvas, bpos[0], bpos[1], ibufb->x, ibufb->y);
+ frombuf= (clonebuf)? clonebuf: ibufb;
+
+ if(torus) {
+ imapaint_set_region(region, bpos[0], bpos[1], 0, 0, frombuf->x, frombuf->y);
+ tot= imapaint_torus_split_region(region, s->canvas, frombuf);
+ }
+ else {
+ imapaint_set_region(region, bpos[0], bpos[1], 0, 0, frombuf->x, frombuf->y);
+ tot= 1;
+ }
/* blend into canvas */
- if(torus)
- IMB_rectblend_torus(s->canvas, (clonebuf)? clonebuf: ibufb,
- bpos[0], bpos[1], 0, 0, ibufb->x, ibufb->y, blend);
- else
- IMB_rectblend(s->canvas, (clonebuf)? clonebuf: ibufb,
- bpos[0], bpos[1], 0, 0, ibufb->x, ibufb->y, blend);
-
+ for(a=0; a<tot; a++) {
+ imapaint_dirty_region(s->image, s->canvas,
+ region[a].destx, region[a].desty,
+ region[a].width, region[a].height);
+
+ IMB_rectblend(s->canvas, frombuf,
+ region[a].destx, region[a].desty,
+ region[a].srcx, region[a].srcy,
+ region[a].width, region[a].height, blend);
+ }
+
if(clonebuf) IMB_freeImBuf(clonebuf);
return 1;
diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h
index 023881a9aed..a77ef54b0b6 100644
--- a/source/blender/imbuf/IMB_imbuf.h
+++ b/source/blender/imbuf/IMB_imbuf.h
@@ -243,8 +243,6 @@ void IMB_rectcpy(struct ImBuf *drect, struct ImBuf *srect, int destx,
int desty, int srcx, int srcy, int width, int height);
void IMB_rectblend(struct ImBuf *dbuf, struct ImBuf *sbuf, int destx,
int desty, int srcx, int srcy, int width, int height, IMB_BlendMode mode);
-void IMB_rectblend_torus(struct ImBuf *dbuf, struct ImBuf *sbuf, int destx,
- int desty, int srcx, int srcy, int width, int height, IMB_BlendMode mode);
/**
* Return the length (in frames) of the given @a anim.
diff --git a/source/blender/imbuf/intern/rectop.c b/source/blender/imbuf/intern/rectop.c
index f320763c80a..3202413a494 100644
--- a/source/blender/imbuf/intern/rectop.c
+++ b/source/blender/imbuf/intern/rectop.c
@@ -443,45 +443,6 @@ void IMB_rectblend(struct ImBuf *dbuf, struct ImBuf *sbuf, int destx,
}
}
-void IMB_rectblend_torus(struct ImBuf *dbuf, struct ImBuf *sbuf, int destx,
- int desty, int srcx, int srcy, int width, int height, IMB_BlendMode mode)
-{
- int origw, origh, w, h;
-
- if (dbuf->x == 0 || dbuf->y == 0 || sbuf->x == 0 || sbuf->y == 0)
- return;
-
- /* convert destination and source coordinates too be withing image */
- destx = destx % dbuf->x;
- if (destx < 0) destx += dbuf->x;
- desty = desty % dbuf->y;
- if (desty < 0) desty += dbuf->y;
- srcx = srcx % sbuf->x;
- if (srcx < 0) srcx += sbuf->x;
- srcy = srcy % sbuf->y;
- if (srcy < 0) srcy += sbuf->y;
-
- /* clip width of blending area to destination imbuf, to avoid writing the
- same pixel twice */
- origw = w = (width > dbuf->x)? dbuf->x: width;
- origh = h = (height > dbuf->y)? dbuf->y: height;
-
- /* clip and blend */
- IMB_rectclip(dbuf, sbuf, &destx, &desty, &srcx, &srcy, &w, &h);
- IMB_rectblend(dbuf, sbuf, destx, desty, srcx, srcy, w, h, mode);
-
- /* do 3 other rects if needed */
- if (w < origw)
- IMB_rectblend(dbuf, sbuf, (destx+w)%dbuf->x, desty, (srcx+w)%sbuf->x, srcy,
- origw-w, h, mode);
- if (h < origh)
- IMB_rectblend(dbuf, sbuf, destx, (desty+h)%dbuf->y, srcx, (srcy+h)%sbuf->y,
- w, origh-h, mode);
- if ((w < origw) && (h < origh))
- IMB_rectblend(dbuf, sbuf, (destx+w)%dbuf->x, (desty+h)%dbuf->y,
- (srcx+w)%sbuf->x, (srcy+h)%sbuf->y, origw-w, origh-h, mode);
-}
-
/* fill */
void IMB_rectfill(struct ImBuf *drect, float col[4])