Page 1 of 1

Script to rename / prefix materials

Unread postPosted: Sun Aug 14, 2022 9:38 am
by seren
Would it be possible to have a script to search a project / scene / context and prefix all the materials.
e.g. materialname is renamed to mtl_materialname

This seems to work, but is it the right approach. It's my first time scripting in Python.

Code: Select all
selCount = ix.selection.get_count()
for i in range(selCount):
    item = ix.selection[i]
    ix.cmds.RenameItem(item.get_full_name(), "mtl_"+item.get_name())
    print item.get_name()
    print item.get_class_name()
print ix.selection.get_count()
print "Items Processed"

Re: Script to rename / prefix materials

Unread postPosted: Wed Aug 17, 2022 5:49 pm
by anemoff

Yes that is correct. Here is a simplified version that wraps all the RenameItem commands within a batch so that you can undo them if needed.

python code

ix.begin_command_batch("Rename items")
for item in ix.selection:
ix.cmds.RenameItem(item.get_full_name(), "mtl_" + item.get_name())
print("Renamed {} items.".format(ix.selection.get_count()))

Here is a simple UI in Python that allows renaming manually a list of selected items. It's very basic but it can give you ideas.
It was posted some time ago in the forums.

python code

tool_name = 'Renamer Tool'
log_tag = '[{}] '.format(tool_name)

class RenameButton(ix.api.GuiPushButton):
line_edits = []
window = None

def __init__(self, parent, x, y, w, h, label, line_edits, window):
ix.api.GuiPushButton.__init__(self, parent, x, y, w, h, label)
self.connect(self, 'EVT_ID_PUSH_BUTTON_CLICK', self.on_click)
self.line_edits = line_edits
self.window = window

def on_click(self, sender, event_id):
for edit in self.line_edits:
path = edit.get_label()
new_name = edit.get_text()
item = ix.get_item(path)
if item:
ix.cmds.RenameItem(path, new_name)

ix.log_info(log_tag + 'Done!')

if self.window:

def create_gui(selection):
window = ix.api.GuiWindow(ix.application, 0, 0, 600, 400, tool_name)

panel = ix.api.GuiPanel(window, 0, 0, window.get_width(), window.get_height())

pad = 4
w = window.get_width() - pad
h = 22
x = 0
y = 0

# title
label = ix.api.GuiLabel(panel, x + pad, y, w, h, 'Old Name -> New Name')
y += h + pad

# line edits for each object
edits = []
for item in selection:
old_name = item.get_full_name()
new_name = item.get_name()

edit = ix.api.GuiLineEdit(panel, x + pad, y, w, h, old_name)

y += h + pad

# rename button
rename_btn = RenameButton(panel, x + pad, y, 60, h, 'Rename', edits, window)
y += h + pad
while window.is_shown(): ix.application.check_for_events()

# Run it
if ix.selection.get_count() > 0:
ix.log_warning(log_tag + 'No objects selects.')
except Exception as e:
ix.log_error('Script error:\n{}'.format(e))

Don't hesitate to read the SDK documentation and search the Scripting forums, or join the Discord server.


Re: Script to rename / prefix materials

Unread postPosted: Wed Aug 17, 2022 6:39 pm
by seren
Thank you very much Anthony :)
How would you do this if you didn't want to select the items/materials but just search the project/context and automatically add mtl_ to the name?

Re: Script to rename / prefix materials

Unread postPosted: Thu Aug 18, 2022 9:41 am
by anemoff
You can use the "get_all_objects" method from OfContext.
Here is an example. You could improve it by adding a "context" parameter to specify where to search. Here it searches at the project root, recursively.

python code

def find_objects_by_class(class_name):
object_factory = ix.application.get_factory()
assert object_factory.get_classes().exists(class_name), 'OfClass "{}" is unknown.'.format(class_name)

root = object_factory.get_root()
objects = ix.api.OfObjectArray()
root.get_all_objects(class_name, objects)
return objects

# Example usage: prefix all material objects with "mtl_"
materials = find_objects_by_class('Material')
prefix = 'mtl_'
rename_count = 0
ix.begin_command_batch('Prefix materials')
for mat in materials:
name = mat.get_name()
if not name.startswith(prefix):
ix.cmds.RenameItem(mat.get_full_name(), prefix + name)
rename_count += 1
print('Renamed {} materials.'.format(rename_count))