forked from bartvdbraak/blender
Fix T41406:
Disallow kernels bigger than 2x2 for blur/sharpen in projective painting due to performance considerations.
This commit is contained in:
parent
fe7de92c47
commit
4e3f76e06b
@ -129,7 +129,8 @@ def brush_texpaint_common(panel, context, layout, brush, settings, projpaint=Fal
|
||||
col.row().prop(brush, "direction", expand=True)
|
||||
col.separator()
|
||||
col.prop(brush, "sharp_threshold")
|
||||
col.prop(brush, "blur_kernel_radius")
|
||||
if not projpaint:
|
||||
col.prop(brush, "blur_kernel_radius")
|
||||
col.separator()
|
||||
col.prop(brush, "blur_mode")
|
||||
elif brush.image_tool == 'MASK':
|
||||
|
@ -510,19 +510,32 @@ void imapaint_image_update(SpaceImage *sima, Image *image, ImBuf *ibuf, short te
|
||||
}
|
||||
}
|
||||
|
||||
/* paint blur kernels */
|
||||
BlurKernel *paint_new_blur_kernel(Brush *br)
|
||||
/* paint blur kernels. Projective painting enforces use of a 2x2 kernel due to lagging */
|
||||
BlurKernel *paint_new_blur_kernel(Brush *br, bool proj)
|
||||
{
|
||||
int i, j;
|
||||
BlurKernel *kernel = MEM_mallocN(sizeof(BlurKernel), "blur kernel");
|
||||
int pixel_len = br->blur_kernel_radius;
|
||||
float radius;
|
||||
int side;
|
||||
BlurKernelType type = br->blur_mode;
|
||||
|
||||
kernel->side = pixel_len * 2 + 1;
|
||||
kernel->side_squared = kernel->side * kernel->side;
|
||||
kernel->wdata = MEM_mallocN(sizeof(float) * kernel->side_squared, "blur kernel data");
|
||||
kernel->pixel_len = pixel_len;
|
||||
|
||||
if (proj) {
|
||||
radius = 0.5f;
|
||||
|
||||
side = kernel->side = 2;
|
||||
kernel->side_squared = kernel->side * kernel->side;
|
||||
kernel->wdata = MEM_mallocN(sizeof(float) * kernel->side_squared, "blur kernel data");
|
||||
kernel->pixel_len = radius;
|
||||
}
|
||||
else {
|
||||
radius = br->blur_kernel_radius;
|
||||
|
||||
side = kernel->side = radius * 2 + 1;
|
||||
kernel->side_squared = kernel->side * kernel->side;
|
||||
kernel->wdata = MEM_mallocN(sizeof(float) * kernel->side_squared, "blur kernel data");
|
||||
kernel->pixel_len = br->blur_kernel_radius;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case KERNEL_BOX:
|
||||
for (i = 0; i < kernel->side_squared; i++)
|
||||
@ -531,26 +544,19 @@ BlurKernel *paint_new_blur_kernel(Brush *br)
|
||||
|
||||
case KERNEL_GAUSSIAN:
|
||||
{
|
||||
float standard_dev = pixel_len / 3.0; /* at standard deviation of 3.0 kernel is at about zero */
|
||||
int i_term = pixel_len + 1;
|
||||
|
||||
/* at standard deviation of 3.0 kernel is at about zero */
|
||||
float standard_dev = radius / 3.0f;
|
||||
|
||||
/* make the necessary adjustment to the value for use in the normal distribution formula */
|
||||
standard_dev = standard_dev * standard_dev * 2;
|
||||
|
||||
kernel->wdata[pixel_len + pixel_len * kernel->side] = 1.0;
|
||||
/* fill in all four quadrants at once */
|
||||
for (i = 0; i < i_term; i++) {
|
||||
for (j = 0; j < pixel_len; j++) {
|
||||
float idist = pixel_len - i;
|
||||
float jdist = pixel_len - j;
|
||||
|
||||
for (i = 0; i < side; i++) {
|
||||
for (j = 0; j < side; j++) {
|
||||
float idist = radius - i;
|
||||
float jdist = radius - j;
|
||||
float value = exp((idist * idist + jdist * jdist) / standard_dev);
|
||||
|
||||
kernel->wdata[i + j * kernel->side] =
|
||||
kernel->wdata[(kernel->side - j - 1) + i * kernel->side] =
|
||||
kernel->wdata[(kernel->side - i - 1) + (kernel->side - j - 1) * kernel->side] =
|
||||
kernel->wdata[j + (kernel->side - i - 1) * kernel->side] =
|
||||
value;
|
||||
|
||||
kernel->wdata[i + j * side] = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1249,7 +1249,7 @@ void *paint_2d_new_stroke(bContext *C, wmOperator *op, int mode)
|
||||
}
|
||||
|
||||
if (brush->imagepaint_tool == PAINT_TOOL_SOFTEN) {
|
||||
s->blurkernel = paint_new_blur_kernel(brush);
|
||||
s->blurkernel = paint_new_blur_kernel(brush, false);
|
||||
}
|
||||
|
||||
paint_brush_init_tex(s->brush);
|
||||
|
@ -3763,7 +3763,7 @@ static void do_projectpaint_soften_f(ProjPaintState *ps, ProjPixel *projPixel, f
|
||||
for (yk = 0; yk < kernel->side; yk++) {
|
||||
for (xk = 0; xk < kernel->side; xk++) {
|
||||
float rgba_tmp[4];
|
||||
float co_ofs[2] = {xk - kernel->pixel_len, yk - kernel->pixel_len};
|
||||
float co_ofs[2] = {2.0f * xk - 1.0f, 2.0f * yk - 1.0f};
|
||||
|
||||
add_v2_v2(co_ofs, projPixel->projCoSS);
|
||||
|
||||
@ -3819,7 +3819,7 @@ static void do_projectpaint_soften(ProjPaintState *ps, ProjPixel *projPixel, flo
|
||||
for (yk = 0; yk < kernel->side; yk++) {
|
||||
for (xk = 0; xk < kernel->side; xk++) {
|
||||
float rgba_tmp[4];
|
||||
float co_ofs[2] = {xk - kernel->pixel_len, yk - kernel->pixel_len};
|
||||
float co_ofs[2] = {2.0f * xk - 1.0f, 2.0f * yk - 1.0f};
|
||||
|
||||
add_v2_v2(co_ofs, projPixel->projCoSS);
|
||||
|
||||
@ -4453,7 +4453,7 @@ static void project_state_init(bContext *C, Object *ob, ProjPaintState *ps, int
|
||||
ps->mode = ((ps->mode == BRUSH_STROKE_INVERT) ^ ((brush->flag & BRUSH_DIR_IN) != 0) ?
|
||||
BRUSH_STROKE_INVERT : BRUSH_STROKE_NORMAL);
|
||||
|
||||
ps->blurkernel = paint_new_blur_kernel(brush);
|
||||
ps->blurkernel = paint_new_blur_kernel(brush, true);
|
||||
}
|
||||
|
||||
/* disable for 3d mapping also because painting on mirrored mesh can create "stripes" */
|
||||
|
@ -293,7 +293,7 @@ typedef struct {
|
||||
|
||||
enum BlurKernelType;
|
||||
/* can be extended to other blur kernels later */
|
||||
BlurKernel *paint_new_blur_kernel(struct Brush *br);
|
||||
BlurKernel *paint_new_blur_kernel(struct Brush *br, bool proj);
|
||||
void paint_delete_blur_kernel(BlurKernel *);
|
||||
|
||||
/* paint curve defines */
|
||||
|
Loading…
Reference in New Issue
Block a user