[Bf-blender-cvs] [003c181a] temp_widgets_update_tagging: Port face map widgets to update tagging system

Julian Eisel noreply at git.blender.org
Fri Apr 15 22:25:41 CEST 2016


Commit: 003c181a640576beef70be5239a6c678d1069eb1
Author: Julian Eisel
Date:   Fri Apr 15 21:08:50 2016 +0200
Branches: temp_widgets_update_tagging
https://developer.blender.org/rB003c181a640576beef70be5239a6c678d1069eb1

Port face map widgets to update tagging system

Face maps behave a bit different than normal widgets, since adding and removing them are common actions. Hence I had to add some special stuff which I'm not so happy about. I see two alternatives, but not sure about them either:
* Re-create all face map widgets on WIDGETMAP_REFRESH - would be done only on data/selection changes etc, not on simple redraw so it's rather harmless, would still like to avoid though.
* Extend/adjust the new update tagging system to natively support more dynamic widget lists. Would be good to have in general, but once again, I'm not sure how this would look (e.g. how would synchronysing with bone assignments work? More callbacks? :/)

Open issues:
* Deleting a bone that has a face map assigned doesn't hide/remove the face map widget
* Un-assigning a widget only hides it, better free it to save memory.
* A face map assinged to multiple bones gets hidden when un-assigning from one of the bones until next redraw.

So would like to re-think things again, but for now it's good enough. I don't want this to be a showstopper.

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

M	source/blender/blenkernel/intern/facemap.c
M	source/blender/editors/include/ED_view3d.h
M	source/blender/editors/space_view3d/space_view3d.c
M	source/blender/editors/space_view3d/view3d_intern.h
M	source/blender/editors/space_view3d/view3d_widgets.c
M	source/blender/makesdna/DNA_widget_types.h
M	source/blender/makesrna/intern/rna_pose.c
M	source/blender/windowmanager/widgets/intern/wm_widgetgroup.c
M	source/blender/windowmanager/widgets/intern/wm_widgetmap.c

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

diff --git a/source/blender/blenkernel/intern/facemap.c b/source/blender/blenkernel/intern/facemap.c
index fb97b7f..c6be004 100644
--- a/source/blender/blenkernel/intern/facemap.c
+++ b/source/blender/blenkernel/intern/facemap.c
@@ -214,12 +214,17 @@ static void object_fmap_remove_object_mode(Object *ob, bFaceMap *fmap, bool purg
 	}
 }
 
-void BKE_object_facemap_remove(Object *ob, bFaceMap *fmap)
+static void fmap_remove_exec(Object *ob, bFaceMap *fmap, const bool is_edit_mode, const bool purge)
 {
-	if (BKE_object_is_in_editmode(ob))
-		object_fmap_remove_edit_mode(ob, fmap, false, true);
+	if (is_edit_mode)
+		object_fmap_remove_edit_mode(ob, fmap, false, purge);
 	else
-		object_fmap_remove_object_mode(ob, fmap, true);
+		object_fmap_remove_object_mode(ob, fmap, purge);
+}
+
+void BKE_object_facemap_remove(Object *ob, bFaceMap *fmap)
+{
+	fmap_remove_exec(ob, fmap, BKE_object_is_in_editmode(ob), true);
 }
 
 void BKE_object_fmap_remove_all(Object *ob)
@@ -231,12 +236,7 @@ void BKE_object_fmap_remove_all(Object *ob)
 
 		while (fmap) {
 			bFaceMap *next_fmap = fmap->next;
-
-			if (edit_mode)
-				object_fmap_remove_edit_mode(ob, fmap, false, false);
-			else
-				object_fmap_remove_object_mode(ob, fmap, false);
-
+			fmap_remove_exec(ob, fmap, edit_mode, false);
 			fmap = next_fmap;
 		}
 	}
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index fcdab8f..9f2e339 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -54,6 +54,7 @@ struct ScrArea;
 struct View3D;
 struct ViewContext;
 struct bContext;
+struct bFaceMap;
 struct bPoseChannel;
 struct bScreen;
 struct bglMats;
@@ -424,4 +425,7 @@ 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/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index 84e7330..62d7b7a 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -743,10 +743,12 @@ static void view3d_widgets(void)
 
 	wmWidgetMapType *wmaptype = WM_widgetmaptype_ensure(&wmap_params);
 
