Notifications
Clear all

[Closed] File Size issue

Hi everyone,

We are having some bad issues with max 2008 and merging files. Merging mesh even when just replacing mesh already existing in the scene causes the file to grow to unreasonable size. I can delete all the mesh, reset the material editor, until there’s absolutely nothing in the scene, and the file is over 100 megs with NOTHING IN IT.

I see that there is some mention of this problem elsewhere, but neither of the max scripts they linked to made any difference.

This is a serious problem we’re having at a large development house, all of our tech artists have taken a look at trying to figure it out with no luck. The files grow until we cannot even load them anymore and crashes max.

http://area.autodesk.com/index.php/forums/viewthread/19279/#96143

Here is the file to take a look at, we have tried a multitude of things on the file with no solution.

14 Replies

Does this also happen when you do a save / re-load / save cycle, or only after having merged something?

Does it always increase after merging said something?  E.g. merge, delete, save -> bloat?

Does said 'something' matter?  E.g. reset max, create a sphere, save.. merge that sphere.. does that bloat as well?

What plugins do you use / do you have installed?

I did notice that the materials in medit render veeery slooow here… default scanline renderer. On a fresh scene, it’s zippy – so it might be something related to materials somewhere somehow.

==========

You didn't specify the things you've tried... here's the few I tried so far...

Load into 3ds Max 2009 and re-save (in case of fix) – no effect
reset the medit materiasl to standard() – no effect
Scene States – none present
Layers – only the default present
Biped track – deleted the track, didn’t help much
Callbacks – none present
Change Handlers – none present
Persistent Globals – some (default) present, removed, didn’t do much for the file size (down by 0.1MB)
Scene Custom Attributes – none present
Anim Layers – none present
File Links – none present
File Summary data – no extra data
Deleted a Schematic View – no effect
Dynamics (old) – no dymanics simulation sets

==========

