Rename Negative Padding Render in Maya

Rename Negative Padding Render in Maya

In this post, I will talk about renaming image sequences for After Effects.

Preface

Xwift is a shelf that contains specialized scripts when I was producing my animated film. I want to write some blogs to document them, in case there’s anyone out there that needs some inspiration.

Everything is developed and tested using Maya 2022.

Swift is not (well, not yet) open-source and therefore I will not share the whole script in my post. However, after reading my posts I believe you can implement your own, given some time and effort.

Introduction

In a lot of times, animators are requested by the director to animate 24 frames before and after a shot.

All is well - until it reaches the render department, because Premiere and After effects won’t recognize rendered images that has a negative padding in its file name.

For example, a scene called example_scene.ma contains animation from -24 to 124 on the timeline, and uses the following render settings:

Render Layer: masterLayer
File name prefix: (not set; using scene name)
Image Format: tif
Frame/Animation ext: name_#.ext
Frame padding: 4


The result after render is a file hierarchy as follows:

scene_folder
    renders
        masterLayer
            example_scene_0-24.tif
            example_scene_0-23.tif
            ...
            example_scene_00-1.tif
            example_scene_0000.tif
            example_scene_0001.tif
            ...
            example_scene_0124.tif
    example_scene.ma


When you want to import this image sequence into After Effects, After Effects will only recognize the frames from 0-124. What we really want to do is to rename all the images with positive numbers so After Effects and other video software can correctly recognize it.

Software Design

The tool works as follows:

GUI

We write a GUI (Graphical User Interface) and ask the user to input the following:

  • The path containing all rendered images. Either the user enter the address by hand or choose from a popup window.
    • In our case, it will be ./scene_folder/renders/masterLayer
  • The name of the scene that we used Maya to render with.
    • In our case, it is example_scene.
  • The “padding”, which is how many digits there is after the file name.
    • In our case, “0-24” has 4 digits, so padding is 4.
  • The format of the render.
    • Usually .png or .tif. In our case, .tif.

The code for GUI is very long (like 150 lines), so I won’t put all the code here.

# This is the skeleton of the GUI
def maya_main_window():
  main_window_ptr = omui.MQtUtil.mainWindow()
  return wrapInstance(int(main_window_ptr), QtWidgets.QWidget)

class ShowDialog(QtWidgets.QDialog):
    def __init__(self, parent = maya_main_window()):
        super(ShowDialog, self).__init__(parent)
        # Code for setting the window
        self.create_widgets()
        self.create_layouts()
    def create_widgets(self):
        # Code for creating widgets
    def create_layouts(self):
        main_layout = QtWidgets.QGridLayout(self)
        # Code for creating layouts
    def on_click(self):
        scene_name = self.scene.text()
        seq_folder = self.filePath.directory().absolutePath() + "/"
        frameEnd = self.frameEnd.value()
        frameStart = self.frameStart.value()
        padding = self.padding.value()
        orig_format = self.format.text()
        folder_name = self.folderPath.text()
        # Other stuff to do when click the start button in GUI

# Main function to call from outside
def rename_renders(self):
  d = ShowDialog()
  d.show()

You can find a very good guide of GUI here, and it is what I followed: PySide 2 GUI for Maya

Algorithm

1. Let’s check if there exists a renamed_renders temporary location.

We need a place to store our newly renamed image sequence. Therefore, we need to create a new folder. If it exists, we delete it.

Why don’t we just overwrite the existing renders? Well, turns out that it is very common to re-render one frame from a shot, since the render process can get interrupted, resulting in a partly-rendered image. It is much easier to keep the original renders and rename again, rather than re-render the entire sequence.

Doing this is pretty simple:

# Create temp folder
temp_folder = seq_folder + "renamed_renders"
if os.path.exists(temp_folder):
    shutil.rmtree(temp_folder)
os.makedirs(temp_folder)

2. Generate a list of strings that is exactly like how Maya produces numbers.

In our case, list_of_strings = ['0-24','0-23', ..., '00-1', '0000', '0001', ... '0124'].

First, let’s generate a list of numbers given the range of renders.

# Make sequence list
sequence_list = list(range(frameStart, frameEnd + 1, 1))  # Make Num List

Then, let’s write a helper function that takes in a number and breaks that number into a list of individual characters. If that number is negative, we add a - in front of the list.

For example: 24 -> ['2', '4'] , but -24 -> ['-', '2', '4'].

def get_numList(self, num):
    '''
    Returns a broken down list of numbers with appropriate "-"
    '''
    isNeg = False
    if (num < 0):
        num = num * -1
        isNeg = True
    res = list(map(str, [int(x) for x in str(num)]))
    if(isNeg):
        res.insert(0, "-")
    return(res)

Using this helper function, let’s create the appropriate file number based on the input from user.

For example, with padding = 4, 24 -> "0024" , but -24 -> "0-24".

def padding_format(self, number, padding):
    """
    Returns the correct padding of a number
    """
    if number >= 0:
        return ("%0" + str(padding) + "d") % number  # Positive + Zero Case
    else:
        number_list = self.get_numList(number)
        if len(number_list) > padding:
            raise Exception("[Xwift Rename Renders] ERROR - number_list is larger than padding!!!")
        elif len(number_list) < padding:
            need_zeroes = padding - len(number_list)
            for x in range(0, need_zeroes):
                number_list.insert(0, "0")
        return "".join(number_list)

3. Use the list of padding, format, scene name, to generate a list of image file names.

That will be list_of_image_names = ['example_scene_0-24.tif', ..., 'example_scene_0124.tif']

for index, value in enumerate(sequence_list):
    sequence_list[index] = scene_name + "_" + self.padding_format(value, padding) + orig_format
    # orig_format example: '.tif'

4. Copy and rename each render with a new file name.

Now we have a sorted list of file names from -24 to 124, it’s time for us to perform the magic.

We want to design an algorithm that enumerates the list from start to finish, and copy and rename that file so it has a file name of a positive number.

For example, example_scene_0-24.tif becomes 1.tif, and example_scene_0124.tif becomes 149.tif. Therefore, Any software that takes image sequence will be happy.

# Copying everything into a new temp folder
counter = 1
for index, value in enumerate(sequence_list):
    source = seq_folder + value
    destination = temp_folder+ "/" + str(counter) + orig_format
    shutil.copyfile(source, destination) 
    percentage = int(100.0 * counter / len(sequence_list))
    print("[Xwift Rename Renders] Image Process Progress: " + str(percentage) + "% [" + str(counter) + "/" + str(len(sequence_list)) + "].") # Just to see progress
    counter += 1

Demo

Done! That is all you need to implement such a program that can make your director and compositor happy.

As a demo, I will use a image sequence called nutmeg_cannon_overwatch_0XXX.tif as an example. This sequence ranges from -24 to 124.

Demo Rename Renders

Conclusion

Hopefully this is helpful for you, and thanks for reading.

Next time when your director assigns you to solve this seemingly easy problem, tell them that nothing can be taken for granted.

If you want to quickly say hi just shoot me a message using the contact portal.

Rename Negative Padding Render in Maya
Older post

Fix broken NURBS surface in Maya

Newer post

Reload Custom Scripts in Maya

Rename Negative Padding Render in Maya