[Bf-blender-cvs] [cc4defac041] temp-udim-images: Support 2D painting onto tiled images

Lukas Stockner noreply at git.blender.org
Mon Jun 11 23:08:44 CEST 2018


Commit: cc4defac041f3d9d2ff6ed38171ade38d9149b96
Author: Lukas Stockner
Date:   Mon Jun 11 23:07:34 2018 +0200
Branches: temp-udim-images
https://developer.blender.org/rBcc4defac041f3d9d2ff6ed38171ade38d9149b96

Support 2D painting onto tiled images

Currently, a limitation is that strokes can not cross between tiles, only the tile in which the stroke started will be affected.

===================================================================

M	source/blender/blenkernel/BKE_image.h
M	source/blender/blenkernel/intern/image.c
M	source/blender/editors/sculpt_paint/paint_image.c
M	source/blender/editors/sculpt_paint/paint_image_2d.c
M	source/blender/editors/sculpt_paint/paint_intern.h

===================================================================

diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h
index 9a39ddd1de7..f795b53e818 100644
--- a/source/blender/blenkernel/BKE_image.h
+++ b/source/blender/blenkernel/BKE_image.h
@@ -283,6 +283,8 @@ void BKE_image_set_bindcode(struct Image *ima, int tile, int type, unsigned int
 struct GPUTexture *BKE_image_get_gpu_texture(struct Image *ima, int tile, int type);
 void BKE_image_set_gpu_texture(struct Image *ima, int tile, int type, struct GPUTexture *tex);
 
+int BKE_image_get_tile_from_pos(struct Image *ima, float uv[2], float new_uv[2], float ofs[2]);
+
 void BKE_image_set_num_tiles(struct Image *ima, int num_tiles);
 
 void BKE_image_get_size(struct Image *image, struct ImageUser *iuser, int *width, int *height);
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index e822d0db469..4edf89fc036 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -556,6 +556,29 @@ bool BKE_image_has_bindcode(Image *ima)
 	return has_bindcode;
 }
 
