[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [17442] branches/projection-paint/source/ blender/src/imagepaint.c: simple workaround slowdown with painting onto multiple parts of an image at once , just use a grid of boundboxes per image.

Campbell Barton ideasman42 at gmail.com
Thu Nov 13 14:17:04 CET 2008


Revision: 17442
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=17442
Author:   campbellbarton
Date:     2008-11-13 14:17:04 +0100 (Thu, 13 Nov 2008)

Log Message:
-----------
simple workaround slowdown with painting onto multiple parts of an image at once, just use a grid of boundboxes per image.
was also running undo calls when it shouldnt, 

Modified Paths:
--------------
    branches/projection-paint/source/blender/src/imagepaint.c

Modified: branches/projection-paint/source/blender/src/imagepaint.c
===================================================================
--- branches/projection-paint/source/blender/src/imagepaint.c	2008-11-13 11:30:34 UTC (rev 17441)
+++ branches/projection-paint/source/blender/src/imagepaint.c	2008-11-13 13:17:04 UTC (rev 17442)
@@ -141,6 +141,8 @@
 
 /* testing options */
 #define PROJ_BUCKET_DIV 128 /* TODO - test other values, this is a guess, seems ok */
+#define PROJ_BOUNDBOX_DIV 6 /* TODO - test other values, this is a guess, seems ok */
+#define PROJ_BOUNDBOX_SQUARED  (PROJ_BOUNDBOX_DIV * PROJ_BOUNDBOX_DIV)
 
 //#define PROJ_DEBUG_PAINT 1
 #define PROJ_DEBUG_NOSCANLINE 1
@@ -200,7 +202,7 @@
 	
 	Image **projectImages;			/* array of images we are painting onto while, use so we can tag for updates */
 	ImBuf **projectImBufs;			/* array of imbufs we are painting onto while, use so we can get the rect and rect_float quickly */
-	ImagePaintPartialRedraw	*projectPartialRedraws;	/* array of partial redraws */
+	ImagePaintPartialRedraw	*projectPartialRedraws[PROJ_BOUNDBOX_SQUARED];	/* array of partial redraws */
 	
 	int projectImageTotal;			/* size of projectImages array */
 	
@@ -245,7 +247,7 @@
 	short x_px, y_px;
 	void *pixel;
 	short image_index; /* if anyone wants to paint onto more then 32000 images they can bite me */
-	short flag;
+	short bb_cell_index;
 } ProjectPixel;
 
 typedef struct ProjectPixelClone {
@@ -281,6 +283,19 @@
 static UndoElem *curundo = NULL;
 static ImagePaintPartialRedraw imapaintpartial = {0, 0, 0, 0, 0};
 
+
+static int BLI_linklist_index(struct LinkNode *list, void *ptr)
+{
+	int index;
+	
+	for (index = 0; list; list= list->next, index++) {
+		if (list->link == ptr)
+			return index;
+	}
+	
+	return -1;
+}
+
 /* UNDO */
 
 /* internal functions */
@@ -1333,6 +1348,12 @@
 		projPixel->x_px = x;
 		projPixel->y_px = y;
 		
+		/* which bounding box cell are we in? */
+		//projPixel->x_bb = (char) ;
+		//projPixel->y_bb = (char) (((float)y/(float)ibuf->y) * PROJ_BOUNDBOX_DIV);
+		
+		projPixel->bb_cell_index = ((int)((((float)x)/((float)ibuf->x)) * PROJ_BOUNDBOX_DIV)) + ((int)((((float)y)/((float)ibuf->y)) * PROJ_BOUNDBOX_DIV)) * PROJ_BOUNDBOX_DIV ;
+		
 		/* done with view3d_project_float inline */
 		if (ps->tool==PAINT_TOOL_CLONE) {
 			float co[2];
@@ -2248,7 +2269,11 @@
 	/* build an array of images we use*/
 	ps->projectImages = BLI_memarena_alloc( ps->projectArena, sizeof(Image *) * ps->projectImageTotal);
 	ps->projectImBufs = BLI_memarena_alloc( ps->projectArena, sizeof(ImBuf *) * ps->projectImageTotal);
-	ps->projectPartialRedraws = BLI_memarena_alloc( ps->projectArena, sizeof(ImagePaintPartialRedraw) * ps->projectImageTotal);
+	*(ps->projectPartialRedraws) = BLI_memarena_alloc( ps->projectArena, sizeof(ImagePaintPartialRedraw) * ps->projectImageTotal * PROJ_BOUNDBOX_SQUARED);
+	
+	for (a=1; a< ps->projectImageTotal; a++) {
+		ps->projectPartialRedraws[a] = *(ps->projectPartialRedraws) + (a * PROJ_BOUNDBOX_SQUARED);
+	}
 	// calloced - memset(ps->projectPartialRedraws, 0, sizeof(ImagePaintPartialRedraw) * ps->projectImageTotal);
 	
 	for (node= image_LinkList, i=0; node; node= node->next, i++) {
@@ -2397,6 +2422,7 @@
 	if(texpaint || G.sima->lock) {
 		int w = imapaintpartial.x2 - imapaintpartial.x1;
 		int h = imapaintpartial.y2 - imapaintpartial.y1;
+		// printf("%d, %d, \n", w, h);
 		GPU_paint_update_image(image, imapaintpartial.x1, imapaintpartial.y1, w, h);
 	}
 }
@@ -2806,27 +2832,35 @@
 /* Loop over all images on this mesh and update any we have touched */
 static int imapaint_refresh_tagged(ProjectPaintState *ps)
 {
-	ImagePaintPartialRedraw *pr = ps->projectPartialRedraws;
-	int a;
+	ImagePaintPartialRedraw *pr;
+	int a,i;
 	int redraw = 0;
 	
 	
-	
-	for (a=0; a < ps->projectImageTotal; a++, pr++) {
+	for (a=0; a < ps->projectImageTotal; a++) {
 		Image *ima = ps->projectImages[a];
 		if (ima->id.flag & LIB_DOIT) {
-			if(U.uiflag & USER_GLOBALUNDO) {
-				// Dont need to set "imapaintpartial" This is updated from imapaint_dirty_region args.
-				imapaint_dirty_region(ima, ps->projectImBufs[a], pr->x1, pr->y1, pr->x2 - pr->x1, pr->y2 - pr->y1);
-			} else {
-				imapaintpartial = ps->projectPartialRedraws[a];
-				
+			/* look over each bound cell */
+			for (i=0; i<PROJ_BOUNDBOX_SQUARED; i++) {
+				pr = &(ps->projectPartialRedraws[a][i]);
+				if (pr->x2 != -1) { /* TODO - use 'enabled' ? */
+					/*
+					if(U.uiflag & USER_GLOBALUNDO) {
+						// Dont need to set "imapaintpartial" This is updated from imapaint_dirty_region args.
+						imapaint_dirty_region(ima, ps->projectImBufs[a], pr->x1, pr->y1, pr->x2 - pr->x1, pr->y2 - pr->y1);
+					} else {
+					*/
+						imapaintpartial = *pr;
+					/*
+					}
+					*/
+					
+					imapaint_image_update(ima, ps->projectImBufs[a], 1 /*texpaint*/ );
+					
+					redraw = 1;
+				}
 			}
 			
-			imapaint_image_update(ima, ps->projectImBufs[a], 1 /*texpaint*/ );
-			
-			redraw = 1;
-			
 			ima->id.flag &= ~LIB_DOIT; /* clear for reuse */
 		}
 	}
@@ -2901,7 +2935,7 @@
 				short mval[2],
 				double time,
 				float pressure,
-				ImagePaintPartialRedraw *projectPartialRedraws,
+				ImagePaintPartialRedraw *projectPartialRedraws[PROJ_BOUNDBOX_SQUARED],
 				int thread_index)
 {
 	LinkNode *node;
@@ -2911,6 +2945,7 @@
 	
 	int last_index = -1;
 	ImagePaintPartialRedraw *last_partial_redraw;
+	ImagePaintPartialRedraw *last_partial_redraw_cell;
 	
 	float rgba[4], alpha, dist, dist_nosqrt;
 	char rgba_ub[4];
@@ -2986,19 +3021,19 @@
 					
 					if (last_index != projPixel->image_index) {
 						last_index = projPixel->image_index;
-						last_partial_redraw = &projectPartialRedraws[last_index];
+						last_partial_redraw = projectPartialRedraws[last_index];
 						
 						ps->projectImages[last_index]->id.flag |= LIB_DOIT; /* halgrind complains this is not threadsafe but probably ok? - we are only setting this flag anyway */
 						is_floatbuf = ps->projectImBufs[last_index]->rect_float ? 1 : 0;
 					}
 					
+					last_partial_redraw_cell = last_partial_redraw + projPixel->bb_cell_index;
+					last_partial_redraw_cell->x1 = MIN2( last_partial_redraw_cell->x1, projPixel->x_px );
+					last_partial_redraw_cell->y1 = MIN2( last_partial_redraw_cell->y1, projPixel->y_px );
 					
-					last_partial_redraw->x1 = MIN2( last_partial_redraw->x1, projPixel->x_px );
-					last_partial_redraw->y1 = MIN2( last_partial_redraw->y1, projPixel->y_px );
+					last_partial_redraw_cell->x2 = MAX2( last_partial_redraw_cell->x2, projPixel->x_px+1 );
+					last_partial_redraw_cell->y2 = MAX2( last_partial_redraw_cell->y2, projPixel->y_px+1 );
 					
-					last_partial_redraw->x2 = MAX2( last_partial_redraw->x2, projPixel->x_px );
-					last_partial_redraw->y2 = MAX2( last_partial_redraw->y2, projPixel->y_px );
-					
 					dist = (float)sqrt(dist_nosqrt);
 					
 					switch(ps->tool) {
@@ -3128,7 +3163,7 @@
 	float pressure;
 	
 	/* annoying but we need to have image bounds per thread, then merge into ps->projectPartialRedraws */
-	ImagePaintPartialRedraw	*projectPartialRedraws;	/* array of partial redraws */
+	ImagePaintPartialRedraw	*projectPartialRedraws[PROJ_BOUNDBOX_SQUARED];	/* array of partial redraws */
 	
 	/* thread settings */
 	int thread_tot;
@@ -3178,6 +3213,8 @@
 	
 	/* get the threads running */
 	for(a=0; a < ps->thread_tot; a++) {
+		int i;
+		
 #ifdef PROJ_DEBUG_PRINT_THREADS
 		printf("INIT THREAD %d\n", a);
 #endif
@@ -3196,10 +3233,14 @@
 		handles[a].thread_index = a;
 		handles[a].ready = 0;
 		
+		*(handles[a].projectPartialRedraws) = (ImagePaintPartialRedraw *)BLI_memarena_alloc(ps->projectArena, ps->projectImageTotal * sizeof(ImagePaintPartialRedraw) * PROJ_BOUNDBOX_SQUARED);
+		
 		/* image bounds */
-		handles[a].projectPartialRedraws = (ImagePaintPartialRedraw *)BLI_memarena_alloc(ps->projectArena, ps->projectImageTotal * sizeof(ImagePaintPartialRedraw));
+		for (i=1; i< ps->projectImageTotal; i++) {
+			handles[a].projectPartialRedraws[i] = *(handles[a].projectPartialRedraws) + (i * PROJ_BOUNDBOX_SQUARED);
+		}
 		
-		memcpy(handles[a].projectPartialRedraws, ps->projectPartialRedraws, ps->projectImageTotal * sizeof(ImagePaintPartialRedraw) );
+		memcpy(*(handles[a].projectPartialRedraws), *(ps->projectPartialRedraws), ps->projectImageTotal * sizeof(ImagePaintPartialRedraw) * PROJ_BOUNDBOX_SQUARED );
 		
 		BLI_insert_thread(&threads, &handles[a]);
 	}
@@ -3218,7 +3259,7 @@
 	
 	/* move threaded bounds back into ps->projectPartialRedraws */
 	for(a=0; a < ps->thread_tot; a++) {
-		partial_redraw_array_merge(ps->projectPartialRedraws, handles[a].projectPartialRedraws, ps->projectImageTotal);
+		partial_redraw_array_merge(*(ps->projectPartialRedraws), *(handles[a].projectPartialRedraws), ps->projectImageTotal * PROJ_BOUNDBOX_SQUARED);
 	}
 	
 	return imapaint_refresh_tagged(ps);
@@ -3310,7 +3351,7 @@
 {
 	int redraw_flag = 0;
 	
-	partial_redraw_array_init(ps->projectPartialRedraws, ps->projectImageTotal);
+	partial_redraw_array_init(*ps->projectPartialRedraws, ps->projectImageTotal * PROJ_BOUNDBOX_SQUARED);
 	
 	/* TODO - support more brush operations, airbrush etc */
 	if (ps->thread_tot > 1) {
@@ -3534,7 +3575,7 @@
 		time= PIL_check_seconds_timer();
 
 		if (project) { /* Projection Painting */
-			if ( ((s.brush->flag & BRUSH_AIRBRUSH) || init)  || (cmp_brush_spacing(mval, prevmval, ps.brush->size/10.0 * ps.brush->spacing )) ) {
+			if ( ((s.brush->flag & BRUSH_AIRBRUSH) || init)  || (cmp_brush_spacing(mval, prevmval, ps.brush->size/100.0 * ps.brush->spacing )) ) {
 				imapaint_paint_stroke_project(&ps, painter, prevmval, mval, stroke_gp ? 0 : 1, time, pressure);
 				prevmval[0]= mval[0];
 				prevmval[1]= mval[1];





More information about the Bf-blender-cvs mailing list