예제 #1
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];
            }
        }
    }
}
예제 #2
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;

	const char *display_device = scene->display_settings.display_device;
	struct ColorManagedDisplay *display = IMB_colormanagement_display_get_named(display_device);

	rctf tex_mapping = painter->tex_mapping;
	struct ImagePool *pool = painter->pool;

	bool use_color_correction = painter->cache.use_color_correction;
	bool use_float = painter->cache.use_float;
	bool is_texbrush = painter->cache.is_texbrush;
	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;

	/* get brush color */
	if (brush->imagepaint_tool == PAINT_TOOL_DRAW) {
		paint_brush_color_get(scene, brush, use_color_correction, painter->cache.invert, 0.0, 1.0, brush_rgb, display);
	}
	else {
		brush_rgb[0] = 1.0f;
		brush_rgb[1] = 1.0f;
		brush_rgb[2] = 1.0f;
	}

	/* fill pixels */
	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) {
						IMB_colormanagement_scene_linear_to_display_v3(rgba, display);
					}
					mul_v3_v3(rgba, brush_rgb);
				}
				else {
					copy_v3_v3(rgba, brush_rgb);
					rgba[3] = 1.0f;
				}
			}

			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) {
					const 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);

				/* 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];

				/* write to brush image buffer */
				b[0] = crgba[0];
				b[1] = crgba[1];
				b[2] = crgba[2];
				b[3] = crgba[3];
			}
		}
	}
}
예제 #3
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;
}
예제 #4
0
/* create imbuf with brush color */
static ImBuf *brush_painter_imbuf_new(BrushPainter *painter, int size, float pressure, float distance)
{
	Scene *scene = painter->scene;
	Brush *brush = painter->brush;

	const char *display_device = scene->display_settings.display_device;
	struct ColorManagedDisplay *display = IMB_colormanagement_display_get_named(display_device);

	rctf tex_mapping = painter->tex_mapping;
	struct ImagePool *pool = painter->pool;

	bool use_color_correction = painter->cache.use_color_correction;
	bool use_float = painter->cache.use_float;
	bool is_texbrush = painter->cache.is_texbrush;

	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) {
		paint_brush_color_get(scene, brush, use_color_correction, painter->cache.invert, distance, pressure, brush_rgb, display);
	}
	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) {
					IMB_colormanagement_scene_linear_to_display_v3(rgba, display);
				}
				mul_v3_v3(rgba, brush_rgb);
			}
			else {
				copy_v3_v3(rgba, brush_rgb);
				rgba[3] = 1.0f;
			}

			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;
}