CGTalk > Software Specific Forums > Autodesk 3ds max > 3dsMax SDK and MaxScript
Login register
reply share thread « Previous Thread | Next Thread »
 
Thread Tools Search this Thread Display Modes
Old 11-15-2013, 06:25 PM   #1
Mambo4
not a jedi yet
 
Mambo4's Avatar
portfolio
Logan Bender
Game Technical Artist
Greater Seattle, USA
 
Join Date: Nov 2010
Posts: 432
Fixing obsolete files in 'Missing External Files'

We have files coming in form outsources that contain references to unneeded files.
The files have no object we can I identify which uses the missing external file.
how do I get rid of these, so that the 'Missing External Files' alert goes away?

I'm looking at the max MAX Scene File Properties help...but it seems like max ought to have some built in tool for this...
 
Old 11-15-2013, 07:26 PM   #2
Mambo4
not a jedi yet
 
Mambo4's Avatar
portfolio
Logan Bender
Game Technical Artist
Greater Seattle, USA
 
Join Date: Nov 2010
Posts: 432
hmmm... poking around with fileproperties and the asset tracker , it seems like these references are very very hard to adjust.

Just to be clear: this is an unused reference to a bitmap file, not used in the scene, not found in the material editor or the bitmap /photometric path editor. it only exists as a reference in the file properties and the annoying ' Missing External Files' popup when the file is opened.

Last edited by Mambo4 : 11-15-2013 at 07:40 PM.
 
Old 11-15-2013, 08:26 PM   #3
denisT
MAX Doctor
 
denisT's Avatar
portfolio
Denis Trofimov
CA, USA
 
Join Date: Jul 2009
Posts: 9,170
Send a message via ICQ to denisT
Quote:
Originally Posted by Mambo4
Just to be clear: this is an unused reference to a bitmap file...

bitmap? or bitmaptexture? where were these bitmaps used?
 
Old 11-15-2013, 10:44 PM   #4
Mambo4
not a jedi yet
 
Mambo4's Avatar
portfolio
Logan Bender
Game Technical Artist
Greater Seattle, USA
 
Join Date: Nov 2010
Posts: 432
I have no idea where the file reference comes from or what it was used on.
It's a path to a TIF that we do not use in anything in the file.
The outsources may have used it perhaps a lighting or camera effect for their own renders, but we do not need them.

They do not exist in sceneMaterials, only in fileProperties and the Asset Tracker.
Right clicking in the asset Tracker and choosing 'strip Path'
will remove the path ans stop the annoying pop up, but the reference stays in the asset tracker with no way to remove it.

the asset name in question is "glare_streaks_start_camera_filter.tif" if that means anything to anyone.

Last edited by Mambo4 : 11-15-2013 at 10:51 PM.
 
Old 11-16-2013, 12:03 AM   #5
denisT
MAX Doctor
 
denisT's Avatar
portfolio
Denis Trofimov
CA, USA
 
Join Date: Jul 2009
Posts: 9,170
Send a message via ICQ to denisT
well... attach a file. i will take a look.
 
Old 11-16-2013, 12:22 AM   #6
Mambo4
not a jedi yet
 
Mambo4's Avatar
portfolio
Logan Bender
Game Technical Artist
Greater Seattle, USA
 
Join Date: Nov 2010
Posts: 432
here goes...nothing in the file but a reference to a missing tif.
Attached Files
File Type: zip example.zip (24.1 KB, 11 views)
 
Old 11-16-2013, 12:51 AM   #7
denisT
MAX Doctor
 
denisT's Avatar
portfolio
Denis Trofimov
CA, USA
 
Join Date: Jul 2009
Posts: 9,170
Send a message via ICQ to denisT
Quote:
Originally Posted by Mambo4
here goes...nothing in the file but a reference to a missing tif.

that is exactly what i like. puzzle
 
Old 11-16-2013, 01:34 AM   #8
denisT
MAX Doctor
 
denisT's Avatar
portfolio
Denis Trofimov
CA, USA
 
Join Date: Jul 2009
Posts: 9,170
Send a message via ICQ to denisT
before looking into the file let me conjecture...
# a missed texture cannot seat in the file without bitmap
# a bitmap in the empty file can be stored in only three places:
  • - material editor
  • - custom attribute
  • - environment map (background image)
