Author Topic: Useful scripts for 3ds Max  (Read 10974 times)

0 Members and 1 Guest are viewing this topic.

Offline zookeeper

  • *knock knock* Who's there? Poe. Poe who?
  • 210
  • Posts: 1,100
Re: Useful scripts for 3ds Max
How about this:
Right. Kinda obvious now that I think of it. :banghead:

 

Offline zookeeper

  • *knock knock* Who's there? Poe. Poe who?
  • 210
  • Posts: 1,100
Re: Useful scripts for 3ds Max
Added two more little scripts which might be of use, and also (finally) put them all into [ code ] blocks instead of attachments so they don't get lost.

 

Offline Scooby_Doo

  • 212
  • Posts: 7,684
Re: Useful scripts for 3ds Max
Here's a few useful ones:


Used to create properties for subobjects (if it's a turret with uvec, fvec it'll copy the values to the destroyed version)
Code: [Select]
macroScript GiveThemProperties category:"Freespace"
(
changeCount = 0

uVecValue = ""
fVecValue = ""

isThisATurret = false
turretDestroyedLocation = -1

-- Go through all the selected objects
for i = 1 to selection.count do
(
test = ""
dummyCount = 0

-- Let's see what we're actually got
if (findString selection[i].name "helper" != undefined) then
continue -- helper object
else if (findString selection[i].name "thruster" != undefined) then
continue -- thruster dummy points
else if (findString selection[i].name "bank" != undefined) then
continue -- missile, gun and glow banks
else if (findString selection[i].name "eye" != undefined) then
continue -- eyepoint
else if (findString selection[i].name "destroyed" != undefined) then
(
-- Possibly a destroyed turret (could be another subsystem)
turretDestroyedLocation = i
continue ;
)
else if (findString selection[i].name "-" != undefined) then
continue -- turret arms, destroyed subsystems
else if (findString selection[i].name "firepoint" != undefined) then
continue -- firepoints
else if (findString selection[i].name "turret" != undefined) then
(
isThisATurret = true
)

-- Retrieve the existing properties, we need to save the uvec,fvec
objectProperties = getUserPropBuffer selection[i]
listofProp = filterString objectProperties "\n\r"

foundUVec = false

-- Save the uvec if theres any
for j = 1 to listofProp.count do
(
if (findstring listofProp[j] "$uvec" != undefined) then
(
foundUVec = true
uVecValue = listofProp[j]
break
)
)

-- Save the fvec if there's any (there should be)
for j = 1 to listofProp.count do
(
if (findstring listofProp[j] "$fvec" != undefined) then
(
fVecValue = listofProp[j]
break
)
)

-- Paste the new data back to the object's property
test = "$special=subsystem\r\n$fov=180\r\n$name=" + selection[i].name

if (foundUVec) then
(
test = test + "\r\n" + uVecValue + "\r\n" + fVecValue
)
changeCount = changeCount + 1

setUserPropBuffer selection[i] test
)

--If this was a turret and had a destroyed version we need to copy the uvec and fvec if they exist
if (isThisATurret) then
(
if (turretDestroyedLocation != -1) then
(
test = uVecValue + "\r\n" + fVecValue
setUserPropBuffer selection[turretDestroyedLocation] test
)
)

if (changeCount == 0) then
(
MessageBox "Nothing useable was selected"
)
)


Remove ALL properties from anything
Code: [Select]
macroScript RemoveProperties category:"Freespace"
(

for i = 1 to selection.count do
(
setUserPropBuffer selection[i] ""
)
)


Numbering turrets (this also renames the turret0X-arm).  Just group select the turet, arm (if any), firepoints, firepoint, helper and destroyed (if exists) click the Renumber Turret and repeat for each additional turret, it'll convert their names to a numbered "turret0X" correctly.  It does not create uvecs or fvecs, use the other scripts for that. 
Code: [Select]
macroScript TurretNumber category:"Freespace"
(
turretNumber = 1

rollout rename_rollout "Turret Renumbering"
(
button ResetCount "Reset Turret Count"
button RenameBase "Renumber Turret"

on ResetCount pressed do
(
turretNumber = 1
)

on RenameBase pressed do
(
print "hello"

changeCount = 0

if (turretNumber < 10) then
newName = "turret0" + turretNumber as String
else
newName = "turret" + turretNumber as String

for loop = 1 to selection.Count do
(
oldname = selection[loop].name
if (findString oldName "turret" != undefined) then
(
if (findString oldName "-arm" != undefined) then
(
selection[loop].Name = newName + "-arm"
changeCount = changeCount + 1
)
else if (findString oldName "-destroyed" != undefined) then
(
selection[loop].Name = newName + "-destroyed"
changeCount = ChangeCount + 1
)
else
(
selection[loop].Name = newName
changeCount = changeCount + 1
)
)
)

if (changeCount == 0) then
(
MessageBox "Nothing useable was selected"
)
else
(
turretNumber = turretNumber + 1
)
)

)--end rollout

createDialog rename_rollout

)


