[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.
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…
- the file wasn’t specified with a full path
- wasn’t local to the IFL file’s folder
- couldn’t be resolved in any other of the configured map paths either.
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