[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [17344] branches/projection-paint/source/ blender/src/imagepaint.c: added support for smear brush type
Campbell Barton
ideasman42 at gmail.com
Thu Nov 6 03:08:47 CET 2008
Revision: 17344
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=17344
Author: campbellbarton
Date: 2008-11-06 03:08:41 +0100 (Thu, 06 Nov 2008)
Log Message:
-----------
added support for smear brush type
Modified Paths:
--------------
branches/projection-paint/source/blender/src/imagepaint.c
Modified: branches/projection-paint/source/blender/src/imagepaint.c
===================================================================
--- branches/projection-paint/source/blender/src/imagepaint.c 2008-11-06 01:30:24 UTC (rev 17343)
+++ branches/projection-paint/source/blender/src/imagepaint.c 2008-11-06 02:08:41 UTC (rev 17344)
@@ -220,7 +220,7 @@
typedef struct ProjectPixelClone {
struct ProjectPixel __pp;
- char backbuf[4]; /* TODO - float buffer? */
+ /*char backbuf[4]; *//* TODO - float buffer? */
char clonebuf[4];
//void *source; /* pointer to source pixels */
} ProjectPixelClone;
@@ -490,7 +490,7 @@
}
/* bucket_index is optional, since in some cases we know it */
-static int screenco_pickcol(ProjectPaintState *ps, int bucket_index, float pt[2], char rgba[4], int interp)
+static int screenco_pickcol(ProjectPaintState *ps, float pt[2], char rgba[4], int interp)
{
float w[3], uv[2];
int side;
@@ -1065,23 +1065,23 @@
projPixel->pixel = (( char * ) ibuf->rect) + (( x + y * ibuf->x ) * pixel_size);
VECCOPY2D(projPixel->projCo2D, pixelScreenCo);
- /* copy pixel color to backbuf */
- memcpy( &(((ProjectPixelClone *)projPixel)->backbuf), projPixel->pixel, pixel_size);
+ /* copy pixel color to backbuf - not used yet */
+ /* memcpy( &(((ProjectPixelClone *)projPixel)->backbuf), projPixel->pixel, pixel_size); */
//((ProjectPixelClone *)projPixel)->source = NULL; /* must be set later */
/* Initialize clone pixels - note that this is a bit of a waste since some of these are being indirectly initialized :/ */
/* TODO - possibly only run this for directly ativated buckets when cloning */
Vec2Subf(co, projPixel->projCo2D, ps->cloneOfs);
-
+
/* no need to initialize the bucket, we're only checking buckets faces and for this
* the faces are alredy initialized in project_paint_delayed_face_init(...) */
- if (!screenco_pickcol(ps, bucket_index, co, ((ProjectPixelClone *)projPixel)->clonebuf, 1)) {
+ if (!screenco_pickcol(ps, co, ((ProjectPixelClone *)projPixel)->clonebuf, 1)) {
((ProjectPixelClone *)projPixel)->clonebuf[3] = 0; /* zero alpha - ignore */
}
-
} else {
- projPixel = (ProjectPixel *)BLI_memarena_alloc(ps->projectArena, sizeof(ProjectPixel));
+ /* smear needs the buffer from a clone pixel */
+ projPixel = (ProjectPixel *)BLI_memarena_alloc(ps->projectArena, (ps->tool==PAINT_TOOL_SMEAR) ? sizeof(ProjectPixelClone) : sizeof(ProjectPixel));
projPixel->pixel = (( char * ) ibuf->rect) + (( x + y * ibuf->x ) * pixel_size);
VECCOPY2D(projPixel->projCo2D, pixelScreenCo);
}
@@ -2293,7 +2293,7 @@
return 0;
}
-static int imapaint_paint_sub_stroke_project(ProjectPaintState *ps, BrushPainter *painter, short mval[2], double time, int update, float pressure)
+static int imapaint_paint_sub_stroke_project(ProjectPaintState *ps, BrushPainter *painter, short prevmval[2], short mval[2], double time, int update, float pressure)
{
/* TODO - texpaint option : is there any use in projection painting from the image window??? - could be interesting */
/* TODO - floating point images */
@@ -2313,11 +2313,14 @@
int bucket_index;
int a;
short blend= ps->blend;
-
char *cp;
-
int bucket_x, bucket_y;
+ /* for smear only */
+ float mval_ofs[2];
+ float co[2];
+ LinkNode *smearPixels = NULL;
+ MemArena *smearArena = NULL; /* mem arena for this brush projection only */
mval_f[0] = mval[0]; mval_f[1] = mval[1];
@@ -2335,6 +2338,14 @@
return 0;
}
+ if (ps->tool==PAINT_TOOL_SMEAR) {
+ mval_ofs[0] = (float)(mval[0] - prevmval[0]);
+ mval_ofs[1] = (float)(mval[1] - prevmval[1]);
+
+ smearArena = BLI_memarena_new(1<<16);
+ }
+
+
/* avoid a square root with every dist comparison */
brush_size_sqared = ps->brush->size * ps->brush->size;
@@ -2377,24 +2388,51 @@
dist = (float)sqrt(dist_nosqrt);
- if (ps->tool==PAINT_TOOL_CLONE && ((char *)((ProjectPixelClone*)projPixel)->clonebuf)[3]) { //&& ((ProjectPixelClone*)projPixel)->source ) {
- alpha = brush_sample_falloff(ps->brush, dist);
-
- if (alpha <= 0.0) {
- /* do nothing */
- } else {
- cp = (char *)((ProjectPixelClone*)projPixel)->clonebuf;
- if (alpha >= 1.0) {
- projPixel->pixel[0] = FTOCHAR( cp[0] );
- projPixel->pixel[1] = FTOCHAR( cp[1] );
- projPixel->pixel[2] = FTOCHAR( cp[2] );
+ switch(ps->tool) {
+ case PAINT_TOOL_CLONE:
+ if (((char *)((ProjectPixelClone*)projPixel)->clonebuf)[3]) {
+ alpha = brush_sample_falloff(ps->brush, dist);
+ if (alpha <= 0.0) {
+ /* do nothing */
} else {
- projPixel->pixel[0] = FTOCHAR( (((cp[0]/255.0) * alpha) + (((projPixel->pixel[0])/255.0)*(1.0-alpha))) );
- projPixel->pixel[1] = FTOCHAR( (((cp[1]/255.0) * alpha) + (((projPixel->pixel[1])/255.0)*(1.0-alpha))) );
- projPixel->pixel[2] = FTOCHAR( (((cp[2]/255.0) * alpha) + (((projPixel->pixel[2])/255.0)*(1.0-alpha))) );
+ cp = (char *)((ProjectPixelClone*)projPixel)->clonebuf;
+ if (alpha >= 1.0) {
+ projPixel->pixel[0] = FTOCHAR( cp[0] );
+ projPixel->pixel[1] = FTOCHAR( cp[1] );
+ projPixel->pixel[2] = FTOCHAR( cp[2] );
+ } else {
+ projPixel->pixel[0] = FTOCHAR( (((cp[0]/255.0) * alpha) + (((projPixel->pixel[0])/255.0)*(1.0-alpha))) );
+ projPixel->pixel[1] = FTOCHAR( (((cp[1]/255.0) * alpha) + (((projPixel->pixel[1])/255.0)*(1.0-alpha))) );
+ projPixel->pixel[2] = FTOCHAR( (((cp[2]/255.0) * alpha) + (((projPixel->pixel[2])/255.0)*(1.0-alpha))) );
+ }
}
+
}
- } else {
+ break;
+ case PAINT_TOOL_SMEAR:
+ Vec2Subf(co, projPixel->projCo2D, mval_ofs);
+ if (screenco_pickcol(ps, co, rgba_ub, 1)) {
+ brush_sample_tex(ps->brush, projPixel->projCo2D, rgba);
+ alpha = rgba[3]*brush_sample_falloff(ps->brush, dist);
+ /* drat! - this could almost be very simple if we ignore
+ * the fact that applying the color directly gives feedback,
+ * instead, collect the colors and apply after :/ */
+
+#if 0 /* looks OK but not correct */
+ *((unsigned int *)projPixel->pixel) = IMB_blend_color( *((unsigned int *)projPixel->pixel), *((unsigned int *)rgba_ub), (int)(alpha*255), blend);
+#endif
+
+ /* add to memarena instead */
+ *((unsigned int *) &((ProjectPixelClone *)projPixel)->clonebuf) = IMB_blend_color( *((unsigned int *)projPixel->pixel), *((unsigned int *)rgba_ub), (int)(alpha*255), blend);
+ BLI_linklist_prepend_arena(
+ &smearPixels,
+ (void *)projPixel,
+ smearArena
+ );
+
+ }
+ break;
+ default:
brush_sample_tex(ps->brush, projPixel->projCo2D, rgba);
alpha = rgba[3]*brush_sample_falloff(ps->brush, dist);
if (alpha > 0.0) {
@@ -2405,13 +2443,15 @@
*((unsigned int *)projPixel->pixel) = IMB_blend_color( *((unsigned int *)projPixel->pixel), *((unsigned int *)rgba_ub), (int)(alpha*255), blend);
}
+ break;
+
}
+
if (last_index != projPixel->image_index) {
last_index = projPixel->image_index;
ps->projectImages[last_index]->id.flag |= LIB_DOIT;
}
-
}
node = node->next;
@@ -2421,6 +2461,18 @@
}
}
+
+ if (ps->tool==PAINT_TOOL_SMEAR) {
+ if ((node = smearPixels)) {
+ do {
+ projPixel = node->link;
+ *((unsigned int *)projPixel->pixel) = *((unsigned int *)(((ProjectPixelClone *)projPixel)->clonebuf));
+ node = node->next;
+ } while (node);
+ }
+
+ BLI_memarena_free(smearArena);
+ }
/* Loop over all images on this mesh and update any we have touched */
for (a=0; a < ps->projectImageTotal; a++) {
Image *ima = ps->projectImages[a];
@@ -2431,7 +2483,6 @@
ima->id.flag &= ~LIB_DOIT; /* clear for reuse */
}
}
-
return redraw;
}
@@ -2522,7 +2573,7 @@
/* TODO - support more brush operations, airbrush etc */
{
- redraw |= imapaint_paint_sub_stroke_project(ps, painter, mval, time, 1, pressure);
+ redraw |= imapaint_paint_sub_stroke_project(ps, painter, prevmval, mval, time, 1, pressure);
}
if (redraw) {
@@ -2626,6 +2677,13 @@
time= PIL_check_seconds_timer();
if (project) { /* Projection Painting */
+ /* TODO - brush outline, dosnt work yet */
+ /*
+ persp(PERSP_WIN);
+ fdrawXORcirc(mval[0], mval[1], ps.brush->size);
+ draw_sel_circle(mval, prevmval, ps.brush->size, ps.brush->size, 0);
+ persp(PERSP_VIEW);
+ */
if((mval[0] != prevmval[0]) || (mval[1] != prevmval[1])) {
imapaint_paint_stroke_project(&ps, painter, prevmval, mval, time, pressure);
prevmval[0]= mval[0];
More information about the Bf-blender-cvs
mailing list