[Bf-blender-cvs] [99e9e4c5caf] custom-manipulators: Merge branch '28' into custom-manipulators

Campbell Barton noreply at git.blender.org
Wed Jun 7 16:06:28 CEST 2017


Commit: 99e9e4c5caf6a5b38b5726710dc3d777cd510bad
Author: Campbell Barton
Date:   Thu Jun 8 00:07:48 2017 +1000
Branches: custom-manipulators
https://developer.blender.org/rB99e9e4c5caf6a5b38b5726710dc3d777cd510bad

Merge branch '28' into custom-manipulators

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



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

diff --cc source/blender/editors/space_view3d/space_view3d.c
index 6422502f066,33121291935..a1524e33d47
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@@ -742,7 -742,6 +742,8 @@@ static void view3d_widgets(void
  	WM_manipulatorgrouptype_append(wmaptype, VIEW3D_WGT_lamp);
  	WM_manipulatorgrouptype_append(wmaptype, VIEW3D_WGT_force_field);
  	WM_manipulatorgrouptype_append(wmaptype, VIEW3D_WGT_camera);
++
++	WM_manipulatorgrouptype_append(wmaptype, VIEW3D_WGT_armature_facemaps);
  }
  
  
diff --cc source/blender/editors/space_view3d/view3d_manipulators.c
index 076dfc4c1d4,8d853498740..146e3b98d53
--- a/source/blender/editors/space_view3d/view3d_manipulators.c
+++ b/source/blender/editors/space_view3d/view3d_manipulators.c
@@@ -26,9 -26,8 +26,9 @@@
  
  
  #include "BLI_blenlib.h"
- #include "BLI_ghash.h"
  #include "BLI_math.h"
  #include "BLI_utildefines.h"
++#include "BLI_ghash.h"
  
  #include "BKE_armature.h"
  #include "BKE_camera.h"
@@@ -333,194 -354,4 +355,204 @@@ void VIEW3D_WGT_force_field(wmManipulat
  	wgt->flag |= WM_MANIPULATORGROUPTYPE_IS_3D;
  }
  