Autodesk -should- be able to tell you what type of data gets saved in the block area of the binary where all the rubbish data seems to live.. (just after 'File Properties -> Contents' data) it could be custom attributes set by a plugin (can't access via script), it might be appdata (good luck finding that).. etc.
Just in case somebody has dealt with this before and would recognize the bloat data.. this is one of the bits of garbage - it repeats itself with slight variations (the unchanging bits are highlighted in green, rarely changing bits in orange).

    FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
    07 A9 4B 40 F8 FE 0B 41 28 57 21 3C 9B B6 D6 3A
    46 76 22 BA E5 FF 7F 3F 23 3F E2 3C EF 31 00 00
    

yeah i tried all that as well, unfortunately this happens on level files with multiple assets inside them and we have yet to be able to isolate the issue. Here some other things we tried

  • save the selected the mesh only (using “Save selected”) , and try to merge this scene into the other scene after a full Max restart

  • restart Max, create a Scene XREF of the faulty scene in your new blank scene, and to a Merge from the XREF dialog

*unloaded all plugins and resaved

Im talking with Autodesk now, but have as of now, not been able to get anywhere.

We have several plugins that are being used none of which should be storing extra data anywhere.

We too thought it would have something to do with the material editor but as you have discovered havent been able to effect it at all.

Thanks for checking all that stuff out, we are certainly narrowing done what it could be.

The ‘isolate selection’ persistents being after the garbage data still seems suspect… I just can’t fathom how they’d actually come into play there, however.


persistents.gather()
#(#Iso2ObjArr, #Iso2View, #Iso2HidFlags, #Iso2Hidden, #Iso2Camera, #Iso2Lations)

I was thinking the same thing, but none of those variables have much in them, i did however wonder if it stored the referenced geometry for them and was just duplicating the info each time it was saved\merged. Maybe if the geometry was deleted before it was hidden or some such…

yeah ! someone also send me a scene with the exact same problem and the scene do have those persistent global too :

(#Iso2ObjArr, #Iso2View, #Iso2HidFlags, #Iso2Hidden, #Iso2Camera, #Iso2Lations)

may be related in some way … does anyone know to witch script/plugin they belong to ?

Martin Dufour

They are part of the isolate selected menu in the tools set. In the standard max plugins.

Ho! It was part of Richard post, sorry :rolleyes:

since I could not find a solution, I’m working on some cleaner to make the export from the infected file easier :


/*

Title : Scene Cleaner v0.51
Author : Martin Dufour
Web : martroyx.890m.com
Email : martroyx@hotmail.com

know limitation :

-Don't export light animation
-Don't export skylight
-Don't export mentalraylight
-Some light property may not export correctly

*/

try (destroydialog Xcleaner) catch ()
(
if (heapsize<64000000L) do (heapsize=64000000L)
--//--
Global Xcleaner
local Xversion="Scene Cleaner v0.51"
local Xfolder=(getdir #scripts + "\\SceneFix") ; makedir Xfolder
local Xpath=undefined
local OriginalName=#()
local ModifiedName=#()
local MaterialList=#()
local WirecolorList=#()
local ClassList=#()
local ScriptedObject=#()
--//--
struct CleanUtil (
	--//--
	fn Write Fpath Fobj Ftype =
		(
		XWriter=(dotnetobject "System.IO.StreamWriter" (Fpath+".Xid") true)
		YWriter=(dotnetobject "System.IO.StreamWriter" (Fpath+".Xsm") true)
		--//--
		case Ftype of
			(
			1:(
				for f in 1 to (getNumFaces Fobj) do
					(
					XWriter.WriteLine(getFaceMatID Fobj f)
					YWriter.WriteLine(getFaceSmoothGroup Fobj f)
					)
				)
			--//--
			2:(
				for f in 1 to (polyop.getNumFaces Fobj) do
					(
					XWriter.WriteLine(polyop.getFaceMatID Fobj f)
					YWriter.WriteLine(polyop.getFaceSmoothGroup Fobj f)
					)
				)
			)
		--//--
		XWriter.close()
		YWriter.close()
		XWriter.dispose()
		YWriter.dispose()
		),
	--//--
	fn Read Fpath Fobj Ftype =
		(
		XReader=(dotnetobject "System.IO.StreamReader" (Fpath+".Xid"))
		YReader=(dotnetobject "System.IO.StreamReader" (Fpath+".Xsm"))
		--//--
		case Ftype of
			(
			1:(
				for f in 1 to (getNumFaces Fobj) where (not XReader.EndOfStream) do
					(
					setFaceMatID Fobj f (XReader.ReadLine() as integer)
					setFaceSmoothGroup Fobj f (YReader.ReadLine() as integer)
					)
				)
			--//--
			2:(
				for f in 1 to (polyop.getNumFaces Fobj) where (not XReader.EndOfStream) do
					(
					polyop.setFaceMatID Fobj f (XReader.ReadLine() as integer)
					polyop.setFaceSmoothGroup Fobj f (YReader.ReadLine() as integer)
					)
				)
			)
		--//--
		XReader.close()
		YReader.close()
		XReader.dispose()
		YReader.dispose()
		),
	--//--
	fn WriteLight Fpath Fobj =
		(
		XWriter=(dotnetobject "System.IO.StreamWriter" (Fpath+".XLg"))
		--//--
		NodeStr="#("
		--//--
		if Fobj.excludeList != undefined and Fobj.excludeList.count != 0 then 
			(
			for f in 1 to Fobj.excludeList.count do
				(
				NodeStr += ("$"+OriginalName[(Fobj.excludeList[f].name as integer)])
				if f != Fobj.excludeList.count then NodeStr += ","
				)
			)
		--//--
		NodeStr += ")"
		XWriter.WriteLine(NodeStr)
		--//--
		--//--
		NodeStr="#("
		--//--
		if Fobj.includeList != undefined and Fobj.includeList.count != 0 then 
			(
			for f in 1 to Fobj.includeList.count do
				(
				NodeStr += ("$"+OriginalName[(Fobj.includeList[f].name as integer)])
				if f != Fobj.includeList.count then NodeStr += ","
				)
			)
		--//--
		NodeStr += ")"
		XWriter.WriteLine(NodeStr)
		--//--
		XWriter.WriteLine(Fobj.inclExclType as string)
		--//--
		XWriter.close()
		XWriter.dispose()
		),
	--//--
	fn ReadLight Fpath Fobj =
		(
		XReader=(dotnetobject "System.IO.StreamReader" (Fpath+".XLg"))
		--//--
		x=(execute (XReader.ReadLine()))
		if x.count != 0 then (Fobj.excludeList = x)
		--//--
		 y=(execute (XReader.ReadLine()))
		 if y.count != 0 then (Fobj.includeList = y)
		--//--
		z=(execute (XReader.ReadLine()))
		Fobj.inclExclType = z
		--//--
		Fobj.wirecolor = (color 255 229 0)
		--//--
		XReader.close()
		XReader.dispose()
		),
	--//--
	fn ExportLight Fpath Fobj Fclass =
		(
		XWriter=(dotnetobject "System.IO.StreamWriter" (Fpath+".ms"))
		--//--
		XWriter.WriteLine("(")
		--//--
		if Fobj.target != undefined then
			(
			XWriter.WriteLine("NewLight = "+(Fclass as string)+" target:(targetObject())")
			XWriter.WriteLine("NewLight.target.transform = "+(Fobj.target.transform as string))
			XWriter.WriteLine("NewLight.target.name = \""+OriginalName[(Fobj.name as integer)]+".target"+"\"")
			)
		else
			(
			XWriter.WriteLine("NewLight = "+(Fclass as string)+"()")
			)
		--//--
		XWriter.WriteLine("NewLight.name = \""+(Fobj.name)+"\"")
		XWriter.WriteLine("NewLight.transform = "+(Fobj.transform as string))		
		--//--
		if (hasProperty Fobj "enabled") then XWriter.WriteLine("NewLight.enabled= "+(Fobj.enabled as string))
		if (hasProperty Fobj "castShadows") then XWriter.WriteLine("NewLight.castShadows= "+(Fobj.castShadows as string)) 
		if (hasProperty Fobj "rgb") then XWriter.WriteLine("NewLight.rgb= "+(Fobj.rgb as string))
		if (hasProperty Fobj "hsv") then XWriter.WriteLine("NewLight.hsv= "+(Fobj.hsv as string)) 
		if (hasProperty Fobj "hue") then XWriter.WriteLine("NewLight.hue= "+(Fobj.hue as string))
		if (hasProperty Fobj "saturation") then XWriter.WriteLine("NewLight.saturation= "+(Fobj.saturation as string)) 
		if (hasProperty Fobj "value") then XWriter.WriteLine("NewLight.value= "+(Fobj.value as string))
		if (hasProperty Fobj "multiplier") then XWriter.WriteLine("NewLight.multiplier= "+(Fobj.multiplier as string))
		if (hasProperty Fobj "contrast") then XWriter.WriteLine("NewLight.contrast= "+(Fobj.contrast as string))
		if (hasProperty Fobj "softenDiffuseEdge") then XWriter.WriteLine("NewLight.softenDiffuseEdge= "+(Fobj.softenDiffuseEdge as string))
		if (hasProperty Fobj "affectDiffuse") then XWriter.WriteLine("NewLight.affectDiffuse= "+(Fobj.affectDiffuse as string))
		if (hasProperty Fobj "affectSpecular") then XWriter.WriteLine("NewLight.affectSpecular= "+(Fobj.affectSpecular as string))
		if (hasProperty Fobj "ambientOnly") then XWriter.WriteLine("NewLight.ambientOnly= "+(Fobj.ambientOnly as string))
		if (hasProperty Fobj "nearAttenStart") then XWriter.WriteLine("NewLight.nearAttenStart= "+(Fobj.nearAttenStart as string))
		if (hasProperty Fobj "nearAttenEnd") then XWriter.WriteLine("NewLight.nearAttenEnd= "+(Fobj.nearAttenEnd as string))
		if (hasProperty Fobj "useNearAtten") then XWriter.WriteLine("NewLight.useNearAtten= "+(Fobj.useNearAtten as string)) 
		if (hasProperty Fobj "showNearAtten") then XWriter.WriteLine("NewLight.showNearAtten= "+(Fobj.showNearAtten as string)) 
		if (hasProperty Fobj "farAttenStart") then XWriter.WriteLine("NewLight.farAttenStart= "+(Fobj.farAttenStart as string)) 
		if (hasProperty Fobj "farAttenEnd") then XWriter.WriteLine("NewLight.farAttenEnd= "+(Fobj.farAttenEnd as string)) 
		if (hasProperty Fobj "useFarAtten") then XWriter.WriteLine("NewLight.useFarAtten= "+(Fobj.useFarAtten as string)) 
		if (hasProperty Fobj "showFarAtten") then XWriter.WriteLine("NewLight.showFarAtten= "+(Fobj.showFarAtten as string)) 
		if (hasProperty Fobj "attenDecay") then XWriter.WriteLine("NewLight.attenDecay= "+(Fobj.attenDecay as string))
		if (hasProperty Fobj "DecayRadius") then XWriter.WriteLine("NewLight.DecayRadius= "+(Fobj.DecayRadius as string))
		if (hasProperty Fobj "useGlobalShadowSettings") then XWriter.WriteLine("NewLight.useGlobalShadowSettings= "+(Fobj.useGlobalShadowSettings as string))
		--//--
		XWriter.WriteLine(")")
		XWriter.close()
		XWriter.dispose()
		),
	--//--
	fn ExportSceneState Fpath =
		(
		XWriter=(dotnetobject "System.IO.StreamWriter" Fpath)	
		--//--
		XWriter.WriteLine("(")
		--//--
		MidChild=#()
		MidChildName=#()
		ChildA=#()
		ChildB=#()
		--//--
		for f in objects where (isGroupHead f) and (f.parent != undefined) do 
			(
			ValidSubChild=true
			--//--
			for i in 1 to f.children.count do 
				(
				if (isGroupHead f.children[i]) then ValidSubChild=false
				)
			--//--
			if ValidSubChild==true then
				(
				NewChild="#("
				--//--
				for i in 1 to f.children.count do 
					(
					NewChild += ("$"+f.children[i].name)
					if i != f.children.count then (NewChild += ",") else (NewChild += ")")
					)
				--//--
				XWriter.WriteLine("group "+NewChild+" name:\""+(f.name)+"\"")
				)
			--//--
			)	
		--//--
		for f in objects where (isGroupHead f) and (f.parent != undefined) do 
			(
			ValidSubChild=true
			--//--
			for i in 1 to f.children.count do 
				(
				if (isGroupHead f.children[i]) then ValidSubChild=false
				)
			--//--
			if ValidSubChild==false then
				(
				NewChild="#("
				--//--
				for i in 1 to f.children.count do 
					(
					NewChild += ("$"+f.children[i].name)
					if i != f.children.count then (NewChild += ",") else (NewChild += ")")
					)
				--//--
				append MidChild ("group "+NewChild)
				append MidChildName f.name
				)
			--//--
			)	
		--//--
		if MidChild.count != 0 then
			(
			for f in 1 to MidChild.count do
				(
				Xfound=false
				--//--
				for i in 1 to MidChildName.count do
					(
					if (matchpattern MidChild[f] pattern:("*"+MidChildName[i]+"*") ignoreCase:true) then
						(
						append ChildB (MidChild[f]+" name:\""+MidChildName[f]+"\"")
						Xfound=true
						)
					)
				--//--
				if Xfound==false then (append ChildA (MidChild[f]+" name:\""+MidChildName[f]+"\""))
				)
			)
		--//--
		for f in ChildA do (XWriter.WriteLine(f))
		for f in ChildB do (XWriter.WriteLine(f))
		--//--
		for f in objects where (isGroupHead f) and (f.parent == undefined) do 
			(
			NewChild="#("
			--//--
			for i in 1 to f.children.count do 
				(
				NewChild += ("$"+f.children[i].name)
				if i != f.children.count then (NewChild += ",") else (NewChild += ")")
				)
			--//--
			XWriter.WriteLine("group "+NewChild+" name:\""+(f.name)+"\"")
			)	
		--//--
		XWriter.WriteLine(")")
		--//--
		XWriter.close()
		XWriter.dispose()
		)
	)
--//--
fn XRepair =
	(
	Xtemp=(Xfolder+"\\"+(getFilenameFile Xpath)) ; makedir Xtemp
	Xout=(Xfolder+"\\"+(getFilenameFile Xpath)+".3ds")
	XFinal=(Xfolder+"\\"+(getFilenameFile Xpath)+"_fixed.max")
	--//--
	resetMaxFile #noPrompt
	loadMaxFile Xpath useFileUnits:true quiet:true
	--//--
	CleanUtil.ExportSceneState (Xtemp+"\\SceneState.ms")
	--//--
	for f in objects where classof f != Targetobject do 
		(
		append OriginalName f.name
		)
	--//--
	for f in 1 to (OriginalName.count) do 
		(
		Xnode=(execute ("$"+"'"+OriginalName[f]+"'"))
		append ModifiedName (f as string)
		append MaterialList Xnode.material
		append WirecolorList Xnode.wirecolor
		Xnode.name=(f as string)
		)
	--//--
	Xcleaner.pb1.value=25
	sleep 0.1
	--//--
	for f in ModifiedName do 
		(
		Xnode=(execute ("$"+f))
		Xclass=classof Xnode
		XSuper=superclassof Xnode
		--//--
		case Xclass of
			(
			Editable_mesh:(
				Xfile=(Xtemp+"\\"+Xnode.name)		
				CleanUtil.Write Xfile Xnode 1
				)
			Editable_Poly:(
				Xfile=(Xtemp+"\\"+Xnode.name)	
				CleanUtil.Write Xfile Xnode 2
				)
			)
		--//--
		case XSuper of
			(
			light:(
				case Xclass of
					(
					Omnilight:(
						Xfile=(Xtemp+"\\"+Xnode.name)
						CleanUtil.WriteLight Xfile Xnode
						append ClassList light
						)
					targetSpot:(
						Xfile=(Xtemp+"\\"+Xnode.name)
						CleanUtil.WriteLight Xfile Xnode
						append ClassList light
						)
					Skylight:(append ClassList "Skip")
					default:(
						Xfile=(Xtemp+"\\"+Xnode.name)
						CleanUtil.ExportLight Xfile Xnode Xclass 
						CleanUtil.WriteLight Xfile Xnode
						append ClassList light
						append ScriptedObject (Xfile+".ms")
						)
					)
				)
			default:(append ClassList Xclass)
			)
		--//--
		)
	--//--
	exportfile Xout #noPrompt 
	resetMaxFile #noPrompt
	importfile Xout #noPrompt 
	deletefile Xout
	--//--
	Xcleaner.pb1.value=50
	sleep 0.1
	--//--
	for f in ScriptedObject do (filein f)
	--//--
	for f in ModifiedName do 
		(
		Xnode=(execute ("$"+f))
		--//--
		case ClassList[(f as integer)] of
			(
			Editable_mesh:(
				Xweld=vertexweld threshold:0.01
				addmodifier Xnode Xweld
				collapsestack Xnode
				Xfile=(Xtemp+"\\"+f)		
				CleanUtil.Read Xfile Xnode 1
				Xnode.material=MaterialList[(f as integer)]
				Xnode.wirecolor=WirecolorList[(f as integer)]
				Xnode.name=OriginalName[(f as integer)]
				)
			Editable_Poly:(
				Xweld=vertexweld threshold:0.01
				addmodifier Xnode Xweld
				collapsestack Xnode
				converttopoly Xnode
				Xfile=(Xtemp+"\\"+f)		
				CleanUtil.Read Xfile Xnode 2
				Xnode.material=MaterialList[(f as integer)]
				Xnode.wirecolor=WirecolorList[(f as integer)]
				Xnode.name=OriginalName[(f as integer)]
				)
			--targetobject:()
			Default:(
				if ClassList[(f as integer)]!="Skip" then
					(
					Xnode.name=OriginalName[(f as integer)]
					)
				)--end default
			)
		)
	--//--
	for f in 1 to OriginalName.count do 
		(
		Xnode=(execute ("$"+OriginalName[f]))
		--//--
		case ClassList[f] of
			(
			light:(
				Xfile=(Xtemp+"\\"+(f as string))	
				CleanUtil.ReadLight Xfile Xnode
				)
			)
		--//--
		)	
	--//--
	Xcleaner.pb1.value=75
	sleep 0.2
	--//--
	Xcleaner.pb1.value=100
	sleep 0.1
	Xcleaner.pb1.value=0
	--//--
	Xpath=undefined
	OriginalName=#()
	ModifiedName=#()
	MaterialList=#()
	WirecolorList=#()
	ClassList=#()
	--//--
	Xcleaner.edt1.text=""
	Xcleaner.btn2.enabled=false
	--//--
	filein (Xtemp+"\\SceneState.ms")
	--//--
	gc()
	--//--
	saveMaxFile XFinal quiet:true
	shellLaunch "explorer.exe" Xfolder
	)
--//--
rollout Xcleaner Xversion width:360 height:98
	(
	edittext edt1 " " pos:[0,8] width:248 height:24 readOnly:true
	button btn1 "Input" pos:[248,8] width:104 height:24
	button btn2 "Clean" pos:[8,65] width:344 height:24 enabled:false
	progressBar pb1 "ProgressBar" pos:[8,41] width:344 height:16 color:(color 255 255 0)
	--//--
	on btn1 pressed do 
		(
		Result=getOpenFileName caption:"Select a .Max file to repair." filename:(getdir #scene+"\\") types:"3dsmax (*.max) | *.max"
		--//--
		if (Result != undefined) and (isMaxFile Result) then
			(
			edt1.text=(filenameFromPath Result)
			Xpath=(Result)
			btn2.enabled=true
			)
		)
	--//--
	on btn2 pressed do 
		(
		Result=yesNoCancelBox "Do you want to proceed ?" title:"Please, save your work first !!!" beep:false
		if Result==#yes then XRepair()
		)
	--//--
	)
--//--
createdialog Xcleaner bgcolor:(color 160 160 160) fgcolor:(color 255 255 255) style:#(#style_sysmenu,#style_toolwindow)
)

I’ll still try to find a suitable solution to this wield bug too !

martin

this looks like its definitely on the right track. I am hearing that some modifiers will keep tags on geometry even after collapsing.

Been running the script… it seems to work fine on an empty scene but if i add geometry it will crash. Cleans up that scene great though, reduced the file size to 189 k

Page 1 / 2