The below method is pretty verbose, because I'm using string operations instead of a regex. This hopefully makes it a bit more readable for you, but I'd suggest moving to a regex whenever you feel comfortable enough.
Please note, the function that deals with the string format to rename your scene will use a minimum of 2 digits (01, 02, etc) and a maximum of 3 digits (100, 101, etc). If you go above 999 iterations, you'll need to modify this slightly.
Note:
This methodology relies on an underscore before your file version (eg. _01.mb) instead of your current string index method.
import maya.cmds as cmds
def getNextVersion():
curName = cmds.file(query=True, expandName=True) # eg. D:/yourScene_01.mb
curVersionFull = curName.split('_')[-1] # eg. 01.mb
versionExtension = curVersionFull.split('.') # eg. ['01', 'mb']
curVersionNum = int(versionExtension[0]) # eg. 1
extension = versionExtension[1] # eg. 'mb'
nextVersionNum = curVersionNum + 1 # increment your version
if nextVersionNum < 100:
nextVersionFull = '{:02d}.{}'.format(nextVersionNum, extension) # eg. 02.mb
else:
nextVersionFull = '{:03d}.{}'.format(nextVersionNum, extension) # eg. 100.mb
newName = curName.replace(curVersionFull, nextVersionFull)
return newName
cmds.file(rename=getNextVersion())
cmds.file(save=True)
Update:
You've already accepted another answer, and I believe the core of your issue is what @green-cell describes. As for how that is even possible, I don't actually know. Maya would generally not let you save to a folder that doesn't exist.
Eg:
import maya.cmds as cmds
cmds.file(rename="D:/doesntexist/somefile.mb")
# Error: An invalid path was specified. : D:/doesntexist/
# Traceback (most recent call last):
# File "<maya console>", line 2, in <module>
# RuntimeError: An invalid path was specified. : D:/doesntexist/ #
Anyway, I've thrown together a more thorough function for you here. Please note that it's difficult to cater for all possible filename patterns, especially if users are allowed to specify their own file names in any part of the process. This time I'm using regular expressions
, which makes your replacement much more robust (though, far from infallible).
import re
import os
import maya.cmds as cmds
def getNextVersion(createDir=True):
'''Find next available filename iteration based on current scene name
Args:
createDir (bool, optional): True to create the output directory if required. False to leave as-is (may trigger a failure)
Returns:
str|None: Full file path with incremented version number. None on failure
'''
# Grab current filename. This always returns something. If unsaved, it will return something unsavory, but still a string
curFile = cmds.file(query=True, expandName=True)
print('Current filename is {}'.format(curFile))
# This matches a digit between 1 and 4 numbers in length, followed immediately by a file extension between 2 and 3 characters long
m = re.match(r'(.+?)(\d{1,4})\.(\w{2,3})', curFile)
if m == None:
print('Failed at regex execution. Filename does not match our desired pattern')
return None
# Extract regex matches
basePath = m.group(1)
version = m.group(2)
extension = m.group(3)
# Failsafe. Should not trigger
if not basePath or not version or not extension:
print('Failed at failsafe. Filename does not match our desired pattern')
return None
# Increment file version
numDigits = len(version)
newFile = None
try:
version = int(version) + 1
# Deal with padding
newLength = len(str(version))
if newLength > numDigits:
numDigits = newLength
# Compile new path
newFile = '{base}{ver:{numDig:02d}d}.{ext}'.format(base=basePath, ver=version, numDig=numDigits, ext=extension)
except Exception as e:
print('Error parsing new version for path {}: {}'.format(curFile, e))
return None
# Another failsafe
if not newFile:
print('Failed at failsafe. Filename calculations succeeded, but new path is not valid')
return None
# Create output dir if needed
dirname = os.path.dirname(newFile)
if createDir and not os.path.isdir(dirname):
try:
os.makedirs(dirname)
print('Created all dirs required to build path {}'.format(dirname))
except Exception as e:
print('Error creating path {}: {}'.format(dirname, e))
return None
return newFile
nextVersion = getNextVersion()
if not nextVersion:
cmds.error('Error parsing new filename increment. Please see console for more information')
else:
cmds.file(rename=nextVersion)
cmds.file(save=True)