Cleaner

88 votes
Date Updated: 
09/26/2017
Author Name: 
Andreas Meissner

This tool can help you to clean and speed up your scene. Hover with your cursor over the clean-buttons to see tooltips for further information.

 

Additional Info: 

Installation:

  • Drag and drop the file "install macro.ms" into your scene
  • You can create a toolbar button by using the macro under: Customize > Category: "# Scripts" > Cleaner

Tips:

  • If you look inside the folder .../Cleaner/clean/deactivated/... you can find further functions. To use them you need to move them into the folder  .../Cleaner/clean/...
  • Before cleaning dublicate objects, you should select and isolate these objects to check if they are really dublicates!
  • The "Texture Filtering" will speed up your rendering cause textures like leafes, flowers and ivys will be set to filtering:none, but this will change the look of your rendering, use with care!

 WARNING: I DONT GIVE ANY WARRANTY, USE AT OWN RISK, BETTER SAVE SCENE BEFORE USE

Version Requirement: 
tested in 2009, 2012 with Vray, 2015 with Vray
AttachmentSize
cleaner8.ms27.6 KB
cleaner_v25.zip25.13 KB

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
finalmethod's picture

excellent script!

I used to do notetrack clean manually with a code I found on the Area site, but I had no idea about Retimers, after using this script on problematic scene, it showed I had 88093 retimers! It took about 6 minutes for this script to clean the scene and now it works fast and saves under 1 minute vs 10 minute! Great job!

strangeneutrino's picture

it works but its a slow script

The below script is from
www.davetyner.com
BUT it needs a little refinement. Its quite slow. any ideas?

--cluster attach courtesy of Tyson Ibele at http://www.tysonibele.com/
function clusterAttach objArr =
(

local j = 1
local count = objArr.count

undo off
(
while objArr.count > 1 do
(
if classof objArr[j] != Editable_Poly then converttopoly objArr[j]

polyop.attach objArr[j] objArr[j+1]
deleteItem objArr (j+1)

j += 1

if (j + 1) > objArr.count then j = 1

)
)
return objArr[1]
)

--this is the start
(
for l = 1 to layermanager.count-1 do
(
lay = (layermanager.getLayer l).name
thesel = for o in objects where matchpattern o.layer.name pattern:lay collect o
if thesel.count > 1 then clusterattach thesel
)
if thesel == 1 then thesel.name = lay --if there is only one item left in the layer, rename it.
)

strangeneutrino's picture

attach all objects in each layer

Hello I didn't know where to post this, i need help with button number 4.
It should attach all objects in a layer, in every layer. any help would be great.

--rollout Panos_Scripts "Vis DWG cleaner"

try (destroyDialog ::rol_Panos_Scripts and ::IRoll) catch() --this removes duplicate dialogs

