[Bf-blender-cvs] [009bc8c] temp_widgets_update_tagging: Better way of handling face map widgets in new tagging system

Julian Eisel noreply at git.blender.org
Thu May 5 02:38:50 CEST 2016


Commit: 009bc8ce0ee946e32b1ecddd42703823f67f2841
Author: Julian Eisel
Date:   Thu May 5 02:34:16 2016 +0200
Branches: temp_widgets_update_tagging
https://developer.blender.org/rB009bc8ce0ee946e32b1ecddd42703823f67f2841

Better way of handling face map widgets in new tagging system

* On widget group init, needed widgets are created and stored in a hash table (wmWidgetGroup.customdata).
* On widget group refresh, a new hash table is created and compared to the old one. For each widget needed we check if it's already existing in the old hash table, if so it's moved to the new one, if not it gets created.
* The remaining widgets in the old hash table get completely deleted, the old hash table gets deleted, the new one is stored (wmWidgetGroup.customdata) and becomes the old one on next refresh.

Solves all issues mentioned in rB003c181a640576b (and removes quite some ugly stuff).
Did minor cleanup in overlapping parts.

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

M	source/blender/editors/include/ED_view3d.h
M	source/blender/editors/space_view3d/view3d_widgets.c
M	source/blender/makesrna/intern/rna_pose.c
M	source/blender/windowmanager/widgets/WM_widget_api.h
M	source/blender/windowmanager/widgets/intern/wm_widget.c
M	source/blender/windowmanager/widgets/intern/wm_widget_intern.h
M	source/blender/windowmanager/widgets/intern/wm_widgetgroup.c
M	source/blender/windowmanager/widgets/intern/wm_widgetmap.c
M	source/blender/windowmanager/widgets/wm_widget_wmapi.h

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

diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index 2c949bd..a3ed21d 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -413,7 +413,4 @@ void ED_view3d_shade_update(struct Main *bmain, struct Scene *scene, struct View
 #define V3D_IS_ZBUF(v3d) \
 	(((v3d)->flag & V3D_ZBUF_SELECT) && ((v3d)->drawtype > OB_WIRE))
 
-/* view3d_widgets.c */
-void ED_armature_facemap_widget_remove(struct Object *fmap_ob, struct bFaceMap *fmap);
-
 #endif /* __ED_VIEW3D_H__ */
diff --git a/source/blender/editors/space_view3d/view3d_widgets.c b/source/blender/editors/space_view3d/view3d_widgets.c
index 6d9ee00..45ebd2e 100644
--- a/source/blender/editors/space_view3d/view3d_widgets.c
+++ b/source/blender/editors/space_view3d/view3d_widgets.c
@@ -294,12 +294,6 @@ void WIDGETGROUP_forcefield_refresh(const bContext *C, wmWidgetGroup *wgroup)
 /* draw facemaps depending on the selected bone in pose mode */
 #define USE_FACEMAP_FROM_BONE
 
-/**
- * Storage of all visible armature face map widgets.
- * We need to access this without having access to wmWidgetGroup.customdata, so storing as global.
- */
-static GHash *armature_facemaps = NULL;
-
 #define MAX_ARMATURE_FACEMAP_NAME (2 * MAX_NAME + 1) /* "OBJECTNAME_FACEMAPNAME" */
 
 
@@ -361,7 +355,7 @@ static void WIDGET_armature_facemaps_select(bContext *C, wmWidget *widget, const
  * Get a string that equals a string generated using
  * #armature_facemap_hashname_create, but without allocating it.
  */
-BLI_INLINE void armature_facemap_hashname_get(
+BLI_INLINE void armature_facemap_hashkey_get(
         Object *fmap_ob, bFaceMap *fmap, size_t maxname,
         char *r_name)
 {
@@ -372,12 +366,25 @@ BLI_INLINE void armature_facemap_hashname_get(
  * Same as #armature_facemap_hashname_get but allocates a new string.
  * \return A string using "OBJECTNAME_FACEMAPNAME" format.
  */
-BLI_INLINE char *armature_facemap_hashname_create(Object *fmap_ob, bFaceMap *fmap)
+BLI_INLINE char *armature_facemap_hashkey_create(Object *fmap_ob, bFaceMap *fmap)
 {
 	return BLI_sprintfN("%s_%s", fmap_ob->id.name + 2, fmap->name);
 }
 
-static wmWidget *armature_facemap_widget_create(wmWidgetGroup *wgroup, GHash *hash, Object *fmap_ob, bFaceMap *fmap)
+BLI_INLINE void armature_facemap_ghash_insert(GHash *hash, wmWidget *widget, Object *fmap_ob, bFaceMap *fmap)
+{
+	BLI_ghash_insert(hash, armature_facemap_hashkey_create(fmap_ob, fmap), widget);
+}
+
+/**
+ * Free armature facemap ghash, used as freeing callback for wmWidgetGroup.customdata.
+ */
+BLI_INLINE void armature_facemap_ghash_free(void *customdata)
+{
+	BLI_ghash_free(customdata, MEM_freeN, NULL);
+}
+
+static wmWidget *armature_facemap_widget_create(wmWidgetGroup *wgroup, Object *fmap_ob, bFaceMap *fmap)
 {
 	wmWidget *widget = WIDGET_facemap_new(wgroup, fmap->name, 0, fmap_ob, BLI_findindex(&fmap_ob->fmaps, fmap));
 
@@ -387,35 +394,9 @@ static wmWidget *armature_facemap_widget_create(wmWidgetGroup *wgroup, GHash *ha
 	PointerRNA *opptr = WM_widget_set_operator(widget, "TRANSFORM_OT_translate");
 	RNA_boolean_set(opptr, "release_confirm", true);
 
-	BLI_ghash_insert(hash, armature_facemap_hashname_create(fmap_ob, fmap), widget);
-
 	return widget;
 }
 
-void ED_armature_facemap_widget_remove(Object *fmap_ob, bFaceMap *fmap)
-{
-	if (!armature_facemaps) {
-		BLI_assert(0);
-		return;
-	}
-
-	char idname[MAX_ARMATURE_FACEMAP_NAME];
-	armature_facemap_hashname_get(fmap_ob, fmap, sizeof(idname), idname);
-
-	wmWidget *widget = BLI_ghash_popkey(armature_facemaps, idname, MEM_freeN);
-	if (widget) {
-		WM_widget_set_flag(widget, WM_WIDGET_HIDDEN, true);
-	}
-}
-
-/**
- * Callback for freeing ghash stored in wmWidgetGroup.customdata.
- */
-static void armature_facemap_customdata_free(void *customdata)
-{
-	BLI_ghash_free(customdata, MEM_freeN, NULL);
-}
-
 void WIDGETGROUP_armature_facemaps_init(const bContext *C, wmWidgetGroup *wgroup)
 {
 	Object *ob = CTX_data_active_object(C);
@@ -423,15 +404,16 @@ void WIDGETGROUP_armature_facemaps_init(const bContext *C, wmWidgetGroup *wgroup
 
 #ifdef USE_FACEMAP_FROM_BONE
 	bPoseChannel *pchan;
-	armature_facemaps = BLI_ghash_str_new(__func__);
+	GHash *hash = BLI_ghash_str_new(__func__);
 
 	for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
 		if (pchan->fmap && (pchan->bone->layer & arm->layer)) {
-			armature_facemap_widget_create(wgroup, armature_facemaps, pchan->fmap_object, pchan->fmap);
+			wmWidget *widget = armature_facemap_widget_create(wgroup, pchan->fmap_object, pchan->fmap);
+			armature_facemap_ghash_insert(hash, widget, pchan->fmap_object, pchan->fmap);
 		}
 	}
-	wgroup->customdata = armature_facemaps;
-	wgroup->customdata_free = armature_facemap_customdata_free;
+	wgroup->customdata = hash;
+	wgroup->customdata_free = armature_facemap_ghash_free;
 #else
 	Object *armature;
 	ModifierData *md;
@@ -472,42 +454,66 @@ void WIDGETGROUP_armature_facemaps_init(const bContext *C, wmWidgetGroup *wgroup
 #endif
 }
 
+/**
+ * We do some special stuff for refreshing facemap widgets nicely:
+ * * On widget group init, needed widgets are created and stored in a hash table (wmWidgetGroup.customdata).
+ * * On widget group refresh, a new hash table is created and compared to the old one. For each widget needed we
+ *   check if it's already existing in the old hash table, if so it's moved to the new one, if not it gets created.
+ * * The remaining widgets in the old hash table get completely deleted, the old hash table gets deleted, the new
+ *   one is stored (wmWidgetGroup.customdata) and becomes the old one on next refresh.
+ */
 void WIDGETGROUP_armature_facemaps_refresh(const bContext *C, wmWidgetGroup *wgroup)
 {
 	if (!wgroup->customdata)
 		return;
-	BLI_assert(wgroup->customdata == armature_facemaps);
 
 	Object *ob = CTX_data_active_object(C);
 	bArmature *arm = (bArmature *)ob->data;
 
 #ifdef USE_FACEMAP_FROM_BONE
-	bPoseChannel *pchan;
-	GHash *hash = wgroup->customdata;
+	/* we create a new hash from the visible members of the old hash */
+	GHash *oldhash = wgroup->customdata;
+	GHash *newhash = BLI_ghash_str_new(__func__);
 
-	for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
+	for (bPoseChannel *pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
 		if (pchan->fmap && (pchan->bone->layer & arm->layer)) {
+			wmWidget *widget;
 			char idname[MAX_ARMATURE_FACEMAP_NAME];
-			armature_facemap_hashname_get(pchan->fmap_object, pchan->fmap, sizeof(idname), idname);
+			armature_facemap_hashkey_get(pchan->fmap_object, pchan->fmap, sizeof(idname), idname);
 
-			wmWidget *widget = BLI_ghash_lookup(hash, idname);
-			const ThemeWireColor *bcol = ED_pchan_get_colorset(arm, ob->pose, pchan);
-			float col[4] = {0.8f, 0.8f, 0.45f, 0.2f};
-			float col_hi[4] = {0.8f, 0.8f, 0.45f, 0.4f};
-
-			/* create new widget for newly assigned facemap */
-			if (!widget) {
-				widget = armature_facemap_widget_create(wgroup, hash, pchan->fmap_object, pchan->fmap);
+			/* create new widget for newly assigned facemap, add it to new hash */
+			if (!(widget = BLI_ghash_lookup(oldhash, idname))) {
+				widget = armature_facemap_widget_create(wgroup, pchan->fmap_object, pchan->fmap);
 				BLI_assert(widget);
 			}
+			armature_facemap_ghash_insert(newhash, widget, pchan->fmap_object, pchan->fmap);
+
 
+			const ThemeWireColor *bcol = ED_pchan_get_colorset(arm, ob->pose, pchan);
+			float col[4] = {0.8f, 0.8f, 0.45f, 0.2f};
+			float col_hi[4] = {0.8f, 0.8f, 0.45f, 0.4f};
 			/* get custom bone group color */
 			if (bcol) {
 				rgb_uchar_to_float(col, (unsigned char *)bcol->solid);
 				rgb_uchar_to_float(col_hi, (unsigned char *)bcol->active);
 			}
 			WM_widget_set_colors(widget, col, col_hi);
+
+			/* remove from old hash */
+			BLI_ghash_remove(oldhash, idname, MEM_freeN, NULL);
 		}
 	}
+
+	/* remove remaining widgets from old hash */
+	GHashIterator ghi;
+	wmWidgetMap *wmap = WM_widgetmap_find(CTX_wm_region(C), &(const struct wmWidgetMapType_Params) {
+	        "View3D", SPACE_VIEW3D, RGN_TYPE_WINDOW, WM_WIDGETMAPTYPE_3D});
+	GHASH_ITER(ghi, oldhash) {
+		wmWidget *found = BLI_ghashIterator_getValue(&ghi);
+		WM_widget_delete(&wgroup->widgets, wmap, found, (bContext *)C);
+	}
+	armature_facemap_ghash_free(oldhash);
+
+	wgroup->customdata = newhash;
 #endif
 }
diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c
index 977dbd5..55c515d 100644
--- a/source/blender/makesrna/intern/rna_pose.c
+++ b/source/blender/makesrna/intern/rna_pose.c
@@ -108,7 +108,6 @@ EnumPropertyItem rna_enum_color_sets_items[] = {
 
 #include "ED_object.h"
 #include "ED_armature.h"
-#include "ED_view3d.h"
 
 #include "WM_api.h"
 
@@ -291,10 +290,6 @@ static void rna_PoseChannel_bone_fmap_object_set(PointerRNA *ptr, PointerRNA val
 {
 	bPoseChannel *pchan = (bPoseChannel *)ptr->data;
 
-	if (pchan->fmap_object && pchan->fmap) {
-		ED_armature_facemap_widget_remove(pchan->fmap_object, pchan->fmap);
-	}
-
 	if (pchan->fmap_object) {
 		id_us_min(&pchan->fmap_object->id);
 		pchan->fmap_object = NULL;
@@ -307,15 +302,6 @@ static void rna_PoseChannel_bone_fmap_object_set(PointerRNA *ptr, PointerRNA val
 	id_us_plus(&pchan->fmap_object->id);
 }
 
-static void rna_PoseChannel_bone_fmap_set(PointerRNA *ptr, PointerRNA value)
-{
-	bPoseChannel *pchan = (bPoseChannel *)ptr->data;
-	if (pchan->fmap_object && pchan->fmap) {
-		ED_armature_facemap_widget_remove(pchan->fmap_object, pchan->fmap);
-	}
-	pchan->fmap = value.data;
-}
-
 static int rna_PoseChannel_has_ik_get(PointerRNA *ptr)
 {
 	Object *ob = (Object *)ptr->id.data;
@@ -866,7 +852,6 @@ static void rna_def_pose_channel(BlenderRNA *brna)
 	RNA_def_property_pointer_sdna(prop, NULL, "fmap");
 	RNA_def_property_struct_type(prop, "FaceMap");
 	RNA_def_property_flag(prop, PROP_EDITABLE);
-	RNA_def_property_pointer_funcs(prop, NULL, "rna_PoseChannel_bone_fmap_set", NULL, NULL);
 	RNA_def_property_ui_text(prop, "Face Map", "Use a face map of the custom object to manipulate this bone");
 	RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_update");
 	
diff --git a/source/blender/windowmanager/widgets/WM_widget_api.h b/source/blende

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list