+ /** \} */
++
++/* -------------------------------------------------------------------- */
++
++/** \name Face Maps
++ * \{ */
++
++
 +#define MAX_ARMATURE_FACEMAP_NAME (2 * MAX_NAME + 1) /* "OBJECTNAME_FACEMAPNAME" */
 +
 +
 +static bool WIDGETGROUP_armature_facemaps_poll(const bContext *C, wmManipulatorGroupType *UNUSED(wgrouptype))
 +{
 +	Object *ob = CTX_data_active_object(C);
 +
 +	if (ob && BKE_object_pose_context_check(ob)) {
 +		for (bPoseChannel *pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
 +			if (pchan->fmap_data) {
 +				return true;
 +			}
 +		}
 +	}
 +	return false;
 +}
 +
 +static void WIDGET_armature_facemaps_select(bContext *C, wmManipulator *widget, const int action)
 +{
 +	Object *ob = CTX_data_active_object(C);
 +
 +	switch (action) {
 +		case SEL_SELECT:
 +			for (bPoseChannel *pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
 +				if (pchan->fmap_data && pchan->fmap_data->fmap == MANIPULATOR_facemap_get_fmap(widget)) {
 +					/* deselect all first */
 +					ED_pose_de_selectall(ob, SEL_DESELECT, false);
 +					ED_pose_bone_select(ob, pchan, true);
 +				}
 +			}
 +			break;
 +		default:
 +			BLI_assert(0);
 +	}
 +}
 +
 +/**
 + * Get a string that equals a string generated using #armature_facemap_hashname_create,
 + * but without allocating it. Only use for comparing with string stored as hash key.
 + */
 +BLI_INLINE void armature_facemap_hashkey_get(
 +        Object *fmap_ob, bFaceMap *fmap, size_t maxname,
 +        char *r_hashkey)
 +{
 +	BLI_snprintf_rlen(r_hashkey, maxname, "%s_%s", fmap_ob->id.name + 2, fmap->name);
 +}
 +
 +/**
 + * Same as #armature_facemap_hashname_get but allocates a new string. Use for storing string as hash key.
 + * \return A string using "OBJECTNAME_FACEMAPNAME" format.
 + */
 +BLI_INLINE char *armature_facemap_hashkey_create(Object *fmap_ob, bFaceMap *fmap)
 +{
 +	return BLI_sprintfN("%s_%s", fmap_ob->id.name + 2, fmap->name);
 +}
 +
 +BLI_INLINE void armature_facemap_ghash_insert(GHash *hash, wmManipulator *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 wmManipulatorGroup.customdata.
 + */
 +BLI_INLINE void armature_facemap_ghash_free(void *customdata)
 +{
 +	BLI_ghash_free(customdata, MEM_freeN, NULL);
 +}
 +
 +static wmManipulator *armature_facemap_widget_create(wmManipulatorGroup *wgroup, Object *fmap_ob, bFaceMap *fmap)
 +{
 +	wmManipulator *widget = MANIPULATOR_facemap_new(wgroup, fmap->name, 0, fmap_ob, BLI_findindex(&fmap_ob->fmaps, fmap));
 +
 +	WM_manipulator_set_operator(widget, "TRANSFORM_OT_translate");
 +	WM_manipulator_set_flag(widget, WM_MANIPULATOR_DRAW_HOVER, true);
 +	WM_manipulator_set_fn_select(widget, WIDGET_armature_facemaps_select);
 +	PointerRNA *opptr = WM_manipulator_set_operator(widget, "TRANSFORM_OT_translate");
 +	RNA_boolean_set(opptr, "release_confirm", true);
 +
 +	return widget;
 +}
 +
 +static void WIDGETGROUP_armature_facemaps_init(const bContext *C, wmManipulatorGroup *wgroup)
 +{
 +	Object *ob = CTX_data_active_object(C);
 +	bArmature *arm = (bArmature *)ob->data;
 +
 +	/* TODO(campbell): only update cache when toggling modes or armature modifiers. */
 +	{
 +		struct Depsgraph *graph = CTX_data_depsgraph(C);
 +		BKE_pose_fmap_cache_update(graph, ob);
 +	}
 +
 +	bPoseChannel *pchan;
 +	GHash *hash = BLI_ghash_str_new(__func__);
 +
 +	for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
 +		if (pchan->fmap_data && (pchan->bone->layer & arm->layer)) {
 +			wmManipulator *widget = armature_facemap_widget_create(
 +			        wgroup, pchan->fmap_data->object, pchan->fmap_data->fmap);
 +			armature_facemap_ghash_insert(
 +			        hash, widget, pchan->fmap_data->object, pchan->fmap_data->fmap);
 +		}
 +	}
 +	wgroup->customdata = hash;
 +	wgroup->customdata_free = armature_facemap_ghash_free;
 +}
 +
 +/**
 + * We do some special stuff for refreshing facemap widgets nicely:
 + * * On widget group init, needed widgets are created and stored in a hash table (wmManipulatorGroup.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 (wmManipulatorGroup.customdata) and becomes the old one on next refresh.
 + */
 +static void WIDGETGROUP_armature_facemaps_refresh(const bContext *C, wmManipulatorGroup *wgroup)
 +{
 +	if (!wgroup->customdata)
 +		return;
 +
 +	Object *ob = CTX_data_active_object(C);
 +	bArmature *arm = (bArmature *)ob->data;
 +	ARegion *ar = CTX_wm_region(C);
 +
 +	/* we create a new hash from the visible members of the old hash */
 +	GHash *oldhash = wgroup->customdata;
 +	GHash *newhash = BLI_ghash_str_new(__func__);
 +	wmManipulator *widget;
 +
 +	for (bPoseChannel *pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
 +		if (pchan->fmap_data == NULL) {
 +			continue;
 +		}
 +
 +		char widgetkey[MAX_ARMATURE_FACEMAP_NAME];
 +		armature_facemap_hashkey_get(pchan->fmap_data->object, pchan->fmap_data->fmap, sizeof(widgetkey), widgetkey);
 +
 +		/* create new widget for newly assigned facemap, add it to new hash */
 +		if (!(widget = BLI_ghash_lookup(oldhash, widgetkey))) {
 +			widget = armature_facemap_widget_create(wgroup, pchan->fmap_data->object, pchan->fmap_data->fmap);
 +			BLI_assert(widget);
 +		}
 +		armature_facemap_ghash_insert(newhash, widget, pchan->fmap_data->object, pchan->fmap_data->fmap);
 +
 +		if ((pchan->bone->layer & arm->layer)) {
 +			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_manipulator_set_color(widget, col);
 +			WM_manipulator_set_color_highlight(widget, col_hi);
 +			WM_manipulator_set_flag(widget, WM_MANIPULATOR_HIDDEN, false);
 +		}
 +		else {
 +			WM_manipulator_set_flag(widget, WM_MANIPULATOR_HIDDEN, true);
 +		}
 +
 +		/* remove from old hash */
 +		BLI_ghash_remove(oldhash, widgetkey, MEM_freeN, NULL);
 +	}
 +
 +	/* remove remaining widgets from old hash */
 +	GHashIterator ghi;
 +	GHASH_ITER(ghi, oldhash) {
 +		wmManipulator *found = BLI_ghashIterator_getValue(&ghi);
 +		WM_manipulator_delete(&wgroup->manipulators, ar->manipulator_map, found, (bContext *)C);
 +	}
 +	armature_facemap_ghash_free(oldhash);
 +
 +	wgroup->customdata = newhash;
 +}
 +
 +void VIEW3D_WGT_armature_facemaps(wmManipulatorGroupType *wgt)
 +{
 +	wgt->name = "Face Map Widgets";
 +
 +	wgt->poll = WIDGETGROUP_armature_facemaps_poll;
 +	wgt->init = WIDGETGROUP_armature_facemaps_init;
 +	wgt->refresh = WIDGETGROUP_armature_facemaps_refresh;
 +
 +	wgt->keymap_init = WM_manipulatorgroup_keymap_common_sel;
 +
 +	wgt->flag |= (WM_MANIPULATORGROUPTYPE_IS_3D |
 +	              WM_MANIPULATORGROUPTYPE_SCALE_3D |
 +	              WM_MANIPULATORGROUPTYPE_SELECTABLE);
 +}
++
++/** \} */




More information about the Bf-blender-cvs mailing list