[Bf-blender-cvs] [1ea4ca5faf8] greasepencil-object: Fix error when edit datablock used in several objects

Antonio Vazquez noreply at git.blender.org
Wed Jun 28 10:43:20 CEST 2017


Commit: 1ea4ca5faf85e8a188c3d563e4115413b7e33818
Author: Antonio Vazquez
Date:   Wed Jun 28 10:40:05 2017 +0200
Branches: greasepencil-object
https://developer.blender.org/rB1ea4ca5faf85e8a188c3d563e4115413b7e33818

Fix error when edit datablock used in several objects

When edit the datablock got segment fault.

Now a new hash is used to determine if the object was duplicated. This hash speed up drawing process too.

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

M	source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
M	source/blender/draw/engines/gpencil/gpencil_engine.c
M	source/blender/draw/engines/gpencil/gpencil_engine.h
M	source/blender/makesdna/DNA_gpencil_types.h

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

diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c b/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
index a3d86ce8320..bc503b452d7 100644
--- a/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
+++ b/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
@@ -90,11 +90,16 @@ static bool gpencil_batch_cache_valid(bGPdata *gpd, int cfra)
 		return false;
 	}
 
+	cache->is_editmode = gpd->flag & (GP_DATA_STROKE_EDITMODE | GP_DATA_STROKE_SCULPTMODE);
+
+	if (gpd->flag & GP_DATA_CACHE_REUSE) {
+		return true;
+	}
+
 	if (gpd->flag & GP_DATA_CACHE_IS_DIRTY) {
 		return false;
 	}
 
-	cache->is_editmode = gpd->flag & (GP_DATA_STROKE_EDITMODE | GP_DATA_STROKE_SCULPTMODE);
 	if (cache->is_editmode) {
 		return false;
 	}
@@ -163,9 +168,11 @@ void gpencil_batch_cache_clear(bGPdata *gpd)
 	if (!cache) {
 		return;
 	}
-	if (gpd->flag & GP_DATA_CACHE_IS_DIRTY) {
+
+	if (cache->cache_size == 0) {
 		return;
 	}
+
 	if (G.debug_value == 668) {
 		printf("gpencil_batch_cache_clear: %s\n", gpd->id.name);
 	}
@@ -412,7 +419,9 @@ static void gpencil_add_editpoints_shgroup(GPENCIL_StorageList *stl, GpencilBatc
 					gpencil_batch_cache_check_free_slots(gpd);
 					cache->batch_edit[cache->cache_idx] = DRW_gpencil_get_edit_geom(gps, ts->gp_sculpt.alpha, gpd->flag);
 				}
-				DRW_shgroup_call_add(stl->g_data->shgrps_edit_volumetric, cache->batch_edit[cache->cache_idx], gpf->viewmatrix);
+				if (cache->batch_edit[cache->cache_idx]) {
+					DRW_shgroup_call_add(stl->g_data->shgrps_edit_volumetric, cache->batch_edit[cache->cache_idx], gpf->viewmatrix);
+				}
 			}
 		}
 	}
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/source/blender/draw/engines/gpencil/gpencil_engine.c
index 07b7311ffcd..874ec91be78 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.c
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.c
@@ -193,14 +193,31 @@ static void GPENCIL_cache_finish(void *vedata)
 	Scene *scene = draw_ctx->scene;
 	ToolSettings *ts = scene->toolsettings;
 
+	stl->g_data->gpd_in_cache = BLI_ghash_str_new("GP datablock");
+
 	/* Draw all pending objects */
 	if (stl->g_data->gp_cache_used > 0) {
 		for (int i = 0; i < stl->g_data->gp_cache_used; ++i) {
 			Object *ob = stl->g_data->gp_object_cache[i].ob;
 			/* save init shading group */
 			stl->g_data->gp_object_cache[i].init_grp = stl->storage->shgroup_id;
+			
+			/* add to hash to avoid duplicate geometry cache*/
+			if (!BLI_ghash_lookup(stl->g_data->gpd_in_cache, ob->gpd->id.name)) {
+				BLI_ghash_insert(stl->g_data->gpd_in_cache, ob->gpd->id.name, ob->gpd);
+				if (ob->gpd->flag & (GP_DATA_STROKE_EDITMODE | GP_DATA_STROKE_SCULPTMODE)) {
+					ob->gpd->flag |= GP_DATA_CACHE_IS_DIRTY;
+					ob->gpd->flag &= ~GP_DATA_CACHE_REUSE;
+				}
+			}
+			else {
+				ob->gpd->flag &= ~GP_DATA_CACHE_IS_DIRTY;
+				ob->gpd->flag |= GP_DATA_CACHE_REUSE;
+			}
+
 			/* fill shading groups */
 			DRW_gpencil_populate_datablock(&e_data, vedata, scene, ob, ts, ob->gpd);
+
 			/* save end shading group */
 			stl->g_data->gp_object_cache[i].end_grp = stl->storage->shgroup_id - 1;
 			if (G.debug_value == 668) {
@@ -209,6 +226,13 @@ static void GPENCIL_cache_finish(void *vedata)
 			}
 		}
 	}
+
+	/* free hash buffer */
+	if (stl->g_data->gpd_in_cache) {
+		BLI_ghash_free(stl->g_data->gpd_in_cache, NULL, NULL);
+		stl->g_data->gpd_in_cache = NULL;
+	}
+	MEM_SAFE_FREE(stl->g_data->gpd_in_cache);
 }
 
 static void GPENCIL_draw_scene(void *vedata)
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.h b/source/blender/draw/engines/gpencil/gpencil_engine.h
index e9afab8e242..ce92893d9cf 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.h
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.h
@@ -102,6 +102,8 @@ typedef struct g_data {
 	int gp_cache_used;
 	int gp_cache_size;
 	struct tGPencilObjectCache *gp_object_cache;
+
+	struct GHash *gpd_in_cache;
 } g_data; /* Transient data */
 
 typedef struct GPENCIL_e_data {
diff --git a/source/blender/makesdna/DNA_gpencil_types.h b/source/blender/makesdna/DNA_gpencil_types.h
index 1d0fbb7c839..2ea0ca36924 100644
--- a/source/blender/makesdna/DNA_gpencil_types.h
+++ b/source/blender/makesdna/DNA_gpencil_types.h
@@ -363,7 +363,9 @@ typedef enum eGPdata_Flag {
 	/* Stroke Editing Mode - Toggle sculpt mode */
 	GP_DATA_STROKE_SCULPTMODE = (1 << 13),
 	/* keep stroke thickness unchanged when zoom change */
-	GP_DATA_STROKE_KEEPTHICKNESS = (1 << 14)
+	GP_DATA_STROKE_KEEPTHICKNESS = (1 << 14),
+	/* Batch drawing cache can be reused */
+	GP_DATA_CACHE_REUSE = (1 << 15)
 
 } eGPdata_Flag;




More information about the Bf-blender-cvs mailing list