[Bf-blender-cvs] [a831b86bfe7] greasepencil-object: WIP: Add layer parenting

Antonio Vazquez noreply at git.blender.org
Thu Apr 13 18:33:07 CEST 2017


Commit: a831b86bfe7d0766ae9b4aae8276ffa209ca2ac0
Author: Antonio Vazquez
Date:   Thu Apr 13 18:32:53 2017 +0200
Branches: greasepencil-object
https://developer.blender.org/rBa831b86bfe7d0766ae9b4aae8276ffa209ca2ac0

WIP: Add layer parenting

There are some memory  leaks

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

M	source/blender/draw/engines/gpencil/gpencil_draw.c
M	source/blender/draw/engines/gpencil/gpencil_mode.c
M	source/blender/draw/engines/gpencil/gpencil_mode.h

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

diff --git a/source/blender/draw/engines/gpencil/gpencil_draw.c b/source/blender/draw/engines/gpencil/gpencil_draw.c
index 7ee9ef84dfe..a9165f5782c 100644
--- a/source/blender/draw/engines/gpencil/gpencil_draw.c
+++ b/source/blender/draw/engines/gpencil/gpencil_draw.c
@@ -33,6 +33,7 @@
 #include "DNA_gpencil_types.h"
 
 #include "BKE_gpencil.h"
+#include "BKE_action.h"
 
 #include "DRW_render.h"
 
@@ -436,3 +437,43 @@ Batch *gpencil_get_edit_geom(bGPDstroke *gps, float alpha, short dflag)
 
 	return Batch_create(PRIM_POINTS, vbo, NULL);
 }
+
+void gpencil_get_parent_matrix(Object *obact, bGPdata *gpd, bGPDlayer *gpl, float diff_mat[4][4])
+{
+	Object *obparent = gpl->parent;
+
+	/* if not layer parented, try with object parented */
+	if (obparent == NULL) {
+		if (obact != NULL) {
+			/* the gpd can be scene, but a gpobject can be active, so need check gpd */
+			if ((obact->type == OB_GPENCIL) && (obact->gpd == gpd)) {
+				copy_m4_m4(diff_mat, obact->obmat);
+				return;
+			}
+		}
+		/* not gpencil object */
+		unit_m4(diff_mat);
+		return;
+	}
+	else {
+		if ((gpl->partype == PAROBJECT) || (gpl->partype == PARSKEL)) {
+			mul_m4_m4m4(diff_mat, obparent->obmat, gpl->inverse);
+			return;
+		}
+		else if (gpl->partype == PARBONE) {
+			bPoseChannel *pchan = BKE_pose_channel_find_name(obparent->pose, gpl->parsubstr);
+			if (pchan) {
+				float tmp_mat[4][4];
+				mul_m4_m4m4(tmp_mat, obparent->obmat, pchan->pose_mat);
+				mul_m4_m4m4(diff_mat, tmp_mat, gpl->inverse);
+			}
+			else {
+				mul_m4_m4m4(diff_mat, obparent->obmat, gpl->inverse); /* if bone not found use object (armature) */
+			}
+			return;
+		}
+		else {
+			unit_m4(diff_mat); /* not defined type */
+		}
+	}
+}
diff --git a/source/blender/draw/engines/gpencil/gpencil_mode.c b/source/blender/draw/engines/gpencil/gpencil_mode.c
index 07b7f3f00b7..3a922a10d27 100644
--- a/source/blender/draw/engines/gpencil/gpencil_mode.c
+++ b/source/blender/draw/engines/gpencil/gpencil_mode.c
@@ -85,12 +85,16 @@ typedef struct GPENCIL_Data {
 } GPENCIL_Data;
 
 /* *********** STATIC *********** */
