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