-	WM_widgetgrouptype_register_ptr(
+	WM_widgetgrouptype_register_ptr_update(
 	        NULL, wmaptype,
 	        WIDGETGROUP_armature_facemaps_poll,
 	        WIDGETGROUP_armature_facemaps_init,
+	        WIDGETGROUP_armature_facemaps_refresh,
+	        NULL,
 	        WM_widgetgroup_keymap_common_sel,
 	        "Face Map Widgets");
 	WM_widgetgrouptype_register_ptr_update(
diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h
index 2798de1..cc565a1 100644
--- a/source/blender/editors/space_view3d/view3d_intern.h
+++ b/source/blender/editors/space_view3d/view3d_intern.h
@@ -285,8 +285,9 @@ void WIDGETGROUP_camera_draw_prepare(const struct bContext *C, struct wmWidgetGr
 int  WIDGETGROUP_forcefield_poll    (const struct bContext *C, struct wmWidgetGroupType *wgrouptype);
 void WIDGETGROUP_forcefield_init    (const struct bContext *C, struct wmWidgetGroup *wgroup);
 void WIDGETGROUP_forcefield_refresh (const struct bContext *C, struct wmWidgetGroup *wgroup);
-int  WIDGETGROUP_armature_facemaps_poll(const struct bContext *C, struct wmWidgetGroupType *wgrouptype);
-void WIDGETGROUP_armature_facemaps_init(const struct bContext *C, struct wmWidgetGroup *wgroup);
+int  WIDGETGROUP_armature_facemaps_poll   (const struct bContext *C, struct wmWidgetGroupType *wgrouptype);
+void WIDGETGROUP_armature_facemaps_init   (const struct bContext *C, struct wmWidgetGroup *wgroup);
+void WIDGETGROUP_armature_facemaps_refresh(const struct bContext *C, struct wmWidgetGroup *wgroup);
 
 /* draw_volume.c */
 void draw_smoke_volume(struct SmokeDomainSettings *sds, struct Object *ob,
diff --git a/source/blender/editors/space_view3d/view3d_widgets.c b/source/blender/editors/space_view3d/view3d_widgets.c
index 45efcf5..6d9ee00 100644
--- a/source/blender/editors/space_view3d/view3d_widgets.c
+++ b/source/blender/editors/space_view3d/view3d_widgets.c
@@ -26,6 +26,7 @@
 
 
 #include "BLI_blenlib.h"
+#include "BLI_ghash.h"
 #include "BLI_math.h"
 #include "BLI_utildefines.h"
 
@@ -293,6 +294,15 @@ 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" */
+
+
 int WIDGETGROUP_armature_facemaps_poll(const bContext *C, wmWidgetGroupType *UNUSED(wgrouptype))
 {
 	Object *ob = CTX_data_active_object(C);
@@ -347,6 +357,65 @@ 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(
+        Object *fmap_ob, bFaceMap *fmap, size_t maxname,
+        char *r_name)
+{
+	BLI_snprintf_rlen(r_name, maxname, "%s_%s", fmap_ob->id.name + 2, fmap->name);
+}
+
+/**
+ * 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)
+{
+	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)
+{
+	wmWidget *widget = WIDGET_facemap_new(wgroup, fmap->name, 0, fmap_ob, BLI_findindex(&fmap_ob->fmaps, fmap));
+
+	WM_widget_set_operator(widget, "TRANSFORM_OT_translate");
+	WM_widget_set_flag(widget, WM_WIDGET_DRAW_HOVER, true);
+	WM_widget_set_func_select(widget, WIDGET_armature_facemaps_select);
+	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);
@@ -354,31 +423,15 @@ void WIDGETGROUP_armature_facemaps_init(const bContext *C, wmWidgetGroup *wgroup
 
 #ifdef USE_FACEMAP_FROM_BONE
 	bPoseChannel *pchan;
+	armature_facemaps = BLI_ghash_str_new(__func__);
 
 	for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
 		if (pchan->fmap && (pchan->bone->layer & arm->layer)) {
-			ThemeWireColor *bcol = ED_pchan_get_colorset(arm, ob->pose, pchan);
-			Object *fmap_ob = pchan->fmap_object;
-			bFaceMap *fmap = pchan->fmap;
-			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);
-			}
-
-			wmWidget *widget = WIDGET_facemap_new(wgroup, fmap->name, 0, fmap_ob, BLI_findindex(&fmap_ob->fmaps, fmap));
-
-			WM_widget_set_operator(widget, "TRANSFORM_OT_translate");
-			WM_widget_set_colors(widget, col, col_hi);
-			WM_widget_set_flag(widget, WM_WIDGET_DRAW_HOVER, true);
-			WM_widget_set_func_select(widget, WIDGET_armature_facemaps_select);
-			PointerRNA *opptr = WM_widget_set_operator(widget, "TRANSFORM_OT_translate");
-			RNA_boolean_set(opptr, "release_confirm", true);
+			armature_facemap_widget_create(wgroup, armature_facemaps, pchan->fmap_object, pchan->fmap);
 		}
 	}
+	wgroup->customdata = armature_facemaps;
+	wgroup->customdata_free = armature_facemap_customdata_free;
 #else
 	Object *armature;
 	ModifierData *md;
@@ -418,3 +471,43 @@ void WIDGETGROUP_armature_facemaps_init(const bContext *C, wmWidgetGroup *wgroup
 	}
 #endif
 }
+
+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;
+
+	for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
+		if (pchan->fmap && (pchan->bone->layer & arm->layer)) {
+			char idname[MAX_ARMATURE_FACEMAP_NAME];
+			armature_facemap_hashname_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);
+				BLI_assert(widget);
+			}
+
+			/* 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);
+		}
+	}
+#endif
+}
diff --git a

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list