[Bf-blender-cvs] [9c946fb5f1b] soc-2016-pbvh-painting: Cleanup: move accumulation structs out of sculpt-session

Campbell Barton noreply at git.blender.org
Wed Sep 27 07:37:38 CEST 2017


Commit: 9c946fb5f1b023d02f7760d189eb92b666dae553
Author: Campbell Barton
Date:   Wed Sep 27 15:40:31 2017 +1000
Branches: soc-2016-pbvh-painting
https://developer.blender.org/rB9c946fb5f1b023d02f7760d189eb92b666dae553

Cleanup: move accumulation structs out of sculpt-session

These were over-allocated to the size of all pbvh nodes.
Now only allocate as-needed,
using the total number of nodes under the brush.

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

M	source/blender/blenkernel/BKE_paint.h
M	source/blender/blenkernel/intern/paint.c
M	source/blender/editors/sculpt_paint/paint_vertex.c
M	source/blender/editors/sculpt_paint/sculpt_intern.h

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

diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index bb2916bcff9..88693600653 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -166,9 +166,6 @@ struct SculptVertexPaintGeomMap {
 	struct MeshElemMap *vert_to_loop;
 	int *poly_map_mem;
 	struct MeshElemMap *vert_to_poly;
-
-	/* Runtime. */
-	unsigned int *tot_loops_hit;
 };
 
 /* Session data (mode-specific) */
@@ -223,9 +220,6 @@ typedef struct SculptSession {
 
 			/* For non-airbrush painting to re-apply from the original (MLoop aligned). */
 			unsigned int *previous_color;
-
-			/* For blur only (PBVH Node aligned). */
-			unsigned int (*average_color)[3];
 		} vpaint;
 
 		struct {
@@ -236,9 +230,6 @@ typedef struct SculptSession {
 			float *previous_weight;
 			/* Keep track of how much each vertex has been painted (non-airbrush only). */
 			float *alpha_weight;
-
-			/* For blur only (PBVH Node aligned). */
-			double *average_weight;
 		} wpaint;
 
 		//struct {
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index d1820479ed0..8341411dcb6 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -682,14 +682,12 @@ void BKE_sculptsession_free_vwpaint_data(struct SculptSession *ss)
 		gmap = &ss->mode.vpaint.gmap;
 
 		/* Free average, blur, and spray brush arrays */
-		MEM_SAFE_FREE(ss->mode.vpaint.average_color);
 		MEM_SAFE_FREE(ss->mode.vpaint.previous_color);
 	}
 	else if (ss->mode_type == OB_MODE_WEIGHT_PAINT) {
 		gmap = &ss->mode.wpaint.gmap;
 
 		/* Free average, blur, and spray brush arrays */
-		MEM_SAFE_FREE(ss->mode.wpaint.average_weight);
 		MEM_SAFE_FREE(ss->mode.wpaint.alpha_weight);
 		MEM_SAFE_FREE(ss->mode.wpaint.previous_weight);
 	}
@@ -700,8 +698,6 @@ void BKE_sculptsession_free_vwpaint_data(struct SculptSession *ss)
 	MEM_SAFE_FREE(gmap->vert_map_mem);
 	MEM_SAFE_FREE(gmap->vert_to_poly);
 	MEM_SAFE_FREE(gmap->poly_map_mem);
-
-	MEM_SAFE_FREE(gmap->tot_loops_hit);
 }
 
 /* Write out the sculpt dynamic-topology BMesh to the Mesh */
diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c
index 78cef13b161..7faa24e8bd2 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex.c
@@ -83,6 +83,17 @@
 #include "sculpt_intern.h"
 #include "paint_intern.h"  /* own include */
 
+/* Use for 'blur' brush, align with PBVH nodes, created and freed on each update. */
+struct VPaintAverageAccum {
+	uint len;
+	uint value[3];
+};
+
+struct WPaintAverageAccum {
+	uint len;
+	double value;
+};
+
 static void defweight_prev_init(const MDeformWeight *dw, float *weight_prev)
 {
 	if (UNLIKELY(*weight_prev == -1.0f)) {
@@ -1724,7 +1735,7 @@ static void vertex_paint_init_session(Scene *scene, Object *ob)
 	}
 }
 
-static void vertex_paint_init_session_maps(Object *ob)
+static void vertex_paint_init_session_data(const ToolSettings *ts, Object *ob)
 {
 	/* Create maps */
 	struct SculptVertexPaintGeomMap *gmap = NULL;
@@ -1737,12 +1748,14 @@ static void vertex_paint_init_session_maps(Object *ob)
 		ob->sculpt->mode_type = OB_MODE_WEIGHT_PAINT;
 	}
 	else {
+		ob->sculpt->mode_type = 0;
 		BLI_assert(0);
 		return;
 	}
 
