Page MenuHome

Batch_Rename.py

############################################################################
# Multi Objects Rename add-on/Tool for Blender 3D
# Copyright (C) 2019 Naser Merati (Nevil)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
############################################################################
bl_info = {
"name": "Batch Rename",
"location": "3D View",
"description": "",
"author": "Naser Merati (Nevil)",
"version": (0, 1, 0, 0),
"blender": (2, 80, 0),
"category": "Object"
}
import bpy
from bpy.types import Operator
from bpy.props import *
def arrange_selected_items(active, selected):
# bring the active object to first in array
items = selected
if active != None:
if active in items:
items.remove(active)
items.insert(0, active)
# if len(selected) == 0 and active != None:
# items.append(active)
return items
def indexstr(count, index):
length = len(str(index))
string = ""
if length < count:
for i in range(length, count):
string += "0"
return (string + str(index))
def renameitems(self, ctx):
Index = self.from_no
for item in self.items:
# Get Object Original Name #
NewName = item.name
# Set the Base name #
if self.use_set_name or len(self.items) == 1:
NewName = self.set_name
# Remove First characters #
if self.clean_digs:
NewName = NewName[self.clean_first : self.clean_first + len(NewName)]
NewName = NewName[1 : len(NewName) - self.clean_last]
# Add Prefix and sufix to the new name #
if self.prefixsuffix:
NewName = self.prefix + NewName
NewName = NewName + self.suffix
# Add Digits to end of new name #
if self.use_digits:
NewName += indexstr(self.digit_length, Index)
Index += 1
# Find and Replace #
if self.find_replace:
NewName = NewName.replace(self.find, self.replace)
# Trim Left and Right #
NewName = NewName.strip()
# Set the new name to the object #
if ctx.area.type == 'NODE_EDITOR':
if self.set_type == 'SetLabel':
item.label = NewName
else:
item.name = NewName
else:
item.name = NewName
def draw_ui(self, ctx):
if len(self.items) > 1:
box = self.layout.box()
if ctx.area.type == 'NODE_EDITOR':
row = box.row(align = True)
row.prop(self, "use_set_name")
spl = row.split(factor = 0.6, align = False)
row = spl.row(align = False)
row.prop(self, "set_type")
spl = row.split(factor = 2.0, align = False)
row = spl.row(align = False)
row.prop(self, "set_name")
else:
row = box.row(align = True)
row.prop(self, "use_set_name")
spl = row.split(factor = 2.0, align = False)
row = spl.row(align = True)
row.prop(self, "set_name")
row = box.row(align = True)
row.prop(self, "find_replace")
row.prop(self, "find")
row.prop(self, "replace")
row = box.row(align = True)
row.prop(self, "clean_digs")
row.prop(self, "clean_first")
row.prop(self, "clean_last")
row = box.row(align = True)
row.prop(self, "prefixsuffix")
row.prop(self, "prefix")
row.prop(self, "suffix")
row = box.row(align = True)
row.prop(self, "use_digits")
spl = row.split()
row = spl.row(align = True)
row.alignment = 'RIGHT'
row.prop(self, "from_no")
row.prop(self, "increment")
row.prop(self, "digit_length")
else:
layout = self.layout
layout.prop(self, "set_name")
def createdialog(self, context):
self.set_name = self.items[0].name
wm = context.window_manager
return wm.invoke_props_dialog(self, width = 400)
### Rename objects ######################################################################
class Objects_OT_BatchRename(Operator):
bl_idname = "object.batchrename"
bl_label = "Batch Rename"
use_set_name: BoolProperty (name = "Set Name:", description = "Set Name")
set_name : StringProperty(name = "", description = "Base Name")
find_replace: BoolProperty (name = "Find / Replace",
description = "Find / Replace")
find : StringProperty(name = "", description = "Find this")
replace : StringProperty(name = "", description = "Replace with this")
clean_digs : BoolProperty (name = "Clean Digits",
description = "Clean Digits")
clean_first : IntProperty (name = "From First", min = 0,
description = "From First")
clean_last : IntProperty (name = "From Last", min = 0,
description = "From End")
prefixsuffix: BoolProperty (name = "Prefix / Suffix",
description = "Prefix / Suffix")
prefix : StringProperty(name = "", description = "Prefix")
suffix : StringProperty(name = "", description = "Suffix")
use_digits : BoolProperty (name = "Add Number:",
description = "Add Number")
from_no : IntProperty (name = "Start",min = 0,
description = "Start From number")
increment : IntProperty (name = "Increment",min = 1, default = 1,
description = "increment value")
digit_length: IntProperty (name = "Length", min = 0, max = 9, default = 3,
description = "e.g NewName_####")
items = []
def draw(self, ctx):
draw_ui(self, ctx)
def execute(self, ctx):
renameitems(self, ctx)
return {'FINISHED'}
def invoke(self, ctx, event):
active = ctx.active_object
selected = ctx.selected_objects
self.items = arrange_selected_items(active, selected)
if len(self.items) == 1:
if ctx.active_object == None:
ctx.view_layer.objects.active = self.items[0]
bpy.ops.wm.call_panel(name = 'TOPBAR_PT_name', keep_open = False)
elif len(self.items) > 1:
return createdialog(self, ctx)
return {'FINISHED'}
### Rename Armature #######################################################################
class Armature_OT_BatchRename(Operator):
bl_idname = "armature.batchrename"
bl_label = "BatchRename"
use_set_name: BoolProperty (name = "Set Name:", description = "Set Name")
set_name : StringProperty(name = "", description = "Base Name")
find_replace: BoolProperty (name = "Find / Replace",
description = "Find / Replace")
find : StringProperty(name = "", description = "Find this")
replace : StringProperty(name = "", description = "Replace with this")
clean_digs : BoolProperty (name = "Clean Digits",
description = "Clean Digits")
clean_first : IntProperty (name = "From First", min = 0,
description = "From First")
clean_last : IntProperty (name = "From Last", min = 0,
description = "From End")
prefixsuffix: BoolProperty (name = "Prefix / Suffix",
description = "Prefix / Suffix")
prefix : StringProperty(name = "", description = "Prefix")
suffix : StringProperty(name = "", description = "Suffix")
use_digits : BoolProperty (name = "Add Number:",
description = "Add Number")
from_no : IntProperty (name = "Start",min = 0,
description = "Start From number")
increment : IntProperty (name = "Increment",min = 1, default = 1,
description = "increment value")
digit_length: IntProperty (name = "Length", min = 0, max = 9, default = 3,
description = "e.g NewName_####")
items = []
def draw(self, ctx):
draw_ui(self, ctx)
def execute(self, ctx):
renameitems(self, ctx)
return {'FINISHED'}
def invoke(self, ctx, event):
active = ctx.active_bone
selected = ctx.selected_bones
self.items = arrange_selected_items(active, selected)
if len(self.items) == 1:
if ctx.active_bone == None:
pass #TODO set self.items[0] as active bone
bpy.ops.wm.call_panel(name = 'TOPBAR_PT_name', keep_open = False)
elif len(self.items) > 1:
return createdialog(self, ctx)
return {'FINISHED'}
### Rename Sequences ######################################################################
class Sequences_OT_BatchRename(Operator):
bl_idname = "sequencer.batchrename"
bl_label = "BatchRename"
use_set_name: BoolProperty (name = "Set Name:", description = "Set Name")
set_name : StringProperty(name = "", description = "Base Name")
find_replace: BoolProperty (name = "Find / Replace",
description = "Find / Replace")
find : StringProperty(name = "", description = "Find this")
replace : StringProperty(name = "", description = "Replace with this")
clean_digs : BoolProperty (name = "Clean Digits",
description = "Clean Digits")
clean_first : IntProperty (name = "From First", min = 0,
description = "From First")
clean_last : IntProperty (name = "From Last", min = 0,
description = "From End")
prefixsuffix: BoolProperty (name = "Prefix / Suffix",
description = "Prefix / Suffix")
prefix : StringProperty(name = "", description = "Prefix")
suffix : StringProperty(name = "", description = "Suffix")
use_digits : BoolProperty (name = "Add Number:",
description = "Add Number")
from_no : IntProperty (name = "Start",min = 0,
description = "Start From number")
increment : IntProperty (name = "Increment",min = 1, default = 1,
description = "increment value")
digit_length: IntProperty (name = "Length", min = 0, max = 9, default = 3,
description = "e.g NewName_####")
items = []
def draw(self, ctx):
draw_ui(self, ctx)
def execute(self, ctx):
renameitems(self, ctx)
return {'FINISHED'}
def invoke(self, ctx, event):
active = None # Get active sequence
selected = ctx.selected_sequences
self.items = arrange_selected_items(active, selected)
if len(self.items) == 1:
return createdialog(self, ctx)
# if active == None:
# pass # Set selected item as active Item
# bpy.ops.wm.call_panel(name = 'TOPBAR_PT_name', keep_open = False)
elif len(self.items) > 1:
return createdialog(self, ctx)
return {'FINISHED'}
### Rename Nodes ######################################################################
class Node_OT_BatchRename(Operator):
bl_idname = "node.batchrename"
bl_label = "Batch Rename"
use_set_name: BoolProperty (name = "", description = "Set Name")
set_type : EnumProperty(name = '', description = '', default = 'SetName',
items =[('SetName', 'SetName', ''),('SetLabel', 'SetLabel', '')])
set_name : StringProperty(name = "", description = "Base Name")
find_replace: BoolProperty (name = "Find / Replace",
description = "Find / Replace")
find : StringProperty(name = "", description = "Find this")
replace : StringProperty(name = "", description = "Replace with this")
clean_digs : BoolProperty (name = "Clean Digits",
description = "Clean Digits")
clean_first : IntProperty (name = "From First", min = 0,
description = "From First")
clean_last : IntProperty (name = "From Last", min = 0,
description = "From End")
prefixsuffix: BoolProperty (name = "Prefix / Suffix",
description = "Prefix / Suffix")
prefix : StringProperty(name = "", description = "Prefix")
suffix : StringProperty(name = "", description = "Suffix")
use_digits : BoolProperty (name = "Add Number:",
description = "Add Number")
from_no : IntProperty (name = "Start",min = 0,
description = "Start From number")
increment : IntProperty (name = "Increment",min = 1, default = 1,
description = "increment value")
digit_length: IntProperty (name = "Length", min = 0, max = 9, default = 3,
description = "e.g NewName_####")
items = []
def draw(self, ctx):
draw_ui(self, ctx)
def execute(self, ctx):
renameitems(self, ctx)
return {'FINISHED'}
def invoke(self, ctx, event):
active = ctx.active_node
selected = ctx.selected_nodes
self.items = arrange_selected_items(active, selected)
if len(self.items) == 1:
return createdialog(self, ctx)
# if active == None:
# pass # Set selected item as active
# bpy.ops.wm.call_panel(name = 'TOPBAR_PT_name', keep_open = False)
elif len(self.items) > 1:
return createdialog(self, ctx)
return {'FINISHED'}
classes = [ Objects_OT_BatchRename,
Armature_OT_BatchRename,
Sequences_OT_BatchRename,
Node_OT_BatchRename]
KeyMaps = []
def CreateKeyMaps():
kcfg = bpy.context.window_manager.keyconfigs.addon
keys = (['Object Mode', 'EMPTY', 'object.batchrename'],
['Armature', 'EMPTY', 'armature.batchrename'],
['Sequencer', 'SEQUENCE_EDITOR', 'sequencer.batchrename'],
['Node Editor', 'NODE_EDITOR', 'node.batchrename'])
if kcfg:
for name, space, operator in keys:
km = kcfg.keymaps.new(name = name, space_type = space, region_type = 'WINDOW')
kmi = km.keymap_items.new(operator, "F2", "PRESS")
KeyMaps.append((km, kmi))
def RemoveKeyMaps():
for km, kmi in KeyMaps:
km.keymap_items.remove(kmi)
KeyMaps.clear()
def register():
for c in classes:
bpy.utils.register_class(c)
CreateKeyMaps()
def unregister():
for c in classes:
bpy.utils.unregister_class(c)
RemoveKeyMaps()
if __name__ == "__main__":
register()

File Metadata

Mime Type
text/x-python
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
f5/a7/97f5a44a072e366f4298eb9e4ae6

Event Timeline