Used to renumber engine thrusters objects (thruster01, thruster02, thruster03.....)  Note this does not create the properties (use the first script above)
Code: [Select]
macroScript EngineNumber category:"Freespace"
(
engineNumber = 1

rollout rename_rollout "Engine Renumbering"
(
button ResetCount "Reset Engine Count"
button RenameBase "Renumber Engine"

on ResetCount pressed do
(
engineNumber = 1
)

on RenameBase pressed do
(
changeCount = 0

if (engineNumber < 10) then
newName = "engine0" + engineNumber as String
else
newName = "engine" + engineNumber as String

for loop = 1 to selection.Count do
(
oldname = selection[loop].name
if (findString oldName "engine" != undefined) then
(
if (findString oldName "-destroyed" == undefined) then
(
selection[loop].Name = newName
changeCount = changeCount + 1
)
else
(
selection[loop].Name = newName + "-destroyed"
changeCount = changeCount + 1
)
)
)

if (changeCount == 0) then
(
MessageBox "Nothing useable was selected"
)
else
(
engineNumber = engineNumber + 1
)
)

)--end rollout

createDialog rename_rollout

)


Same as thrusters but for intakes (if you do have them)
Code: [Select]
macroScript IntakeNumber category:"Freespace"
(
intakeNumber = 1

rollout rename_rollout "Intake Renumbering"
(
button ResetCount "Reset Intake Count"
button RenameBase "Renumber Intake"

on ResetCount pressed do
(
intakeNumber = 1
)

on RenameBase pressed do
(
changeCount = 0

if (intakeNumber < 10) then
newName = "intake0" + intakeNumber as String
else
newName = "intake" + intakeNumber as String

for loop = 1 to selection.Count do
(
oldname = selection[loop].name
if (findString oldName "intake" != undefined) then
(
if (findString oldName "-destroyed" == undefined) then
(
selection[loop].Name = newName
changeCount = changeCount + 1
)
else
(
selection[loop].Name = newName + "-destroyed"
changeCount = changeCount + 1
)
)
)

if (changeCount == 0) then
(
MessageBox "Nothing useable was selected"
)
else
(
intakeNumber = intakeNumber + 1
)
)

)--end rollout

createDialog rename_rollout

)

That's cool and ....disturbing at the same time o_o  - Vasudan Admiral

"Don't play games with me. You just killed someone I like, that is not a safe place to stand. I'm the Doctor. And you're in the biggest library in the universe. Look me up."

"Quick everyone out of the universe now!"

 

Offline Scooby_Doo

  • 212
  • Posts: 7,684
Re: Useful scripts for 3ds Max
4 years later!!  :eek2:

Oh you've added a box, modified it and then copied it many times (be it copy or instances doesn't matter).  Then you realize you probably should have named them better, whoops!  Well this script asks for a name then applies it plus padded number to it... AKA Box becomes Grip01, Grip02, Grip03.... Grip10, Grip11...etc
Rename script:
Code: [Select]
macroScript RenameObjects category:"Fast Utils"
(
rollout renameObjs_rollout "Renaming Objects" width:162 height:72
(
label lbl_Name "New Name"
edittext edit_NewName ""
button btnStart "Start"

on btnStart pressed  do
(
if (edit_NewName.text == "") then
(
MessageBox "You need to give it a name first"
return 0
)

if (selection.Count == 0) then
(
MessageBox "You need to select at least one entry first"
return 0
)

for loop = 1 to selection.Count do
(
-- This keeps the number formatting nice and neat
prefex = ""

upper = ceil ((selection.Count as float)/ (10 as float)) * 10
lower = ceil ((loop as float)/ (10 as float)) * 10

while (lower < upper) do
(
prefex = prefex + "0"
lower = lower * 10
)

selection[loop].Name = edit_NewName.Text + prefex + loop as String
)

destroydialog renameObjs_rollout
)
)

createDialog renameObjs_rollout

)