# if it's a material but not in the material editor it's probably in the slate material editor
# if it's in a custom attribute there two possible places:
  • - max root node
  • - material editor reference object
  • - (there are some other places but an average developer doesn't know about them and very unlikely can put anything there by accident)
# if it's in a background image it's very easy to check

Last edited by denisT : 11-16-2013 at 01:37 AM.
 
Old 11-16-2013, 02:01 PM   #9
Track
Veteran
 
Track's Avatar
portfolio
Alexander Kramer
K-studio
Odessa, Ukraine
 
Join Date: Nov 2006
Posts: 46
This file is present in render settings.
 
Old 11-18-2013, 06:27 PM   #10
Mambo4
not a jedi yet
 
Mambo4's Avatar
portfolio
Logan Bender
Game Technical Artist
Greater Seattle, USA
 
Join Date: Nov 2010
Posts: 432
The filepath shows up using the example enumeratefiles() fucntion
as well usedMaps rootScene
but neither function seems able to retrun exactly what max wrapper object uses the file.

by itertating usedMaps with various maxwrapper values , and some educated guessing,
I isolated the file's user: usedMaps rootScene.renderer.Camera_Output_Shader
returns the bitmap path.

I read further and discoverd that rootScene.renderer.Camera_Output_Shader
is a default value populated automatically by mentalRay.
It cannot be set to a null value, it must have a path.
Even if rootScene.renderer.Enable_Camera_Output_Shader:fal se ,
the bitmap is still referenced as a value and added to the Asset Tracker,
which then alerts the user if it is missing on file open.

The only one way I can find to get this value to stop poppign up an alert on file open:
change the rederer to a non-mental-ray renderer and save the file.
 
Old 11-18-2013, 06:46 PM   #11
DaveWortley
<database error>
 
DaveWortley's Avatar
portfolio
David Wortley
Technical Director
London, United Kingdom
 
Join Date: Dec 2004
Posts: 1,822
Send a message via MSN to DaveWortley
This will remove it from the scene and stop the pop-up without having to reset the renderer.

rootScene.renderer.Camera_Output_Shader.Streak_Ima ge = ""

or more commonly you would write

renderers.current.Camera_Output_Shader.Streak_Imag e = ""
__________________
Maxscript Made Easy...
http://davewortley.wordpress.com/

Last edited by DaveWortley : 11-18-2013 at 07:03 PM.
 
Old 11-18-2013, 06:58 PM   #12
Klunk
Lord of the posts
 
Klunk's Avatar
portfolio
Klunk
United Kingdom
 
Join Date: Sep 2005
Posts: 701
if it's a default file for mental ray and you are not going to use it you can always create a small 64x64 black tif file at that location. It's not pretty but will kill the message
 
Old 11-27-2013, 09:22 PM   #13
JasonB
Veteran
portfolio
Jason Brackman
Relic Entertainment
Vancouver, CA
 
Join Date: Nov 2011
Posts: 39
Using denisT's earlier work this will do what Mambo4 described. It doesn't have DenisT's elegance but someone else may find it of use.

Output should be:

Path: ..\..\..\..\Program Files\Autodesk\3ds Max 2012\Maps\glare\glare_streaks_star_camera_filter.t if
ClassType: GlaretextureMap
ClassPath: rootScene.Renderer.Camera_Output_Shader.Streak_Ima ge
ClassName: DefaultOutputShader


Code:
( struct TextureData (class, classpath, className, value) fn getPropertiesByType node type:"bitmap" = ( /************************************************** ************************************************** ********** <DOC> Use this to pick out only bitmaps from shaders. - DenisT came up with this function on CGTalk Arguments: <node> node: any object node Optional: <string> type: any string representing a property. Default is "bitmap" Return: <Array> returns an zero to n number of NAMES found depending on results. ************************************************** ************************************************** **********/ local filter = " .:" local props = #() local ss = stringStream "", str -- check through delegate if available if (isproperty node #delegate) == true then ( showProperties node.delegate to:ss ) showProperties node to:ss seek ss 0 while not eof ss do ( str = filterstring (readline ss) filter if stricmp str[str.count] type == 0 do append props (str[1] as name) ) free ss props ) fn _strArrayToClass strArray &stringRef:unsupplied = ( local ss = stringstream "" for itm in strArray do format itm to:ss str = (ss as string) if iskindof stringRef string then stringRef = str newRoot = execute(str) ) fn whereIsTheTexture texturePath class:rootscene propArray:#("rootScene") recursive:false results:#() = ( -- prep stringstream with properties of the 'root' passed in. local filter = " .:" local ss = stringStream "" showProperties class to:ss seek ss 0 while not eof ss do ( local str = filterstring (readline ss) filter local currentProp = str[str.count] if (not matchpattern currentProp pattern:"Environment" and not matchpattern currentProp pattern:"Medit_Materials" and isproperty class currentProp) do ( local maps = usedMaps (getproperty class currentProp) if (iskindof maps Array and finditem maps texturePath > 0) then ( -- more properties to examine so we are going to have to rerun the function recursive = true if matchpattern propArray[propArray.count] pattern:"*DirectX_Shader" then ( -- FIX: After solving for somethign in the materialLibrary() class we should step back int the array to this position again. -- replace the last shader with the current one. propArray[propArray.count] = ("." + currentProp) ) else ( append propArray ("." + currentProp) ) newRoot = _strArrayToClass propArray whereIsTheTexture texturePath class:newRoot propArray:propArray )-- end inner if )--end if )-- end while free ss if recursive == false then ( local newString = "" local newRoot = _strArrayToClass propArray stringRef:&newString local results01 = getPropertiesByType newRoot type:"filename" local results02 = getPropertiesByType newRoot type:"bitmap" local fullresults = join results01 results02 for result in fullresults do ( local var = (getproperty class result) as string if matchpattern var pattern:("*"+texturePath) then ( append results (TextureData class:(classof newRoot) \ classpath:(newString + "." + result) \ className:newRoot.name \ value:texturePath ) ) ) ) if results.count > 0 then ( for itm in results do ( format "Path: %\n" itm.value format "\tClassType: %\n" itm.class format "\tClassPath: %\n" itm.classpath format "\tClassName: %\n" itm.classname ) ) ) for path in (usedmaps rootscene) do (whereIsTheTexture path) )


edit: The script should now handle DirectX shaders (I haven't tried on delegates tho...)
edit2: Cleaned up the code a bit.. added an additional line to indicate what the classof the object holding the texture/shader is.
edit3: Now handles multiple shaders. Output provides the class name (which may be the material you are looking for.)

Last edited by JasonB : 11-29-2013 at 08:49 PM.
 
Old 04-07-2014, 08:26 PM   #14
Mambo4
not a jedi yet
 
Mambo4's Avatar
portfolio
Logan Bender
Game Technical Artist
Greater Seattle, USA
 
Join Date: Nov 2010
Posts: 432
sorry to resurrect the thread but I'm back to this annoying problem.

many files no longer used are clogging the Asset tracker and I would love to automatically cull these useless references.

I assumed that AssetManager.ReleaseReference was the ticket but it seems to not accomplish what I need.
I can gather a list of all the files acutally being used by scene objects, compare the files returned by AssetManager. AssetManager.GetAssetByIndex(), and pass IDs of undesired refs to AssetManager.ReleaseReference <ID> which returns true.

but still, the file opens with warnings and the Asset Tracking tool still lists all the no longer existing bitmaps.

how can I use a script to destroy these undesired refs?

Last edited by Mambo4 : 04-07-2014 at 08:31 PM.
 
Old 04-25-2014, 09:51 PM   #15
Mambo4
not a jedi yet
 
Mambo4's Avatar
portfolio
Logan Bender
Game Technical Artist
Greater Seattle, USA
 
Join Date: Nov 2010
Posts: 432
took some digging, but i got it.

the necessary maxscript to effectively manage the Asset Tracker are split between two interfaces:
ATSOps and AssetManager. Both utilizes some of the more obfuscated max script features and types.
(anybody know what the un-google-able "TSTR" or "&TSTR" values are?)

only AssetManager.ReleaseReference() can remove a reference form the asset manager.
you have to pass the function an asset ID which you get from
Code:
AssetManager.GetAssetId <fileName> #Bitmap

unless you then refresh the asset manager with ATSOps.refresh(), max script will not know this has been released.



Code:
ATSOps.GetFilesByFileSystemStatus #Missing &arr --get asset tracker's missing files ATSOps.GetDependencyFileList rootscene &used true --get all files used by scene objects for i=1 to arr.count do( f=arr[i] --is the missing file it list of files used by scene objects? if finditem used f !=0 then( format "% is used\n" f )else( --if not used , get its ID and pass it to AssetManager.ReleaseReference() format "% is unused. released:%\n" f (AssetManager.ReleaseReference(AssetManager.GetAss etId f #Bitmap )) ) ) --update asset tracker ATSOps.refresh()

Last edited by Mambo4 : 04-25-2014 at 10:17 PM.
 
reply share thread


Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
CGSociety
Society of Digital Artists
www.cgsociety.org

Powered by vBulletin
Copyright 2000 - 2006,
Jelsoft Enterprises Ltd.
Minimize Ads
Forum Jump
Miscellaneous

All times are GMT. The time now is 01:03 AM.


Powered by vBulletin
Copyright ©2000 - 2016, Jelsoft Enterprises Ltd.