diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2010-02-15 15:57:16 +0300 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2010-02-15 15:57:16 +0300 |
commit | 5e58daa0983ac7ed58dfde5df578bd5d01b306a3 (patch) | |
tree | a3b2ae66f1d61683f6665d235725dafe556e892d | |
parent | c864df6cfef875101f9b24650f0bac2d553c7d8a (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.
-rw-r--r-- | source/blender/editors/sculpt_paint/paint_image.c | 100 | ||||
-rw-r--r-- | source/blender/imbuf/IMB_imbuf.h | 2 | ||||
-rw-r--r-- | source/blender/imbuf/intern/rectop.c | 39 |
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(®ion[tot++], destx, desty, srcx, srcy, w, h); + + /* do 3 other rects if needed */ + if (w < origw) + imapaint_set_region(®ion[tot++], (destx+w)%dbuf->x, desty, (srcx+w)%sbuf->x, srcy, origw-w, h); + if (h < origh) + imapaint_set_region(®ion[tot++], destx, (desty+h)%dbuf->y, srcx, (srcy+h)%sbuf->y, w, origh-h); + if ((w < origw) && (h < origh)) + imapaint_set_region(®ion[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]) |