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);
 +}
++
++/** \} */

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to