cd7e3b4cb3922dcbe7bf04e32bcaf80f0f9738cd
[blender-staging.git] / source / blender / editors / armature / armature_naming.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * Contributor(s): Blender Foundation, 2002-2009 full recode.
22  *
23  * ***** END GPL LICENSE BLOCK *****
24  *
25  * Operators and API's for renaming bones both in and out of Edit Mode
26  */
27
28 /** \file blender/editors/armature/armature_naming.c
29  *  \ingroup edarmature
30  */
31
32 #include <string.h>
33
34 #include "DNA_armature_types.h"
35 #include "DNA_constraint_types.h"
36 #include "DNA_object_types.h"
37
38 #include "BLI_blenlib.h"
39 #include "BLI_ghash.h"
40 #include "BLI_string_utils.h"
41 #include "BLI_utildefines.h"
42
43 #include "BLT_translation.h"
44
45 #include "BKE_animsys.h"
46 #include "BKE_action.h"
47 #include "BKE_armature.h"
48 #include "BKE_constraint.h"
49 #include "BKE_context.h"
50 #include "BKE_deform.h"
51 #include "BKE_depsgraph.h"
52 #include "BKE_global.h"
53 #include "BKE_main.h"
54 #include "BKE_modifier.h"
55
56 #include "RNA_access.h"
57 #include "RNA_define.h"
58
59 #include "WM_api.h"
60 #include "WM_types.h"
61
62 #include "ED_armature.h"
63 #include "ED_screen.h"
64
65 #include "armature_intern.h"
66
67 /* This file contains functions/API's for renaming bones and/or working with them */
68
69 /* ************************************************** */
70 /* EditBone Names */
71
72 /* note: there's a unique_bone_name() too! */
73 static bool editbone_unique_check(void *arg, const char *name)
74 {
75         struct {ListBase *lb; void *bone; } *data = arg;
76         EditBone *dupli = ED_armature_bone_find_name(data->lb, name);
77         return dupli && dupli != data->bone;
78 }
79
80 void unique_editbone_name(ListBase *edbo, char *name, EditBone *bone)
81 {
82         struct {ListBase *lb; void *bone; } data;
83         data.lb = edbo;
84         data.bone = bone;
85
86         BLI_uniquename_cb(editbone_unique_check, &data, DATA_("Bone"), '.', name, sizeof(bone->name));
87 }
88
89 /* ************************************************** */
90 /* Bone Renaming - API */
91
92 static bool bone_unique_check(void *arg, const char *name)
93 {
94         return BKE_armature_find_bone_name((bArmature *)arg, name) != NULL;
95 }
96
97 static void unique_bone_name(bArmature *arm, char *name)
98 {
99         BLI_uniquename_cb(bone_unique_check, (void *)arm, DATA_("Bone"), '.', name, sizeof(((Bone *)NULL)->name));
100 }
101
102 /* helper call for armature_bone_rename */
103 static void constraint_bone_name_fix(Object *ob, ListBase *conlist, const char *oldname, const char *newname)
104 {
105         bConstraint *curcon;
106         bConstraintTarget *ct;
107         
108         for (curcon = conlist->first; curcon; curcon = curcon->next) {
109                 const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(curcon);
110                 ListBase targets = {NULL, NULL};
111                 
112                 /* constraint targets */
113                 if (cti && cti->get_constraint_targets) {
114                         cti->get_constraint_targets(curcon, &targets);
115                         
116                         for (ct = targets.first; ct; ct = ct->next) {
117                                 if (ct->tar == ob) {
118                                         if (STREQ(ct->subtarget, oldname)) {
119                                                 BLI_strncpy(ct->subtarget, newname, MAXBONENAME);
120                                         }
121                                 }
122                         }
123                         
124                         if (cti->flush_constraint_targets)
125                                 cti->flush_constraint_targets(curcon, &targets, 0);
126                 }
127                 
128                 /* action constraints */
129                 if (curcon->type == CONSTRAINT_TYPE_ACTION) {
130                         bActionConstraint *actcon = (bActionConstraint *)curcon->data;
131                         BKE_action_fix_paths_rename(&ob->id, actcon->act, "pose.bones", oldname, newname, 0, 0, 1);
132                 }
133         }
134 }
135
136 /* called by UI for renaming a bone */
137 /* warning: make sure the original bone was not renamed yet! */
138 /* seems messy, but thats what you get with not using pointers but channel names :) */
139 void ED_armature_bone_rename(bArmature *arm, const char *oldnamep, const char *newnamep)
140 {
141         Object *ob;
142         char newname[MAXBONENAME];
143         char oldname[MAXBONENAME];
144         
145         /* names better differ! */
146         if (!STREQLEN(oldnamep, newnamep, MAXBONENAME)) {
147                 
148                 /* we alter newname string... so make copy */
149                 BLI_strncpy(newname, newnamep, MAXBONENAME);
150                 /* we use oldname for search... so make copy */
151                 BLI_strncpy(oldname, oldnamep, MAXBONENAME);
152                 
153                 /* now check if we're in editmode, we need to find the unique name */
154                 if (arm->edbo) {
155                         EditBone *eBone = ED_armature_bone_find_name(arm->edbo, oldname);
156                         
157                         if (eBone) {
158                                 unique_editbone_name(arm->edbo, newname, NULL);
159                                 BLI_strncpy(eBone->name, newname, MAXBONENAME);
160                         }
161                         else {
162                                 return;
163                         }
164                 }
165                 else {
166                         Bone *bone = BKE_armature_find_bone_name(arm, oldname);
167                         
168                         if (bone) {
169                                 unique_bone_name(arm, newname);
170                                 BLI_strncpy(bone->name, newname, MAXBONENAME);
171                         }
172                         else {
173                                 return;
174                         }
175                 }
176                 
177                 /* do entire dbase - objects */
178                 for (ob = G.main->object.first; ob; ob = ob->id.next) {
179                         ModifierData *md;
180                         
181                         /* we have the object using the armature */
182                         if (arm == ob->data) {
183                                 Object *cob;
184                                 
185                                 /* Rename the pose channel, if it exists */
186                                 if (ob->pose) {
187                                         bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, oldname);
188                                         if (pchan) {
189                                                 GHash *gh = ob->pose->chanhash;
190
191                                                 /* remove the old hash entry, and replace with the new name */
192                                                 if (gh) {
193                                                         BLI_assert(BLI_ghash_haskey(gh, pchan->name));
194                                                         BLI_ghash_remove(gh, pchan->name, NULL, NULL);
195                                                 }
196
197                                                 BLI_strncpy(pchan->name, newname, MAXBONENAME);
198
199                                                 if (gh) {
200                                                         BLI_ghash_insert(gh, pchan->name, pchan);
201                                                 }
202                                         }
203
204                                         BLI_assert(BKE_pose_channels_is_valid(ob->pose) == true);
205                                 }
206                                 
207                                 /* Update any object constraints to use the new bone name */
208                                 for (cob = G.main->object.first; cob; cob = cob->id.next) {
209                                         if (cob->constraints.first)
210                                                 constraint_bone_name_fix(ob, &cob->constraints, oldname, newname);
211                                         if (cob->pose) {
212                                                 bPoseChannel *pchan;
213                                                 for (pchan = cob->pose->chanbase.first; pchan; pchan = pchan->next) {
214                                                         constraint_bone_name_fix(ob, &pchan->constraints, oldname, newname);
215                                                 }
216                                         }
217                                 }
218                         }
219                         
220                         /* See if an object is parented to this armature */
221                         if (ob->parent && (ob->parent->data == arm)) {
222                                 if (ob->partype == PARBONE) {
223                                         /* bone name in object */
224                                         if (STREQ(ob->parsubstr, oldname))
225                                                 BLI_strncpy(ob->parsubstr, newname, MAXBONENAME);
226                                 }
227                         }
228                         
229                         if (modifiers_usesArmature(ob, arm)) {
230                                 bDeformGroup *dg = defgroup_find_name(ob, oldname);
231                                 if (dg) {
232                                         BLI_strncpy(dg->name, newname, MAXBONENAME);
233                                 }
234                         }
235                         
236                         /* fix modifiers that might be using this name */
237                         for (md = ob->modifiers.first; md; md = md->next) {
238                                 switch (md->type) {
239                                         case eModifierType_Hook:
240                                         {
241                                                 HookModifierData *hmd = (HookModifierData *)md;
242
243                                                 if (hmd->object && (hmd->object->data == arm)) {
244                                                         if (STREQ(hmd->subtarget, oldname))
245                                                                 BLI_strncpy(hmd->subtarget, newname, MAXBONENAME);
246                                                 }
247                                                 break;
248                                         }
249                                         case eModifierType_UVWarp:
250                                         {
251                                                 UVWarpModifierData *umd = (UVWarpModifierData *)md;
252
253                                                 if (umd->object_src && (umd->object_src->data == arm)) {
254                                                         if (STREQ(umd->bone_src, oldname))
255                                                                 BLI_strncpy(umd->bone_src, newname, MAXBONENAME);
256                                                 }
257                                                 if (umd->object_dst && (umd->object_dst->data == arm)) {
258                                                         if (STREQ(umd->bone_dst, oldname))
259                                                                 BLI_strncpy(umd->bone_dst, newname, MAXBONENAME);
260                                                 }
261                                                 break;
262                                         }
263                                         default:
264                                                 break;
265                                 }
266                         }
267                 }
268                 
269                 /* Fix all animdata that may refer to this bone - we can't just do the ones attached to objects, since
270                  * other ID-blocks may have drivers referring to this bone [#29822]
271                  */
272                 // XXX: the ID here is for armatures, but most bone drivers are actually on the object instead...
273                 {
274                         
275                         BKE_animdata_fix_paths_rename_all(&arm->id, "pose.bones", oldname, newname);
276                 }
277                 
278                 /* correct view locking */
279                 {
280                         bScreen *screen;
281                         for (screen = G.main->screen.first; screen; screen = screen->id.next) {
282                                 ScrArea *sa;
283                                 /* add regions */
284                                 for (sa = screen->areabase.first; sa; sa = sa->next) {
285                                         SpaceLink *sl;
286                                         for (sl = sa->spacedata.first; sl; sl = sl->next) {
287                                                 if (sl->spacetype == SPACE_VIEW3D) {
288                                                         View3D *v3d = (View3D *)sl;
289                                                         if (v3d->ob_centre && v3d->ob_centre->data == arm) {
290                                                                 if (STREQ(v3d->ob_centre_bone, oldname)) {
291                                                                         BLI_strncpy(v3d->ob_centre_bone, newname, MAXBONENAME);
292                                                                 }
293                                                         }
294                                                 }
295                                         }
296                                 }
297                         }
298                 }
299         }
300 }
301
302 typedef struct BoneFlipNameData {
303         struct BoneFlipNameData *next, *prev;
304         char *name;
305         char name_flip[MAXBONENAME];
306 } BoneFlipNameData;
307
308 /**
309  * Renames (by flipping) all selected bones at once.
310  *
311  * This way if we are flipping related bones (e.g., Bone.L, Bone.R) at the same time
312  * all the bones are safely renamed, without conflicting with each other.
313  *
314  * \param arm: Armature the bones belong to
315  * \param bones_names: List of BoneConflict elems.
316  * \param do_flip_numbers: if set, try to get rid of dot-numbers at end of bone names.
317  */
318 void ED_armature_bones_flip_names(bArmature *arm, ListBase *bones_names, const bool do_strip_numbers)
319 {
320         ListBase bones_names_conflicts = {NULL};
321         BoneFlipNameData *bfn;
322
323         /* First pass: generate flip names, and blindly rename.
324          * If rename did not yield expected result, store both bone's name and expected flipped one into temp list
325          * for second pass. */
326         for (LinkData *link = bones_names->first; link; link = link->next) {
327                 char name_flip[MAXBONENAME];
328                 char *name = link->data;
329
330                 /* WARNING: if do_strip_numbers is set, expect completely mismatched names in cases like
331                  * Bone.R, Bone.R.001, Bone.R.002, etc. */
332                 BLI_string_flip_side_name(name_flip, name, do_strip_numbers, sizeof(name_flip));
333
334                 ED_armature_bone_rename(arm, name, name_flip);
335
336                 if (!STREQ(name, name_flip)) {
337                         bfn = alloca(sizeof(BoneFlipNameData));
338                         bfn->name = name;
339                         BLI_strncpy(bfn->name_flip, name_flip, sizeof(bfn->name_flip));
340                         BLI_addtail(&bones_names_conflicts, bfn);
341                 }
342         }
343
344         /* Second pass to handle the bones that have naming conflicts with other bones.
345          * Note that if the other bone was not selected, its name was not flipped, so conflict remains and that second
346          * rename simply generates a new numbered alternative name. */
347         for (bfn = bones_names_conflicts.first; bfn; bfn = bfn->next) {
348                 ED_armature_bone_rename(arm, bfn->name, bfn->name_flip);
349         }
350 }
351
352 /* ************************************************** */
353 /* Bone Renaming - EditMode */
354
355 static int armature_flip_names_exec(bContext *C, wmOperator *op)
356 {
357         Object *ob = CTX_data_edit_object(C);
358         bArmature *arm;
359
360         /* paranoia checks */
361         if (ELEM(NULL, ob, ob->pose))
362                 return OPERATOR_CANCELLED;
363
364         const bool do_strip_numbers = RNA_boolean_get(op->ptr, "do_strip_numbers");
365
366         arm = ob->data;
367
368         ListBase bones_names = {NULL};
369
370         CTX_DATA_BEGIN(C, EditBone *, ebone, selected_editable_bones)
371         {
372                 BLI_addtail(&bones_names, BLI_genericNodeN(ebone->name));
373         }
374         CTX_DATA_END;
375
376         ED_armature_bones_flip_names(arm, &bones_names, do_strip_numbers);
377
378         BLI_freelistN(&bones_names);
379         
380         /* since we renamed stuff... */
381         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
382
383         /* copied from #rna_Bone_update_renamed */
384         /* redraw view */
385         WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
386
387         /* update animation channels */
388         WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN, ob->data);
389
390         return OPERATOR_FINISHED;
391 }
392
393 void ARMATURE_OT_flip_names(wmOperatorType *ot)
394 {
395         /* identifiers */
396         ot->name = "Flip Names";
397         ot->idname = "ARMATURE_OT_flip_names";
398         ot->description = "Flips (and corrects) the axis suffixes of the names of selected bones";
399         
400         /* api callbacks */
401         ot->exec = armature_flip_names_exec;
402         ot->poll = ED_operator_editarmature;
403         
404         /* flags */
405         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
406
407         RNA_def_boolean(ot->srna, "do_strip_numbers", false, "Strip Numbers",
408                         "Try to remove right-most dot-number from flipped names "
409                         "(WARNING: may result in incoherent naming in some cases)");
410 }
411
412
413 static int armature_autoside_names_exec(bContext *C, wmOperator *op)
414 {
415         Object *ob = CTX_data_edit_object(C);
416         bArmature *arm;
417         char newname[MAXBONENAME];
418         short axis = RNA_enum_get(op->ptr, "type");
419         
420         /* paranoia checks */
421         if (ELEM(NULL, ob, ob->pose)) 
422                 return OPERATOR_CANCELLED;
423         arm = ob->data;
424         
425         /* loop through selected bones, auto-naming them */
426         CTX_DATA_BEGIN(C, EditBone *, ebone, selected_editable_bones)
427         {
428                 BLI_strncpy(newname, ebone->name, sizeof(newname));
429                 if (bone_autoside_name(newname, 1, axis, ebone->head[axis], ebone->tail[axis]))
430                         ED_armature_bone_rename(arm, ebone->name, newname);
431         }
432         CTX_DATA_END;
433         
434         /* since we renamed stuff... */
435         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
436
437         /* note, notifier might evolve */
438         WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
439         
440         return OPERATOR_FINISHED;
441 }
442
443 void ARMATURE_OT_autoside_names(wmOperatorType *ot)
444 {
445         static const EnumPropertyItem axis_items[] = {
446                 {0, "XAXIS", 0, "X-Axis", "Left/Right"},
447                 {1, "YAXIS", 0, "Y-Axis", "Front/Back"},
448                 {2, "ZAXIS", 0, "Z-Axis", "Top/Bottom"},
449                 {0, NULL, 0, NULL, NULL}
450         };
451         
452         /* identifiers */
453         ot->name = "AutoName by Axis";
454         ot->idname = "ARMATURE_OT_autoside_names";
455         ot->description = "Automatically renames the selected bones according to which side of the target axis they fall on";
456         
457         /* api callbacks */
458         ot->invoke = WM_menu_invoke;
459         ot->exec = armature_autoside_names_exec;
460         ot->poll = ED_operator_editarmature;
461         
462         /* flags */
463         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
464         
465         /* settings */
466         ot->prop = RNA_def_enum(ot->srna, "type", axis_items, 0, "Axis", "Axis tag names with");
467 }
468