[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