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