Notifications
Clear all

[Closed] save incremental

hi there,

I have a problem saving a file incremental.
that’s what I have so far:


saveFilePath = maxFilePath + maxFileName

fn existFile fname = (getfiles fname).count != 0

fn saveFileUnique theFile =
(
		incCount += 1
		case of
		(
		(incCount < 10) : incCountStr = "0" + (incCount as string)
		default: incCountStr = incCount
		)
		
	theFileComplete = (getFilenamePath saveFilePath) + (getFilenameFile saveFilePath) + theFile + incCountStr + (getFilenameType saveFilePath)
	 if (existFile theFileComplete) == true then
	(
	saveFileUnique (theFile + incCountStr)
	)
	else
	(
	saveScene theFileComplete
	incCount = 0
	)
)

saveFileUnique "_unwrapped"

but this does not work correctly.
It outputs something like “testscene_unwrapped0102.max” or “testscene_unwrapped010203.max” instead of “testscene_unwrapped02.max” and so on.

I don’t get it right :shrug:

9 Replies

You’re not trimming the increment counter off of the filename before you add on the new counter.

mhhh… ok.
but if I trim let me say the last two chars of the filename and the filename is “testscene.max” only (without 01, 02,…) so the next file will be “testsce01.max” :shrug:

Ok, here is some code that might do what you want:


  (
  --Get the base name without any digits:
  fn removeTrailingNumber theFilename =
  (
  	local theNumbers = #("0","1","2","3","4","5","6","7","8","9")
  	for i = theFilename.count to 1 by -1 do
  		if findItem theNumbers theFilename[i] == 0 do 
  			return (substring theFilename 1 i)
  	""		
  )
  
  --Get digits only from the file name:
  fn collectTrailingNumber theFilename =
  (
  	local theNumbers = #("0","1","2","3","4","5","6","7","8","9")
  	local theString = ""
  	for i = theFilename.count to 1 by -1 do
  		if findItem theNumbers theFilename[i] == 0 then
  			return theString
  		else
  			theString = theFilename[i] + theString
  	theString 		
  )
  
  --Get zeros string (for the format 0001,0123 etc.)
  --If you want just 01,02, you can change this or use your code:
  fn getZeros theNumber =
  (
  	theCount = (theNumber as string).count
  	if theCount > 3 then "" else substring "0000" 1 (4-theCount) 
  )
  
  --get the max path and name without the trailing number.
  --if the scene is untitled, make sure you fix the "" to "Untitled"
  theMaxName = maxFileName
  if theMaxName == "" do theMaxName = "Untitled"
  thePath = maxFilePath
  theName = removeTrailingNumber (getFileNameFile theMaxName)
  
  --get all files matching this pattern:
  allFiles = getFiles (thePath + theName + "*.max")
  
  --collect all numbers from all collected files 
  allNumbers = sort (for f in allFiles collect execute (collectTrailingNumber (getFileNameFile f)))
  
  --figure out what the highest number is
  if allNumbers.count > 0 then
  (
  	lastNumber = allNumbers[allNumbers.count]
  	if classof lastNumber != Integer do lastNumber = 0
  )	
  else
  	lastNumber = 0	
  
  --increment the last number and build the new file name
  nextNumber = lastNumber + 1
  newFilename = thePath + theName +getZeros nextNumber + nextNumber as string + ".max"
  
  --then do something with it, like saving the scene...
  
  )--end script
  
  

wow, thank you!
very interesting script

This is a variation of the function using substring conversion to MAXScript value and checking the class against Integer.


  fn removeTrailingNumber theFilename =
 (
 	for i = theFilename.count to 1 by -1 do
 		if classof (execute (substring theFilename i -1)) != Integer do
 			return (substring theFilename 1 i)
 	""		
 )
  

Note that this version is a bit shorter, but slower.
For 100000 iterations, the findItem() version I posted before needed 6562 ms, this version needed 10469 ms. So my previous code would be 62.68% faster if executed very often. Of course, we are talking MICROseconds here, trying to stop the time of a single execution of both functions would return 0 miliseconds, so it is negligable…

A solution I wrote last week for a similar problem isn’t quite as robust as Bobo’s solution but works very well. It’s based on the count of the number of files that exist in the destination directory with the same name as the unincremented file. Then the incrementor just adds 1 to the file count and adds that as a suffix to the filename.

fn get_incremented_name base_path scene_filename file_extension =
(
    -- Returns an incremented file path

ame for the provided directory and
– filename.

    base_filename = (base_path + scene_filename)
    file_count =  (getFiles (base_filename + "*" + file_extension)).count

    case of (
        (file_count == 0): base_filename += "_00"
        ((file_count &gt; 0) and (file_count &lt; 10)): base_filename = (base_filename + "_0" + (file_count as string))
        (file_count &gt;= 10): base_filename = (base_filename + "_" + (file_count as string))
    )

    return (base_filename + file_extension)
)

The main caveat with this approach is that if you have a discontinuity in the file naming, you might end up with an existing file name.
For example, if you have file names file01, file02, file04, the count is 3, the new file should be file04, thus overwriting the existing file04.
This could be fixed by incrementing, building the file name, checking using doesFileExist() and then incrementing again until you find a file name that does not exist…

1 Reply
(@jeff_hanna)
Joined: 10 months ago

Posts: 0

A very good point, and a simple addtion to the code. I think I’ll go add that now. Thanks Bobo.

so many solutions

THX