Hey, there guys. Blender seems to have a problem in which it doesn’t correctly update references to custom properties when their names are changed. To deal with this I am attempting to right a renaming script. The user will input the name of the property they want to change and the new name and the script will then go through and rename references to that name in animation curves and driver property variables. I feel like what I have so far should be working but I am not getting expected results, ie, the data is not changing. On a related note, I don’t think that I am accessing the custom properties animation data correctly in the “Update Property Animation Curves” section. I’m sure I am doing most of this wrong/the hard way so any help would be appreciated.
#----------------------RENAME PROPERTIES-----------------------#
bpy.types.Scene.OldPropertyName = bpy.props.StringProperty(default="Property To Change")
bpy.types.Scene.RenameProperties = bpy.props.StringProperty(default="New Name")
class renameProperties (bpy.types.Operator):
bl_idname = "object.rename_properties"
bl_label = "Rename Properties"
bl_options = {"REGISTER", "UNDO"}
def execute(self,context):
objects = bpy.context.selected_objects[:]
old_name = bpy.context.scene.OldPropertyName
new_name = bpy.context.scene.RenameProperties
for obj in objects:
if obj == bpy.context.active_object:
#--------Add Property Names to A List---------#
for key in obj.keys():
if key == old_name:
if key != "_RNA_UI":
print("old key is ", key)
key = new_name
print("new key is ", key)
#-------Get Actions In Scene--------#
actions = bpy.data.actions
#-------Get FCurves-------#
for action in actions:
act_curve = bpy.data.actions[action.name].groups
for curve in act_curve:
#print("curves", curve.name)
#--------Update Property Animation Curves ------#
if curve.name == old_name:
print("old curve name", curve.name)
curve.name = new_name
print("new curve name", curve.name)
#--------Get Driver Datapaths--------#
drivers = bpy.context.object.animation_data.drivers
for driver in range(len(drivers)):
variables = drivers[driver].driver.variables
for var in range(len(variables)):
target = variables[var].targets
for path in range(len(target)):
path_name = target[path].data_path
#--------Update Driver Variable Path--------#
if path_name == "[\"{0}\"]".format(old_name):
print(True, var_name)
print("new_name", new_name)
path_name == new_name
print("new var name", var_name)
return {'FINISHED'}
Today I am back at it trying to find a solution to this problem. Today I worked on renaming FCurves. I thought I had made some progress but it looks like my solution doesn’t work. Here is what I did today:
import bpy
actions = bpy.data.actions
for action in actions:
curves = bpy.data.actions[action.name].fcurves
for path in curves:
if "upperarm.L" in str(path.data_path):
old_path = str(path.data_path)
new_path = old_path.replace("upperarm.L", "UpArmL")
I am going to be going over this code soon but I wanted to reply. First off thanks for the response. Secondly, there are few things that you’ve done that I just don’t understand yet. Specifically, I don’t understand what property_enum is. This is one of a number of aspects of the blender api that just seem so confusing to me. bpy.types.EnumProperty(Property) this is what I see when I look at the docs and it just doesn’t tell me at all how its used. There just seems to be so many ways to try and approach the data and I am missing some fundamental understanding of how Blender api is structured.
I am just getting back to this problem after a while. The code you posted only renames the custom properties themselves and doesn’t fix associated data paths. I have attempted a number of times to write something myself that does so but have not come up with anything that works properly. When I print out what’s going on it looks like paths are being update but really aren’t. I am getting to the point where I am starting to think that this is a bug in the python implementation. Before I submit a bug report I would ask you to take a look at the blend file I am linking and the code in it to see if it should be renaming the paths to the animation data and drivers. I appreciate this a bunch.
Well, name changes are only tracked for built-in properties which store a reference to an ID datablock. A python-defined StringProperty that refers to a datablock will become invalid if the referenced datablock is renamed. There is no way to define ID properties with Python.
technically, it is possible to change f-curve data_paths and driver paths, but seems pretty tricky to me to implement a script that works reliably. Unless you let the user do the mapping in a GUI…
I don’t really need a GUI. This is really for my own use. Although I would imagine a tool like that would be useful to the wider community. Its hard for me to understand how this hasn’t been addressed before. Well, I’d be willing to pay for some help with on this issue. I have a lot of animated data that needs to be redirected and soon.
Is it already “broken”, as in driver expressions and f-curve data paths are already out of sync? Or do you plan on changing names at the moment? For the latter case, it would be so much easier to solve, you would only need a UI to rename stuff and a function to not only to to rename objects, but also data paths and driver expressions.
Things aren’t “broken” yet. I have a bunch of custom properties that I am exporting with their associated animations. I need to rename the custom properties so that they follow a naming convention. When I rename the properties I need the animation data to be relinked as well as the drivers that refer to those properties.