Example #1
0
/* create a mask with the mask texture */
static unsigned short *brush_painter_mask_ibuf_new(BrushPainter *painter, int size)
{
	Scene *scene = painter->scene;
	Brush *brush = painter->brush;
	rctf mask_mapping = painter->mask_mapping;
	struct ImagePool *pool = painter->pool;

	float texco[3];
	unsigned short *mask, *m;
	int x, y, thread = 0;

	mask = MEM_mallocN(sizeof(unsigned short) * size * size, "brush_painter_mask");
	m = mask;

	for (y = 0; y < size; y++) {
		for (x = 0; x < size; x++, m++) {
			float res;
			brush_imbuf_tex_co(&mask_mapping, x, y, texco);
			res = BKE_brush_sample_masktex(scene, brush, texco, thread, pool);
			*m = (unsigned short)(65535.0f * res);
		}
	}

	return mask;
}
Example #2
0
/* update rectangular section of the brush image */
static void brush_painter_mask_imbuf_update(
        BrushPainter *painter, unsigned short *tex_mask_old,
        int origx, int origy, int w, int h, int xt, int yt, int diameter)
{
	Scene *scene = painter->scene;
	Brush *brush = painter->brush;
	rctf tex_mapping = painter->mask_mapping;
	struct ImagePool *pool = painter->pool;
	unsigned short res;

	bool use_texture_old = (tex_mask_old != NULL);

	int x, y, thread = 0;

	unsigned short *tex_mask = painter->cache.tex_mask;
	unsigned short *tex_mask_cur = painter->cache.tex_mask_old;

	/* fill pixels */
	for (y = origy; y < h; y++) {
		for (x = origx; x < w; x++) {
			/* sample texture */
			float texco[3];

			/* handle byte pixel */
			unsigned short *b = tex_mask + (y * diameter + x);
			unsigned short *t = tex_mask_cur + (y * diameter + x);

			if (!use_texture_old) {
				brush_imbuf_tex_co(&tex_mapping, x, y, texco);
				res = (unsigned short)(65535.0f * BKE_brush_sample_masktex(scene, brush, texco, thread, pool));
			}

			/* read from old texture buffer */
			if (use_texture_old) {
				res = *(tex_mask_old + ((y - origy + yt) * painter->cache.tex_mask_old_w + (x - origx + xt)));
			}

			/* write to new texture mask */
			*t = res;
			/* write to mask image buffer */
			*b = res;
		}
	}
}
Example #3
0
/* 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);
                    /* TODO(sergey): Support texture paint color space. */
                    if (!use_float) {
                        linearrgb_to_srgb_v3_v3(rgba, rgba);
                    }
                    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];
            }
        }
    }
}
Example #4
0
/* 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);
                /* TODO(sergey): Support texture paint color space. */
                if (!use_float) {
                    linearrgb_to_srgb_v3_v3(rgba, rgba);
                }
                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;
}