code cleanup: favor braces when blocks have mixed brace use.
[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 {
156                                 return;
157                         }
158                 }
159                 else {
160                         Bone *bone = BKE_armature_find_bone_name(arm, oldname);
161                         
162                         if (bone) {
163                                 unique_bone_name(arm, newname);
164                                 BLI_strncpy(bone->name, newname, MAXBONENAME);
165                         }
166                         else {
167                                 return;
168                         }
169                 }
170                 
171                 /* do entire dbase - objects */
172                 for (ob = G.main->object.first; ob; ob = ob->id.next) {
173                         ModifierData *md;
174                         
175                         /* we have the object using the armature */
176                         if (arm == ob->data) {
177                                 Object *cob;
178                                 
179                                 /* Rename the pose channel, if it exists */
180                                 if (ob->pose) {
181                                         bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, oldname);
182                                         if (pchan) {
183                                                 BLI_strncpy(pchan->name, newname, MAXBONENAME);
184                                                 
185                                                 if (ob->pose->chanhash) {
186                                                         GHash *gh = ob->pose->chanhash;
187                                                         
188                                                         /* remove the old hash entry, and replace with the new name */
189                                                         BLI_ghash_remove(gh, oldname, NULL, NULL);
190                                                         BLI_ghash_insert(gh, pchan->name, pchan);
191                                                 }
192                                         }
193                                 }
194                                 
195                                 /* Update any object constraints to use the new bone name */
196                                 for (cob = G.main->object.first; cob; cob = cob->id.next) {
197                                         if (cob->constraints.first)
198                                                 constraint_bone_name_fix(ob, &cob->constraints, oldname, newname);
199                                         if (cob->pose) {
200                                                 bPoseChannel *pchan;
201                                                 for (pchan = cob->pose->chanbase.first; pchan; pchan = pchan->next) {
202                                                         constraint_bone_name_fix(ob, &pchan->constraints, oldname, newname);
203                                                 }
204                                         }
205                                 }
206                         }
207                         
208                         /* See if an object is parented to this armature */
209                         if (ob->parent && (ob->parent->data == arm)) {
210                                 if (ob->partype == PARBONE) {
211                                         /* bone name in object */
212                                         if (!strcmp(ob->parsubstr, oldname))
213                                                 BLI_strncpy(ob->parsubstr, newname, MAXBONENAME);
214                                 }
215                         }
216                         
217                         if (modifiers_usesArmature(ob, arm)) {
218                                 bDeformGroup *dg = defgroup_find_name(ob, oldname);
219                                 if (dg) {
220                                         BLI_strncpy(dg->name, newname, MAXBONENAME);
221                                 }
222                         }
223                         
224                         /* fix modifiers that might be using this name */
225                         for (md = ob->modifiers.first; md; md = md->next) {
226                                 if (md->type == eModifierType_Hook) {
227                                         HookModifierData *hmd = (HookModifierData *)md;
228                                         
229                                         /* uses armature, so may use the affected bone name */
230                                         if (hmd->object && (hmd->object->data == arm)) {
231                                                 if (!strcmp(hmd->subtarget, oldname))
232                                                         BLI_strncpy(hmd->subtarget, newname, MAXBONENAME);
233                                         }
234                                 }
235                         }
236                 }
237                 
238                 /* Fix all animdata that may refer to this bone - we can't just do the ones attached to objects, since
239                  * other ID-blocks may have drivers referring to this bone [#29822]
240                  */
241                 {
242                         
243                         BKE_all_animdata_fix_paths_rename(&arm->id, "pose.bones", oldname, newname);
244                 }
245                 
246                 /* correct view locking */
247                 {
248                         bScreen *screen;
249                         for (screen = G.main->screen.first; screen; screen = screen->id.next) {
250                                 ScrArea *sa;
251                                 /* add regions */
252                                 for (sa = screen->areabase.first; sa; sa = sa->next) {
253                                         SpaceLink *sl;
254                                         for (sl = sa->spacedata.first; sl; sl = sl->next) {
255                                                 if (sl->spacetype == SPACE_VIEW3D) {
256                                                         View3D *v3d = (View3D *)sl;
257                                                         if (v3d->ob_centre && v3d->ob_centre->data == arm) {
258                                                                 if (!strcmp(v3d->ob_centre_bone, oldname)) {
259                                                                         BLI_strncpy(v3d->ob_centre_bone, newname, MAXBONENAME);
260                                                                 }
261                                                         }
262                                                 }
263                                         }
264                                 }
265                         }
266                 }
267         }
268 }
269
270 /* ************************************************** */
271 /* Bone Renaming - EditMode */
272
273 static int armature_flip_names_exec(bContext *C, wmOperator *UNUSED(op))
274 {
275         Object *ob = CTX_data_edit_object(C);
276         bArmature *arm;
277         char newname[MAXBONENAME];
278         
279         /* paranoia checks */
280         if (ELEM(NULL, ob, ob->pose)) 
281                 return OPERATOR_CANCELLED;
282         arm = ob->data;
283         
284         /* loop through selected bones, auto-naming them */
285         CTX_DATA_BEGIN(C, EditBone *, ebone, selected_editable_bones)
286         {
287                 flip_side_name(newname, ebone->name, TRUE); // 1 = do strip off number extensions
288                 ED_armature_bone_rename(arm, ebone->name, newname);
289         }
290         CTX_DATA_END;
291         
292         /* since we renamed stuff... */
293         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
294
295         /* note, notifier might evolve */
296         WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
297         
298         return OPERATOR_FINISHED;
299 }
300
301 void ARMATURE_OT_flip_names(wmOperatorType *ot)
302 {
303         /* identifiers */
304         ot->name = "Flip Names";
305         ot->idname = "ARMATURE_OT_flip_names";
306         ot->description = "Flips (and corrects) the axis suffixes of the names of selected bones";
307         
308         /* api callbacks */
309         ot->exec = armature_flip_names_exec;
310         ot->poll = ED_operator_editarmature;
311         
312         /* flags */
313         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
314 }
315
316
317 static int armature_autoside_names_exec(bContext *C, wmOperator *op)
318 {
319         Object *ob = CTX_data_edit_object(C);
320         bArmature *arm;
321         char newname[MAXBONENAME];
322         short axis = RNA_enum_get(op->ptr, "type");
323         
324         /* paranoia checks */
325         if (ELEM(NULL, ob, ob->pose)) 
326                 return OPERATOR_CANCELLED;
327         arm = ob->data;
328         
329         /* loop through selected bones, auto-naming them */
330         CTX_DATA_BEGIN(C, EditBone *, ebone, selected_editable_bones)
331         {
332                 BLI_strncpy(newname, ebone->name, sizeof(newname));
333                 if (bone_autoside_name(newname, 1, axis, ebone->head[axis], ebone->tail[axis]))
334                         ED_armature_bone_rename(arm, ebone->name, newname);
335         }
336         CTX_DATA_END;
337         
338         /* since we renamed stuff... */
339         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
340
341         /* note, notifier might evolve */
342         WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
343         
344         return OPERATOR_FINISHED;
345 }
346
347 void ARMATURE_OT_autoside_names(wmOperatorType *ot)
348 {
349         static EnumPropertyItem axis_items[] = {
350                 {0, "XAXIS", 0, "X-Axis", "Left/Right"},
351                 {1, "YAXIS", 0, "Y-Axis", "Front/Back"},
352                 {2, "ZAXIS", 0, "Z-Axis", "Top/Bottom"},
353                 {0, NULL, 0, NULL, NULL}
354         };
355         
356         /* identifiers */
357         ot->name = "AutoName by Axis";
358         ot->idname = "ARMATURE_OT_autoside_names";
359         ot->description = "Automatically renames the selected bones according to which side of the target axis they fall on";
360         
361         /* api callbacks */
362         ot->invoke = WM_menu_invoke;
363         ot->exec = armature_autoside_names_exec;
364         ot->poll = ED_operator_editarmature;
365         
366         /* flags */
367         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
368         
369         /* settings */
370         ot->prop = RNA_def_enum(ot->srna, "type", axis_items, 0, "Axis", "Axis tag names with");
371 }
372