forked from bartvdbraak/blender
split code for applying each paint tool into its own function.
This commit is contained in:
parent
6d8a2dd9ef
commit
00cc0f6852
@ -1413,6 +1413,7 @@ static ProjPixel *project_paint_uvpixel_init(
|
|||||||
}
|
}
|
||||||
|
|
||||||
projPixel = (ProjPixel *)BLI_memarena_alloc(arena, size);
|
projPixel = (ProjPixel *)BLI_memarena_alloc(arena, size);
|
||||||
|
//memset(projPixel, 0, size);
|
||||||
|
|
||||||
if (ibuf->rect_float) {
|
if (ibuf->rect_float) {
|
||||||
projPixel->pixel.f_pt = (float *)ibuf->rect_float + ((x_px + y_px * ibuf->x) * 4);
|
projPixel->pixel.f_pt = (float *)ibuf->rect_float + ((x_px + y_px * ibuf->x) * 4);
|
||||||
@ -1494,10 +1495,10 @@ static ProjPixel *project_paint_uvpixel_init(
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (ibuf->rect_float) {
|
if (ibuf->rect_float) {
|
||||||
((ProjPixelClone *)projPixel)->clonepx.ch[3] = 0;
|
((ProjPixelClone *)projPixel)->clonepx.f[3] = 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
((ProjPixelClone *)projPixel)->clonepx.f[3] = 0;
|
((ProjPixelClone *)projPixel)->clonepx.ch[3] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3869,6 +3870,103 @@ static void blend_color_mix_float(float *cp, const float *cp1, const float *cp2,
|
|||||||
cp[2]= mfac*cp1[2] + fac*cp2[2];
|
cp[2]= mfac*cp1[2] + fac*cp2[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void do_projectpaint_clone(ProjPaintState *ps, ProjPixel *projPixel, float *rgba, float alpha, short blend)
|
||||||
|
{
|
||||||
|
if (ps->is_airbrush==0 && projPixel->mask < 1.0f) {
|
||||||
|
projPixel->newColor.uint = IMB_blend_color(projPixel->newColor.uint, ((ProjPixelClone*)projPixel)->clonepx.uint, (int)(alpha*255), blend);
|
||||||
|
blend_color_mix(projPixel->pixel.ch_pt, projPixel->origColor.ch, projPixel->newColor.ch, (int)(projPixel->mask*255));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*projPixel->pixel.uint_pt = IMB_blend_color(*projPixel->pixel.uint_pt, ((ProjPixelClone*)projPixel)->clonepx.uint, (int)(alpha*255), blend);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void do_projectpaint_clone_f(ProjPaintState *ps, ProjPixel *projPixel, float *rgba, float alpha, short blend)
|
||||||
|
{
|
||||||
|
if (ps->is_airbrush==0 && projPixel->mask < 1.0f) {
|
||||||
|
IMB_blend_color_float(projPixel->newColor.f, projPixel->newColor.f, ((ProjPixelClone *)projPixel)->clonepx.f, alpha, blend);
|
||||||
|
blend_color_mix_float(projPixel->pixel.f_pt, projPixel->origColor.f, projPixel->newColor.f, projPixel->mask);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
IMB_blend_color_float(projPixel->pixel.f_pt, projPixel->pixel.f_pt, ((ProjPixelClone *)projPixel)->clonepx.f, alpha, blend);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* do_projectpaint_smear*
|
||||||
|
*
|
||||||
|
* note, mask is used to modify the alpha here, this is not correct since it allows
|
||||||
|
* accumulation of color greater then 'projPixel->mask' however in the case of smear its not
|
||||||
|
* really that important to be correct as it is with clone and painting
|
||||||
|
*/
|
||||||
|
static void do_projectpaint_smear(ProjPaintState *ps, ProjPixel *projPixel, float *rgba, float alpha, short blend, MemArena *smearArena, LinkNode **smearPixels, float co[2])
|
||||||
|
{
|
||||||
|
unsigned char rgba_ub[4];
|
||||||
|
|
||||||
|
if (project_paint_PickColor(ps, co, NULL, rgba_ub, 1)==0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
((ProjPixelClone *)projPixel)->clonepx.uint = IMB_blend_color(*projPixel->pixel.uint_pt, *((unsigned int *)rgba_ub), (int)(alpha*projPixel->mask*255), blend);
|
||||||
|
BLI_linklist_prepend_arena(smearPixels, (void *)projPixel, smearArena);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void do_projectpaint_smear_f(ProjPaintState *ps, ProjPixel *projPixel, float *rgba, float alpha, short blend, MemArena *smearArena, LinkNode **smearPixels_f, float co[2])
|
||||||
|
{
|
||||||
|
unsigned char rgba_ub[4];
|
||||||
|
unsigned char rgba_smear[4];
|
||||||
|
|
||||||
|
if (project_paint_PickColor(ps, co, NULL, rgba_ub, 1)==0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
IMAPAINT_FLOAT_RGBA_TO_CHAR(rgba_smear, projPixel->pixel.f_pt);
|
||||||
|
((ProjPixelClone *)projPixel)->clonepx.uint = IMB_blend_color(*((unsigned int *)rgba_smear), *((unsigned int *)rgba_ub), (int)(alpha*projPixel->mask*255), blend);
|
||||||
|
BLI_linklist_prepend_arena(smearPixels_f, (void *)projPixel, smearArena);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void do_projectpaint_draw(ProjPaintState *ps, ProjPixel *projPixel, float *rgba, float alpha, short blend)
|
||||||
|
{
|
||||||
|
unsigned char rgba_ub[4];
|
||||||
|
|
||||||
|
if (ps->is_texbrush) {
|
||||||
|
rgba_ub[0] = FTOCHAR(rgba[0] * ps->brush->rgb[0]);
|
||||||
|
rgba_ub[1] = FTOCHAR(rgba[1] * ps->brush->rgb[1]);
|
||||||
|
rgba_ub[2] = FTOCHAR(rgba[2] * ps->brush->rgb[2]);
|
||||||
|
rgba_ub[3] = FTOCHAR(rgba[3]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
IMAPAINT_FLOAT_RGB_TO_CHAR(rgba_ub, ps->brush->rgb);
|
||||||
|
rgba_ub[3] = 255;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ps->is_airbrush==0 && projPixel->mask < 1.0f) {
|
||||||
|
projPixel->newColor.uint = IMB_blend_color(projPixel->newColor.uint, *((unsigned int *)rgba_ub), (int)(alpha*255), blend);
|
||||||
|
blend_color_mix(projPixel->pixel.ch_pt, projPixel->origColor.ch, projPixel->newColor.ch, (int)(projPixel->mask*255));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*projPixel->pixel.uint_pt = IMB_blend_color(*projPixel->pixel.uint_pt, *((unsigned int *)rgba_ub), (int)(alpha*255), blend);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void do_projectpaint_draw_f(ProjPaintState *ps, ProjPixel *projPixel, float *rgba, float alpha, short blend) {
|
||||||
|
if (ps->is_texbrush) {
|
||||||
|
rgba[0] *= ps->brush->rgb[0];
|
||||||
|
rgba[1] *= ps->brush->rgb[1];
|
||||||
|
rgba[2] *= ps->brush->rgb[2];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
VECCOPY(rgba, ps->brush->rgb);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ps->is_airbrush==0 && projPixel->mask < 1.0f) {
|
||||||
|
IMB_blend_color_float(projPixel->newColor.f, projPixel->newColor.f, rgba, alpha, blend);
|
||||||
|
blend_color_mix_float(projPixel->pixel.f_pt, projPixel->origColor.f, projPixel->newColor.f, projPixel->mask);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
IMB_blend_color_float(projPixel->pixel.f_pt, projPixel->pixel.f_pt, rgba, alpha, blend);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* run this for single and multithreaded painting */
|
/* run this for single and multithreaded painting */
|
||||||
static void *do_projectpaint_thread(void *ph_v)
|
static void *do_projectpaint_thread(void *ph_v)
|
||||||
{
|
{
|
||||||
@ -3888,7 +3986,6 @@ static void *do_projectpaint_thread(void *ph_v)
|
|||||||
ImagePaintPartialRedraw *last_partial_redraw_cell;
|
ImagePaintPartialRedraw *last_partial_redraw_cell;
|
||||||
|
|
||||||
float rgba[4], alpha, dist, dist_nosqrt;
|
float rgba[4], alpha, dist, dist_nosqrt;
|
||||||
unsigned char rgba_ub[4];
|
|
||||||
|
|
||||||
float brush_size_sqared;
|
float brush_size_sqared;
|
||||||
int bucket_index;
|
int bucket_index;
|
||||||
@ -3898,11 +3995,11 @@ static void *do_projectpaint_thread(void *ph_v)
|
|||||||
rctf bucket_bounds;
|
rctf bucket_bounds;
|
||||||
|
|
||||||
/* for smear only */
|
/* for smear only */
|
||||||
char rgba_smear[4];
|
|
||||||
float pos_ofs[2];
|
float pos_ofs[2];
|
||||||
float co[2];
|
float co[2];
|
||||||
|
|
||||||
LinkNode *smearPixels = NULL;
|
LinkNode *smearPixels = NULL;
|
||||||
LinkNode *smearPixels_float = NULL;
|
LinkNode *smearPixels_f = NULL;
|
||||||
MemArena *smearArena = NULL; /* mem arena for this brush projection only */
|
MemArena *smearArena = NULL; /* mem arena for this brush projection only */
|
||||||
|
|
||||||
|
|
||||||
@ -3926,9 +4023,6 @@ static void *do_projectpaint_thread(void *ph_v)
|
|||||||
project_bucket_init(ps, thread_index, bucket_index, &bucket_bounds);
|
project_bucket_init(ps, thread_index, bucket_index, &bucket_bounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO - we may want to init clone data in a separate to project_bucket_init
|
|
||||||
* so we don't go overboard and init too many clone pixels */
|
|
||||||
|
|
||||||
for (node = ps->bucketRect[bucket_index]; node; node = node->next) {
|
for (node = ps->bucketRect[bucket_index]; node; node = node->next) {
|
||||||
|
|
||||||
projPixel = (ProjPixel *)node->link;
|
projPixel = (ProjPixel *)node->link;
|
||||||
@ -3969,102 +4063,25 @@ static void *do_projectpaint_thread(void *ph_v)
|
|||||||
case PAINT_TOOL_CLONE:
|
case PAINT_TOOL_CLONE:
|
||||||
if (is_floatbuf) {
|
if (is_floatbuf) {
|
||||||
if (((ProjPixelClone *)projPixel)->clonepx.f[3]) {
|
if (((ProjPixelClone *)projPixel)->clonepx.f[3]) {
|
||||||
|
do_projectpaint_clone_f(ps, projPixel, rgba, alpha, blend);
|
||||||
if (ps->is_airbrush==0 && projPixel->mask < 1.0f) {
|
|
||||||
IMB_blend_color_float(projPixel->newColor.f, projPixel->newColor.f, ((ProjPixelClone *)projPixel)->clonepx.f, alpha, blend);
|
|
||||||
blend_color_mix_float(projPixel->pixel.f_pt, projPixel->origColor.f, projPixel->newColor.f, projPixel->mask);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
IMB_blend_color_float(projPixel->pixel.f_pt, projPixel->pixel.f_pt, ((ProjPixelClone *)projPixel)->clonepx.f, alpha, blend);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (((ProjPixelClone*)projPixel)->clonepx.ch[3]) {
|
if (((ProjPixelClone*)projPixel)->clonepx.ch[3]) {
|
||||||
if (ps->is_airbrush==0 && projPixel->mask < 1.0f) {
|
do_projectpaint_clone(ps, projPixel, rgba, alpha, blend);
|
||||||
projPixel->newColor.uint = IMB_blend_color(projPixel->newColor.uint, ((ProjPixelClone*)projPixel)->clonepx.uint, (int)(alpha*255), blend);
|
|
||||||
blend_color_mix(projPixel->pixel.ch_pt, projPixel->origColor.ch, projPixel->newColor.ch, (int)(projPixel->mask*255));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
*projPixel->pixel.uint_pt = IMB_blend_color(*projPixel->pixel.uint_pt, ((ProjPixelClone*)projPixel)->clonepx.uint, (int)(alpha*255), blend);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PAINT_TOOL_SMEAR:
|
case PAINT_TOOL_SMEAR:
|
||||||
Vec2Subf(co, projPixel->projCoSS, pos_ofs);
|
Vec2Subf(co, projPixel->projCoSS, pos_ofs);
|
||||||
if (project_paint_PickColor(ps, co, NULL, rgba_ub, 1)) {
|
|
||||||
|
|
||||||
/* note, mask is used to modify the alpha here, this is not correct since it allows
|
if (is_floatbuf) do_projectpaint_smear_f(ps, projPixel, rgba, alpha, blend, smearArena, &smearPixels_f, co);
|
||||||
* accumulation of color greater then 'projPixel->mask' however in the case of smear its not
|
else do_projectpaint_smear(ps, projPixel, rgba, alpha, blend, smearArena, &smearPixels, co);
|
||||||
* really that important to be correct as it is with clone and painting
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* 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 - also would need float buffer */
|
|
||||||
*projPixel->pixel.uint_pt = IMB_blend_color(*projPixel->pixel.uint_pt, *((unsigned int *)rgba_ub), (int)(alpha*projPixel->mask*256), blend);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* add to memarena instead */
|
|
||||||
if (is_floatbuf) {
|
|
||||||
/* TODO FLOAT */ /* Smear wont do float properly yet */
|
|
||||||
/* Note, alpha*255 makes pixels darker */
|
|
||||||
IMAPAINT_FLOAT_RGBA_TO_CHAR(rgba_smear, projPixel->pixel.f_pt);
|
|
||||||
((ProjPixelClone *)projPixel)->clonepx.uint = IMB_blend_color(*((unsigned int *)rgba_smear), *((unsigned int *)rgba_ub), (int)(alpha*projPixel->mask*255), blend);
|
|
||||||
BLI_linklist_prepend_arena(&smearPixels_float, (void *)projPixel, smearArena);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
((ProjPixelClone *)projPixel)->clonepx.uint = IMB_blend_color(*projPixel->pixel.uint_pt, *((unsigned int *)rgba_ub), (int)(alpha*projPixel->mask*255), blend);
|
|
||||||
BLI_linklist_prepend_arena(&smearPixels, (void *)projPixel, smearArena);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (is_floatbuf) {
|
if (is_floatbuf) do_projectpaint_draw_f(ps, projPixel, rgba, alpha, blend);
|
||||||
if (ps->is_texbrush) {
|
else do_projectpaint_draw(ps, projPixel, rgba, alpha, blend);
|
||||||
rgba[0] *= ps->brush->rgb[0];
|
|
||||||
rgba[1] *= ps->brush->rgb[1];
|
|
||||||
rgba[2] *= ps->brush->rgb[2];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
VECCOPY(rgba, ps->brush->rgb);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ps->is_airbrush==0 && projPixel->mask < 1.0f) {
|
|
||||||
IMB_blend_color_float(projPixel->newColor.f, projPixel->newColor.f, rgba, alpha, blend);
|
|
||||||
blend_color_mix_float(projPixel->pixel.f_pt, projPixel->origColor.f, projPixel->newColor.f, projPixel->mask);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
IMB_blend_color_float(projPixel->pixel.f_pt, projPixel->pixel.f_pt, rgba, alpha, blend);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
|
|
||||||
if (ps->is_texbrush) {
|
|
||||||
rgba_ub[0] = FTOCHAR(rgba[0] * ps->brush->rgb[0]);
|
|
||||||
rgba_ub[1] = FTOCHAR(rgba[1] * ps->brush->rgb[1]);
|
|
||||||
rgba_ub[2] = FTOCHAR(rgba[2] * ps->brush->rgb[2]);
|
|
||||||
rgba_ub[3] = FTOCHAR(rgba[3]);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
IMAPAINT_FLOAT_RGB_TO_CHAR(rgba_ub, ps->brush->rgb);
|
|
||||||
rgba_ub[3] = 255;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ps->is_airbrush==0 && projPixel->mask < 1.0f) {
|
|
||||||
projPixel->newColor.uint = IMB_blend_color(projPixel->newColor.uint, *((unsigned int *)rgba_ub), (int)(alpha*255), blend);
|
|
||||||
blend_color_mix(projPixel->pixel.ch_pt, projPixel->origColor.ch, projPixel->newColor.ch, (int)(projPixel->mask*255));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
*projPixel->pixel.uint_pt = IMB_blend_color(*projPixel->pixel.uint_pt, *((unsigned int *)rgba_ub), (int)(alpha*255), blend);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* done painting */
|
/* done painting */
|
||||||
@ -4080,7 +4097,7 @@ static void *do_projectpaint_thread(void *ph_v)
|
|||||||
*projPixel->pixel.uint_pt = ((ProjPixelClone *)projPixel)->clonepx.uint;
|
*projPixel->pixel.uint_pt = ((ProjPixelClone *)projPixel)->clonepx.uint;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (node= smearPixels_float; node; node= node->next) { /* this wont run for a float image */
|
for (node= smearPixels_f; node; node= node->next) { /* this wont run for a float image */
|
||||||
projPixel = node->link;
|
projPixel = node->link;
|
||||||
IMAPAINT_CHAR_RGBA_TO_FLOAT(projPixel->pixel.f_pt, ((ProjPixelClone *)projPixel)->clonepx.ch);
|
IMAPAINT_CHAR_RGBA_TO_FLOAT(projPixel->pixel.f_pt, ((ProjPixelClone *)projPixel)->clonepx.ch);
|
||||||
node = node->next;
|
node = node->next;
|
||||||
@ -4433,6 +4450,8 @@ void imagepaint_paint(short mousebutton, short texpaint)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getmouseco_areawin(mval); /* make sure this runs before project_paint_begin() */
|
||||||
|
|
||||||
/* note, if we have no UVs on the derived mesh, then we must return here */
|
/* note, if we have no UVs on the derived mesh, then we must return here */
|
||||||
if (project) {
|
if (project) {
|
||||||
/* setup projection painting data */
|
/* setup projection painting data */
|
||||||
@ -4464,8 +4483,6 @@ void imagepaint_paint(short mousebutton, short texpaint)
|
|||||||
/* create painter and paint once */
|
/* create painter and paint once */
|
||||||
painter= brush_painter_new(s.brush);
|
painter= brush_painter_new(s.brush);
|
||||||
|
|
||||||
getmouseco_areawin(mval);
|
|
||||||
|
|
||||||
pressure = get_pressure();
|
pressure = get_pressure();
|
||||||
s.blend = (get_activedevice() == 2)? BRUSH_BLEND_ERASE_ALPHA: s.brush->blend;
|
s.blend = (get_activedevice() == 2)? BRUSH_BLEND_ERASE_ALPHA: s.brush->blend;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user