196b8064967bf5f50debf150d8645545c42f42f9
[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
41 #include "BLF_translation.h"
42
43 #include "BKE_animsys.h"
44 #include "BKE_action.h"
45 #include "BKE_armature.h"
46 #include "BKE_constraint.h"
47 #include "BKE_context.h"
48 #include "BKE_deform.h"
49 #include "BKE_depsgraph.h"
50 #include "BKE_global.h"
51 #include "BKE_main.h"
52 #include "BKE_modifier.h"
53
54 #include "RNA_access.h"
55 #include "RNA_define.h"
56
57 #include "WM_api.h"
58 #include "WM_types.h"
59
60 #include "ED_armature.h"
61 #include "ED_screen.h"
62
63 #include "armature_intern.h"
64
65 /* This file contains functions/API's for renaming bones and/or working with them */
66
67 /* ************************************************** */
68 /* EditBone Names */
69
70 /* checks if an EditBone with a matching name already, returning the matching bone if it exists */
71 EditBone *editbone_name_exists(ListBase *edbo, const char *name)
72 {
73         return BLI_findstring(edbo, name, offsetof(EditBone, name));
74 }
75
76 /* note: there's a unique_bone_name() too! */
77 static bool editbone_unique_check(void *arg, const char *name)
78 {
79         struct {ListBase *lb; void *bone; } *data = arg;
80         EditBone *dupli = editbone_name_exists(data->lb, name);
81         return dupli && dupli != data->bone;
82 }
83
84 void unique_editbone_name(ListBase *edbo, char *name, EditBone *bone)
85 {
86         struct {ListBase *lb; void *bone; } data;
87         data.lb = edbo;
88         data.bone = bone;
89
90         BLI_uniquename_cb(editbone_unique_check, &data, DATA_("Bone"), '.', name, sizeof(bone->name));
91 }
92
93 /* ************************************************** */
94 /* Bone Renaming - API */
95
96 static bool bone_unique_check(void *arg, const char *name)
97 {
98         return BKE_armature_find_bone_name((bArmature *)arg, name) != NULL;
99 }
100
101 static void unique_bone_name(bArmature *arm, char *name)
102 {
103         BLI_uniquename_cb(bone_unique_check, (void *)arm, DATA_("Bone"), '.', name, sizeof(((Bone *)NULL)->name));
104 }
105
106 /* helper call for armature_bone_rename */
107 static void constraint_bone_name_fix(Object *ob, ListBase *conlist, char *oldname, char *newname)
108 {
109         bConstraint *curcon;
110         bConstraintTarget *ct;
111         
112         for (curcon = conlist->first; curcon; curcon = curcon->next) {
113                 bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(curcon);
114                 ListBase targets = {NULL, NULL};
115                 
116                 if (cti && cti->get_constraint_targets) {
117                         cti->get_constraint_targets(curcon, &targets);
118                         
119                         for (ct = targets.first; ct; ct = ct->next) {
120                                 if (ct->tar == ob) {
121                                         if (!strcmp(ct->subtarget, oldname) )
122                                                 BLI_strncpy(ct->subtarget, newname, MAXBONENAME);
123                                 }
124                         }
125                         
126                         if (cti->flush_constraint_targets)
127                                 cti->flush_constraint_targets(curcon, &targets, 0);
128                 }
129         }
130 }
131
132 /* called by UI for renaming a bone */
133 /* warning: make sure the original bone was not renamed yet! */
134 /* seems messy, but thats what you get with not using pointers but channel names :) */
135 void ED_armature_bone_rename(bArmature *arm, const char *oldnamep, const char *newnamep)
136 {
137         Object *ob;
138         char newname[MAXBONENAME];
139         char oldname[MAXBONENAME];
140         
141         /* names better differ! */
142         if (strncmp(oldnamep, newnamep, MAXBONENAME)) {
143                 
144                 /* we alter newname string... so make copy */
145                 BLI_strncpy(newname, newnamep, MAXBONENAME);
146                 /* we use oldname for search... so make copy */
147                 BLI_strncpy(oldname, oldnamep, MAXBONENAME);
148                 
149                 /* now check if we're in editmode, we need to find the unique name */
150                 if (arm->edbo) {
151                         EditBone *eBone = editbone_name_exists(arm->edbo, oldname);
152                         
153                         if (eBone) {
154                                 unique_editbone_name(arm->edbo, newname, NULL);
155                                 BLI_strncpy(eBone->name, newname, MAXBONENAME);
156                         }
157                         else {
158                                 return;
159                         }
160                 }
161                 else {
162                         Bone *bone = BKE_armature_find_bone_name(arm, oldname);
163                         
164                         if (bone) {
165                                 unique_bone_name(arm, newname);
166                                 BLI_strncpy(bone->name, newname, MAXBONENAME);
167                         }
168                         else {
169                                 return;
170                         }
171                 }
172                 
173                 /* do entire dbase - objects */
174                 for (ob = G.main->object.first; ob; ob = ob->id.next) {
175                         ModifierData *md;
176                         
177                         /* we have the object using the armature */
178                         if (arm == ob->data) {
179                                 Object *cob;
180                                 
181                                 /* Rename the pose channel, if it exists */
182                                 if (ob->pose) {
183                                         bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, oldname);
184                                         if (pchan) {
185                                                 BLI_strncpy(pchan->name, newname, MAXBONENAME);
186                                                 
187                                                 if (ob->pose->chanhash) {
188                                                         GHash *gh = ob->pose->chanhash;
189                                                         
190                                                         /* remove the old hash entry, and replace with the new name */
191                                                         BLI_ghash_remove(gh, oldname, NULL, NULL);
192                                                         BLI_ghash_insert(gh, pchan->name, pchan);
193                                                 }
194                                         }
195                                 }
196                                 
197                                 /* Update any object constraints to use the new bone name */
198                                 for (cob = G.main->object.first; cob; cob = cob->id.next) {
199                                         if (cob->constraints.first)
200                                                 constraint_bone_name_fix(ob, &cob->constraints, oldname, newname);
201                                         if (cob->pose) {
202                                                 bPoseChannel *pchan;
203                                                 for (pchan = cob->pose->chanbase.first; pchan; pchan = pchan->next) {
204                                                         constraint_bone_name_fix(ob, &pchan->constraints, oldname, newname);
205                                                 }
206                                         }
207                                 }
208                         }
209                         
210                         /* See if an object is parented to this armature */
211                         if (ob->parent && (ob->parent->data == arm)) {
212                                 if (ob->partype == PARBONE) {
213                                         /* bone name in object */
214                                         if (!strcmp(ob->parsubstr, oldname))
215                                                 BLI_strncpy(ob->parsubstr, newname, MAXBONENAME);
216                                 }
217                         }
218                         
219                         if (modifiers_usesArmature(ob, arm)) {
220                                 bDeformGroup *dg = defgroup_find_name(ob, oldname);
221                                 if (dg) {
222                                         BLI_strncpy(dg->name, newname, MAXBONENAME);
223                                 }
224                         }
225                         
226                         /* fix modifiers that might be using this name */
227                         for (md = ob->modifiers.first; md; md = md->next) {
228                                 if (md->type == eModifierType_Hook) {
229                                         HookModifierData *hmd = (HookModifierData *)md;
230                                         
231                                         /* uses armature, so may use the affected bone name */
232                                         if (hmd->object && (hmd->object->data == arm)) {
233                                                 if (!strcmp(hmd->subtarget, oldname))
234                                                         BLI_strncpy(hmd->subtarget, newname, MAXBONENAME);
235                                         }
236                                 }
237                         }
238                 }
239                 
240                 /* Fix all animdata that may refer to this bone - we can't just do the ones attached to objects, since
241                  * other ID-blocks may have drivers referring to this bone [#29822]
242                  */
243                 {
244                         
245                         BKE_all_animdata_fix_paths_rename(&arm->id, "pose.bones", oldname, newname);
246                 }
247                 
248                 /* correct view locking */
249                 {
250                         bScreen *screen;
251                         for (screen = G.main->screen.first; screen; screen = screen->id.next) {
252                                 ScrArea *sa;
253                                 /* add regions */
254                                 for (sa = screen->areabase.first; sa; sa = sa->next) {
255                                         SpaceLink *sl;
256                                         for (sl = sa->spacedata.first; sl; sl = sl->next) {
257                                                 if (sl->spacetype == SPACE_VIEW3D) {
258                                                         View3D *v3d = (View3D *)sl;
259                                                         if (v3d->ob_centre && v3d->ob_centre->data == arm) {
260                                                                 if (!strcmp(v3d->ob_centre_bone, oldname)) {
261                                                                         BLI_strncpy(v3d->ob_centre_bone, newname, MAXBONENAME);
262                                                                 }
263                                                         }
264                                                 }
265                                         }
266                                 }
267                         }
268                 }
269         }
270 }
271
272 /* ************************************************** */
273 /* Bone Renaming - EditMode */
274
275 static int armature_flip_names_exec(bContext *C, wmOperator *UNUSED(op))
276 {
277         Object *ob = CTX_data_edit_object(C);
278         bArmature *arm;
279         char newname[MAXBONENAME];
280         
281         /* paranoia checks */
282         if (ELEM(NULL, ob, ob->pose)) 
283                 return OPERATOR_CANCELLED;
284         arm = ob->data;
285         
286         /* loop through selected bones, auto-naming them */
287         CTX_DATA_BEGIN(C, EditBone *, ebone, selected_editable_bones)
288         {
289                 flip_side_name(newname, ebone->name, TRUE); // 1 = do strip off number extensions
290                 ED_armature_bone_rename(arm, ebone->name, newname);
291         }
292         CTX_DATA_END;
293         
294         /* since we renamed stuff... */
295         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
296
297         /* note, notifier might evolve */
298         WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
299         
300         return OPERATOR_FINISHED;
301 }
302
303 void ARMATURE_OT_flip_names(wmOperatorType *ot)
304 {
305         /* identifiers */
306         ot->name = "Flip Names";
307         ot->idname = "ARMATURE_OT_flip_names";
308         ot->description = "Flips (and corrects) the axis suffixes of the names of selected bones";
309         
310         /* api callbacks */
311         ot->exec = armature_flip_names_exec;
312         ot->poll = ED_operator_editarmature;
313         
314         /* flags */
315         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
316 }
317
318
319 static int armature_autoside_names_exec(bContext *C, wmOperator *op)
320 {
321         Object *ob = CTX_data_edit_object(C);
322         bArmature *arm;
323         char newname[MAXBONENAME];
324         short axis = RNA_enum_get(op->ptr, "type");
325         
326         /* paranoia checks */
327         if (ELEM(NULL, ob, ob->pose)) 
328                 return OPERATOR_CANCELLED;
329         arm = ob->data;
330         
331         /* loop through selected bones, auto-naming them */
332         CTX_DATA_BEGIN(C, EditBone *, ebone, selected_editable_bones)
333         {
334                 BLI_strncpy(newname, ebone->name, sizeof(newname));
335                 if (bone_autoside_name(newname, 1, axis, ebone->head[axis], ebone->tail[axis]))
336                         ED_armature_bone_rename(arm, ebone->name, newname);
337         }
338         CTX_DATA_END;
339         
340         /* since we renamed stuff... */
341         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
342
343         /* note, notifier might evolve */
344         WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
345         
346         return OPERATOR_FINISHED;
347 }
348
349 void ARMATURE_OT_autoside_names(wmOperatorType *ot)
350 {
351         static EnumPropertyItem axis_items[] = {
352                 {0, "XAXIS", 0, "X-Axis", "Left/Right"},
353                 {1, "YAXIS", 0, "Y-Axis", "Front/Back"},
354                 {2, "ZAXIS", 0, "Z-Axis", "Top/Bottom"},
355                 {0, NULL, 0, NULL, NULL}
356         };
357         
358         /* identifiers */
359         ot->name = "AutoName by Axis";
360         ot->idname = "ARMATURE_OT_autoside_names";
361         ot->description = "Automatically renames the selected bones according to which side of the target axis they fall on";
362         
363         /* api callbacks */
364         ot->invoke = WM_menu_invoke;
365         ot->exec = armature_autoside_names_exec;
366         ot->poll = ED_operator_editarmature;
367         
368         /* flags */
369         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
370         
371         /* settings */
372         ot->prop = RNA_def_enum(ot->srna, "type", axis_items, 0, "Axis", "Axis tag names with");
373 }
374