Notifications
Clear all

[Closed] selecting single images from ifl

Hi everybody,

I am trying to select particular images from an ifl file. Actuall what I try to do is:

-select an ifl
-take “n” numbered image of the sequence
-assign that image to a materials diffuse slot.
-do that for several times for different materials

I tried to use same ifl file on all materials, then changed its playback rate to 0 and start frame to “n”. I was so sure that will work but it didnt. (that was my second disappointment with controlling time of texture sequences)

Then I thought a different approach, using the getFilenameFile command tried to find each frame from the path. But since the script dont know the actual extension (.tga, .jpg whatever) of the ifl file, It suddenly become more complicated then I expected.

Later I realized ifl file is actually a very simple text file which contains all the images in the corrent time order.
Somehow accessing that file from maxscript and reading from there may be the solution I seek for.

Does anyone had a similar situation? Are there anyone to lead me to the most effective way?
Thanks for your time and interest.

7 Replies

With a bit research guess I found the answer. For people who may have a similar situation, I wrote an example code.

(
local selected_txt
IFL_file=openFile "D:\\workplace\	est\
eat00.ifl" --Loads the IFL file
	
fn image_fromIFL IFL_file numb = 
(
--Each readline command reads the next line for the loaded ifl
--Run the command until you reach the desired line
	for i = 1 to numb do 
		(
		Selected_txt=readLine IFL_file 
		)
)

image_fromIFL IFL_file 4
print selected_txt
)

Here’s a function which will load the image sequence from an ifl file. The function returns an array of filenames (including path) so it should be easy to loop through them and assign to different materials:

(
	-- Collects the images contained in an ifl file
	fn CollectIflFiles iflFile =
	(
		local iflImages = #()
		
		if doesFileExist iflFile then
		(
			local iflPath = getFilenamePath iflFile
			local iflHandle = openFile iflFile
			
			if iflHandle != undefined then
			(
				while not eof iflHandle do
				(
					iflLine = trimLeft (trimRight (readLine iflHandle))
					
					if iflLine.count > 0 then
					(
						if findString iflLine "\\" == undefined then
							iflLine = iflPath + iflLine
						
						append iflImages iflLine
					)
				)
				
				close iflHandle
			)
		)
		
		iflImages
	)
)

Cheers,
Martijn

For what it’s worth, here’s a shorter version using .NET’s very convenient ReadAllLines method:

(
	-- Collects the image sequence from an ifl file
	fn CollectIflFiles iflFile =
	(
		local iflImages = #()
		if doesFileExist iflFile then
		(
			-- Store path to IFL file
			local iflPath = getFilenamePath iflFile
			-- Get entire sequence
			iflImages = (dotnetClass "System.IO.File").ReadAllLines iflFile
			-- Make sure path is included
			for i = 1 to iflImages.count where findString iflImages[i] "\\" == undefined do iflImages[i] = iflPath + iflImages[i]
		)
		iflImages
	)
)

Cheers,
Martijn

here’s a slightly adjusted version, to take into account:

  • comment lines
  • frame repetition
  • absolute path references
  • path resolving (optional)

  -- Collects the images contained in an ifl file
fn CollectIflFiles iflFile resolvePaths:false = (
	local iflImages = #()
	local iflHandle = openFile iflFile
	iflPath = getFilenamePath iflFile
	if (iflHandle != undefined) then (
		while not eof iflHandle do (
			iflLine = trimLeft (trimRight (readLine iflHandle))
			if (iflLine.count > 0) then ( -- empty line, ignore
				if (iflLine[1] != ";") then ( -- comment, ignore
					local repetition = 1
					local fileName = trimRight iflLine " 0123456789"
					if (fileName.count != iflLine.count) then ( -- uh oh, frame repetition
						repetition = trimLeft(subString iflLine (fileName.count + 1) -1) as integer
						if (repetition == undefined) OR (repetition == 0) then ( repetition = 1 )
					)
					if (findString fileName "\\" == undefined) then ( -- no direct path references
						fileName = iflPath + fileName -- so assume it's a local file
					)
					for i = 1 to repetition do (
						if (doesFileExist fileName) then ( append iflImages fileName )
						else (
							if (resolvePaths) then (
								local filenameResolved = mapPaths.getFullFilePath fileName
								if (filenameResolved == "") then ( append iflImages undefined ) -- FAIL
								else (append iflImages filenameResolved ) -- SUCCESS
							)
							else (
								append iflImages fileName -- DONTCARE
							)
						)
					)
				)
			)
		)
		close iflHandle
	)
	iflImages
)
  

Sample IFL file:


  ; this is a comment
  grassy.jpg 3
  test0220.tga 2
  maze takes too long.png 0
  freakylights.jpg
  c:	emp\quizzy_eva.jpg
  c:	emp\garlic.tga
  

Sample output without resolving paths:


  print (CollectIflFiles testIFL)
  "C:\zwonkle\grassy.jpg"
  "C:\zwonkle\grassy.jpg"
  "C:\zwonkle\grassy.jpg"
  "C:\zwonkle	est0220.tga"
  "C:\zwonkle	est0220.tga"
  "C:\zwonkle\maze takes too long.png"
  "C:\zwonkle\freakylights.jpg"
  "c:	emp\quizzy_eva.jpg"
  "c:	emp\garlic.tga"
  

Sample output with resolving paths:


  "C:\zwonkle\grassy.jpg"
  "C:\zwonkle\grassy.jpg"
  "C:\zwonkle\grassy.jpg"
  "C:\zwonkle	est0220.tga"
  "C:\zwonkle	est0220.tga"
  "c:\3dsmax11\Maps\maze takes too long.png"
  "C:\zwonkle\freakylights.jpg"
  undefined
  "c:\3dsmax11\Maps\garlic.tga"
  

The ‘undefined’ above means that…

  1. the file wasn’t specified with a full path
  2. wasn’t local to the IFL file’s folder
  3. couldn’t be resolved in any other of the configured map paths either.

Richard, you’ve obviously got too much time on your hands

if I did, I’d make a .NET version

actually I tried running it on a file here and it broke on the first few lines, which were comment fields containing the scene file name and some summary information… figured I might as well have a poke at it

wow… I was desperate, now I have too much options.

Thank you guys.