+	Mesh *me = ob->data;
+
 	if (gmap->vert_to_loop == NULL) {
-		Mesh *me = ob->data;
 		gmap->vert_map_mem = NULL;
 		gmap->vert_to_loop = NULL;
 		gmap->poly_map_mem = NULL;
@@ -1757,38 +1770,8 @@ static void vertex_paint_init_session_maps(Object *ob)
 		        me->mpoly, me->mloop, me->totvert, me->totpoly, me->totloop);
 	}
 
-	if (gmap->tot_loops_hit == NULL) {
-		/* I think the totNodes might include internal nodes, and we really only need the tot leaves. */
-		int nodes_len = BKE_pbvh_get_num_nodes(ob->sculpt->pbvh);
-
-		gmap->tot_loops_hit =
-		        MEM_callocN(nodes_len * sizeof(uint), "tot_loops_hit");
-	}
-}
-
-static void vertex_paint_init_session_average_arrays(const ToolSettings *ts, Object *ob)
-{
-	const Brush *brush = ob->sculpt->cache->brush;
-
-	/* Even though we only want 'PBVH_Leaf' nodes, align with 'pbvh->nodes'. */
-	const int nodes_len = BKE_pbvh_get_num_nodes(ob->sculpt->pbvh);
-	const Mesh *me = BKE_mesh_from_object(ob);
-
 	/* Create average brush arrays */
 	if (ob->mode == OB_MODE_VERTEX_PAINT) {
-		ob->sculpt->mode_type = OB_MODE_VERTEX_PAINT;
-
-
-		if (brush->vertexpaint_tool == PAINT_BLEND_AVERAGE) {
-			if (ob->sculpt->mode.vpaint.average_color == NULL) {
-				ob->sculpt->mode.vpaint.average_color =
-				        MEM_callocN(nodes_len * sizeof(uint[3]), "average_color");
-			}
-		}
-		else {
-			MEM_SAFE_FREE(ob->sculpt->mode.vpaint.average_color);
-		}
-
 		if ((ts->vpaint->flag & VP_SPRAY) == 0) {
 			if (ob->sculpt->mode.vpaint.previous_color == NULL) {
 				ob->sculpt->mode.vpaint.previous_color =
@@ -1800,16 +1783,6 @@ static void vertex_paint_init_session_average_arrays(const ToolSettings *ts, Obj
 		}
 	}
 	else if (ob->mode == OB_MODE_WEIGHT_PAINT) {
-		ob->sculpt->mode_type = OB_MODE_WEIGHT_PAINT;
-
-		if (brush->vertexpaint_tool == PAINT_BLEND_AVERAGE) {
-			ob->sculpt->mode.wpaint.average_weight =
-			        MEM_callocN(nodes_len * sizeof(double), "average_weight");
-		}
-		else {
-			MEM_SAFE_FREE(ob->sculpt->mode.wpaint.average_weight);
-		}
-
 		if ((ts->wpaint->flag & VP_SPRAY) == 0) {
 			if (ob->sculpt->mode.wpaint.alpha_weight == NULL) {
 				ob->sculpt->mode.wpaint.alpha_weight =
@@ -1825,6 +1798,7 @@ static void vertex_paint_init_session_average_arrays(const ToolSettings *ts, Obj
 			MEM_SAFE_FREE(ob->sculpt->mode.wpaint.previous_weight);
 		}
 	}
+
 }
 
 /* *************** set wpaint operator ****************** */
@@ -2285,8 +2259,7 @@ static bool wpaint_stroke_test_start(bContext *C, wmOperator *op, const float mo
 	/* If not previously created, create vertex/weight paint mode session data */
 	vertex_paint_init_session(scene, ob);
 	vwpaint_update_cache_invariants(C, vd, ss, op, mouse);
-	vertex_paint_init_session_maps(ob);
-	vertex_paint_init_session_average_arrays(ts, ob);
+	vertex_paint_init_session_data(ts, ob);
 
 	if (ss->mode.wpaint.previous_weight != NULL) {
 		copy_vn_fl(ss->mode.wpaint.previous_weight, me->totvert, -1.0f);
@@ -2611,7 +2584,6 @@ static void do_wpaint_brush_smear_task_cb_ex(
 	}
 }
 
-
 static void do_wpaint_brush_draw_task_cb_ex(
         void *userdata, void *UNUSED(userdata_chunk), const int n, const int UNUSED(thread_id))
 {
@@ -2688,15 +2660,14 @@ static void do_wpaint_brush_calc_average_weight_cb_ex(
 	SculptSession *ss = data->ob->sculpt;
 	StrokeCache *cache = ss->cache;
 	CCGDerivedMesh *ccgdm = BKE_pbvh_get_ccgdm(ss->pbvh);
-	const struct SculptVertexPaintGeomMap *gmap = &ss->mode.wpaint.gmap;
 
-	double weight = 0.0;
-
-	gmap->tot_loops_hit[n] = 0.0;
-	data->ob->sculpt->mode.wpaint.average_weight[n] = 0.0;
 	const bool use_face_sel = (data->me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
 	const bool use_vert_sel = (data->me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0;
 
+	struct WPaintAverageAccum *accum = (struct WPaintAverageAccum *)data->custom_data + n;
+	accum->len = 0;
+	accum->value = 0.0;
+
 	SculptBrushTest test;
 	sculpt_brush_test_init(ss, &test);
 
@@ -2714,39 +2685,43 @@ static void do_wpaint_brush_calc_average_weight_cb_ex(
 
 				/* If the vertex is selected. */
 				if (!(use_face_sel || use_vert_sel) || v_flag & SELECT) {
-					gmap->tot_loops_hit[n] += 1;
 					const MDeformVert *dv = &data->me->dvert[v_index];
-					weight += defvert_find_weight(dv, data->wpi->active.index);
+					accum->len += 1;
+					accum->value += defvert_find_weight(dv, data->wpi->active.index);
 				}
 			}
 		}
 	}
 	BKE_pbvh_vertex_iter_end;
-	data->ob->sculpt->mode.wpaint.average_weight[n] = weight;
 }
 
 static void calculate_average_weight(SculptThreadedTaskData *data, PBVHNode **UNUSED(nodes), int totnode)
 {
 	Scene *scene = CTX_data_scene(data->C);
-	const struct SculptVertexPaintGeomMap *gmap = &data->ob->sculpt->mode.wpaint.gmap;
 	UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
+
+	struct WPaintAverageAccum *accum = MEM_mallocN(sizeof(*accum) * totnode, __func__);
+	data->custom_data = accum;
+
 	BLI_task_parallel_range_ex(
 	        0, totnode, data, NULL, 0, do_wpaint_brush_calc_average_weight_cb_ex,
 	        ((data->sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_THREADED_LIMIT), false);
 
-	uint total_hit_loops = 0;
-	double total_weight = 0.0;
+	uint accum_len = 0;
+	double accum_weight = 0.0;
 	for (int i = 0; i < totnode; i++) {
-		total_hit_loops += gmap->tot_loops_hit[i];
-		total_weight += data->ob->sculpt->mode.wpaint.average_weight[i];
+		accum_len += accum[i].len;
+		accum_weight += accum[i].value;
 	}
-	if (total_hit_loops != 0) {
-		total_weight /= total_hit_loops;
+	if (accum_len != 0) {
+		accum_weight /= accum_len;
 		if (ups->flag & UNIFIED_PAINT_WEIGHT)
-			ups->weight = (float)total_weight;
+			ups->weight = (float)accum_weight;
 		else
-			data->brush->weight = (float)total_weight;
+			data->brush->weight = (float)accum_weight;
 	}
+
+	MEM_SAFE_FREE(data->custom_data);  /* 'accum' */
 }
 
 
@@ -3307,8 +3282,7 @@ static bool vpaint_stroke_test_start(bContext *C, struct wmOperator *op, const f
 	/* If not previously created, create vertex/weight paint mode session data */
 	vertex_paint_init_session(scene, ob);
 	vwpaint_update_cache_invariants(C, vp, ss, op, mouse);
-	vertex_paint_init_session_maps(ob);
-	vertex_paint_init_session_average_arrays(ts, ob);
+	vertex_paint_init_session_data(ts, ob);
 
 	if (ob->sculpt->mode.vpaint.previous_color != NULL) {
 		memset(ob->sculpt->mode.vpaint.previous_color, 0, sizeof(uint) * me->totloop);
@@ -3327,11 +3301,14 @@ static void do_vpaint_brush_calc_average_color_cb_ex(
 
 	StrokeCache *cache = ss->cache;
 	uint *lcol = data->lcol;
-	uint blend[3] = {0};
 	char *col;
-	gmap->tot_loops_hit[n] = 0;
+
 	const bool use_face_sel = (data->me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
 
+	struct VPaintAverageAccum *accum = (struct VPaintAverageAccum *)data->custom_data + n;
+	accum->len = 0;
+	memset(accum->value, 0, sizeof(accum->value));
+
 	SculptBrushTest test;
 	sculpt_brush_test_init(ss

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list