rollout rol_Panos_Scripts "Vis DWG cleaner"
(
group ""
(
button btn1 "Block Remove" width:100 height:18
button btn2 "Make Unique" width:100 height:18
button btn3 "Shape Remove" width:100 height:18
button btn4 "Attach Obj in lyrs" width:100 height:18
button btn5 "Random Wirecolor" width:100 height:18
button btn6 "Obj name from Lyr" width:100 height:18
button btn7 "Mtl from Lyr" width:100 height:18
button btn8 "AutoEdge" width:100 height:18
)

on btn1 pressed do
(
max select all
for obj in selection do obj.Transform.controller = prs()
b=#()
for o in objects do if classof o==LinkComposite then append b o
delete b
)

on btn3 pressed do
(
delete shapes
)

on btn4 pressed do
(

with redraw off
(
max modify mode
for obj in selection do obj.layer.select true
for o in selection do attach selection
for o in selection do hide selection
)
)

on btn6 pressed do
(
fn renameLayerNodes considerZeroLayer:on =
(
e = if considerZeroLayer then 0 else 1
local getLay = LayerManager.getLayer, layer
for i = e to layerManager.count-1 where ((layer = getLay i).nodes &nodes ; nodes).count > 0 do
(
for n in nodes do n.name = uniquename layer.name
)
)
renameLayerNodes()
) -- dont forget to close

on btn7 pressed do

(

global lmRoll
if lmRoll != undefined do try (destroyDialog lmRoll) catch()
rollout lmRoll " Material from Layer"
(
local matLibPath = "C:/Windows/Temp/"
fn filterGeo obj = iskindof obj geometryclass and not isKindOf obj TargetObject
fn defMtlListArr =
(
local RendArr = rendererClass.classes, txt = "", resultArr = #()
if ((for o in RendArr where matchPattern (o as string) pattern:"*V_Ray*" collect o).count > 0) do ( append txt "v")
if ((for o in RendArr where matchPattern (o as string) pattern:"*finalRender*" collect o).count > 0) do ( append txt "f" )
case txt of (
("vf"): (#("• Standard", "• Arch&Design", "• VRayMtl", "• fR-Advanced", "• fR-Architectural"))
("v"): (#("• Standard", "• Arch&Design", "• VRayMtl"))
("f"): (#("• Standard", "• Arch&Design", "• fR-Advanced", "• fR-Architectural"))
default: (#("• Standard", "• Arch&Design"))
)
)
fn randWcolor clr: bw: toner: cp: =
(
case of (
(clr == true): (random (color 0 0 0) (color 255 255 255))
(bw == true): (rc = (random 0 255) ; (color rc rc rc))
(toner == true): (clr = cp ; clr.s = (random 50 255) ; clr.v = (random 50 255) ; clr)
)
)
edittext etxt_browseDir "*.mat directory:" pos:[0,0] width:0 height:0 readonly:true text:(pathConfig.stripPathToLeaf matLibPath) -- these are to small to see
button btn_browseDir "B" pos:[0,0] width:0 height:0 -- these are to small to see
edittext etxt_matLibName "*.mat name: " pos:[0,0] width:0 height:0 text:"tempMatLib" -- these are too small to see
checkbutton cbtn_UseLWClr "L" pos:[0,0] width:0 height:0 highlightColor:[28,28,28] modal:true enabled:true tooltip:"fuck it" -- these are too small to see
label lbl_ddl_mtlType " material type:" pos:[0,59] width:0 height:0 -- these are too small to see
dropdownlist ddl_mtlType "" pos:[2,2] width:100 items:(defMtlListArr()) tooltip:"pick materilal"
button btn_clm "Material from layer" pos:[2,20] width:100 height:18 tooltip:"do the job!"

local checkArr = #(cbtn_UseLWClr)

fn layerMaterial matpath: mtlTypeCtrl: checkCtrls: cpCtrl: =
(
saveMaterialLibrary matpath
matLib = loadTempMaterialLibrary matpath
idx = mtlTypeCtrl.selection
mtlType = mtlTypeCtrl.items[idx]
for m = 0 to layerManager.count-1 do
(
lmLayer = layerManager.getLayer m
layerName = lmLayer.name
layerColor = case of (
(checkCtrls[1].checked == true): (lmLayer.wirecolor)
default:(color 128 128 128)
)
layerMtl = case mtlType of (
("• Standard"): Standardmaterial name:layerName Diffuse:layerColor
("• Arch&Design"): Arch___Design__mi name:layerName diff_color:layerColor
("• VRayMtl"): VRayMtl name:layerName Diffuse:layerColor
("• fR-Advanced"): fR_Advanced name:layerName diffuseColor:layerColor
("• fR-Architectural"): fR_Architectural name:layerName diffuseColor:layerColor
)
append matLib layerMtl
layer = ILayerManager.getLayerObject m
for n in (refs.dependents layer) where filterGeo n do n.material = matLib[matLib.count]
)
saveTempMaterialLibrary matLib matpath
)
on btn_browseDir pressed do
(
matLibPath = getSavePath()
etxt_browseDir.text = pathConfig.stripPathToLeaf matLibPath
)
on btn_rndLWC pressed do
(
for m = 0 to layerManager.count-1 do
(
lmLayer = layerManager.getLayer m
checkstate = (for c in 2 to checkArr.count where checkArr[c].checked == true collect checkArr[c].checked).count
if checkstate == 1 do lmLayer.wirecolor = randWcolor clr:(cbtn_UseClr.checked) bw:(cbtn_UseBW.checked) toner:(cbtn_UseTone.checked) cp:(cp_Tone.color)
)
)
on cbtn_UseLWClr changed state do (if state == on do for c in checkArr where c != cbtn_UseLWClr do (c.checked = false) ; cp_Tone.enabled = false)
on cbtn_UseClr changed state do (if state == on do for c in checkArr where c != cbtn_UseClr do (c.checked = false) ; cp_Tone.enabled = false)
on cbtn_UseBW changed state do (if state == on do for c in checkArr where c != cbtn_UseBW do (c.checked = false) ; cp_Tone.enabled = false)
on cbtn_UseTone changed state do (if state == on then (for c in checkArr where c != cbtn_UseTone do (c.checked = false) ; cp_Tone.enabled = true) else cp_Tone.enabled = false)
on btn_clm pressed do
(
matPath = matLibPath + "\\" + etxt_matLibName.text + ".mat"
layerMaterial matpath:matPath mtlTypeCtrl:ddl_mtlType checkCtrls:checkArr cpCtrl:cp_Tone
)
)
createdialog lmRoll 100 35 1167 547 style:#(#style_titlebar, #style_sysmenu, #style_toolwindow) bgcolor:[115,115,115] fgcolor:[115,115,115]
)
on btn5 pressed do
(
max select all
(
for i in selection do
(
i.wirecolor = (color (random 0 255) (random 0 255) (random 0 255))
)

)

)
on btn2 pressed do
(
groups = for o in helpers where isGroupHead o collect o
while groups.count > 0 do
( ungroup groups[groups.count] ; groups.count = groups.count-1 )
max select all
for obj in $ do
(
if (InstanceMgr.CanMakeObjectsUnique obj == true) then
(
InstanceMgr.MakeObjectsUnique obj #individual
)
)
)

on btn8 pressed do
(

disablesceneredraw()
original_selection = getcurrentselection()
count = selection.count
max modify mode

-- Running Autoedge on grouped objects breaks Max very badly and unrecoverably on some systems.
-- (Something to do with UI enables code). This loop traps for it.

for i in selection where isgroupmember i == true do
(
messagebox "At least one selected object is a group member.\nObjects must be ungrouped before being AutoEdge-d.\nPress OK to process non-grouped objects."
new_selection = #()
for j in selection where (isgroupmember j == false) and (isgrouphead j == false) do append new_selection j
count = new_selection.count
original_selection = new_selection
select new_selection
exit
)

for i in selection where classof i.baseobject == trimeshgeometry do -- Takes care of Acad 'Mesh' objects
(
AddModifier i (Turn_to_Mesh())
convertToMesh i
)

max modify mode

for i in 1 to count where ((classof selection[i] == Editable_Mesh) and (isgroupmember selection[i] == false)) do try
(
select selection[i]
modpanel.setCurrentObject selection[1].baseobject
subobjectLevel = 2
max select all
meshops.autoedge $
subobjectLevel = 0
select original_selection
)catch
(
enablesceneredraw()
redrawviews()
)
enablesceneredraw()
redrawviews()

)
)

createDialog rol_Panos_Scripts height:215 width:120 pos:[150,200]
--createDialog Panos_Scripts 500 100

thhm's picture

thnks!

great script! really useful.

Fransvh's picture

disable normal bump and raytrace reflections.

Hi, I love your script, using it a lot.

Would be nice it there where functions to disable the normal bump and raytrace reflection mapping. In my workflow these are the cause of many crashes.

er.cchadw.ck@gmail.com's picture

Thank you!

Thank you for this great script!

My scene had 51 million note tracks. Probably from merging my client's V-Ray assets into mine.

I went from 810mb per max file down to 5mb!

3D Game Artist - http://ericchadwick.com
Admin for the Polycount wiki - http://wiki.polycount.com

real08121985's picture

I checked the download link,

I checked the download link, it works for me.

stahuu's picture

Help!!!!!!

why i can't download????

gLab's picture

@ vitalquaD

It seems that Max2014 does remove notetracks automatically when opening files.
So when you open cleaner they are gone already.

I did a quick test with an old Max2012 scene (242MB before, 92 MB after cleaning)
Opening it in Max2014 and resaving it reduces file size to 92MB (no "compress on save" in both versions)

juumax's picture

Sorry its been a while but I

Sorry its been a while but I am having the same issue with brazil again in max 2014.

Thanks

https://dl.dropboxusercontent.com/u/16347771/brazil_test.max

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.