[Closed] PLEASE HELP!Detach by material ID without opening window for options
Hi
I am trying to detach materials by id like this script
http://www.scriptspot.com/3ds-max/scripts/detach-by-material-id
but i don’t want a rollout window with options
I just want it to work with just running the script with no open dialogs
because I want to batch multiple files and i can’t do it with detach-by-material-id script because you have to select options in a windows before you can run it
I want these options below as default so there is no need to select options in a window
naming should be
material name
it should
Propagate Materials
delete Original
optional
Random wire colors
I hope this makes sense, let me know if i need to explain better
I hope that you have tested the script and with give settings it works for you.
Here is the same script that works with no UI.
/*
Detach by Material ID
Version: 2
by Jefferson Lim
Terabye Inc./ Shirogumi Inc.
[features]
Detach Polygons based on its Material ID
- works on a selection of objects
- Options to name detached objects
- material propagation
- this will assign a corresponding material by id to the detached object
[usage]
1. select any number of objects
2. set the desired paramteters
3. optional: if you know the maximun number of ids the object has
set the Max IDs to help speed up detachment.
4. press detach
[Internal Operations]
Procedure:
- object[s] is/are copied
- then collapsed to an editable poly
- faces are finally detached by material ID
Naming:
- "Numbered"
- will creae numbered names
- e.g. 0,1,2,3
- preferable to use with the Prefix option checked
- "Bitmap Name"
- if not diffuse bitmap found, it will use the material name
- if no material applied, it will use the object's name
- "Material Name"
- if no material applied, it will use the object's name
- "Object Name"
- will create a unique name based on the object's name
*/
-- try(destroyDialog detachByID)catch()
-- rollout detachByID "Detach by ID" width:140 height:250
(
local name_type = 2
local the_polyobj
local ran_color = true
local the_name
local the_mat_arr = #()
local id_list = #()
-- label lbl_maxids "Max IDs:" pos:[10,190] width:55 height:15
-- GroupBox grp_naming "Naming: " pos:[5,0] width:130 height:125
-- GroupBox grp_prefix "" pos:[5,75] width:130 height:50
-- GroupBox grp_ops "Options:" pos:[5,125] width:130 height:90
-- radiobuttons rb_naming "" pos:[10,15] width:107 height:64 enabled:true labels:#("Object Name", "Material Name", "Bitmap Name", "Numbered") default:2 columns:1
-- checkbox chk_prefix "Use Prefix" pos:[10,85] width:70 height:15 checked:false
-- edittext edt_prefix "" pos:[5,100] width:125
-- checkbox chk_prop "Propagate Materials" pos:[10,140] width:120 height:15 checked:true
-- checkbox btn_del "Delete Original" pos:[10,155] width:120 height:15 checked:true
-- checkbox chk_rancolor "Random Wire Colors" pos:[10,170] width:120 height:15 checked:true
-- spinner spn_maxids "" pos:[70,190] width:60 height:16 range:[0,99,99] type:#integer scale:0.05
local maxIds = 99
-- button detach_bot "DETACH" pos:[5,220] width:130 height:25
fn getMaterialIDs obj =
(
id_arr = #()
-- for i in 1 to spn_maxids.value do
for i in 1 to maxIds do
(
obj.selectByMaterial i
the_faces = getFaceSelection obj
if (the_faces as array).count != 0 do
(
append id_arr i
)
)
id_arr
)
fn getMatTextureName mat =
(
local the_map_name = the_polyobj.name
try
(
bmp = mat.diffusemap
if classof bmp == Bitmaptexture then
(
the_mapfile = mat.diffuseMap.bitmap.filename
the_map_name = getFileNameFile the_mapfile
)
else
(
the_map_name = mat.name
)
)
catch()
the_map_name
)
-- on rb_naming changed val do
-- (
-- name_type = val
-- the_name = edt_prefix.text
-- )
-- on edt_prefix entered txt do
-- (
-- the_name = txt
-- )
-- on chk_rancolor changed val do
-- (
-- ran_color = val
-- )
-- on detach_bot pressed do
-- (
undo "Detach by ID" on
(
the_sel = selection as array
if the_sel.count != 0 do
(
for obj in the_sel where \
superclassof obj == GeometryClass and \
obj.material != undefined do
(
try(convertToPoly obj)catch(exit; print "DetacByID: Error Occured on Object Conversion")
the_orig = obj
the_polyobj = copy the_orig
the_mat = obj.material
id_count = the_mat.numSubs
id_list = getMaterialIDs the_polyobj
-- start detaching
for i in id_list do
(
the_polyobj.selectByMaterial i
the_faces = getFaceSelection the_polyobj
case name_type of
(
1: the_name = uniquename (the_polyobj.name)
2: the_name = uniquename (the_mat[i].name)
3: the_name = uniquename (getMatTextureName the_mat[i])
4: the_name = uniquename the_name
)
-- if chk_prefix.checked do the_name = edt_prefix.text + the_name
polyOp.detachFaces the_polyobj the_faces asnode:true name:the_name
theDetachedObj = (getnodebyname the_name)
if isValidNode theDetachedObj do
(
/* if chk_prop.checked do */theDetachedObj.material = the_mat[i]
if ran_color do theDetachedObj.wirecolor = random black white
)
)-- end detach loop
/* if btn_del.checked do */delete the_orig
)-- end object check loop
)-- end selection loop
)-- end Undo
-- )-- end button press
)
-- createDialog detachByID style:#(#style_sysmenu,#style_toolwindow)
/*
[2.0]
2008-12-09
- added material propagation
- faster detachment procedure
- old script was looping through every face to look for IDs
- the new procedure will only search thru the <Max IDs> set by the user
- cleaned up code
- reworked UI
[1.0]
2005-05-24
- initial public release
[to do]
- make a more intuitive naming option
- save settings to ini file
- add progress bar
[notes]
- script request by Eye of Hawk (CGTalk)
- "Propagate Materials" feature request by titane357 (scriptspot)
*/
Hello
I am trying to use it in this script so i can batch a whole bunch of files out
thePath = getSavePath()--get a path dialog to specify the path
if thePath != undefined do--if the user did not cancel
(
theFiles = getFiles (thePath+"\\*.max") --collect all max files in the dir.
for f in theFiles do-- go through all of them
(
loadMaxFile f--load the next file
-----------------------------------------------------------
-- MAKE SOME SCRIPTED CHANGES TO THE SCENE HERE...
-----------------------------------------------------------
saveMaxFile f --save the file back to disk
)--end f loop
resetMaxFile #noPrompt --at the end, you can reset
)--end if
I try paste your code in the
-----------------------------------------------------------
-- MAKE SOME SCRIPTED CHANGES TO THE SCENE HERE...
-----------------------------------------------------------
but i get a
– Compile error: No outer local variable references permitted here: maxIds
– In line: for i in 1 to maxIds d
Try with this:
(
local name_type = 2
local the_polyobj
local ran_color = true
local the_name
local the_mat_arr = #()
local id_list = #()
local maxIds = 99
fn getMaterialIDs obj =
(
id_arr = #()
-- for i in 1 to spn_maxids.value do
for i in 1 to maxIds do
(
obj.selectByMaterial i
the_faces = getFaceSelection obj
if (the_faces as array).count != 0 do
(
append id_arr i
)
)
id_arr
)
fn getMatTextureName mat =
(
local the_map_name = the_polyobj.name
try
(
bmp = mat.diffusemap
if classof bmp == Bitmaptexture then
(
the_mapfile = mat.diffuseMap.bitmap.filename
the_map_name = getFileNameFile the_mapfile
)
else
(
the_map_name = mat.name
)
)
catch()
the_map_name
)
thePath = getSavePath()--get a path dialog to specify the path
if thePath != undefined do--if the user did not cancel
(
theFiles = getFiles (thePath+"\\*.max") --collect all max files in the dir.
for f in theFiles do-- go through all of them
(
resetMaxFile #noPrompt
loadMaxFile f--load the next file
-----------------------------------------------------------
-- MAKE SOME SCRIPTED CHANGES TO THE SCENE HERE...
undo "Detach by ID" on
(
the_sel = selection as array
if the_sel.count != 0 do
(
for obj in the_sel where \
superclassof obj == GeometryClass and \
obj.material != undefined do
(
try(convertToPoly obj)catch(exit; print "DetacByID: Error Occured on Object Conversion")
the_orig = obj
the_polyobj = copy the_orig
the_mat = obj.material
id_count = the_mat.numSubs
id_list = getMaterialIDs the_polyobj
-- start detaching
for i in id_list do
(
the_polyobj.selectByMaterial i
the_faces = getFaceSelection the_polyobj
case name_type of
(
1: the_name = uniquename (the_polyobj.name)
2: the_name = uniquename (the_mat[i].name)
3: the_name = uniquename (getMatTextureName the_mat[i])
4: the_name = uniquename the_name
)
-- if chk_prefix.checked do the_name = edt_prefix.text + the_name
polyOp.detachFaces the_polyobj the_faces asnode:true name:the_name
theDetachedObj = (getnodebyname the_name)
if isValidNode theDetachedObj do
(
/* if chk_prop.checked do */theDetachedObj.material = the_mat[i]
if ran_color do theDetachedObj.wirecolor = random black white
)
)-- end detach loop
/* if btn_del.checked do */delete the_orig
)-- end object check loop
)-- end selection loop
)
-----------------------------------------------------------
saveMaxFile f --save the file back to disk
)--end f loop
resetMaxFile #noPrompt --at the end, you can reset
)--end if
)
I still get a
– Compile error: No outer local variable references permitted here: maxIds
– In line: for i in 1 to maxIds d
This is cleaner version:
(
MeshopDetachFaces = meshop.detachFaces
mapped fn SplitMeshByMaterialID Obj =
(
if
isvalidnode Obj and
(Mat = Obj.material) != undefined and
classof Mat == Multimaterial and
convertToMesh Obj != undefined
do
(
Mesh = Obj.mesh
FaceCount = Mesh.numfaces
IDs = #()
for i = 1 to FaceCount do appendifunique IDs (getFaceMatID Mesh i)
for ID in IDs do
(
Faces = for i = 1 to FaceCount where getFaceMatID Mesh i == ID collect i
NewObj = Editable_mesh()
NewObj.transform = Obj.transform
NewObj.mesh = MeshopDetachFaces Obj Faces delete:true asMesh:true
NewObj.material = Mat[ID]
NewObj.name = Mat[ID].name
NewObj.wirecolor = random black white
converttopoly NewObj
)
delete Obj
)
)
if (Dir = getSavePath()) != undefined do
(
disablesceneredraw()
for f in getFiles (Dir+"\\*.max") do
(
loadmaxfile f quiet:true
undo off
(
SplitMeshByMaterialID (geometry as array)
)
savemaxfile f
)
enablesceneredraw()
resetmaxfile #noprompt
messagebox "Done."
)
)
Thank you guys for this amazing script.
I have been for a long time looking for it.
I wanted to detach by id but instead of converting it into an editablepoly to do it into an editablemesh.
I just changed the “converttopoly NewObj” into “converttomesh NewObj”.
Anyway I am quite new on scripting and I have been trying to modify this script so it would work on a selected object on an opened 3dsmax file.
Could someone help me out here?
Thank you everyone!