This repository has been archived on 2023-10-09. You can view files and clone it, but cannot push or open issues or pull requests.
Files
blender-archive/source/blender/editors/sculpt_paint/paint_image_2d.c

1154 lines
33 KiB
C
Raw Normal View History

/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
2013-01-02 01:49:07 +00:00
/** \file blender/editors/sculpt_paint/paint_image_2d.c
* \ingroup bke
*/
//#include <math.h>
#include <string.h>
#include "MEM_guardedalloc.h"
#include "DNA_brush_types.h"
#include "DNA_scene_types.h"
Texture paint refactoring commit This is as close as I can get to keeping the old code intact. After this commit, I will have to change existing code paths, making testing of functionality harder. Changes: * Keep only projective texturing code in paint_image_proj.c * Move 2D code to paint_image_2d.c. This needed the introduction of allocation/cleanup functions for the relevant structures. * Common code interface for both modes stays in paint_image.c (which still includes all old code, system should work as it did with the exception of non-projective 3D paint mode) and is made public. This is not a lot of code, only rectangle invalidation and undo system. * Changed the naming in the new code slightly: imapaint_ prefixed functions refer to common functions used by both systems, paint_2d_ prefixed to 2d painting. There will be an interface for the projection painting as well. Probably there is some leftover naming conversions to do. TODO: * Move operator init/exec/modal to common interface file * Get rid of old BKE_brush_painter_paint, now brush_painter_2d_paint. All code uses stroke system for the stroke management * Write space pressure management for the paint stroke system (for other systems to access as well :) ) * Move texture paint tablet presssure exception code for old bugs to stroke system (makes me wonder...aren't other systems also influenced by these pressure issues?) or up in the function hierarchy inside texture paint. This code is still not there so users with tablets may notice some issues. * possibly change other systems to pre-multiply pressure with the relevant influenced attributes in the stroke function. This could get tricky though and it's possible that it could backfire.
2013-03-07 12:11:38 +00:00
#include "DNA_space_types.h"
#include "DNA_object_types.h"
2013-03-09 05:35:49 +00:00
#include "BLI_math.h"
#include "BLI_rect.h"
2013-03-09 05:35:49 +00:00
Texture paint refactoring commit This is as close as I can get to keeping the old code intact. After this commit, I will have to change existing code paths, making testing of functionality harder. Changes: * Keep only projective texturing code in paint_image_proj.c * Move 2D code to paint_image_2d.c. This needed the introduction of allocation/cleanup functions for the relevant structures. * Common code interface for both modes stays in paint_image.c (which still includes all old code, system should work as it did with the exception of non-projective 3D paint mode) and is made public. This is not a lot of code, only rectangle invalidation and undo system. * Changed the naming in the new code slightly: imapaint_ prefixed functions refer to common functions used by both systems, paint_2d_ prefixed to 2d painting. There will be an interface for the projection painting as well. Probably there is some leftover naming conversions to do. TODO: * Move operator init/exec/modal to common interface file * Get rid of old BKE_brush_painter_paint, now brush_painter_2d_paint. All code uses stroke system for the stroke management * Write space pressure management for the paint stroke system (for other systems to access as well :) ) * Move texture paint tablet presssure exception code for old bugs to stroke system (makes me wonder...aren't other systems also influenced by these pressure issues?) or up in the function hierarchy inside texture paint. This code is still not there so users with tablets may notice some issues. * possibly change other systems to pre-multiply pressure with the relevant influenced attributes in the stroke function. This could get tricky though and it's possible that it could backfire.
2013-03-07 12:11:38 +00:00
#include "BKE_context.h"
#include "BKE_brush.h"
Texture paint refactoring commit This is as close as I can get to keeping the old code intact. After this commit, I will have to change existing code paths, making testing of functionality harder. Changes: * Keep only projective texturing code in paint_image_proj.c * Move 2D code to paint_image_2d.c. This needed the introduction of allocation/cleanup functions for the relevant structures. * Common code interface for both modes stays in paint_image.c (which still includes all old code, system should work as it did with the exception of non-projective 3D paint mode) and is made public. This is not a lot of code, only rectangle invalidation and undo system. * Changed the naming in the new code slightly: imapaint_ prefixed functions refer to common functions used by both systems, paint_2d_ prefixed to 2d painting. There will be an interface for the projection painting as well. Probably there is some leftover naming conversions to do. TODO: * Move operator init/exec/modal to common interface file * Get rid of old BKE_brush_painter_paint, now brush_painter_2d_paint. All code uses stroke system for the stroke management * Write space pressure management for the paint stroke system (for other systems to access as well :) ) * Move texture paint tablet presssure exception code for old bugs to stroke system (makes me wonder...aren't other systems also influenced by these pressure issues?) or up in the function hierarchy inside texture paint. This code is still not there so users with tablets may notice some issues. * possibly change other systems to pre-multiply pressure with the relevant influenced attributes in the stroke function. This could get tricky though and it's possible that it could backfire.
2013-03-07 12:11:38 +00:00
#include "BKE_main.h"
#include "BKE_image.h"
#include "BKE_paint.h"
#include "BKE_report.h"
#include "ED_screen.h"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
Texture paint refactoring commit This is as close as I can get to keeping the old code intact. After this commit, I will have to change existing code paths, making testing of functionality harder. Changes: * Keep only projective texturing code in paint_image_proj.c * Move 2D code to paint_image_2d.c. This needed the introduction of allocation/cleanup functions for the relevant structures. * Common code interface for both modes stays in paint_image.c (which still includes all old code, system should work as it did with the exception of non-projective 3D paint mode) and is made public. This is not a lot of code, only rectangle invalidation and undo system. * Changed the naming in the new code slightly: imapaint_ prefixed functions refer to common functions used by both systems, paint_2d_ prefixed to 2d painting. There will be an interface for the projection painting as well. Probably there is some leftover naming conversions to do. TODO: * Move operator init/exec/modal to common interface file * Get rid of old BKE_brush_painter_paint, now brush_painter_2d_paint. All code uses stroke system for the stroke management * Write space pressure management for the paint stroke system (for other systems to access as well :) ) * Move texture paint tablet presssure exception code for old bugs to stroke system (makes me wonder...aren't other systems also influenced by these pressure issues?) or up in the function hierarchy inside texture paint. This code is still not there so users with tablets may notice some issues. * possibly change other systems to pre-multiply pressure with the relevant influenced attributes in the stroke function. This could get tricky though and it's possible that it could backfire.
2013-03-07 12:11:38 +00:00
#include "IMB_colormanagement.h"
#include "WM_api.h"
#include "WM_types.h"
#include "UI_view2d.h"
#include "RE_shader_ext.h"
Texture paint refactoring commit This is as close as I can get to keeping the old code intact. After this commit, I will have to change existing code paths, making testing of functionality harder. Changes: * Keep only projective texturing code in paint_image_proj.c * Move 2D code to paint_image_2d.c. This needed the introduction of allocation/cleanup functions for the relevant structures. * Common code interface for both modes stays in paint_image.c (which still includes all old code, system should work as it did with the exception of non-projective 3D paint mode) and is made public. This is not a lot of code, only rectangle invalidation and undo system. * Changed the naming in the new code slightly: imapaint_ prefixed functions refer to common functions used by both systems, paint_2d_ prefixed to 2d painting. There will be an interface for the projection painting as well. Probably there is some leftover naming conversions to do. TODO: * Move operator init/exec/modal to common interface file * Get rid of old BKE_brush_painter_paint, now brush_painter_2d_paint. All code uses stroke system for the stroke management * Write space pressure management for the paint stroke system (for other systems to access as well :) ) * Move texture paint tablet presssure exception code for old bugs to stroke system (makes me wonder...aren't other systems also influenced by these pressure issues?) or up in the function hierarchy inside texture paint. This code is still not there so users with tablets may notice some issues. * possibly change other systems to pre-multiply pressure with the relevant influenced attributes in the stroke function. This could get tricky though and it's possible that it could backfire.
2013-03-07 12:11:38 +00:00
#include "GPU_draw.h"
#include "paint_intern.h"
/* Brush Painting for 2D image editor */
/* Defines and Structs */
/* FTOCHAR as inline function */
BLI_INLINE unsigned char f_to_char(const float val)
{
return FTOCHAR(val);
}
#define IMAPAINT_FLOAT_RGB_TO_CHAR(c, f) { \
(c)[0] = f_to_char((f)[0]); \
(c)[1] = f_to_char((f)[1]); \
(c)[2] = f_to_char((f)[2]); \
} (void)0
#define IMAPAINT_CHAR_RGB_TO_FLOAT(f, c) { \
(f)[0] = IMAPAINT_CHAR_TO_FLOAT((c)[0]); \
(f)[1] = IMAPAINT_CHAR_TO_FLOAT((c)[1]); \
(f)[2] = IMAPAINT_CHAR_TO_FLOAT((c)[2]); \
Texture paint refactoring commit This is as close as I can get to keeping the old code intact. After this commit, I will have to change existing code paths, making testing of functionality harder. Changes: * Keep only projective texturing code in paint_image_proj.c * Move 2D code to paint_image_2d.c. This needed the introduction of allocation/cleanup functions for the relevant structures. * Common code interface for both modes stays in paint_image.c (which still includes all old code, system should work as it did with the exception of non-projective 3D paint mode) and is made public. This is not a lot of code, only rectangle invalidation and undo system. * Changed the naming in the new code slightly: imapaint_ prefixed functions refer to common functions used by both systems, paint_2d_ prefixed to 2d painting. There will be an interface for the projection painting as well. Probably there is some leftover naming conversions to do. TODO: * Move operator init/exec/modal to common interface file * Get rid of old BKE_brush_painter_paint, now brush_painter_2d_paint. All code uses stroke system for the stroke management * Write space pressure management for the paint stroke system (for other systems to access as well :) ) * Move texture paint tablet presssure exception code for old bugs to stroke system (makes me wonder...aren't other systems also influenced by these pressure issues?) or up in the function hierarchy inside texture paint. This code is still not there so users with tablets may notice some issues. * possibly change other systems to pre-multiply pressure with the relevant influenced attributes in the stroke function. This could get tricky though and it's possible that it could backfire.
2013-03-07 12:11:38 +00:00
} (void)0
#define IMAPAINT_FLOAT_RGB_COPY(a, b) copy_v3_v3(a, b)
typedef struct BrushPainterCache {
int size; /* size override, if 0 uses 2*BKE_brush_size_get(brush) */
bool use_float; /* need float imbuf? */
bool use_color_correction; /* use color correction for float */
bool use_masking; /* use masking? */
bool is_texbrush;
bool is_maskbrush;
int lastsize;
float lastalpha;
float lastjitter;
float last_tex_rotation;
float last_mask_rotation;
ImBuf *ibuf;
ImBuf *texibuf;
unsigned short *mask;
} BrushPainterCache;
typedef struct BrushPainter {
Scene *scene;
Brush *brush;
float lastpaintpos[2]; /* position of last paint op */
float startpaintpos[2]; /* position of first paint */
short firsttouch; /* first paint op */
struct ImagePool *pool; /* image pool */
rctf tex_mapping; /* texture coordinate mapping */
rctf mask_mapping; /* mask texture coordinate mapping */
BrushPainterCache cache;
} BrushPainter;
Texture paint refactoring commit This is as close as I can get to keeping the old code intact. After this commit, I will have to change existing code paths, making testing of functionality harder. Changes: * Keep only projective texturing code in paint_image_proj.c * Move 2D code to paint_image_2d.c. This needed the introduction of allocation/cleanup functions for the relevant structures. * Common code interface for both modes stays in paint_image.c (which still includes all old code, system should work as it did with the exception of non-projective 3D paint mode) and is made public. This is not a lot of code, only rectangle invalidation and undo system. * Changed the naming in the new code slightly: imapaint_ prefixed functions refer to common functions used by both systems, paint_2d_ prefixed to 2d painting. There will be an interface for the projection painting as well. Probably there is some leftover naming conversions to do. TODO: * Move operator init/exec/modal to common interface file * Get rid of old BKE_brush_painter_paint, now brush_painter_2d_paint. All code uses stroke system for the stroke management * Write space pressure management for the paint stroke system (for other systems to access as well :) ) * Move texture paint tablet presssure exception code for old bugs to stroke system (makes me wonder...aren't other systems also influenced by these pressure issues?) or up in the function hierarchy inside texture paint. This code is still not there so users with tablets may notice some issues. * possibly change other systems to pre-multiply pressure with the relevant influenced attributes in the stroke function. This could get tricky though and it's possible that it could backfire.
2013-03-07 12:11:38 +00:00
typedef struct ImagePaintRegion {
int destx, desty;
int srcx, srcy;
int width, height;
} ImagePaintRegion;
typedef struct ImagePaintState {
BrushPainter *painter;
SpaceImage *sima;
View2D *v2d;
Scene *scene;
bScreen *screen;
struct ImagePool *image_pool;
Texture paint refactoring commit This is as close as I can get to keeping the old code intact. After this commit, I will have to change existing code paths, making testing of functionality harder. Changes: * Keep only projective texturing code in paint_image_proj.c * Move 2D code to paint_image_2d.c. This needed the introduction of allocation/cleanup functions for the relevant structures. * Common code interface for both modes stays in paint_image.c (which still includes all old code, system should work as it did with the exception of non-projective 3D paint mode) and is made public. This is not a lot of code, only rectangle invalidation and undo system. * Changed the naming in the new code slightly: imapaint_ prefixed functions refer to common functions used by both systems, paint_2d_ prefixed to 2d painting. There will be an interface for the projection painting as well. Probably there is some leftover naming conversions to do. TODO: * Move operator init/exec/modal to common interface file * Get rid of old BKE_brush_painter_paint, now brush_painter_2d_paint. All code uses stroke system for the stroke management * Write space pressure management for the paint stroke system (for other systems to access as well :) ) * Move texture paint tablet presssure exception code for old bugs to stroke system (makes me wonder...aren't other systems also influenced by these pressure issues?) or up in the function hierarchy inside texture paint. This code is still not there so users with tablets may notice some issues. * possibly change other systems to pre-multiply pressure with the relevant influenced attributes in the stroke function. This could get tricky though and it's possible that it could backfire.
2013-03-07 12:11:38 +00:00
Brush *brush;
short tool, blend;
Image *image;
ImBuf *canvas;
ImBuf *clonecanvas;
char *warnpackedfile;
char *warnmultifile;
bool do_masking;
Texture paint refactoring commit This is as close as I can get to keeping the old code intact. After this commit, I will have to change existing code paths, making testing of functionality harder. Changes: * Keep only projective texturing code in paint_image_proj.c * Move 2D code to paint_image_2d.c. This needed the introduction of allocation/cleanup functions for the relevant structures. * Common code interface for both modes stays in paint_image.c (which still includes all old code, system should work as it did with the exception of non-projective 3D paint mode) and is made public. This is not a lot of code, only rectangle invalidation and undo system. * Changed the naming in the new code slightly: imapaint_ prefixed functions refer to common functions used by both systems, paint_2d_ prefixed to 2d painting. There will be an interface for the projection painting as well. Probably there is some leftover naming conversions to do. TODO: * Move operator init/exec/modal to common interface file * Get rid of old BKE_brush_painter_paint, now brush_painter_2d_paint. All code uses stroke system for the stroke management * Write space pressure management for the paint stroke system (for other systems to access as well :) ) * Move texture paint tablet presssure exception code for old bugs to stroke system (makes me wonder...aren't other systems also influenced by these pressure issues?) or up in the function hierarchy inside texture paint. This code is still not there so users with tablets may notice some issues. * possibly change other systems to pre-multiply pressure with the relevant influenced attributes in the stroke function. This could get tricky though and it's possible that it could backfire.
2013-03-07 12:11:38 +00:00
/* viewport texture paint only, but _not_ project paint */
Object *ob;
int faceindex;
float uv[2];
int do_facesel;
bool need_redraw;
Texture paint refactoring commit This is as close as I can get to keeping the old code intact. After this commit, I will have to change existing code paths, making testing of functionality harder. Changes: * Keep only projective texturing code in paint_image_proj.c * Move 2D code to paint_image_2d.c. This needed the introduction of allocation/cleanup functions for the relevant structures. * Common code interface for both modes stays in paint_image.c (which still includes all old code, system should work as it did with the exception of non-projective 3D paint mode) and is made public. This is not a lot of code, only rectangle invalidation and undo system. * Changed the naming in the new code slightly: imapaint_ prefixed functions refer to common functions used by both systems, paint_2d_ prefixed to 2d painting. There will be an interface for the projection painting as well. Probably there is some leftover naming conversions to do. TODO: * Move operator init/exec/modal to common interface file * Get rid of old BKE_brush_painter_paint, now brush_painter_2d_paint. All code uses stroke system for the stroke management * Write space pressure management for the paint stroke system (for other systems to access as well :) ) * Move texture paint tablet presssure exception code for old bugs to stroke system (makes me wonder...aren't other systems also influenced by these pressure issues?) or up in the function hierarchy inside texture paint. This code is still not there so users with tablets may notice some issues. * possibly change other systems to pre-multiply pressure with the relevant influenced attributes in the stroke function. This could get tricky though and it's possible that it could backfire.
2013-03-07 12:11:38 +00:00
} ImagePaintState;
static BrushPainter *brush_painter_2d_new(Scene *scene, Brush *brush)
{
BrushPainter *painter = MEM_callocN(sizeof(BrushPainter), "BrushPainter");
painter->brush = brush;
painter->scene = scene;
painter->firsttouch = 1;
painter->cache.lastsize = -1; /* force ibuf create in refresh */
return painter;
}
static void brush_painter_2d_require_imbuf(BrushPainter *painter, bool use_float, bool use_color_correction, bool use_masking)
{
Brush *brush = painter->brush;
if ((painter->cache.use_float != use_float)) {
if (painter->cache.ibuf) IMB_freeImBuf(painter->cache.ibuf);
if (painter->cache.mask) MEM_freeN(painter->cache.mask);
painter->cache.ibuf = NULL;
painter->cache.mask = NULL;
painter->cache.lastsize = -1; /* force ibuf create in refresh */
}
if (painter->cache.use_float != use_float) {
if (painter->cache.texibuf) IMB_freeImBuf(painter->cache.texibuf);
painter->cache.texibuf = NULL;
painter->cache.lastsize = -1; /* force ibuf create in refresh */
}
painter->cache.use_float = use_float;
painter->cache.use_color_correction = use_float && use_color_correction;
painter->cache.use_masking = use_masking;
painter->cache.is_texbrush = (brush->mtex.tex && brush->imagepaint_tool == PAINT_TOOL_DRAW) ? true : false;
painter->cache.is_maskbrush = (brush->mask_mtex.tex) ? true : false;
}
static void brush_painter_2d_free(BrushPainter *painter)
{
if (painter->cache.ibuf) IMB_freeImBuf(painter->cache.ibuf);
if (painter->cache.texibuf) IMB_freeImBuf(painter->cache.texibuf);
if (painter->cache.mask) MEM_freeN(painter->cache.mask);
MEM_freeN(painter);
}
static void brush_imbuf_tex_co(rctf *mapping, int x, int y, float texco[3])
{
texco[0] = mapping->xmin + x * mapping->xmax;
texco[1] = mapping->ymin + y * mapping->ymax;
texco[2] = 0.0f;
}
/* create a mask with the falloff strength and optionally brush alpha */
static unsigned short *brush_painter_mask_new(BrushPainter *painter, int size)
{
Scene *scene = painter->scene;
Brush *brush = painter->brush;
bool use_masking = painter->cache.use_masking;
float alpha = (use_masking)? 1.0f: BKE_brush_alpha_get(scene, brush);
int radius = BKE_brush_size_get(scene, brush);
int xoff = -size * 0.5f + 0.5f;
int yoff = -size * 0.5f + 0.5f;
unsigned short *mask, *m;
int x, y;
2013-05-14 06:58:35 +00:00
mask = MEM_callocN(sizeof(unsigned short) * size * size, "brush_painter_mask");
m = mask;
for (y = 0; y < size; y++) {
for (x = 0; x < size; x++, m++) {
float xy[2] = {x + xoff, y + yoff};
float len = len_v2(xy);
float strength = alpha;
strength *= BKE_brush_curve_strength_clamp(brush, len, radius);
*m = (unsigned short)(65535.0f * strength);
}
}
return mask;
}
/* create imbuf with brush color */
static ImBuf *brush_painter_imbuf_new(BrushPainter *painter, int size)
{
Scene *scene = painter->scene;
Brush *brush = painter->brush;
rctf tex_mapping = painter->tex_mapping;
rctf mask_mapping = painter->mask_mapping;
struct ImagePool *pool = painter->pool;
bool use_masking = painter->cache.use_masking;
bool use_color_correction = painter->cache.use_color_correction;
bool use_float = painter->cache.use_float;
bool is_texbrush = painter->cache.is_texbrush;
bool is_maskbrush = painter->cache.is_maskbrush;
float alpha = (use_masking)? 1.0f: BKE_brush_alpha_get(scene, brush);
int radius = BKE_brush_size_get(scene, brush);
int xoff = -size * 0.5f + 0.5f;
int yoff = -size * 0.5f + 0.5f;
int x, y, thread = 0;
float brush_rgb[3];
/* allocate image buffer */
ImBuf *ibuf = IMB_allocImBuf(size, size, 32, (use_float) ? IB_rectfloat : IB_rect);
/* get brush color */
if (brush->imagepaint_tool == PAINT_TOOL_DRAW) {
copy_v3_v3(brush_rgb, brush->rgb);
if (use_color_correction)
srgb_to_linearrgb_v3_v3(brush_rgb, brush_rgb);
}
else {
brush_rgb[0] = 1.0f;
brush_rgb[1] = 1.0f;
brush_rgb[2] = 1.0f;
}
/* fill image buffer */
for (y = 0; y < size; y++) {
for (x = 0; x < size; x++) {
/* sample texture and multiply with brush color */
float texco[3], rgba[4];
if (is_texbrush) {
brush_imbuf_tex_co(&tex_mapping, x, y, texco);
BKE_brush_sample_tex_3D(scene, brush, texco, rgba, thread, pool);
mul_v3_v3(rgba, brush_rgb);
}
else {
copy_v3_v3(rgba, brush_rgb);
rgba[3] = 1.0f;
}
if (is_maskbrush) {
brush_imbuf_tex_co(&mask_mapping, x, y, texco);
rgba[3] *= BKE_brush_sample_masktex(scene, brush, texco, thread, pool);
}
/* when not using masking, multiply in falloff and strength */
if (!use_masking) {
float xy[2] = {x + xoff, y + yoff};
float len = len_v2(xy);
rgba[3] *= alpha * BKE_brush_curve_strength_clamp(brush, len, radius);
}
if (use_float) {
/* write to float pixel */
float *dstf = ibuf->rect_float + (y * size + x) * 4;
mul_v3_v3fl(dstf, rgba, rgba[3]); /* premultiply */
dstf[3] = rgba[3];
}
else {
/* write to byte pixel */
unsigned char *dst = (unsigned char *)ibuf->rect + (y * size + x) * 4;
rgb_float_to_uchar(dst, rgba);
dst[3] = FTOCHAR(rgba[3]);
}
}
}
return ibuf;
}
/* update rectangular section of the brush image */
static void brush_painter_imbuf_update(BrushPainter *painter, ImBuf *oldtexibuf,
int origx, int origy, int w, int h, int xt, int yt)
{
Scene *scene = painter->scene;
Brush *brush = painter->brush;
rctf tex_mapping = painter->tex_mapping;
rctf mask_mapping = painter->mask_mapping;
struct ImagePool *pool = painter->pool;
bool use_masking = painter->cache.use_masking;
bool use_color_correction = painter->cache.use_color_correction;
bool use_float = painter->cache.use_float;
bool is_texbrush = painter->cache.is_texbrush;
bool is_maskbrush = painter->cache.is_maskbrush;
bool use_texture_old = (oldtexibuf != NULL);
int x, y, thread = 0;
float brush_rgb[3];
ImBuf *ibuf = painter->cache.ibuf;
ImBuf *texibuf = painter->cache.texibuf;
unsigned short *mask = painter->cache.mask;
/* get brush color */
if (brush->imagepaint_tool == PAINT_TOOL_DRAW) {
copy_v3_v3(brush_rgb, brush->rgb);
if (use_color_correction)
srgb_to_linearrgb_v3_v3(brush_rgb, brush_rgb);
}
else {
brush_rgb[0] = 1.0f;
brush_rgb[1] = 1.0f;
brush_rgb[2] = 1.0f;
}
/* fill pixes */
for (y = origy; y < h; y++) {
for (x = origx; x < w; x++) {
/* sample texture and multiply with brush color */
float texco[3], rgba[4];
if (!use_texture_old) {
if (is_texbrush) {
brush_imbuf_tex_co(&tex_mapping, x, y, texco);
BKE_brush_sample_tex_3D(scene, brush, texco, rgba, thread, pool);
mul_v3_v3(rgba, brush_rgb);
}
else {
copy_v3_v3(rgba, brush_rgb);
rgba[3] = 1.0f;
}
if (is_maskbrush) {
brush_imbuf_tex_co(&mask_mapping, x, y, texco);
rgba[3] *= BKE_brush_sample_masktex(scene, brush, texco, thread, pool);
}
}
if (use_float) {
/* handle float pixel */
float *bf = ibuf->rect_float + (y * ibuf->x + x) * 4;
float *tf = texibuf->rect_float + (y * texibuf->x + x) * 4;
/* read from old texture buffer */
if (use_texture_old) {
float *otf = oldtexibuf->rect_float + ((y - origy + yt) * oldtexibuf->x + (x - origx + xt)) * 4;
copy_v4_v4(rgba, otf);
}
/* write to new texture buffer */
copy_v4_v4(tf, rgba);
/* if not using masking, multiply in the mask now */
if (!use_masking) {
unsigned short *m = mask + (y * ibuf->x + x);
rgba[3] *= *m * (1.0f / 65535.0f);
}
/* output premultiplied float image, mf was already premultiplied */
mul_v3_v3fl(bf, rgba, rgba[3]);
bf[3] = rgba[3];
}
else {
unsigned char crgba[4];
/* handle byte pixel */
unsigned char *b = (unsigned char *)ibuf->rect + (y * ibuf->x + x) * 4;
unsigned char *t = (unsigned char *)texibuf->rect + (y * texibuf->x + x) * 4;
/* read from old texture buffer */
if (use_texture_old) {
unsigned char *ot = (unsigned char *)oldtexibuf->rect + ((y - origy + yt) * oldtexibuf->x + (x - origx + xt)) * 4;
crgba[0] = ot[0];
crgba[1] = ot[1];
crgba[2] = ot[2];
crgba[3] = ot[3];
}
else
rgba_float_to_uchar(crgba, rgba);
/* write to new texture buffer */
t[0] = crgba[0];
t[1] = crgba[1];
t[2] = crgba[2];
t[3] = crgba[3];
/* if not using masking, multiply in the mask now */
if (!use_masking) {
unsigned short *m = mask + (y * ibuf->x + x);
crgba[3] = (crgba[3] * (*m)) / 65535;
}
/* write to brush image buffer */
b[0] = crgba[0];
b[1] = crgba[1];
b[2] = crgba[2];
b[3] = crgba[3];
}
}
}
}
/* update the brush image by trying to reuse the cached texture result. this
* can be considerably faster for brushes that change size due to pressure or
* textures that stick to the surface where only part of the pixels are new */
static void brush_painter_imbuf_partial_update(BrushPainter *painter, const float pos[2])
{
const Scene *scene = painter->scene;
Brush *brush = painter->brush;
BrushPainterCache *cache = &painter->cache;
ImBuf *oldtexibuf, *ibuf;
int imbflag, destx, desty, srcx, srcy, w, h, x1, y1, x2, y2;
int diameter = 2 * BKE_brush_size_get(scene, brush);
/* create brush image buffer if it didn't exist yet */
imbflag = (cache->use_float) ? IB_rectfloat : IB_rect;
if (!cache->ibuf)
cache->ibuf = IMB_allocImBuf(diameter, diameter, 32, imbflag);
ibuf = cache->ibuf;
/* create new texture image buffer with coordinates relative to old */
oldtexibuf = cache->texibuf;
cache->texibuf = IMB_allocImBuf(diameter, diameter, 32, imbflag);
if (oldtexibuf) {
srcx = srcy = 0;
destx = (int)painter->lastpaintpos[0] - (int)pos[0];
desty = (int)painter->lastpaintpos[1] - (int)pos[1];
w = oldtexibuf->x;
h = oldtexibuf->y;
IMB_rectclip(cache->texibuf, oldtexibuf, &destx, &desty, &srcx, &srcy, &w, &h);
}
else {
srcx = srcy = 0;
destx = desty = 0;
w = h = 0;
}
x1 = destx;
y1 = desty;
x2 = min_ii(destx + w, ibuf->x);
y2 = min_ii(desty + h, ibuf->y);
/* blend existing texture in new position */
if ((x1 < x2) && (y1 < y2))
brush_painter_imbuf_update(painter, oldtexibuf, x1, y1, x2, y2, srcx, srcy);
if (oldtexibuf)
IMB_freeImBuf(oldtexibuf);
/* sample texture in new areas */
if ((0 < x1) && (0 < ibuf->y))
brush_painter_imbuf_update(painter, NULL, 0, 0, x1, ibuf->y, 0, 0);
if ((x2 < ibuf->x) && (0 < ibuf->y))
brush_painter_imbuf_update(painter, NULL, x2, 0, ibuf->x, ibuf->y, 0, 0);
if ((x1 < x2) && (0 < y1))
brush_painter_imbuf_update(painter, NULL, x1, 0, x2, y1, 0, 0);
if ((x1 < x2) && (y2 < ibuf->y))
brush_painter_imbuf_update(painter, NULL, x1, y2, x2, ibuf->y, 0, 0);
}
static void brush_painter_2d_tex_mapping(ImagePaintState *s, int size, const float startpos[2], const float pos[2], int mapmode, rctf *mapping)
{
2013-05-01 02:53:45 +00:00
float invw = 1.0f / (float)s->canvas->x;
float invh = 1.0f / (float)s->canvas->y;
int xmin, ymin, xmax, ymax;
int ipos[2];
/* find start coordinate of brush in canvas */
ipos[0] = (int)floorf((pos[0] - size / 2) + 1.0f);
ipos[1] = (int)floorf((pos[1] - size / 2) + 1.0f);
if (ELEM(mapmode, MTEX_MAP_MODE_STENCIL, MTEX_MAP_MODE_VIEW)) {
/* map from view coordinates of brush to region coordinates */
2013-05-01 02:53:45 +00:00
UI_view2d_to_region_no_clip(s->v2d, ipos[0] * invw, ipos[1] * invh, &xmin, &ymin);
UI_view2d_to_region_no_clip(s->v2d, (ipos[0] + size) * invw, (ipos[1] + size) * invh, &xmax, &ymax);
/* output mapping from brush ibuf x/y to region coordinates */
mapping->xmin = xmin;
mapping->ymin = ymin;
mapping->xmax = (xmax - xmin) / (float)size;
mapping->ymax = (ymax - ymin) / (float)size;
}
else if (mapmode == MTEX_MAP_MODE_3D) {
/* 3D mapping, just mapping to canvas 0..1 */
2013-05-01 02:53:45 +00:00
mapping->xmin = ipos[0] * invw;
mapping->ymin = ipos[1] * invh;
mapping->xmax = size * invw / (float)size;
mapping->ymax = size * invh / (float)size;
}
else {
/* other mapping */
mapping->xmin = -size * 0.5f + 0.5f;
mapping->ymin = -size * 0.5f + 0.5f;
mapping->xmax = 1.0f;
mapping->ymax = 1.0f;
}
if (mapmode == MTEX_MAP_MODE_TILED) {
/* offset relative to start position for tiled */
mapping->xmin += (int)pos[0] - (int)startpos[0];
mapping->ymin += (int)pos[1] - (int)startpos[1];
}
}
static void brush_painter_2d_refresh_cache(ImagePaintState *s, BrushPainter *painter, const float pos[2])
{
const Scene *scene = painter->scene;
2013-03-15 09:48:51 +00:00
UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
Brush *brush = painter->brush;
BrushPainterCache *cache = &painter->cache;
const int diameter = 2 * BKE_brush_size_get(scene, brush);
const int size = (cache->size) ? cache->size : diameter;
const float alpha = BKE_brush_alpha_get(scene, brush);
const bool use_masking = painter->cache.use_masking;
bool do_random = false;
bool do_partial_update = false;
bool do_view = false;
float tex_rotation = -brush->mtex.rot;
float mask_rotation = -brush->mask_mtex.rot;
/* determine how can update based on textures used */
if (painter->cache.is_texbrush) {
if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_VIEW) {
do_view = true;
tex_rotation += ups->brush_rotation;
}
else if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_RANDOM)
do_random = true;
else
do_partial_update = true;
brush_painter_2d_tex_mapping(s, size, painter->startpaintpos, pos,
brush->mtex.brush_map_mode, &painter->tex_mapping);
}
2013-03-15 09:48:51 +00:00
if (painter->cache.is_maskbrush) {
if (brush->mask_mtex.brush_map_mode == MTEX_MAP_MODE_VIEW) {
do_view = true;
mask_rotation += ups->brush_rotation;
}
else if (brush->mask_mtex.brush_map_mode == MTEX_MAP_MODE_RANDOM)
do_random = true;
else
do_partial_update = true;
brush_painter_2d_tex_mapping(s, size, painter->startpaintpos,
2013-05-14 06:58:35 +00:00
pos, brush->mask_mtex.brush_map_mode, &painter->mask_mapping);
2013-03-15 09:48:51 +00:00
}
if (do_view || do_random)
do_partial_update = false;
painter->pool = BKE_image_pool_new();
/* detect if we need to recreate image brush buffer */
if (diameter != cache->lastsize ||
alpha != cache->lastalpha ||
2013-03-15 09:48:51 +00:00
brush->jitter != cache->lastjitter ||
tex_rotation != cache->last_tex_rotation ||
mask_rotation != cache->last_mask_rotation ||
do_random)
{
if (cache->ibuf) {
IMB_freeImBuf(cache->ibuf);
cache->ibuf = NULL;
}
if (cache->mask) {
MEM_freeN(cache->mask);
cache->mask = NULL;
}
if (do_partial_update) {
/* do partial update of texture + recreate mask */
cache->mask = brush_painter_mask_new(painter, size);
brush_painter_imbuf_partial_update(painter, pos);
}
else {
/* create brush and mask from scratch */
if (use_masking)
cache->mask = brush_painter_mask_new(painter, size);
cache->ibuf = brush_painter_imbuf_new(painter, size);
}
cache->lastsize = diameter;
cache->lastalpha = alpha;
cache->lastjitter = brush->jitter;
cache->last_tex_rotation = tex_rotation;
cache->last_mask_rotation = mask_rotation;
}
else if (do_partial_update) {
/* do only partial update of texture */
int dx = (int)painter->lastpaintpos[0] - (int)pos[0];
int dy = (int)painter->lastpaintpos[1] - (int)pos[1];
if ((dx != 0) || (dy != 0)) {
brush_painter_imbuf_partial_update(painter, pos);
}
}
BKE_image_pool_free(painter->pool);
painter->pool = NULL;
}
Texture paint refactoring commit This is as close as I can get to keeping the old code intact. After this commit, I will have to change existing code paths, making testing of functionality harder. Changes: * Keep only projective texturing code in paint_image_proj.c * Move 2D code to paint_image_2d.c. This needed the introduction of allocation/cleanup functions for the relevant structures. * Common code interface for both modes stays in paint_image.c (which still includes all old code, system should work as it did with the exception of non-projective 3D paint mode) and is made public. This is not a lot of code, only rectangle invalidation and undo system. * Changed the naming in the new code slightly: imapaint_ prefixed functions refer to common functions used by both systems, paint_2d_ prefixed to 2d painting. There will be an interface for the projection painting as well. Probably there is some leftover naming conversions to do. TODO: * Move operator init/exec/modal to common interface file * Get rid of old BKE_brush_painter_paint, now brush_painter_2d_paint. All code uses stroke system for the stroke management * Write space pressure management for the paint stroke system (for other systems to access as well :) ) * Move texture paint tablet presssure exception code for old bugs to stroke system (makes me wonder...aren't other systems also influenced by these pressure issues?) or up in the function hierarchy inside texture paint. This code is still not there so users with tablets may notice some issues. * possibly change other systems to pre-multiply pressure with the relevant influenced attributes in the stroke function. This could get tricky though and it's possible that it could backfire.
2013-03-07 12:11:38 +00:00
/* keep these functions in sync */
static void paint_2d_ibuf_rgb_get(ImBuf *ibuf, int x, int y, const short is_torus, float r_rgb[3])
{
Texture paint refactoring commit This is as close as I can get to keeping the old code intact. After this commit, I will have to change existing code paths, making testing of functionality harder. Changes: * Keep only projective texturing code in paint_image_proj.c * Move 2D code to paint_image_2d.c. This needed the introduction of allocation/cleanup functions for the relevant structures. * Common code interface for both modes stays in paint_image.c (which still includes all old code, system should work as it did with the exception of non-projective 3D paint mode) and is made public. This is not a lot of code, only rectangle invalidation and undo system. * Changed the naming in the new code slightly: imapaint_ prefixed functions refer to common functions used by both systems, paint_2d_ prefixed to 2d painting. There will be an interface for the projection painting as well. Probably there is some leftover naming conversions to do. TODO: * Move operator init/exec/modal to common interface file * Get rid of old BKE_brush_painter_paint, now brush_painter_2d_paint. All code uses stroke system for the stroke management * Write space pressure management for the paint stroke system (for other systems to access as well :) ) * Move texture paint tablet presssure exception code for old bugs to stroke system (makes me wonder...aren't other systems also influenced by these pressure issues?) or up in the function hierarchy inside texture paint. This code is still not there so users with tablets may notice some issues. * possibly change other systems to pre-multiply pressure with the relevant influenced attributes in the stroke function. This could get tricky though and it's possible that it could backfire.
2013-03-07 12:11:38 +00:00
if (is_torus) {
x %= ibuf->x;
if (x < 0) x += ibuf->x;
y %= ibuf->y;
if (y < 0) y += ibuf->y;
}
if (ibuf->rect_float) {
float *rrgbf = ibuf->rect_float + (ibuf->x * y + x) * 4;
IMAPAINT_FLOAT_RGB_COPY(r_rgb, rrgbf);
}
else {
char *rrgb = (char *)ibuf->rect + (ibuf->x * y + x) * 4;
IMAPAINT_CHAR_RGB_TO_FLOAT(r_rgb, rrgb);
}
}
static void paint_2d_ibuf_rgb_set(ImBuf *ibuf, int x, int y, const short is_torus, const float rgb[3])
{
if (is_torus) {
x %= ibuf->x;
if (x < 0) x += ibuf->x;
y %= ibuf->y;
if (y < 0) y += ibuf->y;
}
if (ibuf->rect_float) {
float *rrgbf = ibuf->rect_float + (ibuf->x * y + x) * 4;
IMAPAINT_FLOAT_RGB_COPY(rrgbf, rgb);
}
else {
char *rrgb = (char *)ibuf->rect + (ibuf->x * y + x) * 4;
IMAPAINT_FLOAT_RGB_TO_CHAR(rrgb, rgb);
}
}
static int paint_2d_ibuf_add_if(ImBuf *ibuf, unsigned int x, unsigned int y, float *outrgb, short torus)
{
float inrgb[3];
// XXX: signed unsigned mismatch
if ((x >= (unsigned int)(ibuf->x)) || (y >= (unsigned int)(ibuf->y))) {
if (torus) paint_2d_ibuf_rgb_get(ibuf, x, y, 1, inrgb);
else return 0;
}
else {
paint_2d_ibuf_rgb_get(ibuf, x, y, 0, inrgb);
}
outrgb[0] += inrgb[0];
outrgb[1] += inrgb[1];
outrgb[2] += inrgb[2];
return 1;
}
static void paint_2d_lift_soften(ImBuf *ibuf, ImBuf *ibufb, int *pos, const short is_torus)
{
int x, y, count, xi, yi, xo, yo;
int out_off[2], in_off[2], dim[2];
float outrgb[3];
dim[0] = ibufb->x;
dim[1] = ibufb->y;
in_off[0] = pos[0];
in_off[1] = pos[1];
out_off[0] = out_off[1] = 0;
if (!is_torus) {
IMB_rectclip(ibuf, ibufb, &in_off[0], &in_off[1], &out_off[0],
&out_off[1], &dim[0], &dim[1]);
if ((dim[0] == 0) || (dim[1] == 0))
return;
}
for (y = 0; y < dim[1]; y++) {
for (x = 0; x < dim[0]; x++) {
/* get input pixel */
xi = in_off[0] + x;
yi = in_off[1] + y;
count = 1;
paint_2d_ibuf_rgb_get(ibuf, xi, yi, is_torus, outrgb);
count += paint_2d_ibuf_add_if(ibuf, xi - 1, yi - 1, outrgb, is_torus);
count += paint_2d_ibuf_add_if(ibuf, xi - 1, yi, outrgb, is_torus);
count += paint_2d_ibuf_add_if(ibuf, xi - 1, yi + 1, outrgb, is_torus);
count += paint_2d_ibuf_add_if(ibuf, xi, yi - 1, outrgb, is_torus);
count += paint_2d_ibuf_add_if(ibuf, xi, yi + 1, outrgb, is_torus);
count += paint_2d_ibuf_add_if(ibuf, xi + 1, yi - 1, outrgb, is_torus);
count += paint_2d_ibuf_add_if(ibuf, xi + 1, yi, outrgb, is_torus);
count += paint_2d_ibuf_add_if(ibuf, xi + 1, yi + 1, outrgb, is_torus);
mul_v3_fl(outrgb, 1.0f / (float)count);
/* write into brush buffer */
xo = out_off[0] + x;
yo = out_off[1] + y;
paint_2d_ibuf_rgb_set(ibufb, xo, yo, 0, outrgb);
}
}
}
static void paint_2d_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 paint_2d_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);
paint_2d_set_region(&region[tot++], destx, desty, srcx, srcy, w, h);
/* do 3 other rects if needed */
if (w < origw)
paint_2d_set_region(&region[tot++], (destx + w) % dbuf->x, desty, (srcx + w) % sbuf->x, srcy, origw - w, h);
if (h < origh)
paint_2d_set_region(&region[tot++], destx, (desty + h) % dbuf->y, srcx, (srcy + h) % sbuf->y, w, origh - h);
if ((w < origw) && (h < origh))
paint_2d_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 paint_2d_lift_smear(ImBuf *ibuf, ImBuf *ibufb, int *pos)
{
ImagePaintRegion region[4];
int a, tot;
paint_2d_set_region(region, 0, 0, pos[0], pos[1], ibufb->x, ibufb->y);
tot = paint_2d_torus_split_region(region, ibufb, ibuf);
for (a = 0; a < tot; a++)
IMB_rectblend(ibufb, ibufb, ibuf, NULL, NULL, 0, region[a].destx, region[a].desty,
region[a].destx, region[a].desty,
Texture paint refactoring commit This is as close as I can get to keeping the old code intact. After this commit, I will have to change existing code paths, making testing of functionality harder. Changes: * Keep only projective texturing code in paint_image_proj.c * Move 2D code to paint_image_2d.c. This needed the introduction of allocation/cleanup functions for the relevant structures. * Common code interface for both modes stays in paint_image.c (which still includes all old code, system should work as it did with the exception of non-projective 3D paint mode) and is made public. This is not a lot of code, only rectangle invalidation and undo system. * Changed the naming in the new code slightly: imapaint_ prefixed functions refer to common functions used by both systems, paint_2d_ prefixed to 2d painting. There will be an interface for the projection painting as well. Probably there is some leftover naming conversions to do. TODO: * Move operator init/exec/modal to common interface file * Get rid of old BKE_brush_painter_paint, now brush_painter_2d_paint. All code uses stroke system for the stroke management * Write space pressure management for the paint stroke system (for other systems to access as well :) ) * Move texture paint tablet presssure exception code for old bugs to stroke system (makes me wonder...aren't other systems also influenced by these pressure issues?) or up in the function hierarchy inside texture paint. This code is still not there so users with tablets may notice some issues. * possibly change other systems to pre-multiply pressure with the relevant influenced attributes in the stroke function. This could get tricky though and it's possible that it could backfire.
2013-03-07 12:11:38 +00:00
region[a].srcx, region[a].srcy,
region[a].width, region[a].height, IMB_BLEND_COPY_RGB);
}
static ImBuf *paint_2d_lift_clone(ImBuf *ibuf, ImBuf *ibufb, int *pos)
{
/* note: allocImbuf returns zero'd memory, so regions outside image will
* have zero alpha, and hence not be blended onto the image */
int w = ibufb->x, h = ibufb->y, destx = 0, desty = 0, srcx = pos[0], srcy = pos[1];
ImBuf *clonebuf = IMB_allocImBuf(w, h, ibufb->planes, ibufb->flags);
IMB_rectclip(clonebuf, ibuf, &destx, &desty, &srcx, &srcy, &w, &h);
IMB_rectblend(clonebuf, clonebuf, ibuf, NULL, NULL, 0, destx, desty, destx, desty, srcx, srcy, w, h,
Texture paint refactoring commit This is as close as I can get to keeping the old code intact. After this commit, I will have to change existing code paths, making testing of functionality harder. Changes: * Keep only projective texturing code in paint_image_proj.c * Move 2D code to paint_image_2d.c. This needed the introduction of allocation/cleanup functions for the relevant structures. * Common code interface for both modes stays in paint_image.c (which still includes all old code, system should work as it did with the exception of non-projective 3D paint mode) and is made public. This is not a lot of code, only rectangle invalidation and undo system. * Changed the naming in the new code slightly: imapaint_ prefixed functions refer to common functions used by both systems, paint_2d_ prefixed to 2d painting. There will be an interface for the projection painting as well. Probably there is some leftover naming conversions to do. TODO: * Move operator init/exec/modal to common interface file * Get rid of old BKE_brush_painter_paint, now brush_painter_2d_paint. All code uses stroke system for the stroke management * Write space pressure management for the paint stroke system (for other systems to access as well :) ) * Move texture paint tablet presssure exception code for old bugs to stroke system (makes me wonder...aren't other systems also influenced by these pressure issues?) or up in the function hierarchy inside texture paint. This code is still not there so users with tablets may notice some issues. * possibly change other systems to pre-multiply pressure with the relevant influenced attributes in the stroke function. This could get tricky though and it's possible that it could backfire.
2013-03-07 12:11:38 +00:00
IMB_BLEND_COPY_RGB);
IMB_rectblend(clonebuf, clonebuf, ibufb, NULL, NULL, 0, destx, desty, destx, desty, destx, desty, w, h,
Texture paint refactoring commit This is as close as I can get to keeping the old code intact. After this commit, I will have to change existing code paths, making testing of functionality harder. Changes: * Keep only projective texturing code in paint_image_proj.c * Move 2D code to paint_image_2d.c. This needed the introduction of allocation/cleanup functions for the relevant structures. * Common code interface for both modes stays in paint_image.c (which still includes all old code, system should work as it did with the exception of non-projective 3D paint mode) and is made public. This is not a lot of code, only rectangle invalidation and undo system. * Changed the naming in the new code slightly: imapaint_ prefixed functions refer to common functions used by both systems, paint_2d_ prefixed to 2d painting. There will be an interface for the projection painting as well. Probably there is some leftover naming conversions to do. TODO: * Move operator init/exec/modal to common interface file * Get rid of old BKE_brush_painter_paint, now brush_painter_2d_paint. All code uses stroke system for the stroke management * Write space pressure management for the paint stroke system (for other systems to access as well :) ) * Move texture paint tablet presssure exception code for old bugs to stroke system (makes me wonder...aren't other systems also influenced by these pressure issues?) or up in the function hierarchy inside texture paint. This code is still not there so users with tablets may notice some issues. * possibly change other systems to pre-multiply pressure with the relevant influenced attributes in the stroke function. This could get tricky though and it's possible that it could backfire.
2013-03-07 12:11:38 +00:00
IMB_BLEND_COPY_ALPHA);
return clonebuf;
}
static void paint_2d_convert_brushco(ImBuf *ibufb, const float pos[2], int ipos[2])
{
ipos[0] = (int)floorf((pos[0] - ibufb->x / 2) + 1.0f);
ipos[1] = (int)floorf((pos[1] - ibufb->y / 2) + 1.0f);
}
static int paint_2d_op(void *state, ImBuf *ibufb, unsigned short *maskb, const float lastpos[2], const float pos[2])
Texture paint refactoring commit This is as close as I can get to keeping the old code intact. After this commit, I will have to change existing code paths, making testing of functionality harder. Changes: * Keep only projective texturing code in paint_image_proj.c * Move 2D code to paint_image_2d.c. This needed the introduction of allocation/cleanup functions for the relevant structures. * Common code interface for both modes stays in paint_image.c (which still includes all old code, system should work as it did with the exception of non-projective 3D paint mode) and is made public. This is not a lot of code, only rectangle invalidation and undo system. * Changed the naming in the new code slightly: imapaint_ prefixed functions refer to common functions used by both systems, paint_2d_ prefixed to 2d painting. There will be an interface for the projection painting as well. Probably there is some leftover naming conversions to do. TODO: * Move operator init/exec/modal to common interface file * Get rid of old BKE_brush_painter_paint, now brush_painter_2d_paint. All code uses stroke system for the stroke management * Write space pressure management for the paint stroke system (for other systems to access as well :) ) * Move texture paint tablet presssure exception code for old bugs to stroke system (makes me wonder...aren't other systems also influenced by these pressure issues?) or up in the function hierarchy inside texture paint. This code is still not there so users with tablets may notice some issues. * possibly change other systems to pre-multiply pressure with the relevant influenced attributes in the stroke function. This could get tricky though and it's possible that it could backfire.
2013-03-07 12:11:38 +00:00
{
ImagePaintState *s = ((ImagePaintState *)state);
ImBuf *clonebuf = NULL, *frombuf, *tmpbuf = NULL;
Texture paint refactoring commit This is as close as I can get to keeping the old code intact. After this commit, I will have to change existing code paths, making testing of functionality harder. Changes: * Keep only projective texturing code in paint_image_proj.c * Move 2D code to paint_image_2d.c. This needed the introduction of allocation/cleanup functions for the relevant structures. * Common code interface for both modes stays in paint_image.c (which still includes all old code, system should work as it did with the exception of non-projective 3D paint mode) and is made public. This is not a lot of code, only rectangle invalidation and undo system. * Changed the naming in the new code slightly: imapaint_ prefixed functions refer to common functions used by both systems, paint_2d_ prefixed to 2d painting. There will be an interface for the projection painting as well. Probably there is some leftover naming conversions to do. TODO: * Move operator init/exec/modal to common interface file * Get rid of old BKE_brush_painter_paint, now brush_painter_2d_paint. All code uses stroke system for the stroke management * Write space pressure management for the paint stroke system (for other systems to access as well :) ) * Move texture paint tablet presssure exception code for old bugs to stroke system (makes me wonder...aren't other systems also influenced by these pressure issues?) or up in the function hierarchy inside texture paint. This code is still not there so users with tablets may notice some issues. * possibly change other systems to pre-multiply pressure with the relevant influenced attributes in the stroke function. This could get tricky though and it's possible that it could backfire.
2013-03-07 12:11:38 +00:00
ImagePaintRegion region[4];
short torus = s->brush->flag & BRUSH_TORUS;
short blend = s->blend;
float *offset = s->brush->clone.offset;
float liftpos[2];
float brush_alpha = BKE_brush_alpha_get(s->scene, s->brush);
unsigned short mask_max = (unsigned short)(brush_alpha * 65535.0f);
Texture paint refactoring commit This is as close as I can get to keeping the old code intact. After this commit, I will have to change existing code paths, making testing of functionality harder. Changes: * Keep only projective texturing code in paint_image_proj.c * Move 2D code to paint_image_2d.c. This needed the introduction of allocation/cleanup functions for the relevant structures. * Common code interface for both modes stays in paint_image.c (which still includes all old code, system should work as it did with the exception of non-projective 3D paint mode) and is made public. This is not a lot of code, only rectangle invalidation and undo system. * Changed the naming in the new code slightly: imapaint_ prefixed functions refer to common functions used by both systems, paint_2d_ prefixed to 2d painting. There will be an interface for the projection painting as well. Probably there is some leftover naming conversions to do. TODO: * Move operator init/exec/modal to common interface file * Get rid of old BKE_brush_painter_paint, now brush_painter_2d_paint. All code uses stroke system for the stroke management * Write space pressure management for the paint stroke system (for other systems to access as well :) ) * Move texture paint tablet presssure exception code for old bugs to stroke system (makes me wonder...aren't other systems also influenced by these pressure issues?) or up in the function hierarchy inside texture paint. This code is still not there so users with tablets may notice some issues. * possibly change other systems to pre-multiply pressure with the relevant influenced attributes in the stroke function. This could get tricky though and it's possible that it could backfire.
2013-03-07 12:11:38 +00:00
int bpos[2], blastpos[2], bliftpos[2];
int a, tot;
paint_2d_convert_brushco(ibufb, pos, bpos);
/* lift from canvas */
if (s->tool == PAINT_TOOL_SOFTEN) {
paint_2d_lift_soften(s->canvas, ibufb, bpos, torus);
}
else if (s->tool == PAINT_TOOL_SMEAR) {
if (lastpos[0] == pos[0] && lastpos[1] == pos[1])
return 0;
paint_2d_convert_brushco(ibufb, lastpos, blastpos);
paint_2d_lift_smear(s->canvas, ibufb, blastpos);
}
else if (s->tool == PAINT_TOOL_CLONE && s->clonecanvas) {
liftpos[0] = pos[0] - offset[0] * s->canvas->x;
liftpos[1] = pos[1] - offset[1] * s->canvas->y;
paint_2d_convert_brushco(ibufb, liftpos, bliftpos);
clonebuf = paint_2d_lift_clone(s->clonecanvas, ibufb, bliftpos);
}
frombuf = (clonebuf) ? clonebuf : ibufb;
if (torus) {
paint_2d_set_region(region, bpos[0], bpos[1], 0, 0, frombuf->x, frombuf->y);
tot = paint_2d_torus_split_region(region, s->canvas, frombuf);
}
else {
paint_2d_set_region(region, bpos[0], bpos[1], 0, 0, frombuf->x, frombuf->y);
tot = 1;
}
if (s->do_masking)
tmpbuf = IMB_allocImBuf(IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE, 32, 0);
Texture paint refactoring commit This is as close as I can get to keeping the old code intact. After this commit, I will have to change existing code paths, making testing of functionality harder. Changes: * Keep only projective texturing code in paint_image_proj.c * Move 2D code to paint_image_2d.c. This needed the introduction of allocation/cleanup functions for the relevant structures. * Common code interface for both modes stays in paint_image.c (which still includes all old code, system should work as it did with the exception of non-projective 3D paint mode) and is made public. This is not a lot of code, only rectangle invalidation and undo system. * Changed the naming in the new code slightly: imapaint_ prefixed functions refer to common functions used by both systems, paint_2d_ prefixed to 2d painting. There will be an interface for the projection painting as well. Probably there is some leftover naming conversions to do. TODO: * Move operator init/exec/modal to common interface file * Get rid of old BKE_brush_painter_paint, now brush_painter_2d_paint. All code uses stroke system for the stroke management * Write space pressure management for the paint stroke system (for other systems to access as well :) ) * Move texture paint tablet presssure exception code for old bugs to stroke system (makes me wonder...aren't other systems also influenced by these pressure issues?) or up in the function hierarchy inside texture paint. This code is still not there so users with tablets may notice some issues. * possibly change other systems to pre-multiply pressure with the relevant influenced attributes in the stroke function. This could get tricky though and it's possible that it could backfire.
2013-03-07 12:11:38 +00:00
/* blend into canvas */
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);
if (s->do_masking) {
/* masking, find original pixels tiles from undo buffer to composite over */
int tilex, tiley, tilew, tileh, tx, ty;
imapaint_region_tiles(s->canvas, region[a].destx, region[a].desty,
region[a].width, region[a].height,
2013-05-01 02:53:45 +00:00
&tilex, &tiley, &tilew, &tileh);
for (ty = tiley; ty <= tileh; ty++) {
for (tx = tilex; tx <= tilew; tx++) {
/* retrieve original pixels + mask from undo buffer */
unsigned short *mask;
int origx = region[a].destx - tx * IMAPAINT_TILE_SIZE;
int origy = region[a].desty - ty * IMAPAINT_TILE_SIZE;
if (s->canvas->rect_float)
tmpbuf->rect_float = image_undo_find_tile(s->image, s->canvas, tx, ty, &mask);
else
tmpbuf->rect = image_undo_find_tile(s->image, s->canvas, tx, ty, &mask);
IMB_rectblend(s->canvas, tmpbuf, frombuf, mask,
maskb, mask_max,
2013-05-01 02:53:45 +00:00
region[a].destx, region[a].desty,
origx, origy,
region[a].srcx, region[a].srcy,
region[a].width, region[a].height, blend);
}
}
}
else {
/* no masking, composite brush directly onto canvas */
IMB_rectblend(s->canvas, s->canvas, frombuf, NULL, NULL, 0,
2013-05-01 02:53:45 +00:00
region[a].destx, region[a].desty,
region[a].destx, region[a].desty,
region[a].srcx, region[a].srcy,
region[a].width, region[a].height, blend);
}
Texture paint refactoring commit This is as close as I can get to keeping the old code intact. After this commit, I will have to change existing code paths, making testing of functionality harder. Changes: * Keep only projective texturing code in paint_image_proj.c * Move 2D code to paint_image_2d.c. This needed the introduction of allocation/cleanup functions for the relevant structures. * Common code interface for both modes stays in paint_image.c (which still includes all old code, system should work as it did with the exception of non-projective 3D paint mode) and is made public. This is not a lot of code, only rectangle invalidation and undo system. * Changed the naming in the new code slightly: imapaint_ prefixed functions refer to common functions used by both systems, paint_2d_ prefixed to 2d painting. There will be an interface for the projection painting as well. Probably there is some leftover naming conversions to do. TODO: * Move operator init/exec/modal to common interface file * Get rid of old BKE_brush_painter_paint, now brush_painter_2d_paint. All code uses stroke system for the stroke management * Write space pressure management for the paint stroke system (for other systems to access as well :) ) * Move texture paint tablet presssure exception code for old bugs to stroke system (makes me wonder...aren't other systems also influenced by these pressure issues?) or up in the function hierarchy inside texture paint. This code is still not there so users with tablets may notice some issues. * possibly change other systems to pre-multiply pressure with the relevant influenced attributes in the stroke function. This could get tricky though and it's possible that it could backfire.
2013-03-07 12:11:38 +00:00
}
if (clonebuf) IMB_freeImBuf(clonebuf);
if (tmpbuf) IMB_freeImBuf(tmpbuf);
Texture paint refactoring commit This is as close as I can get to keeping the old code intact. After this commit, I will have to change existing code paths, making testing of functionality harder. Changes: * Keep only projective texturing code in paint_image_proj.c * Move 2D code to paint_image_2d.c. This needed the introduction of allocation/cleanup functions for the relevant structures. * Common code interface for both modes stays in paint_image.c (which still includes all old code, system should work as it did with the exception of non-projective 3D paint mode) and is made public. This is not a lot of code, only rectangle invalidation and undo system. * Changed the naming in the new code slightly: imapaint_ prefixed functions refer to common functions used by both systems, paint_2d_ prefixed to 2d painting. There will be an interface for the projection painting as well. Probably there is some leftover naming conversions to do. TODO: * Move operator init/exec/modal to common interface file * Get rid of old BKE_brush_painter_paint, now brush_painter_2d_paint. All code uses stroke system for the stroke management * Write space pressure management for the paint stroke system (for other systems to access as well :) ) * Move texture paint tablet presssure exception code for old bugs to stroke system (makes me wonder...aren't other systems also influenced by these pressure issues?) or up in the function hierarchy inside texture paint. This code is still not there so users with tablets may notice some issues. * possibly change other systems to pre-multiply pressure with the relevant influenced attributes in the stroke function. This could get tricky though and it's possible that it could backfire.
2013-03-07 12:11:38 +00:00
return 1;
}
static int paint_2d_canvas_set(ImagePaintState *s, Image *ima)
{
ImBuf *ibuf = BKE_image_acquire_ibuf(ima, s->sima ? &s->sima->iuser : NULL, NULL);
/* verify that we can paint and set canvas */
if (ima == NULL) {
return 0;
}
else if (ima->packedfile && ima->rr) {
s->warnpackedfile = ima->id.name + 2;
return 0;
}
else if (ibuf && ibuf->channels != 4) {
s->warnmultifile = ima->id.name + 2;
return 0;
}
else if (!ibuf || !(ibuf->rect || ibuf->rect_float))
return 0;
s->image = ima;
s->canvas = ibuf;
/* set clone canvas */
if (s->tool == PAINT_TOOL_CLONE) {
ima = s->brush->clone.image;
ibuf = BKE_image_acquire_ibuf(ima, s->sima ? &s->sima->iuser : NULL, NULL);
if (!ima || !ibuf || !(ibuf->rect || ibuf->rect_float)) {
BKE_image_release_ibuf(ima, ibuf, NULL);
BKE_image_release_ibuf(s->image, s->canvas, NULL);
return 0;
}
Texture paint refactoring commit This is as close as I can get to keeping the old code intact. After this commit, I will have to change existing code paths, making testing of functionality harder. Changes: * Keep only projective texturing code in paint_image_proj.c * Move 2D code to paint_image_2d.c. This needed the introduction of allocation/cleanup functions for the relevant structures. * Common code interface for both modes stays in paint_image.c (which still includes all old code, system should work as it did with the exception of non-projective 3D paint mode) and is made public. This is not a lot of code, only rectangle invalidation and undo system. * Changed the naming in the new code slightly: imapaint_ prefixed functions refer to common functions used by both systems, paint_2d_ prefixed to 2d painting. There will be an interface for the projection painting as well. Probably there is some leftover naming conversions to do. TODO: * Move operator init/exec/modal to common interface file * Get rid of old BKE_brush_painter_paint, now brush_painter_2d_paint. All code uses stroke system for the stroke management * Write space pressure management for the paint stroke system (for other systems to access as well :) ) * Move texture paint tablet presssure exception code for old bugs to stroke system (makes me wonder...aren't other systems also influenced by these pressure issues?) or up in the function hierarchy inside texture paint. This code is still not there so users with tablets may notice some issues. * possibly change other systems to pre-multiply pressure with the relevant influenced attributes in the stroke function. This could get tricky though and it's possible that it could backfire.
2013-03-07 12:11:38 +00:00
s->clonecanvas = ibuf;
/* temporarily add float rect for cloning */
if (s->canvas->rect_float && !s->clonecanvas->rect_float) {
IMB_float_from_rect(s->clonecanvas);
}
else if (!s->canvas->rect_float && !s->clonecanvas->rect)
IMB_rect_from_float(s->clonecanvas);
}
/* set masking */
s->do_masking = (s->brush->flag & BRUSH_AIRBRUSH ||
(s->brush->imagepaint_tool == PAINT_TOOL_SMEAR) ||
(s->brush->mtex.tex && !ELEM3(s->brush->mtex.brush_map_mode, MTEX_MAP_MODE_TILED, MTEX_MAP_MODE_STENCIL, MTEX_MAP_MODE_3D)))
2013-05-01 02:53:45 +00:00
? false : true;
Texture paint refactoring commit This is as close as I can get to keeping the old code intact. After this commit, I will have to change existing code paths, making testing of functionality harder. Changes: * Keep only projective texturing code in paint_image_proj.c * Move 2D code to paint_image_2d.c. This needed the introduction of allocation/cleanup functions for the relevant structures. * Common code interface for both modes stays in paint_image.c (which still includes all old code, system should work as it did with the exception of non-projective 3D paint mode) and is made public. This is not a lot of code, only rectangle invalidation and undo system. * Changed the naming in the new code slightly: imapaint_ prefixed functions refer to common functions used by both systems, paint_2d_ prefixed to 2d painting. There will be an interface for the projection painting as well. Probably there is some leftover naming conversions to do. TODO: * Move operator init/exec/modal to common interface file * Get rid of old BKE_brush_painter_paint, now brush_painter_2d_paint. All code uses stroke system for the stroke management * Write space pressure management for the paint stroke system (for other systems to access as well :) ) * Move texture paint tablet presssure exception code for old bugs to stroke system (makes me wonder...aren't other systems also influenced by these pressure issues?) or up in the function hierarchy inside texture paint. This code is still not there so users with tablets may notice some issues. * possibly change other systems to pre-multiply pressure with the relevant influenced attributes in the stroke function. This could get tricky though and it's possible that it could backfire.
2013-03-07 12:11:38 +00:00
return 1;
}
static void paint_2d_canvas_free(ImagePaintState *s)
{
BKE_image_release_ibuf(s->image, s->canvas, NULL);
BKE_image_release_ibuf(s->brush->clone.image, s->clonecanvas, NULL);
if (s->do_masking)
image_undo_remove_masks();
Texture paint refactoring commit This is as close as I can get to keeping the old code intact. After this commit, I will have to change existing code paths, making testing of functionality harder. Changes: * Keep only projective texturing code in paint_image_proj.c * Move 2D code to paint_image_2d.c. This needed the introduction of allocation/cleanup functions for the relevant structures. * Common code interface for both modes stays in paint_image.c (which still includes all old code, system should work as it did with the exception of non-projective 3D paint mode) and is made public. This is not a lot of code, only rectangle invalidation and undo system. * Changed the naming in the new code slightly: imapaint_ prefixed functions refer to common functions used by both systems, paint_2d_ prefixed to 2d painting. There will be an interface for the projection painting as well. Probably there is some leftover naming conversions to do. TODO: * Move operator init/exec/modal to common interface file * Get rid of old BKE_brush_painter_paint, now brush_painter_2d_paint. All code uses stroke system for the stroke management * Write space pressure management for the paint stroke system (for other systems to access as well :) ) * Move texture paint tablet presssure exception code for old bugs to stroke system (makes me wonder...aren't other systems also influenced by these pressure issues?) or up in the function hierarchy inside texture paint. This code is still not there so users with tablets may notice some issues. * possibly change other systems to pre-multiply pressure with the relevant influenced attributes in the stroke function. This could get tricky though and it's possible that it could backfire.
2013-03-07 12:11:38 +00:00
}
void paint_2d_stroke(void *ps, const float prev_mval[2], const float mval[2], int eraser)
Texture paint refactoring commit This is as close as I can get to keeping the old code intact. After this commit, I will have to change existing code paths, making testing of functionality harder. Changes: * Keep only projective texturing code in paint_image_proj.c * Move 2D code to paint_image_2d.c. This needed the introduction of allocation/cleanup functions for the relevant structures. * Common code interface for both modes stays in paint_image.c (which still includes all old code, system should work as it did with the exception of non-projective 3D paint mode) and is made public. This is not a lot of code, only rectangle invalidation and undo system. * Changed the naming in the new code slightly: imapaint_ prefixed functions refer to common functions used by both systems, paint_2d_ prefixed to 2d painting. There will be an interface for the projection painting as well. Probably there is some leftover naming conversions to do. TODO: * Move operator init/exec/modal to common interface file * Get rid of old BKE_brush_painter_paint, now brush_painter_2d_paint. All code uses stroke system for the stroke management * Write space pressure management for the paint stroke system (for other systems to access as well :) ) * Move texture paint tablet presssure exception code for old bugs to stroke system (makes me wonder...aren't other systems also influenced by these pressure issues?) or up in the function hierarchy inside texture paint. This code is still not there so users with tablets may notice some issues. * possibly change other systems to pre-multiply pressure with the relevant influenced attributes in the stroke function. This could get tricky though and it's possible that it could backfire.
2013-03-07 12:11:38 +00:00
{
float newuv[2], olduv[2];
ImagePaintState *s = ps;
BrushPainter *painter = s->painter;
ImBuf *ibuf = BKE_image_acquire_ibuf(s->image, s->sima ? &s->sima->iuser : NULL, NULL);
const bool is_data = (ibuf && ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA);
Texture paint refactoring commit This is as close as I can get to keeping the old code intact. After this commit, I will have to change existing code paths, making testing of functionality harder. Changes: * Keep only projective texturing code in paint_image_proj.c * Move 2D code to paint_image_2d.c. This needed the introduction of allocation/cleanup functions for the relevant structures. * Common code interface for both modes stays in paint_image.c (which still includes all old code, system should work as it did with the exception of non-projective 3D paint mode) and is made public. This is not a lot of code, only rectangle invalidation and undo system. * Changed the naming in the new code slightly: imapaint_ prefixed functions refer to common functions used by both systems, paint_2d_ prefixed to 2d painting. There will be an interface for the projection painting as well. Probably there is some leftover naming conversions to do. TODO: * Move operator init/exec/modal to common interface file * Get rid of old BKE_brush_painter_paint, now brush_painter_2d_paint. All code uses stroke system for the stroke management * Write space pressure management for the paint stroke system (for other systems to access as well :) ) * Move texture paint tablet presssure exception code for old bugs to stroke system (makes me wonder...aren't other systems also influenced by these pressure issues?) or up in the function hierarchy inside texture paint. This code is still not there so users with tablets may notice some issues. * possibly change other systems to pre-multiply pressure with the relevant influenced attributes in the stroke function. This could get tricky though and it's possible that it could backfire.
2013-03-07 12:11:38 +00:00
if (!ibuf)
return;
Texture paint refactoring commit This is as close as I can get to keeping the old code intact. After this commit, I will have to change existing code paths, making testing of functionality harder. Changes: * Keep only projective texturing code in paint_image_proj.c * Move 2D code to paint_image_2d.c. This needed the introduction of allocation/cleanup functions for the relevant structures. * Common code interface for both modes stays in paint_image.c (which still includes all old code, system should work as it did with the exception of non-projective 3D paint mode) and is made public. This is not a lot of code, only rectangle invalidation and undo system. * Changed the naming in the new code slightly: imapaint_ prefixed functions refer to common functions used by both systems, paint_2d_ prefixed to 2d painting. There will be an interface for the projection painting as well. Probably there is some leftover naming conversions to do. TODO: * Move operator init/exec/modal to common interface file * Get rid of old BKE_brush_painter_paint, now brush_painter_2d_paint. All code uses stroke system for the stroke management * Write space pressure management for the paint stroke system (for other systems to access as well :) ) * Move texture paint tablet presssure exception code for old bugs to stroke system (makes me wonder...aren't other systems also influenced by these pressure issues?) or up in the function hierarchy inside texture paint. This code is still not there so users with tablets may notice some issues. * possibly change other systems to pre-multiply pressure with the relevant influenced attributes in the stroke function. This could get tricky though and it's possible that it could backfire.
2013-03-07 12:11:38 +00:00
s->blend = s->brush->blend;
if (eraser)
s->blend = IMB_BLEND_ERASE_ALPHA;
Texture paint refactoring commit This is as close as I can get to keeping the old code intact. After this commit, I will have to change existing code paths, making testing of functionality harder. Changes: * Keep only projective texturing code in paint_image_proj.c * Move 2D code to paint_image_2d.c. This needed the introduction of allocation/cleanup functions for the relevant structures. * Common code interface for both modes stays in paint_image.c (which still includes all old code, system should work as it did with the exception of non-projective 3D paint mode) and is made public. This is not a lot of code, only rectangle invalidation and undo system. * Changed the naming in the new code slightly: imapaint_ prefixed functions refer to common functions used by both systems, paint_2d_ prefixed to 2d painting. There will be an interface for the projection painting as well. Probably there is some leftover naming conversions to do. TODO: * Move operator init/exec/modal to common interface file * Get rid of old BKE_brush_painter_paint, now brush_painter_2d_paint. All code uses stroke system for the stroke management * Write space pressure management for the paint stroke system (for other systems to access as well :) ) * Move texture paint tablet presssure exception code for old bugs to stroke system (makes me wonder...aren't other systems also influenced by these pressure issues?) or up in the function hierarchy inside texture paint. This code is still not there so users with tablets may notice some issues. * possibly change other systems to pre-multiply pressure with the relevant influenced attributes in the stroke function. This could get tricky though and it's possible that it could backfire.
2013-03-07 12:11:38 +00:00
UI_view2d_region_to_view(s->v2d, mval[0], mval[1], &newuv[0], &newuv[1]);
UI_view2d_region_to_view(s->v2d, prev_mval[0], prev_mval[1], &olduv[0], &olduv[1]);
Texture paint refactoring commit This is as close as I can get to keeping the old code intact. After this commit, I will have to change existing code paths, making testing of functionality harder. Changes: * Keep only projective texturing code in paint_image_proj.c * Move 2D code to paint_image_2d.c. This needed the introduction of allocation/cleanup functions for the relevant structures. * Common code interface for both modes stays in paint_image.c (which still includes all old code, system should work as it did with the exception of non-projective 3D paint mode) and is made public. This is not a lot of code, only rectangle invalidation and undo system. * Changed the naming in the new code slightly: imapaint_ prefixed functions refer to common functions used by both systems, paint_2d_ prefixed to 2d painting. There will be an interface for the projection painting as well. Probably there is some leftover naming conversions to do. TODO: * Move operator init/exec/modal to common interface file * Get rid of old BKE_brush_painter_paint, now brush_painter_2d_paint. All code uses stroke system for the stroke management * Write space pressure management for the paint stroke system (for other systems to access as well :) ) * Move texture paint tablet presssure exception code for old bugs to stroke system (makes me wonder...aren't other systems also influenced by these pressure issues?) or up in the function hierarchy inside texture paint. This code is still not there so users with tablets may notice some issues. * possibly change other systems to pre-multiply pressure with the relevant influenced attributes in the stroke function. This could get tricky though and it's possible that it could backfire.
2013-03-07 12:11:38 +00:00
newuv[0] *= ibuf->x;
newuv[1] *= ibuf->y;
Texture paint refactoring commit This is as close as I can get to keeping the old code intact. After this commit, I will have to change existing code paths, making testing of functionality harder. Changes: * Keep only projective texturing code in paint_image_proj.c * Move 2D code to paint_image_2d.c. This needed the introduction of allocation/cleanup functions for the relevant structures. * Common code interface for both modes stays in paint_image.c (which still includes all old code, system should work as it did with the exception of non-projective 3D paint mode) and is made public. This is not a lot of code, only rectangle invalidation and undo system. * Changed the naming in the new code slightly: imapaint_ prefixed functions refer to common functions used by both systems, paint_2d_ prefixed to 2d painting. There will be an interface for the projection painting as well. Probably there is some leftover naming conversions to do. TODO: * Move operator init/exec/modal to common interface file * Get rid of old BKE_brush_painter_paint, now brush_painter_2d_paint. All code uses stroke system for the stroke management * Write space pressure management for the paint stroke system (for other systems to access as well :) ) * Move texture paint tablet presssure exception code for old bugs to stroke system (makes me wonder...aren't other systems also influenced by these pressure issues?) or up in the function hierarchy inside texture paint. This code is still not there so users with tablets may notice some issues. * possibly change other systems to pre-multiply pressure with the relevant influenced attributes in the stroke function. This could get tricky though and it's possible that it could backfire.
2013-03-07 12:11:38 +00:00
olduv[0] *= ibuf->x;
olduv[1] *= ibuf->y;
if (painter->firsttouch) {
float startuv[2];
UI_view2d_region_to_view(s->v2d, 0, 0, &startuv[0], &startuv[1]);
/* paint exactly once on first touch */
2013-05-01 02:53:45 +00:00
painter->startpaintpos[0] = startuv[0] * ibuf->x;
painter->startpaintpos[1] = startuv[1] * ibuf->y;
painter->firsttouch = 0;
copy_v2_v2(painter->lastpaintpos, newuv);
}
else {
copy_v2_v2(painter->lastpaintpos, olduv);
}
Texture paint refactoring commit This is as close as I can get to keeping the old code intact. After this commit, I will have to change existing code paths, making testing of functionality harder. Changes: * Keep only projective texturing code in paint_image_proj.c * Move 2D code to paint_image_2d.c. This needed the introduction of allocation/cleanup functions for the relevant structures. * Common code interface for both modes stays in paint_image.c (which still includes all old code, system should work as it did with the exception of non-projective 3D paint mode) and is made public. This is not a lot of code, only rectangle invalidation and undo system. * Changed the naming in the new code slightly: imapaint_ prefixed functions refer to common functions used by both systems, paint_2d_ prefixed to 2d painting. There will be an interface for the projection painting as well. Probably there is some leftover naming conversions to do. TODO: * Move operator init/exec/modal to common interface file * Get rid of old BKE_brush_painter_paint, now brush_painter_2d_paint. All code uses stroke system for the stroke management * Write space pressure management for the paint stroke system (for other systems to access as well :) ) * Move texture paint tablet presssure exception code for old bugs to stroke system (makes me wonder...aren't other systems also influenced by these pressure issues?) or up in the function hierarchy inside texture paint. This code is still not there so users with tablets may notice some issues. * possibly change other systems to pre-multiply pressure with the relevant influenced attributes in the stroke function. This could get tricky though and it's possible that it could backfire.
2013-03-07 12:11:38 +00:00
/* OCIO_TODO: float buffers are now always linear, so always use color correction
* this should probably be changed when texture painting color space is supported
*/
brush_painter_2d_require_imbuf(painter, (ibuf->rect_float != NULL), !is_data, s->do_masking);
brush_painter_2d_refresh_cache(s, painter, newuv);
if (paint_2d_op(s, painter->cache.ibuf, painter->cache.mask, olduv, newuv))
s->need_redraw = true;
Texture paint refactoring commit This is as close as I can get to keeping the old code intact. After this commit, I will have to change existing code paths, making testing of functionality harder. Changes: * Keep only projective texturing code in paint_image_proj.c * Move 2D code to paint_image_2d.c. This needed the introduction of allocation/cleanup functions for the relevant structures. * Common code interface for both modes stays in paint_image.c (which still includes all old code, system should work as it did with the exception of non-projective 3D paint mode) and is made public. This is not a lot of code, only rectangle invalidation and undo system. * Changed the naming in the new code slightly: imapaint_ prefixed functions refer to common functions used by both systems, paint_2d_ prefixed to 2d painting. There will be an interface for the projection painting as well. Probably there is some leftover naming conversions to do. TODO: * Move operator init/exec/modal to common interface file * Get rid of old BKE_brush_painter_paint, now brush_painter_2d_paint. All code uses stroke system for the stroke management * Write space pressure management for the paint stroke system (for other systems to access as well :) ) * Move texture paint tablet presssure exception code for old bugs to stroke system (makes me wonder...aren't other systems also influenced by these pressure issues?) or up in the function hierarchy inside texture paint. This code is still not there so users with tablets may notice some issues. * possibly change other systems to pre-multiply pressure with the relevant influenced attributes in the stroke function. This could get tricky though and it's possible that it could backfire.
2013-03-07 12:11:38 +00:00
BKE_image_release_ibuf(s->image, ibuf, NULL);
}
2013-03-08 04:00:06 +00:00
void *paint_2d_new_stroke(bContext *C, wmOperator *op)
{
Texture paint refactoring commit This is as close as I can get to keeping the old code intact. After this commit, I will have to change existing code paths, making testing of functionality harder. Changes: * Keep only projective texturing code in paint_image_proj.c * Move 2D code to paint_image_2d.c. This needed the introduction of allocation/cleanup functions for the relevant structures. * Common code interface for both modes stays in paint_image.c (which still includes all old code, system should work as it did with the exception of non-projective 3D paint mode) and is made public. This is not a lot of code, only rectangle invalidation and undo system. * Changed the naming in the new code slightly: imapaint_ prefixed functions refer to common functions used by both systems, paint_2d_ prefixed to 2d painting. There will be an interface for the projection painting as well. Probably there is some leftover naming conversions to do. TODO: * Move operator init/exec/modal to common interface file * Get rid of old BKE_brush_painter_paint, now brush_painter_2d_paint. All code uses stroke system for the stroke management * Write space pressure management for the paint stroke system (for other systems to access as well :) ) * Move texture paint tablet presssure exception code for old bugs to stroke system (makes me wonder...aren't other systems also influenced by these pressure issues?) or up in the function hierarchy inside texture paint. This code is still not there so users with tablets may notice some issues. * possibly change other systems to pre-multiply pressure with the relevant influenced attributes in the stroke function. This could get tricky though and it's possible that it could backfire.
2013-03-07 12:11:38 +00:00
Scene *scene = CTX_data_scene(C);
ToolSettings *settings = scene->toolsettings;
Brush *brush = BKE_paint_brush(&settings->imapaint.paint);
Texture paint refactoring commit This is as close as I can get to keeping the old code intact. After this commit, I will have to change existing code paths, making testing of functionality harder. Changes: * Keep only projective texturing code in paint_image_proj.c * Move 2D code to paint_image_2d.c. This needed the introduction of allocation/cleanup functions for the relevant structures. * Common code interface for both modes stays in paint_image.c (which still includes all old code, system should work as it did with the exception of non-projective 3D paint mode) and is made public. This is not a lot of code, only rectangle invalidation and undo system. * Changed the naming in the new code slightly: imapaint_ prefixed functions refer to common functions used by both systems, paint_2d_ prefixed to 2d painting. There will be an interface for the projection painting as well. Probably there is some leftover naming conversions to do. TODO: * Move operator init/exec/modal to common interface file * Get rid of old BKE_brush_painter_paint, now brush_painter_2d_paint. All code uses stroke system for the stroke management * Write space pressure management for the paint stroke system (for other systems to access as well :) ) * Move texture paint tablet presssure exception code for old bugs to stroke system (makes me wonder...aren't other systems also influenced by these pressure issues?) or up in the function hierarchy inside texture paint. This code is still not there so users with tablets may notice some issues. * possibly change other systems to pre-multiply pressure with the relevant influenced attributes in the stroke function. This could get tricky though and it's possible that it could backfire.
2013-03-07 12:11:38 +00:00
ImagePaintState *s = MEM_callocN(sizeof(ImagePaintState), "ImagePaintState");
s->sima = CTX_wm_space_image(C);
s->v2d = &CTX_wm_region(C)->v2d;
s->scene = scene;
s->screen = CTX_wm_screen(C);
s->brush = brush;
s->tool = brush->imagepaint_tool;
s->blend = brush->blend;
s->image = s->sima->image;
if (!paint_2d_canvas_set(s, s->image)) {
if (s->warnmultifile)
BKE_report(op->reports, RPT_WARNING, "Image requires 4 color channels to paint");
if (s->warnpackedfile)
BKE_report(op->reports, RPT_WARNING, "Packed MultiLayer files cannot be painted");
MEM_freeN(s);
return NULL;
}
paint_brush_init_tex(s->brush);
/* create painter */
s->painter = brush_painter_2d_new(scene, s->brush);
return s;
}
void paint_2d_redraw(const bContext *C, void *ps, bool final)
2013-03-08 04:00:06 +00:00
{
Texture paint refactoring commit This is as close as I can get to keeping the old code intact. After this commit, I will have to change existing code paths, making testing of functionality harder. Changes: * Keep only projective texturing code in paint_image_proj.c * Move 2D code to paint_image_2d.c. This needed the introduction of allocation/cleanup functions for the relevant structures. * Common code interface for both modes stays in paint_image.c (which still includes all old code, system should work as it did with the exception of non-projective 3D paint mode) and is made public. This is not a lot of code, only rectangle invalidation and undo system. * Changed the naming in the new code slightly: imapaint_ prefixed functions refer to common functions used by both systems, paint_2d_ prefixed to 2d painting. There will be an interface for the projection painting as well. Probably there is some leftover naming conversions to do. TODO: * Move operator init/exec/modal to common interface file * Get rid of old BKE_brush_painter_paint, now brush_painter_2d_paint. All code uses stroke system for the stroke management * Write space pressure management for the paint stroke system (for other systems to access as well :) ) * Move texture paint tablet presssure exception code for old bugs to stroke system (makes me wonder...aren't other systems also influenced by these pressure issues?) or up in the function hierarchy inside texture paint. This code is still not there so users with tablets may notice some issues. * possibly change other systems to pre-multiply pressure with the relevant influenced attributes in the stroke function. This could get tricky though and it's possible that it could backfire.
2013-03-07 12:11:38 +00:00
ImagePaintState *s = ps;
if (s->need_redraw) {
ImBuf *ibuf = BKE_image_acquire_ibuf(s->image, s->sima ? &s->sima->iuser : NULL, NULL);
imapaint_image_update(s->sima, s->image, ibuf, false);
imapaint_clear_partial_redraw();
BKE_image_release_ibuf(s->image, ibuf, NULL);
s->need_redraw = false;
}
else if (!final) {
return;
}
Texture paint refactoring commit This is as close as I can get to keeping the old code intact. After this commit, I will have to change existing code paths, making testing of functionality harder. Changes: * Keep only projective texturing code in paint_image_proj.c * Move 2D code to paint_image_2d.c. This needed the introduction of allocation/cleanup functions for the relevant structures. * Common code interface for both modes stays in paint_image.c (which still includes all old code, system should work as it did with the exception of non-projective 3D paint mode) and is made public. This is not a lot of code, only rectangle invalidation and undo system. * Changed the naming in the new code slightly: imapaint_ prefixed functions refer to common functions used by both systems, paint_2d_ prefixed to 2d painting. There will be an interface for the projection painting as well. Probably there is some leftover naming conversions to do. TODO: * Move operator init/exec/modal to common interface file * Get rid of old BKE_brush_painter_paint, now brush_painter_2d_paint. All code uses stroke system for the stroke management * Write space pressure management for the paint stroke system (for other systems to access as well :) ) * Move texture paint tablet presssure exception code for old bugs to stroke system (makes me wonder...aren't other systems also influenced by these pressure issues?) or up in the function hierarchy inside texture paint. This code is still not there so users with tablets may notice some issues. * possibly change other systems to pre-multiply pressure with the relevant influenced attributes in the stroke function. This could get tricky though and it's possible that it could backfire.
2013-03-07 12:11:38 +00:00
if (final) {
if (s->image && !(s->sima && s->sima->lock))
GPU_free_image(s->image);
/* compositor listener deals with updating */
WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, s->image);
}
else {
if (!s->sima || !s->sima->lock)
ED_region_tag_redraw(CTX_wm_region(C));
else
WM_event_add_notifier(C, NC_IMAGE | NA_PAINTING, s->image);
Texture paint refactoring commit This is as close as I can get to keeping the old code intact. After this commit, I will have to change existing code paths, making testing of functionality harder. Changes: * Keep only projective texturing code in paint_image_proj.c * Move 2D code to paint_image_2d.c. This needed the introduction of allocation/cleanup functions for the relevant structures. * Common code interface for both modes stays in paint_image.c (which still includes all old code, system should work as it did with the exception of non-projective 3D paint mode) and is made public. This is not a lot of code, only rectangle invalidation and undo system. * Changed the naming in the new code slightly: imapaint_ prefixed functions refer to common functions used by both systems, paint_2d_ prefixed to 2d painting. There will be an interface for the projection painting as well. Probably there is some leftover naming conversions to do. TODO: * Move operator init/exec/modal to common interface file * Get rid of old BKE_brush_painter_paint, now brush_painter_2d_paint. All code uses stroke system for the stroke management * Write space pressure management for the paint stroke system (for other systems to access as well :) ) * Move texture paint tablet presssure exception code for old bugs to stroke system (makes me wonder...aren't other systems also influenced by these pressure issues?) or up in the function hierarchy inside texture paint. This code is still not there so users with tablets may notice some issues. * possibly change other systems to pre-multiply pressure with the relevant influenced attributes in the stroke function. This could get tricky though and it's possible that it could backfire.
2013-03-07 12:11:38 +00:00
}
}
2013-03-08 04:00:06 +00:00
void paint_2d_stroke_done(void *ps)
{
Texture paint refactoring commit This is as close as I can get to keeping the old code intact. After this commit, I will have to change existing code paths, making testing of functionality harder. Changes: * Keep only projective texturing code in paint_image_proj.c * Move 2D code to paint_image_2d.c. This needed the introduction of allocation/cleanup functions for the relevant structures. * Common code interface for both modes stays in paint_image.c (which still includes all old code, system should work as it did with the exception of non-projective 3D paint mode) and is made public. This is not a lot of code, only rectangle invalidation and undo system. * Changed the naming in the new code slightly: imapaint_ prefixed functions refer to common functions used by both systems, paint_2d_ prefixed to 2d painting. There will be an interface for the projection painting as well. Probably there is some leftover naming conversions to do. TODO: * Move operator init/exec/modal to common interface file * Get rid of old BKE_brush_painter_paint, now brush_painter_2d_paint. All code uses stroke system for the stroke management * Write space pressure management for the paint stroke system (for other systems to access as well :) ) * Move texture paint tablet presssure exception code for old bugs to stroke system (makes me wonder...aren't other systems also influenced by these pressure issues?) or up in the function hierarchy inside texture paint. This code is still not there so users with tablets may notice some issues. * possibly change other systems to pre-multiply pressure with the relevant influenced attributes in the stroke function. This could get tricky though and it's possible that it could backfire.
2013-03-07 12:11:38 +00:00
ImagePaintState *s = ps;
paint_2d_canvas_free(s);
brush_painter_2d_free(s->painter);
paint_brush_exit_tex(s->brush);
MEM_freeN(s);
}