+int BKE_image_get_tile_from_pos(struct Image *ima, float uv[2], float new_uv[2], float ofs[2])
+{
+	copy_v2_v2(new_uv, uv);
+	zero_v2(ofs);
+
+	if ((ima->source != IMA_SRC_TILED) || uv[0] < 0.0f || uv[1] < 0.0f || uv[0] >= 10.0f) {
+		return 0;
+	}
+
+	int ix = (int) uv[0];
+	int iy = (int) uv[1];
+	int tile = 10*iy + ix;
+
+	if (tile >= ima->num_tiles) {
+		return 0;
+	}
+
+	ofs[0] = ix;
+	ofs[1] = iy;
+	sub_v2_v2(new_uv, ofs);
+	return tile;
+}
+
 static void image_init_color_management(Image *ima)
 {
 	ImBuf *ibuf;
diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c
index 93fa3aac0d7..52d4802fd19 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.c
@@ -472,7 +472,7 @@ static PaintOperation *texture_paint_init(bContext *C, wmOperator *op, const flo
 	}
 	else {
 		pop->mode = PAINT_MODE_2D;
-		pop->custom_paint = paint_2d_new_stroke(C, op, mode);
+		pop->custom_paint = paint_2d_new_stroke(C, op, mouse, mode);
 	}
 
 	if (!pop->custom_paint) {
diff --git a/source/blender/editors/sculpt_paint/paint_image_2d.c b/source/blender/editors/sculpt_paint/paint_image_2d.c
index a75d6344849..4e76d9efc84 100644
--- a/source/blender/editors/sculpt_paint/paint_image_2d.c
+++ b/source/blender/editors/sculpt_paint/paint_image_2d.c
@@ -145,6 +145,9 @@ typedef struct ImagePaintState {
 
 	bool need_redraw;
 
+	int tile;
+	float uv_ofs[2];
+
 	BlurKernel *blurkernel;
 } ImagePaintState;
 
@@ -1189,6 +1192,9 @@ static int paint_2d_op(void *state, ImBuf *ibufb, unsigned short *curveb, unsign
 
 static int paint_2d_canvas_set(ImagePaintState *s, Image *ima)
 {
+	if (s->sima) {
+		s->sima->iuser.tile = s->tile;
+	}
 	ImBuf *ibuf = BKE_image_acquire_ibuf(ima, s->sima ? &s->sima->iuser : NULL, NULL);
 
 	/* verify that we can paint and set canvas */
@@ -1212,6 +1218,9 @@ static int paint_2d_canvas_set(ImagePaintState *s, Image *ima)
 	/* set clone canvas */
 	if (s->tool == PAINT_TOOL_CLONE) {
 		ima = s->brush->clone.image;
+		if (s->sima) {
+			s->sima->iuser.tile = s->tile;
+		}
 		ibuf = BKE_image_acquire_ibuf(ima, s->sima ? &s->sima->iuser : NULL, NULL);
 
 		if (!ima || !ibuf || !(ibuf->rect || ibuf->rect_float)) {
@@ -1249,11 +1258,20 @@ static void paint_2d_canvas_free(ImagePaintState *s)
 	image_undo_remove_masks();
 }
 
+static void paint_2d_transform_mouse(ImagePaintState *s, const float in[2], float out[2])
+{
+	UI_view2d_region_to_view(s->v2d, in[0], in[1], &out[0], &out[1]);
+	sub_v2_v2(out, s->uv_ofs);
+}
+
 void paint_2d_stroke(void *ps, const float prev_mval[2], const float mval[2], const bool eraser, float pressure, float distance, float size)
 {
 	float newuv[2], olduv[2];
 	ImagePaintState *s = ps;
 	BrushPainter *painter = s->painter;
+	if (s->sima) {
+		s->sima->iuser.tile = s->tile;
+	}
 	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);
 
@@ -1264,8 +1282,8 @@ void paint_2d_stroke(void *ps, const float prev_mval[2], const float mval[2], co
 	if (eraser)
 		s->blend = IMB_BLEND_ERASE_ALPHA;
 
-	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]);
+	paint_2d_transform_mouse(s, mval, newuv);
+	paint_2d_transform_mouse(s, prev_mval, olduv);
 
 	newuv[0] *= ibuf->x;
 	newuv[1] *= ibuf->y;
@@ -1276,7 +1294,8 @@ void paint_2d_stroke(void *ps, const float prev_mval[2], const float mval[2], co
 	if (painter->firsttouch) {
 		float startuv[2];
 
-		UI_view2d_region_to_view(s->v2d, 0, 0, &startuv[0], &startuv[1]);
+		zero_v2(startuv);
+		paint_2d_transform_mouse(s, startuv, startuv);
 
 		/* paint exactly once on first touch */
 		painter->startpaintpos[0] = startuv[0] * ibuf->x;
@@ -1302,7 +1321,7 @@ void paint_2d_stroke(void *ps, const float prev_mval[2], const float mval[2], co
 	BKE_image_release_ibuf(s->image, ibuf, NULL);
 }
 
-void *paint_2d_new_stroke(bContext *C, wmOperator *op, int mode)
+void *paint_2d_new_stroke(bContext *C, wmOperator *op, const float mouse[2], int mode)
 {
 	Scene *scene = CTX_data_scene(C);
 	ToolSettings *settings = scene->toolsettings;
@@ -1322,6 +1341,11 @@ void *paint_2d_new_stroke(bContext *C, wmOperator *op, int mode)
 	s->image = s->sima->image;
 	s->symmetry = settings->imapaint.paint.symmetry_flags;
 
+	float uv[2];
+	paint_2d_transform_mouse(s, mouse, uv);
+	s->tile = BKE_image_get_tile_from_pos(s->image, uv, uv, s->uv_ofs);
+	//negate_v2(s->uv_ofs);
+
 	if (!paint_2d_canvas_set(s, s->image)) {
 		if (s->warnmultifile)
 			BKE_report(op->reports, RPT_WARNING, "Image requires 4 color channels to paint");
@@ -1349,6 +1373,9 @@ void paint_2d_redraw(const bContext *C, void *ps, bool final)
 	ImagePaintState *s = ps;
 
 	if (s->need_redraw) {
+		if (s->sima) {
+			s->sima->iuser.tile = s->tile;
+		}
 		ImBuf *ibuf = BKE_image_acquire_ibuf(s->image, s->sima ? &s->sima->iuser : NULL, NULL);
 
 		imapaint_image_update(s->sima, s->image, ibuf, false);
@@ -1453,6 +1480,7 @@ void paint_2d_bucket_fill(
 	if (!ima)
 		return;
 
+	sima->iuser.tile = s->tile;
 	ibuf = BKE_image_acquire_ibuf(ima, &sima->iuser, NULL);
 
 	if (!ibuf)
@@ -1505,7 +1533,7 @@ void paint_2d_bucket_fill(
 		/* We are comparing to sum of three squared values (assumed in range [0,1]), so need to multiply... */
 		float threshold_sq = br->fill_threshold * br->fill_threshold * 3;
 
-		UI_view2d_region_to_view(s->v2d, mouse_init[0], mouse_init[1], &image_init[0], &image_init[1]);
+		paint_2d_transform_mouse(s, mouse_init, image_init);
 
 		x_px = image_init[0] * ibuf->x;
 		y_px = image_init[1] * ibuf->y;
@@ -1631,13 +1659,14 @@ void paint_2d_gradient_fill(
 	if (!ima)
 		return;
 
+	sima->iuser.tile = s->tile;
 	ibuf = BKE_image_acquire_ibuf(ima, &sima->iuser, NULL);
 
 	if (!ibuf)
 		return;
 
-	UI_view2d_region_to_view(s->v2d, mouse_final[0], mouse_final[1], &image_final[0], &image_final[1]);
-	UI_view2d_region_to_view(s->v2d, mouse_init[0], mouse_init[1], &image_init[0], &image_init[1]);
+	paint_2d_transform_mouse(s, mouse_final, image_final);
+	paint_2d_transform_mouse(s, mouse_init, image_init);
 
 	image_final[0] *= ibuf->x;
 	image_final[1] *= ibuf->y;
diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h
index 8d94978f5c6..6f9e5eeb751 100644
--- a/source/blender/editors/sculpt_paint/paint_intern.h
+++ b/source/blender/editors/sculpt_paint/paint_intern.h
@@ -185,7 +185,7 @@ struct ImagePaintPartialRedraw *get_imapaintpartial(void);
 void set_imapaintpartial(struct ImagePaintPartialRedraw *ippr);
 void imapaint_region_tiles(struct ImBuf *ibuf, int x, int y, int w, int h, int *tx, int *ty, int *tw, int *th);
 int get_imapaint_zoom(struct bContext *C, float *zoomx, float *zoomy);
-void *paint_2d_new_stroke(struct bContext *, struct wmOperator *, int mode);
+void *paint_2d_new_stroke(struct bContext *, struct wmOperator *, const float mouse[2], int mode);
 void paint_2d_redraw(const struct bContext *C, void *ps, bool final);
 void paint_2d_stroke_done(void *ps);
 void paint_2d_stroke(



More information about the Bf-blender-cvs mailing list