+typedef struct GPENCIL_parent {
+	float matrix[4][4];
+} GPENCIL_parent;
 
 typedef struct g_data{
 	int t_flip;
 	int t_mix;
 	int fill_style;
 	DRWShadingGroup *shgrps_volumetric;
+	GPENCIL_parent *parents;
 } g_data; /* Transient data */
 
 static struct {
@@ -206,6 +210,7 @@ static void GPENCIL_cache_init(void *vedata)
 	if (!stl->g_data) {
 		/* Alloc transient pointers */
 		stl->g_data = MEM_mallocN(sizeof(g_data), "g_data");
+		stl->g_data->parents = MEM_mallocN(sizeof(GPENCIL_parent), "GPENCIL_parents");
 	}
 
 	{
@@ -246,11 +251,17 @@ static void GPENCIL_cache_populate(void *vedata, Object *ob)
 	ToolSettings *ts = CTX_data_tool_settings(C);
 	float ink[4];
 	float tcolor[4];
+	float matrix[4][4];
 
 	UNUSED_VARS(psl, stl);
 
-	if (ob->type == OB_GPENCIL && ob->gpd)  {
-		for (bGPDlayer *gpl = ob->gpd->layers.first; gpl; gpl = gpl->next) {
+	if (ob->type == OB_GPENCIL && ob->gpd) {
+		/* prepare to save parent matrix */
+		int totlayers = BLI_listbase_count(&ob->gpd->layers);
+		stl->g_data->parents = MEM_recallocN(stl->g_data->parents, sizeof(GPENCIL_parent) * totlayers);
+		
+		int i = 0;
+		for (bGPDlayer *gpl = ob->gpd->layers.first; gpl; gpl = gpl->next, i++) {
 			/* don't draw layer if hidden */
 			if (gpl->flag & GP_LAYER_HIDE)
 				continue;
@@ -272,6 +283,10 @@ static void GPENCIL_cache_populate(void *vedata, Object *ob)
 			}
 #endif
 
+			/* get parent matrix and set as static data */
+			gpencil_get_parent_matrix(ob, ob->gpd, gpl, matrix);
+			copy_m4_m4(stl->g_data->parents[i].matrix, matrix);
+
 			for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
 				/* check if stroke can be drawn */
 				if (gpencil_can_draw_stroke(gps) == false) {
@@ -297,7 +312,7 @@ static void GPENCIL_cache_populate(void *vedata, Object *ob)
 					tfill[3] = gps->palcolor->fill[3] * gpl->opacity;
 					if ((tfill[3] > GPENCIL_ALPHA_OPACITY_THRESH) || (gps->palcolor->fill_style > 0)) {
 						struct Batch *fill_geom = gpencil_get_fill_geom(gps, tfill);
-						DRW_shgroup_call_add(fillgrp, fill_geom, ob->obmat);
+						DRW_shgroup_call_add(fillgrp, fill_geom, stl->g_data->parents[i].matrix);
 					}
 				}
 
@@ -309,7 +324,7 @@ static void GPENCIL_cache_populate(void *vedata, Object *ob)
 				short sthickness = gps->thickness + gpl->thickness;
 				if (sthickness > 0) {
 					struct Batch *stroke_geom = gpencil_get_stroke_geom(gps, sthickness, ink);
-					DRW_shgroup_call_add(strokegrp, stroke_geom, ob->obmat);
+					DRW_shgroup_call_add(strokegrp, stroke_geom, stl->g_data->parents[i].matrix);
 				}
 
 				/* edit points (only in edit mode) */
@@ -318,7 +333,7 @@ static void GPENCIL_cache_populate(void *vedata, Object *ob)
 					if (gps->flag & GP_STROKE_SELECT) {
 						if ((gpl->flag & GP_LAYER_UNLOCK_COLOR) || ((gps->palcolor->flag & PC_COLOR_LOCKED) == 0)) {
 							struct Batch *edit_geom = gpencil_get_edit_geom(gps, ts->gp_sculpt.alpha, ob->gpd->flag);
-							DRW_shgroup_call_add(stl->g_data->shgrps_volumetric, edit_geom,ob->obmat);
+							DRW_shgroup_call_add(stl->g_data->shgrps_volumetric, edit_geom, stl->g_data->parents[i].matrix);
 
 						}
 					}
@@ -339,6 +354,11 @@ static void GPENCIL_cache_populate(void *vedata, Object *ob)
 static void GPENCIL_cache_finish(void *vedata)
 {
 	GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
+	/* TODO: Need to free parents memory (here is not the right place)
+	if (stl->g_data->parents) {
+		MEM_freeN(stl->g_data->parents);
+	}
+	*/
 }
 
 static void GPENCIL_draw_scene(void *vedata)
diff --git a/source/blender/draw/engines/gpencil/gpencil_mode.h b/source/blender/draw/engines/gpencil/gpencil_mode.h
index b7690656c3f..096b7ae241a 100644
--- a/source/blender/draw/engines/gpencil/gpencil_mode.h
+++ b/source/blender/draw/engines/gpencil/gpencil_mode.h
@@ -33,5 +33,6 @@ struct Batch *gpencil_get_fill_geom(struct bGPDstroke *gps, const float color[4]
 struct Batch *gpencil_get_edit_geom(struct bGPDstroke *gps, float alpha, short dflag);
 
 bool gpencil_can_draw_stroke(const struct bGPDstroke *gps);
+void gpencil_get_parent_matrix(struct Object *obact, struct bGPdata *gpd, struct bGPDlayer *gpl, float diff_mat[4][4]);
 
 #endif /* __GPENCIL_MODE_H__ */
\ No newline at end of file




More information about the Bf-blender-cvs mailing list