Next script, let's say you have all those boxes now named properly, but let's say you want to change something on them, thats when you realize you made a copy and not a reference/instance, oh  :mad:. Well this fixes that (with some caveats).  Simply select the parent object, then select all of the children and it will replace each of the children with a copy/instance/reference of the parent.  The selected object is then deleted. It will also orientate and scale them correctly, HOWEVER, if you have rotated and/or scaled the object to be replaced then did a xreset, the scale/angle info was lost and it'll simply put a new object in the (0,0,0) orientation and 100% scale.
Code: [Select]
macroScript ReplaceWithClones category:"Fast Utils"
(
rollout ReplaceObjs_rollout "Replace objects with clones" width:162 height:227
(
 
button btnSelectParent "Select as Parent" pos:[34,7] width:93 height:21
 
button btnProcessInstances "Replace Selected" pos:[49,191] width:56 height:21
edittext edtParentName "" pos:[4,36] width:149 height:25 enabled:false
radiobuttons rdo1 "Replace By..." pos:[10,69] width:73 height:62 labels:#("Copy", "Instance", "Reference") default:2
checkbox chk1 "Delete original" pos:[10,150] width:96 height:20 checked:true


on btnSelectParent pressed do
(
if (selection.count != 1) then
(
MessageBox "Missing object for parent"
return 0
)

parent = selection[1]
edtParentName.text = selection[1].Name
)
on btnProcessInstances pressed do
(
if (edtParentName.Text == "") then
(
MessageBox "First need to select a parent object to copy"
return 0
)

for loop = 1 to selection.Count do
(
case rdo1.state of
(
1:
child = copy parent
2:
child = instance parent
3:
child = reference parent
)

child.pos = selection[loop].pos
child.rotation = selection[loop].rotation
child.scale = selection[loop].scale

)

if (chk1.Checked) then
(
for loop = 1 to selection.Count do
(
delete selection[1]
)
)
)
)
createDialog ReplaceObjs_rollout

)

And last....
This isn't really useful for POF as exporting to DAE and PCS can handle it well, but it seems to clear up problems exporting to Unreal 4.  What this script does is save your selected objects first, make copies of those objects, collapse just those, stuff those into a layer "ExportLayer", select all those and let's you export however necessary.  Finally there is a cleanup Finish, which deletes those objects, removes the layer and then reselects the objects you had originally selected, as if nothing had happened.  It's not foolproof and might be buggy, thats why I had the collapsed meshes put into a unique layer, so if things go bad you can simply delete everything from that layer.  Oh and ya don't have a "ExportLayer" in your project.  It can take sometime to actually process, depending on how complicated your model is.  It takes about a half minute to export a 300K model with some 130+ objects.  Couple other notes: if you see a bug in your model after prepping, don't fix it there, it'll just get deleted, nuke that export (hit "finish") fix the problem and try again.  Two: Groups seem to cause some problems, they will appear as big boxes that are empty, just delete them for now, the actual meshes will still be there (they're no longer part of the group upon resetting).
Code: [Select]
macroScript PrepForExport category:"Fast Utils"
(
mySavedArray = #()
rollout ExportPrep_rollout "Prep for Export" width:162 height:68
(
 
button btnSelect "Select object(s)" pos:[34,7] width:93 height:21
 
button btnFinish "Finished exporting" pos:[34,40] width:93 height:21

on btnSelect pressed do
(
if (selection.Count == 0) then
(
MessageBox "You need to select at least one entry first"
return 0
)


myNewArray = #()

layer = LayerManager.newLayer ()
layer.setName "ExportLayer"

for loop = 1 to selection.count do
(
entry = copy selection[loop]
print entry.Name

collapseStack entry
ResetXForm entry
collapseStack entry
layer.addnode entry

append myNewArray entry

windows.processpostedmessages ()

)

for obj in selection do
(
append mySavedArray obj
windows.processpostedmessages ()
)
max select none
select myNewArray

result = IsolateSelection.EnterIsolateSelectionMode()

MessageBox "You may now export your model"
)
on btnFinish pressed do
(
max select none

layer = LayerManager.GetLayerFromName "ExportLayer"

if (layer == undefined) then
(
return 0
)

layer.nodes &temp

select temp
delete selection

LayerManager.DeleteLayerByName "ExportLayer"

result = IsolateSelection.ExitIsolateSelectionMode ()
select mySavedArray
)
)
createDialog ExportPrep_rollout

)

Whew!
« Last Edit: March 29, 2015, 04:54:23 am by Scooby_Doo »
That's cool and ....disturbing at the same time o_o  - Vasudan Admiral

"Don't play games with me. You just killed someone I like, that is not a safe place to stand. I'm the Doctor. And you're in the biggest library in the universe. Look me up."

"Quick everyone out of the universe now!"